رؤوس الأمان
رؤوس الأمان
رؤوس أمان HTTP توفر حماية دفاعية متعددة الطبقات ضد ثغرات الويب الشائعة. الرؤوس المكونة بشكل صحيح تمنع هجمات XSS والنقر الخادع واستنشاق MIME وهجمات أخرى على مستوى المتصفح.
سياسة أمان المحتوى (CSP)
CSP هو أقوى رأس أمان، يمنع هجمات XSS من خلال التحكم في الموارد التي يمكن تحميلها:
Content-Security-Policy: default-src 'self'
// تكوين CSP التفصيلي
<?php
header(
"Content-Security-Policy: " .
"default-src 'self'; " . // الافتراضي: نفس الأصل
"script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; " . // النصوص البرمجية
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " . // الأنماط
"img-src 'self' data: https:; " . // الصور
"font-src 'self' https://fonts.gstatic.com; " . // الخطوط
"connect-src 'self' https://api.example.com; " . // AJAX/WebSocket
"frame-src 'none'; " . // إطارات iframe
"object-src 'none'; " . // Flash/المكونات الإضافية
"base-uri 'self'; " . // علامة <base>
"form-action 'self'; " . // إرسالات النماذج
"frame-ancestors 'none'; " . // حماية التضمين
"upgrade-insecure-requests" // HTTP → HTTPS
);
?>
// تكوين Apache
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'"
// تكوين Nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'" always;
default-src: الاحتياطي لجميع توجيهات الجلب
script-src: مصادر JavaScript
style-src: مصادر CSS
img-src: مصادر الصور
font-src: مصادر الخطوط
connect-src: AJAX، WebSocket، EventSource
frame-src: مصادر Iframe
object-src: Flash، تطبيقات Java الصغيرة
كلمات مصدر CSP الرئيسية
تستخدم CSP كلمات رئيسية خاصة لتعريف المصادر المسموح بها:
'none' // حظر جميع المصادر
'self' // نفس الأصل (البروتوكول + النطاق + المنفذ)
'unsafe-inline' // السماح بالنصوص/الأنماط المضمنة (غير موصى به)
'unsafe-eval' // السماح بـ eval() وما شابه (غير موصى به)
data: // السماح بعناوين URL لـ data: (صور base64)
https: // السماح بأي عنوان URL لـ HTTPS
*.example.com // السماح بالنطاقات الفرعية
// CSP القائم على Nonce (موصى به للنصوص المضمنة)
<?php
$nonce = base64_encode(random_bytes(16));
header("Content-Security-Policy: script-src 'self' 'nonce-$nonce'");
?>
<!-- استخدم nonce في علامات script -->
<script nonce="<?php echo $nonce; ?>">
// JavaScript مضمن مسموح به مع هذا nonce
console.log('Secure inline script');
</script>
// CSP القائم على Hash (للنصوص المضمنة الثابتة)
<?php
$script = "console.log('hello');";
$hash = base64_encode(hash('sha256', $script, true));
header("Content-Security-Policy: script-src 'self' 'sha256-$hash'");
?>
'unsafe-inline' و 'unsafe-eval'. استخدم nonces للمحتوى الديناميكي أو hashes للمحتوى الثابت. هذا يوفر أقصى حماية من XSS.تقارير CSP
يمكن لـ CSP الإبلاغ عن الانتهاكات للمساعدة في تحديد المشكلات قبل فرض سياسات صارمة:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
// وضع الفرض مع التقارير
Content-Security-Policy: default-src 'self'; report-uri /csp-report
// معالج تقرير PHP
<?php
// نقطة نهاية /csp-report
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$report = json_decode(file_get_contents('php://input'), true);
error_log(sprintf(
"CSP Violation: %s blocked %s on %s",
$report['csp-report']['violated-directive'] ?? 'unknown',
$report['csp-report']['blocked-uri'] ?? 'unknown',
$report['csp-report']['document-uri'] ?? 'unknown'
));
// تخزين في قاعدة البيانات للتحليل
logCspViolation($report);
http_response_code(204);
}
?>
// واجهة برمجة تطبيقات Report-To (بديل حديث لـ report-uri)
Content-Security-Policy: default-src 'self'; report-to csp-endpoint
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"/csp-report"}]}
X-Frame-Options
يمنع هجمات النقر الخادع من خلال التحكم في ما إذا كان يمكن تضمين موقعك في إطارات iframe:
X-Frame-Options: DENY // لا تسمح أبدًا بالتأطير
X-Frame-Options: SAMEORIGIN // السماح بالتأطير بنفس الأصل فقط
X-Frame-Options: ALLOW-FROM https://example.com // مهمل
// تنفيذ PHP
<?php
header('X-Frame-Options: DENY');
// أو
header('X-Frame-Options: SAMEORIGIN');
?>
// تكوين Apache
Header always set X-Frame-Options "SAMEORIGIN"
// تكوين Nginx
add_header X-Frame-Options "SAMEORIGIN" always;
// بديل CSP الحديث (أكثر مرونة)
Content-Security-Policy: frame-ancestors 'self'
Content-Security-Policy: frame-ancestors 'none'
Content-Security-Policy: frame-ancestors 'self' https://trusted.com
ALLOW-FROM مهمل وغير مدعوم من قبل معظم المتصفحات. استخدم توجيه CSP frame-ancestors بدلاً من ذلك للتحكم في iframe متعدد النطاقات.X-Content-Type-Options
يمنع استنشاق نوع MIME، مما يجبر المتصفحات على احترام Content-Type المعلن:
X-Content-Type-Options: nosniff
// تنفيذ PHP
<?php
header('X-Content-Type-Options: nosniff');
?>
// تكوين Apache
Header always set X-Content-Type-Options "nosniff"
// تكوين Nginx
add_header X-Content-Type-Options "nosniff" always;
// لماذا هذا مهم:
// بدون nosniff: قد ينفذ المتصفح text/plain كـ JavaScript
<script src="user-uploaded-file.txt"></script> // يمكن أن ينفذ!
// مع nosniff: يحترم المتصفح Content-Type
// ملف text/plain لن ينفذ كـ JavaScript
سياسة المُحيل (Referrer-Policy)
تتحكم في مقدار معلومات المُحيل المرسلة مع الطلبات:
no-referrer // لا ترسل أبدًا المُحيل
no-referrer-when-downgrade // افتراضي: أرسل ما لم يكن HTTPS → HTTP
origin // أرسل الأصل فقط (https://example.com)
origin-when-cross-origin // عنوان URL الكامل لنفس الأصل، الأصل للأصول المتقاطعة
same-origin // أرسل المُحيل إلى نفس الأصل فقط
strict-origin // أرسل الأصل ما لم يكن HTTPS → HTTP
strict-origin-when-cross-origin // موصى به: عنوان URL الكامل نفس الأصل، الأصل الأصول المتقاطعة
unsafe-url // أرسل دائمًا عنوان URL الكامل (غير موصى به)
// تنفيذ PHP
<?php
header('Referrer-Policy: strict-origin-when-cross-origin');
?>
// تكوين Apache
Header always set Referrer-Policy "strict-origin-when-cross-origin"
// تكوين Nginx
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
// علامة HTML Meta
<meta name="referrer" content="strict-origin-when-cross-origin">
strict-origin-when-cross-origin كسياسة متوازنة. إنها تحمي خصوصية المستخدم مع توفير بيانات تحليلية مفيدة للتنقل بنفس الأصل.سياسة الأذونات (Permissions-Policy سابقًا Feature-Policy)
تتحكم في ميزات المتصفح وواجهات برمجة التطبيقات التي يمكن استخدامها:
Permissions-Policy: geolocation=(), camera=(), microphone=()
// تكوين تفصيلي
<?php
header(
"Permissions-Policy: " .
"geolocation=(), " . // حظر تحديد الموقع الجغرافي
"camera=(), " . // حظر الكاميرا
"microphone=(), " . // حظر الميكروفون
"payment=(self), " . // السماح بواجهات برمجة تطبيقات الدفع لنفس الأصل
"usb=(), " . // حظر الوصول إلى USB
"accelerometer=(), " . // حظر مقياس التسارع
"gyroscope=(), " . // حظر الجيروسكوب
"magnetometer=(), " . // حظر المغناطيسي
"fullscreen=(self)" // السماح بملء الشاشة لنفس الأصل
);
?>
// السماح بأصول محددة
Permissions-Policy: camera=(self "https://trusted-video.com")
// Feature-Policy القديم (مهمل ولكن لا يزال مدعومًا)
Feature-Policy: geolocation 'none'; camera 'none'; microphone 'none'
// تكوين Apache
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
// تكوين Nginx
add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always;
X-XSS-Protection (قديم)
التحكم في مرشح XSS القديم. يجب أن تعتمد المواقع الحديثة على CSP بدلاً من ذلك:
X-XSS-Protection: 0 // تعطيل مرشح XSS
X-XSS-Protection: 1 // تمكين مرشح XSS
X-XSS-Protection: 1; mode=block // تمكين وحظر الصفحة
// تنفيذ PHP
<?php
// موصى به: تعطيل (يتعارض مع CSP)
header('X-XSS-Protection: 0');
?>
// تكوين Apache
Header always set X-XSS-Protection "0"
// لماذا التعطيل؟
// - المتصفحات الحديثة أهملت هذه الميزة
// - يمكن أن يُدخل ثغرات
// - CSP يوفر حماية أفضل
// - يخلق شعورًا زائفًا بالأمان
تكوين رؤوس الأمان الكامل
إعداد رؤوس أمان جاهز للإنتاج:
<?php
// فرض HTTPS
header('Strict-Transport-Security: max-age=31536000; includeSubDomains; preload');
// سياسة أمان المحتوى
$nonce = base64_encode(random_bytes(16));
header(
"Content-Security-Policy: " .
"default-src 'self'; " .
"script-src 'self' 'nonce-$nonce' https://cdn.jsdelivr.net; " .
"style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " .
"img-src 'self' data: https:; " .
"font-src 'self' https://fonts.gstatic.com; " .
"connect-src 'self'; " .
"frame-src 'none'; " .
"object-src 'none'; " .
"base-uri 'self'; " .
"form-action 'self'; " .
"frame-ancestors 'none'; " .
"upgrade-insecure-requests; " .
"block-all-mixed-content"
);
// حماية النقر الخادع
header('X-Frame-Options: DENY');
// منع استنشاق MIME
header('X-Content-Type-Options: nosniff');
// سياسة المُحيل
header('Referrer-Policy: strict-origin-when-cross-origin');
// سياسة الأذونات
header('Permissions-Policy: geolocation=(), camera=(), microphone=()');
// تعطيل مرشح XSS (مهمل)
header('X-XSS-Protection: 0');
?>
// Apache - تكوين كامل
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Content-Security-Policy "default-src 'self'; script-src 'self'"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "geolocation=(), camera=(), microphone=()"
Header always set X-XSS-Protection "0"
</IfModule>
// Nginx - تكوين كامل
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), camera=(), microphone=()" always;
add_header X-XSS-Protection "0" always;
Helmet.js لـ Node.js/Express
يقوم Helmet.js تلقائيًا بتعيين رؤوس الأمان لتطبيقات Node.js:
npm install helmet
// التنفيذ الأساسي
const express = require('express');
const helmet = require('helmet');
const app = express();
// استخدام جميع الرؤوس الافتراضية
app.use(helmet());
// تكوين مخصص
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'unsafe-inline'", "cdn.jsdelivr.net"],
styleSrc: ["'self'", "'unsafe-inline'", "fonts.googleapis.com"],
imgSrc: ["'self'", "data:", "https:"],
fontSrc: ["'self'", "fonts.gstatic.com"],
connectSrc: ["'self'"],
frameSrc: ["'none'"],
objectSrc: ["'none'"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
preload: true,
},
frameguard: {
action: 'deny',
},
referrerPolicy: {
policy: 'strict-origin-when-cross-origin',
},
})
);
// رؤوس فردية
app.use(helmet.contentSecurityPolicy({ /* options */ }));
app.use(helmet.hsts({ /* options */ }));
app.use(helmet.frameguard({ action: 'deny' }));
app.use(helmet.noSniff());
app.use(helmet.referrerPolicy({ policy: 'strict-origin-when-cross-origin' }));
اختبار وتدقيق رؤوس الأمان
أدوات وتقنيات للتحقق من تكوين رؤوس الأمان بشكل صحيح:
# فحص الرؤوس باستخدام curl
curl -I https://example.com
# فحص رأس محدد
curl -I https://example.com | grep "Content-Security-Policy"
// أدوات تطوير المتصفح
// 1. افتح DevTools (F12)
// 2. علامة تبويب الشبكة (Network)
// 3. أعد تحميل الصفحة
// 4. انقر على الطلب
// 5. عرض قسم "الرؤوس" (Headers)
// ماسحات رؤوس الأمان عبر الإنترنت
// 1. https://securityheaders.com/
// - درجات من A+ إلى F
// - توصيات تفصيلية
// 2. https://observatory.mozilla.org/
// - فحص أمان شامل
// - مدقق CSP
// 3. https://csp-evaluator.withgoogle.com/
// - محلل سياسة CSP
// - يحدد نقاط الضعف
// نص PHP لاختبار الرؤوس
<?php
function checkSecurityHeaders($url) {
$headers = get_headers($url, 1);
$requiredHeaders = [
'Strict-Transport-Security',
'Content-Security-Policy',
'X-Frame-Options',
'X-Content-Type-Options',
'Referrer-Policy'
];
foreach ($requiredHeaders as $header) {
if (isset($headers[$header])) {
echo "✓ $header: {$headers[$header]}\n";
} else {
echo "✗ $header: مفقود\n";
}
}
}
checkSecurityHeaders('https://example.com');
?>
1. أنشئ نص PHP يعين جميع رؤوس الأمان الموصى بها
2. قم بتطبيق CSP القائم على nonce للنصوص المضمنة
3. قم بتكوين HSTS مع max-age لمدة سنة واحدة و preload
4. قم بإعداد نقطة نهاية تقارير CSP لتسجيل الانتهاكات
5. قم بتكوين Referrer-Policy و Permissions-Policy
6. اختبر الرؤوس في securityheaders.com (هدف درجة A+)
7. أضف رؤوس الأمان إلى تكوين Apache أو Nginx
8. تحقق من الرؤوس باستخدام أدوات تطوير المتصفح
9. اختبر CSP من خلال محاولة تحميل موارد محظورة
10. راقب تقارير انتهاكات CSP لمدة أسبوع واحد لتحديد المشكلات