Python ile Basit Bir Web Uygulaması Güvenlik Tarayıcısı Oluşturma: Yeni Başlayan Kılavuz
Bu makalede, web uygulamalarındaki yaygın güvenlik açıklarını belirlemede yardımcı olabilecek temel bir güvenlik aracı oluşturmayı öğreneceksiniz.
Burada iki hedefim var. Birincisi, web sitelerinizin genel güvenlik duruşunu geliştirmeye yardımcı olabilecek araçlar geliştirme becerileri ile güçlendirmektir. İkincisi, bazı Python programlamaları uygulamanıza yardımcı olmaktır.
Bu kılavuzda, XSS, SQL enjeksiyonu ve hassas PII (kişisel olarak tanımlanabilir bilgiler) tespit edebilen Python tabanlı bir güvenlik tarayıcısı oluşturacaksınız.
Güvenlik açıkları türleri
Genel olarak, web güvenlik açıklarını aşağıdaki kovalara kategorize edebiliriz (daha fazla kova için OWASP Top 10'u kontrol edin):
-
SQL enjeksiyonu: Saldırganların, doğrulanmamış girişler aracılığıyla SQL sorgularına kötü amaçlı SQL kodu ekleyebildiği ve veritabanı içeriğini değiştirmelerine/okumalarına olanak tanıyan bir teknik.
Siteler Arası Komut Dosyası Çalıştırma (XSS): Saldırganların güvenilen web sitelerine kötü amaçlı JavaScript yerleştirdiği bir teknik. Bu, onların tarayıcı bağlamında JavaScript kodunu yürütmelerine, hassas bilgileri çalmalarına veya yetkisiz işlemler gerçekleştirmelerine olanak tanır.
Hassas bilgilerin açığa çıkması: Bir uygulamanın günlükler, güvenli olmayan depolama ve diğer güvenlik açıkları aracılığıyla şifreler, API anahtarları vb. gibi hassas verileri istemeden açığa çıkardığı bir güvenlik sorunu.
Yaygın güvenlik yanlış yapılandırmaları: Yönetici hesapları için varsayılan kimlik bilgileri, etkinleştirilen hata ayıklama modu, zayıf kimlik bilgilerine sahip herkese açık yönetici kontrol panelleri vb. gibi web sunucularının hatalı yapılandırılması nedeniyle ortaya çıkan güvenlik sorunları.
Temel Kimlik Doğrulama Zayıf Yönleri : Parola politikalarındaki turlar, kullanıcı kimlik doğrulaması işlemleri, uygunsuz oturum yönetimi vb.
İçindekiler
Önkoşul
Geliştirme Ortamımızı Kurma
Temel Tarayıcı Sınıfımızı Oluşturuyoruz
Tarayıcının Uygulanması
Güvenlik Kontrollerinin Tasarlanması ve Uygulanması
-
SQL Enjeksiyon Algılama Kontrolü
-
XSS (Siteler Arası Komut Dosyası) Kontrol
Hassas Bilgi Maruz Kalma Kontrolü
Ana tarama mantığını uygulamak
Güvenlik Tarayıcısını Genişletme
Sarma
Önkoşullar
Bu öğreticiyi takip etmek için aşağıdakilere ihtiyacınız olacak:
Python 3.x
HTTP protokollerinin temel anlayışı
Web uygulamalarının temel anlayışı
-
XSS, SQL enjeksiyonu ve temel güvenlik saldırılarının nasıl çalıştığına dair temel anlayış
Geliştirme Ortamımızı Kurma
Aşağıdaki komutla gerekli bağımlılıklarımızı yükleyelim:
pip install requests beautifulsoup4 urllib3 colorama
Bu bağımlılıkları kod dosyamızda kullanacağız:
# Required packages
import requests
from bs4 import BeautifulSoup
import urllib.parse
import colorama
import re
from concurrent.futures import ThreadPoolExecutor
import sys
from typing import List, Dict, Set
Temel Tarayıcı Sınıfımızı Oluşturma
Bağımlılıklara sahip olduğunuzda, çekirdek tarayıcı sınıfını yazmanın zamanı geldi.
Bu sınıf, web güvenliği tarama işlevini yürütecek ana sınıfımız olarak görev yapacak. Ziyaret ettiğimiz sayfalarımızı takip edecek ve bulgularımızı da saklayacak.
Daha önce görülmüş olan URL'leri yeniden yayınlamadığınızdan emin olmak için kullanacağımız https://example.com/page?id=1
normalleştirdikten sonra https://example.com/page
olur.
class WebSecurityScanner:
def __init__(self, target_url: str, max_depth: int = 3):
"""
Initialize the security scanner with a target URL and maximum crawl depth.
Args:
target_url: The base URL to scan
max_depth: Maximum depth for crawling links (default: 3)
"""
self.target_url = target_url
self.max_depth = max_depth
self.visited_urls: Set[str] = set()
self.vulnerabilities: List[Dict] = []
self.session = requests.Session()
# Initialize colorama for cross-platform colored output
colorama.init()
def normalize_url(self, url: str) -> str:
"""Normalize the URL to prevent duplicate checks"""
parsed = urllib.parse.urlparse(url)
return f"{parsed.scheme}://{parsed.netloc}{parsed.path}"
Paletli uygulama
Tarayıcımızdaki ilk adım, belirli bir hedef uygulamadaki sayfaları ve URL'leri keşfedecek bir web tarayıcısı uygulamaktır. Bu işlevleri WebSecurityScanner
sınıfımıza yazdığınızdan emin olun.
def crawl(self, url: str, depth: int = 0) -> None:
"""
Crawl the website to discover pages and endpoints.
Args:
url: Current URL to crawl
depth: Current depth in the crawl tree
"""
if depth > self.max_depth or url in self.visited_urls:
return
try:
self.visited_urls.add(url)
response = self.session.get(url, verify=False)
soup = BeautifulSoup(response.text, 'html.parser')
# Find all links in the page
links = soup.find_all('a', href=True)
for link in links:
next_url = urllib.parse.urljoin(url, link['href'])
if next_url.startswith(self.target_url):
self.crawl(next_url, depth + 1)
except Exception as e:
print(f"Error crawling {url}: {str(e)}")
Bu tarama
işlevi, bir web sitesinde derinlemesine tarama yapmamıza yardımcı olur. Belirtilen etki alanı içinde kalarak bir web sitesinin tüm sayfalarını keşfedecektir.
Örneğin, bu tarayıcıyı https://google.com
üzerinde kullanmayı planlıyorsanız, işlev önce tüm URL'leri alacak ve ardından bunların belirtilen alana ait olup olmadığını tek tek kontrol edecektir ( yani google.com
). Eğer öyleyse, görülen URL'yi, işleve argüman olarak derinlik
parametresi ile sağlanan belirli bir derinliğe kadar yinelemeli olarak taramaya devam edecektir. Ayrıca hataları sorunsuz bir şekilde ele aldığımızdan ve tarama sırasında hataları bildirdiğimizden emin olmak için bazı istisna işleme yöntemlerimiz de vardır.
Güvenlik kontrollerinin tasarlanması ve uygulanması
Şimdi nihayet işin ilginç kısmına geçelim ve güvenlik kontrollerimizi uygulayalım. İlk olarak SQL Injection ile başlayacağız.
SQL Enjeksiyon Algılama Kontrolü
def check_sql_injection(self, url: str) -> None:
"""Test for potential SQL injection vulnerabilities"""
sql_payloads = ["'", "1' OR '1'='1", "' OR 1=1--", "' UNION SELECT NULL--"]
for payload in sql_payloads:
try:
# Test GET parameters
parsed = urllib.parse.urlparse(url)
params = urllib.parse.parse_qs(parsed.query)
for param in params:
test_url = url.replace(f"{param}={params[param][0]}",
f"{param}={payload}")
response = self.session.get(test_url)
# Look for SQL error messages
if any(error in response.text.lower() for error in
['sql', 'mysql', 'sqlite', 'postgresql', 'oracle']):
self.report_vulnerability({
'type': 'SQL Injection',
'url': url,
'parameter': param,
'payload': payload
})
except Exception as e:
print(f"Error testing SQL injection on {url}: {str(e)}")
Bu işlev esas olarak, URL'yi ortak SQL enjeksiyon yüklerine karşı test ederek ve güvenlik açığı için ipucu verebilecek hata mesajları arayarak temel SQL enjeksiyon kontrollerini gerçekleştirir.
URL'de basit bir GET isteği gerçekleştirdikten sonra alınan hata mesajına dayanarak, bu mesajın bir veritabanı hatası olup olmadığını kontrol ediyoruz. Eğer öyleyse, son raporumuzda bu komut dosyasının oluşturulacağını bildirmek için report_vulnerability
işlevini kullanırız. Bu örnek uğruna, yaygın olarak test edilmiş birkaç SQL enjeksiyon yükü seçiyoruz, ancak daha fazla test etmek için bunu genişletebilirsiniz.
XSS (Siteler Arası Komut Dosyası) Kontrol
Şimdi XSS payloadları için ikinci güvenlik kontrolünü uygulayalım.
def check_xss(self, url: str) -> None:
"""Test for potential Cross-Site Scripting vulnerabilities"""
xss_payloads = [
"<script>alert('XSS')</script>",
"<img src=x onerror=alert('XSS')>",
"javascript:alert('XSS')"
]
for payload in xss_payloads:
try:
# Test GET parameters
parsed = urllib.parse.urlparse(url)
params = urllib.parse.parse_qs(parsed.query)
for param in params:
test_url = url.replace(f"{param}={params[param][0]}",
f"{param}={urllib.parse.quote(payload)}")
response = self.session.get(test_url)
if payload in response.text:
self.report_vulnerability({
'type': 'Cross-Site Scripting (XSS)',
'url': url,
'parameter': param,
'payload': payload
})
except Exception as e:
print(f"Error testing XSS on {url}: {str(e)}")
Bu işlev, tıpkı SQL enjeksiyon test cihazı gibi, bir dizi ortak XSS verisi kullanır ve aynı fikri uygular. Ancak buradaki temel fark, bir hata mesajı aramak yerine, enjekte edilen yükümüzün yanıtımızda değiştirilmemiş görünmesini aramamızdır.
Enjekte edilen yükümüzü görebiliyorsanız, büyük olasılıkla mağdurun tarayıcısı bağlamında yansıtılan bir XSS saldırısı olarak yürütülecektir.
Hassas Bilgi Maruz Kalma Kontrolü
Şimdi hassas PII için son kontrolümüzü uygulayalım.
def check_sensitive_info(self, url: str) -> None:
"""Check for exposed sensitive information"""
sensitive_patterns = {
'email': r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}',
'phone': r'\b\d{3}[-.]?\d{3}[-.]?\d{4}\b',
'ssn': r'\b\d{3}-\d{2}-\d{4}\b',
'api_key': r'api[_-]?key[_-]?([\'"|`])([a-zA-Z0-9]{32,45})\1'
}
try:
response = self.session.get(url)
for info_type, pattern in sensitive_patterns.items():
matches = re.finditer(pattern, response.text)
for match in matches:
self.report_vulnerability({
'type': 'Sensitive Information Exposure',
'url': url,
'info_type': info_type,
'pattern': pattern
})
except Exception as e:
print(f"Error checking sensitive information on {url}: {str(e)}")
Bu işlev, e-postalar, telefon numaraları, SSN'ler ve API anahtarları (api-key-
Önceki iki işlevde olduğu gibi, yanıt metninde bu PII'leri bulmak için URL'ye ilişkin yanıt metnini ve Regex modellerimizi kullanırız. Herhangi bir şey bulursak report_vulnerability
işleviyle bildiririz. Tüm bu işlevlerin WebSecurityScanner
sınıfında tanımlandığından emin olun.
Ana Tarama Mantığını Uygulama
Son olarak WebSecurityScanner
sınıfında scan
ve report_vulnerability
işlevini tanımlayarak her şeyi bir araya getirelim:
def scan(self) -> List[Dict]:
"""
Main scanning method that coordinates the security checks
Returns:
List of discovered vulnerabilities
"""
print(f"\n{colorama.Fore.BLUE}Starting security scan of {self.target_url}{colorama.Style.RESET_ALL}\n")
# First, crawl the website
self.crawl(self.target_url)
# Then run security checks on all discovered URLs
with ThreadPoolExecutor(max_workers=5) as executor:
for url in self.visited_urls:
executor.submit(self.check_sql_injection, url)
executor.submit(self.check_xss, url)
executor.submit(self.check_sensitive_info, url)
return self.vulnerabilities
def report_vulnerability(self, vulnerability: Dict) -> None:
"""Record and display found vulnerabilities"""
self.vulnerabilities.append(vulnerability)
print(f"{colorama.Fore.RED}[VULNERABILITY FOUND]{colorama.Style.RESET_ALL}")
for key, value in vulnerability.items():
print(f"{key}: {value}")
print()
Bu kod, esasen tarama
işlevini çağıracak ve yinelemeli olarak web sitesini taramaya başlayacak olan tarama
işlevimizi tanımlar. Çoklu iş parçacığıyla, ziyaret edilen URL'lere üç güvenlik kontrolünün tümünü uygulayacağız.
Ayrıca, güvenlik açığımızı konsola etkili bir şekilde yazdıracak ve bunları güvenlik açıklarımızda
dizimizde saklayacak report_vulnerability
işlevini de tanımladık.
Şimdi son olarak tarayıcımızı scanner.py
olarak kaydederek kullanalım:
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python scanner.py <target_url>")
sys.exit(1)
target_url = sys.argv[1]
scanner = WebSecurityScanner(target_url)
vulnerabilities = scanner.scan()
# Print summary
print(f"\n{colorama.Fore.GREEN}Scan Complete!{colorama.Style.RESET_ALL}")
print(f"Total URLs scanned: {len(scanner.visited_urls)}")
print(f"Vulnerabilities found: {len(vulnerabilities)}")
Hedef URL bir sistem argümanı olarak sağlanacak ve taranan URL'lerin ve taramamızın sonunda bulunan güvenlik açıklarının özetini alacağız. Şimdi tarayıcıyı nasıl genişletebileceğinizi ve daha fazla özellik ekleyebileceğinizi tartışalım.
Güvenlik tarayıcısının genişletilmesi
İşte bu temel güvenlik tarayıcısını daha da gelişmiş bir şeye genişletmek için bazı fikirler:
CSRF tespiti, dizin geçişi vb. gibi daha fazla güvenlik açığı kontrolü ekleyin.
HTML veya PDF çıktısıyla raporlamayı iyileştirin.
Tarama yoğunluğu ve arama kapsamı için yapılandırma seçenekleri ekleyin (bir CLI bağımsız değişkeni aracılığıyla taramaların derinliğini belirterek).
Uygun oran sınırlamasının uygulanması.
Oturum tabanlı kimlik doğrulaması gerektiren URL'leri test etmek için kimlik doğrulama desteği ekleme.
Sarma
Artık temel bir güvenlik tarayıcısının nasıl oluşturulacağını biliyorsunuz! Bu tarayıcı Web Güvenliğinin birkaç temel kavramını göstermektedir.
Bu öğreticinin yalnızca eğitim amaçlı kullanılması gerektiğini unutmayın. Burp Suite ve OWASP ZAP gibi, çok daha büyük bir ölçekte yüzlerce güvenlik açıklığını kontrol edebilen profesyonel olarak tasarlanmış birkaç kurumsal sınıf uygulaması vardır.
Umarım web güvenliğinin temellerini ve biraz da Python programlamayı öğrenmişsinizdir.