Security Headers
כותרות HTTP לאבטחה מהווים שכבת הגנה יסודית ולעתים קרובות בלתי מנוצלת עבור אפליקציות ווב מודרניות, ופועלים כהנחיות המורות לדפדפנים להפעיל מנגנוני הגנה מובנים כנגד מגוון רחב של וקטורי תקיפה נפוצים. כותרות תגובת HTTP אלו פועלים כמדיניות אבטחה דקלרטיבית, ומגדירים כללים לגבי אופן שבו הדפדפן צריך לעבד ולרנדר את תוכן העמוד, לשלוט בהרצת סקריפטים, לנהל cookies ולקיים אינטראקציה עם משאבים של צדדים שלישיים. כאשר מוגדרות כראוי, כותרות כמו Content-Security-Policy (CSP), Strict-Transport-Security (HSTS), X-Frame-Options ו- X-Content-Type-Options יוצרות מחסומים משמעותיים כנגד תקיפות Cross-Site Scripting (XSS), clickjacking, MIME sniffing, דיגרוד פרוטוקול והזרקת קוד זדוני. היישום הנכון של כותרות אלו מהווה אחת הדרכים היעילות ביותר ל-hardening של אפליקציות ווב, משום שהוא אינו דורש שינויים בקוד האפליקציה ומספק הגנה מיידית כנגד מחלקות שלמות של פגיעויות. מחקרים מראים שהרוב המכריע של האתרים עדיין אינו מיישם כראוי כותרות אלו, ומשאיר את המשתמשים שלו חשופים לתקיפות שניתן היה למתן עם תצורות פשוטות יחסית בשרת ה-ווב. הזנחה זו קריטית במיוחד בהתחשב בכך ש כלי סריקת אבטחה אוטומטיים מעריכים את הנוכחות והתצורה התקינה של כותרות אלו כמדדים ראשוניים למצב האבטחה של אפליקציה.
Content-Security-Policy (CSP)
CSP מונע XSS על ידי הגדרת whitelist של מקורות מהימנים עבור scripts, styles, images ומשאבים אחרים.
# CSP קשיחה (מומלץ)
Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-';
style-src 'self' 'nonce-';
img-src 'self' https: data:;
font-src 'self';
connect-src 'self' https://api.example.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self';
# CSP עם report-only (מצב בדיקה)
Content-Security-Policy-Report-Only:
default-src 'self';
report-uri /csp-violation-report
דירקטיבות CSP קריטיות
- default-src: Fallback עבור דירקטיבות אחרות
- script-src: Whitelist עבור הרצת JavaScript
- style-src: מקורות CSS מותרים
- frame-ancestors: מונע clickjacking
- upgrade-insecure-requests: כופה HTTPS
Strict-Transport-Security (HSTS)
HSTS כופה דפדפנים להשתמש תמיד ב-HTTPS, ומונע downgrade attacks ו-SSL stripping.
# HSTS עם preload ותת-דומיינים
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# שלבים ל-HSTS preload:
1. להגדיר כותרת HSTS עם preload
2. להגיש את הדומיין ב-hstspreload.org
3. הדומיין ייכלל ב-preload lists של הדפדפנים
X-Frame-Options
מונע clickjacking על ידי שליטה באם העמוד יכול להיות מרונדר ב-frame/iframe.
# לדחות כל framing (הבטוח ביותר)
X-Frame-Options: DENY
# לאפשר רק את אותו ה-origin
X-Frame-Options: SAMEORIGIN
# לאפשר דומיין ספציפי (מיושן - יש להשתמש ב-CSP frame-ancestors)
X-Frame-Options: ALLOW-FROM https://trusted.com
X-Content-Type-Options
מונע תקיפות MIME sniffing על ידי כפיית הדפדפן לכבד את ה-Content-Type המוצהר.
# להשבית MIME sniffing
X-Content-Type-Options: nosniff
Referrer-Policy
שולט בכמות ה-referrer information הנשלחת ב-requests.
# מדיניות מומלצת
Referrer-Policy: strict-origin-when-cross-origin
# אפשרויות:
# - no-referrer: לעולם אל תשלח referrer
# - no-referrer-when-downgrade: ללא referrer ב-HTTPS→HTTP
# - same-origin: לשלוח רק לאותו ה-origin
# - strict-origin: לשלוח רק את ה-origin (ללא path)
Permissions-Policy
שולט באילו browser features ו-APIs העמוד רשאי להשתמש (מחליף את Feature-Policy).
# להשבית תכונות מסוכנות
Permissions-Policy:
geolocation=(),
microphone=(),
camera=(),
payment=(),
usb=(),
interest-cohort=()
תצורה לפי שרת
Nginx
# nginx.conf
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" 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 Content-Security-Policy "default-src 'self';" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
Apache
# .htaccess או httpd.conf
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
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 Content-Security-Policy "default-src 'self';"
Node.js/Express
// להשתמש ב-middleware של Helmet
const helmet = require('helmet');
app.use(helmet());
// תצורה מותאמת אישית
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", "'nonce-'"],
styleSrc: ["'self'", "'nonce-'"],
}
}));
בדיקת Security Headers
- securityheaders.com: סריקה ודירוג A+
- Mozilla Observatory: ניתוח מקיף
- Chrome DevTools: כרטיסיית Network → Headers
- curl:
curl -I https://example.com
מלכודות נפוצות
- CSP מתירנית מדי עם 'unsafe-inline' ו-'unsafe-eval'
- HSTS ללא includeSubDomains משאיר תת-דומיינים פגיעים
- כותרות מוגדרות אך לא מוחלות (חסר הדגל always)
- לבדוק רק את דף הבית - הכותרות צריכות להיות בכל הדפים
צ'קליסט מלא
- [OK] Content-Security-Policy קשיחה מוגדרת
- [OK] HSTS עם max-age של שנה + includeSubDomains
- [OK] X-Frame-Options: DENY או CSP frame-ancestors
- [OK] X-Content-Type-Options: nosniff
- [OK] Referrer-Policy מוגדרת
- [OK] Permissions-Policy משביתה תכונות שאינן בשימוש
- [OK] הכותרות נבדקו ב-securityheaders.com (דירוג A+)
- [OK] CSP נבדקה תחילה ב-report-only mode
