HSTS: כפיית HTTPS ברמת הדפדפן באתר WordPress

HSTS אומר לדפדפן לעולם לא לבקש את האתר ב-HTTP. שכבת הגנה חיונית מעל ה-redirect הסטנדרטי.

HSTS, ראשי תיבות של HTTP Strict Transport Security, הוא header HTTP שמורה לדפדפן: 'מהיום הזה ולשנה הקרובה, תבקש את האתר רק ב-HTTPS, אפילו אם המשתמש הקליד http בכוונה'. זוהי שכבת הגנה הכרחית מעל הפניית 301 הרגילה - לא תחליף לה, אלא משלימה.

למה זה משנה

כפיית HTTPS באמצעות redirect 301 לבד משאירה חלון פגיעות בבקשה הראשונה. נסה את התרחיש הבא: משתמש בבית קפה מתחבר ל-Wi-Fi של הקפה ומקליד 'example.com' בכתובת. הדפדפן שולח בקשת HTTP. תוקף שיושב באותו Wi-Fi (התקפה הנקראת SSL stripping) מתערב באמצע, מחזיר את הדף שלך אבל בלי redirect ל-HTTPS, ושומר את הסשן על HTTP - ולכן יכול לקרוא את הקוקיז של ההתחברות. עם HSTS, אם המשתמש ביקר באתר פעם אחת בעבר, הדפדפן זוכר את ההנחיה ולא שולח בכלל את בקשת ה-HTTP - הוא ישר עובר ל-HTTPS, ולא נותן לתוקף הזדמנות. גם משתמש שיש לו bookmark ישן של http://example.com מוגן: בפעם הבאה שהוא לוחץ על ה-bookmark, הדפדפן ממיר אוטומטית. בנוסף, HSTS מונע מהמשתמש 'ללחוץ continue' באזהרת תעודה - ברגע שיש HSTS, הדפדפן לא נותן אפשרות לעקוף.

איך לזהות

הבדיקה מבצעת HEAD לעמוד הראשי וקוראת את header Strict-Transport-Security. אם הוא חסר - הבדיקה אדומה. גם אם הוא קיים אבל max-age קטן מ-2592000 (30 יום), זה נחשב חלש. ידנית:

curl -I https://example.com | grep -i strict
אמור להחזיר משהו כמו: 'Strict-Transport-Security: max-age=31536000; includeSubDomains'. גם אתר ה-securityheaders.com מציג את הציון.

איך לתקן

  1. תנאי הכרחי: ודא שהאתר עובד ב-HTTPS באופן יציב לפחות שבועיים בלי בעיות mixed content. אם תפעיל HSTS על אתר עם בעיות, הדפדפן יחסום משאבים שעדיין נטענים ב-HTTP.
  2. התחל עם max-age קצר כדי לאמת: 300 שניות (5 דקות). הוסף את ה-header.
  3. בדוק שהוא מופיע ב-curl. בדוק שהאתר עדיין עובד.
  4. אם הכל בסדר, הגדל ל-31536000 (שנה).
  5. Apache ב-.htaccess בשורש:
    <IfModule mod_headers.c>
        Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    </IfModule>
  6. Nginx בקונפיג ה-server block:
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
  7. הוסף את הדגל includeSubDomains רק אחרי שאתה בטוח שכל הסאבדומיינים גם הם ב-HTTPS. אם יש לך blog.example.com שעדיין רץ HTTP, הוא יישבר.
  8. בדוק שה-header נשלח: curl -I https://example.com | grep -i strict.
  9. שקול הוספה ל-HSTS preload list של Chrome ב-hstspreload.org - דורש את הדגל preload בערך ה-header. זוהי החלטה כמעט בלתי הפיכה: הסרה מה-preload list לוקחת חודשים.

טעויות נפוצות

אל תפעיל HSTS לפני HTTPS יציב - דפדפנים יחסמו את האתר עד שה-max-age יסתיים, אפילו אם תבטל את ה-header. אל תפעיל preload בשליפה ראשונה - זה מחייב 1) max-age=31536000 לפחות, 2) includeSubDomains, 3) preload directive, 4) HTTPS על כל הסאבדומיינים. אל תפעיל includeSubDomains בלי לבדוק שכל הסאבדומיינים מוכנים. אל תסיים את הערך ב-':' - syntax לא תקין שורף שעות באיתור.

בדיקה לאחר תיקון

הרץ curl -I https://example.com - אמור לראות את ה-header. בדוק את האתר ב-securityheaders.com - אמור לעלות לציון A או A+. גש לאתר ב-http://example.com - הדפדפן אמור לעבור אוטומטית ל-HTTPS לפני שמגיע לשרת (בכרום, יש שורה ב-DevTools 'HSTS internal redirect').

טיפ: אל תפעיל preload לפני שאתה ב-100% בטוח. preload הוא רשימה ש-Chrome, Firefox ו-Safari טוענים מראש. אם תרצה לבטל - תהליך של חודשים, וחלק מהמשתמשים לא יוכלו להגיע לאתר עד שה-cache שלהם יתעדכן.

שיקולים נוספים

כדי לאמת את ה-HSTS שלך אחרי הגדרה, השתמש ב-https://hstspreload.org - גם אם אתה לא מתכוון להוסיף ל-preload list, האתר מציג בדיוק איך הדפדפן יפרש את ה-header שלך. אם אתה משתמש ב-Cloudflare, יש שם הגדרה 'HSTS' תחת SSL/TLS > Edge Certificates שמחילה את ה-header אוטומטית - שים לב שהיא דורסת כל header שתשלח מהשרת, אז אם הגדרת בשני מקומות, רק זה של Cloudflare יחול. WordPress עצמו לא שולח HSTS - חייב הגדרה ברמת השרת או ב-CDN.