חיפוש

מדריך הוספת Security Headers לאתרי וורדפרס

Security Headers בוורדפרס מוסיפים שכבת הגנה נוספת מפני מתקפות נפוצות, ללא צורך להוסיף או לשנות משהו בקוד של האפליקציה שלכם.

לאבטחת אתרים או אפליקציות Web קיימים מספר היבטים שצריך לתת עליהם את הדעת. מקום טוב להתחיל בחיזוק האבטחה של אתרי וורדפרס הוא בהוספת Security Headers.

מה הם Security Headers?

Security Headers הם כותרות תגובה (HTTP Response Headers) שמורות לדפדפן כיצד להתנהג בעת טיפול בתוכן האתר שלכם. הם עוזרים למנוע מתקפות שונות – כולל Clickjacking, Cross-Site Scripting (XSS) והתקפות שדרוג פרוטוקול – על ידי הגבלת מה שהדפדפן רשאי לעשות.

בפוסט זה נעבור על ה-Security Headers החשובים ביותר ונראה כיצד להוסיף אותם לאתר שלכם, בין אם אתם מריצים שרת Apache או שרת NGINX.

חשוב לציין כי ההגדרות המוצגות בפוסט זה אינן בהכרח מתאימות לכל אתר. עליכם לבדוק כל header בנפרד ולוודא שאין שגיאות בקונסול לאחר כל שינוי.

הגדרה שגויה של Security Headers עלולה לגרום לשגיאת שרת 500 או לשבור חלקים באתר. בצעו תמיד גיבוי של קובץ .htaccess או nginx.conf לפני ביצוע שינויים, וודאו שיש לכם גישת FTP או מנהל קבצים כדי שתוכלו לשחזר במידה והאתר נופל.

למידע מעמיק על כל header והפרמטרים שלו, ראו את תיעוד MDN בנושא HTTP Security Headers.

Security Headers מומלצים

הנה ה-Security Headers המומלצים לאתרי וורדפרס. הוסיפו אותם אחד אחד ובדקו לאחר כל שינוי.

א. HTTP Strict Transport Security (HSTS)

HTTP Strict Transport Security (HSTS) מורה לדפדפנים להתחבר לאתר שלכם רק באמצעות HTTPS, ולעולם לא באמצעות HTTP רגיל. זה מונע התקפות שדרוג פרוטוקול וגניבת Cookies.

על האתר שלכם כבר להיות עם תעודת SSL תקינה ולעבוד באופן מלא על HTTPS לפני הפעלת HSTS.

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

הערך max-age=31536000 אומר שהדפדפן יזכור את המדיניות למשך שנה. ההנחיה includeSubDomains מחילה את המדיניות גם על כל תתי-הדומיינים – השתמשו בה רק אם כל תתי-הדומיינים שלכם תומכים ב-HTTPS.

אם אתם מגדירים HSTS בפעם הראשונה, התחילו עם max-age קצר (למשל 300 עבור 5 דקות) והגדילו בהדרגה לאחר שווידאתם שהכל עובד.

ב. X-Frame-Options

X-Frame-Options מגן על הגולשים מפני התקפות מסוג Clickjacking. ללא header זה, תוקף יכול לטעון את האתר שלכם בתוך iframe באתר שלו ולגרום למשתמשים ללחוץ על אלמנטים מוסתרים.

זה מסוכן במיוחד כשהמשתמש מחובר לאזור הדורש אימות באתר שלכם.

<IfModule mod_headers.c>
Header always append X-Frame-Options SAMEORIGIN
</IfModule>
add_header X-Frame-Options "SAMEORIGIN" always;

הערך SAMEORIGIN מאפשר לאתר שלכם לטעון את עצמו ב-iframe (שימושי לתצוגות מקדימות בממשק הניהול של וורדפרס) אך חוסם דומיינים אחרים מלעשות זאת.

ג. X-Content-Type-Options

קביעת ה-header מסוג X-Content-Type-Options מונעת מהדפדפן לנחש (או "לרחרח") את סוג ה-MIME של קובץ. ללא header זה, דפדפן עלול לפרש קובץ זדוני כ-JavaScript או HTML.

Header set X-Content-Type-Options nosniff
add_header X-Content-Type-Options "nosniff" always;

זהו אחד ה-headers הפשוטים ביותר להוספה וכמעט ללא סיכון לשבירת האתר.

ד. Content-Security-Policy

ה-header מסוג Content Security Policy (CSP) הוא החזק ביותר – וגם המורכב ביותר – מבין ה-Security Headers. הוא מורה לדפדפן בדיוק מאילו מקורות מותר לטעון סקריפטים, סגנונות, תמונות, פונטים ומשאבים אחרים.

CSP מחמיר יכול למנוע ביעילות התקפות XSS. עם זאת, תבניות ותוספים בוורדפרס מסתמכים רבות על סקריפטים וסגנונות inline, מה שמקשה על יישום מדיניות מחמירה ללא שבירת פונקציונליות.

נקודת התחלה ריאלית לרוב אתרי וורדפרס:

Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' https: data:; font-src 'self' https: data:; connect-src 'self' https:; frame-ancestors 'self';"
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' https: data:; font-src 'self' https: data:; connect-src 'self' https:; frame-ancestors 'self';" always;

ההנחיות unsafe-inline ו-unsafe-eval מחלישות את הגנת ה-CSP, אך הן נדרשות כרגע עבור רוב אתרי וורדפרס כדי לתפקד. ליבת וורדפרס, Gutenberg ותוספים רבים תלויים בסקריפטים inline. הסרת הנחיות אלו כנראה תשבור את האתר שלכם. השתמשו בהן כפשרה מעשית והדקו את המדיניות עם הזמן ככל שוורדפרס תשפר את תמיכת ה-CSP שלה.

אם אתם רוצים לבדוק את ה-CSP לפני אכיפתו, השתמשו ב-Content-Security-Policy-Report-Only במקום. זה מתעד הפרות בקונסול הדפדפן מבלי לחסום דבר, כך שתוכלו לראות מה היה נשבר.

ה. Referrer-Policy

ה-header מסוג Referrer-Policy שולט בכמה מידע referrer הדפדפן שולח כשגולשים מהאתר שלכם לאתר אחר.

Header set Referrer-Policy "strict-origin-when-cross-origin"
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

הערך strict-origin-when-cross-origin שולח את הכתובת המלאה עבור בקשות מאותו מקור, אך רק את הדומיין עבור בקשות חוצות-מקור. זהו איזון טוב בין פרטיות לפונקציונליות – הוא שומר על נתוני אנליטיקס מבלי לחשוף נתיבי עמודים מלאים לאתרים חיצוניים.

ו. Permissions-Policy

ה-header מסוג Permissions-Policy (לשעבר Feature-Policy) שולט באילו תכונות ו-APIs של הדפדפן האתר שלכם יכול להשתמש, כגון מצלמה, מיקרופון, מיקום גיאוגרפי ו-APIs של תשלום.

רוב אתרי וורדפרס אינם זקוקים לגישה לתכונות אלו, כך שהשבתתן מצמצמת את שטח ההתקפה:

Header set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()"
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;

הסוגריים הריקים () משביתים כל תכונה לחלוטין. אם האתר שלכם משתמש באחת מתכונות אלו (למשל מאתר חנויות שצריך מיקום גיאוגרפי), התאימו בהתאם: geolocation=(self).

ז. X-XSS-Protection (מיושן)

ה-header מסוג X-XSS-Protection תוכנן להפעיל את מסנן ה-XSS המובנה בדפדפן. עם זאת, header זה מיושן והוסר מכל הדפדפנים המודרניים (Chrome הסיר אותו בגרסה 78, Firefox מעולם לא תמך בו, ו-Edge הסיר אותו בגרסה 17).

מסנן ה-XSS נמצא כבעל פגמי אבטחה משלו – ניתן היה לנצל אותו ליצירת דליפות מידע חוצות-אתרים. הגישה המומלצת היא להשמיט header זה לחלוטין או להשבית אותו במפורש:

Header set X-XSS-Protection "0"
add_header X-XSS-Protection "0" always;

השתמשו ב-Content-Security-Policy במקום להגנה מפני XSS. אם היה לכם בעבר X-XSS-Protection: 1; mode=block בהגדרות, ניתן להסיר אותו בבטחה.

דוגמת הגדרה מלאה

הנה הגדרת .htaccess מלאה עם כל ה-headers המומלצים:

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains" env=HTTPS
Header set X-Content-Type-Options nosniff
Header always append X-Frame-Options SAMEORIGIN
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()"
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:; img-src 'self' https: data:; font-src 'self' https: data:; connect-src 'self' https:; frame-ancestors 'self';"
</IfModule>

אם אתם מקבלים שגיאת שרת 500 לאחר הוספת ה-headers, נסו הגדרה מינימלית תחילה והוסיפו headers אחד אחד כדי לזהות איזה מהם גורם לבעיה:

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS
Header set X-Content-Type-Options nosniff
Header always append X-Frame-Options SAMEORIGIN
Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>

בדיקת ה-Security Headers

לאחר הוספת ה-headers, ודאו שהם עובדים כראוי. תוכלו לבדוק את האתר שלכם ב-securityheaders.com כדי לקבל ציון ולראות אילו headers קיימים.

בדיקת Security Headers

ניתן גם לבדוק headers בכלי המפתחים של הדפדפן. פתחו את לשונית Network, לחצו על בקשת המסמך הראשית, והסתכלו בקטע Response Headers כדי לאשר שה-headers שלכם נשלחים.

שאלות נפוצות

שאלות נפוצות בנושא Security Headers בוורדפרס:

האם Security Headers יכולים לשבור את אתר הוורדפרס שלי?
כן. Content-Security-Policy שגוי יכול לחסום סקריפטים, סגנונות או תמונות שהאתר צריך. רשומה פגומה ב-.htaccess יכולה לגרום לשגיאת 500. הוסיפו תמיד headers אחד אחד, בדקו לאחר כל שינוי, ושמרו גיבוי של קובץ ההגדרות המקורי כדי שתוכלו לשחזר במהירות.
למה ה-CSP שלי צריך unsafe-inline ו-unsafe-eval?
ליבת וורדפרס, עורך Gutenberg ורוב התוספים מסתמכים על סקריפטים inline וקוד שנוצר באופן דינמי. הסרת unsafe-inline ו-unsafe-eval מה-CSP תשבור את ממשק הניהול של וורדפרס וכנראה גם את חזית האתר. הנחיות אלו הן פשרה מעשית עד שליבת וורדפרס תשפר את תאימות ה-CSP שלה.
האם X-XSS-Protection עדיין שימושי?
לא. ה-header מסוג X-XSS-Protection הוסר מכל הדפדפנים המודרניים. Chrome הסיר אותו בגרסה 78 (2019), Firefox מעולם לא תמך בו, ו-Edge הסיר אותו בגרסה 17. מסנן ה-XSS המובנה נמצא כבעל פגמי אבטחה משלו. השתמשו ב-Content-Security-Policy להגנה מפני XSS במקום.
האם אני צריך HSTS אם כבר יש לי תעודת SSL?
כן. תעודת SSL מצפינה את החיבור, אך ללא HSTS הדפדפן עדיין עשוי לנסות חיבור HTTP ראשוני לפני ההפניה ל-HTTPS. אותה בקשה ראשונה לא מוצפנת פגיעה להתקפות man-in-the-middle. HSTS מורה לדפדפן לדלג על HTTP לחלוטין ולהתחבר תמיד באמצעות HTTPS.
האם כדאי להשתמש ב-includeSubDomains ב-HSTS?
רק אם כל תתי-הדומיינים שלכם תומכים ב-HTTPS. ההנחיה includeSubDomains מכריחה HTTPS על כל תת-דומיין, כולל כלים פנימיים או סביבות staging. אם לתת-דומיין כלשהו אין תעודת SSL תקינה, הוא יהפוך לבלתי נגיש. ודאו שכל תתי-הדומיינים עובדים על HTTPS לפני הפעלת אפשרות זו.
האם ניתן להוסיף Security Headers באמצעות תוסף וורדפרס?
כן. תוספים כמו "Headers Security Advanced and HSTS WP" או "Really Simple SSL" יכולים להגדיר Security Headers מממשק הניהול של וורדפרס. עם זאת, הוספת headers ברמת השרת (דרך .htaccess או nginx.conf) אמינה יותר ומבצעת טוב יותר מכיוון שה-headers נקבעים לפני שוורדפרס בכלל נטענת.

לסיכום

Security Headers הם אחת הדרכים הקלות ביותר לשפר את רמת האבטחה של אתר הוורדפרס שלכם. התחילו עם ה-headers בעלי הסיכון הנמוך (X-Content-Type-Options, X-Frame-Options, Referrer-Policy), לאחר מכן הוסיפו HSTS ברגע שאתם בטוחים שהגדרת ה-HTTPS שלכם יציבה, ולבסוף עבדו על Content-Security-Policy ו-Permissions-Policy.

הכלל המרכזי: הוסיפו header אחד בכל פעם, בדקו, ושמרו גיבוי. אם משהו נשבר, תמיד תוכלו לשחזר.

שאלות, תיקונים ושיפורים יתקבלו בברכה בתגובות.

דיון ותגובות
7 תגובות  ]
  • חתול 17 יוני 2021, 11:58

    ההגדרות המומלצות של securityheaders.com מחמירות מדי ולא מתאימות לאתר וורדפרס.
    וורדפרס צריך לאפשר גם JS ו־CSS מ־inline ולפעמים גם eval. ייתכן מאוד שאתה גם משתמש במשאבים מאתרים אחרים ותרצה לאפשר גם אותם. הגדרות סבירות תהיינה משהו כמו:

    Content-Security-Policy "default-src 'self'; font-src * data:;img-src * data:; script-src * 'unsafe-inline' 'unsafe-eval'; style-src * 'unsafe-inline' 'unsafe-eval'; media-src *";

    כדאי להיזהר עם ההגדרות האלה כי קל לשבור את האתר אם הן מחמירות מדי.

    Permissions-Policy קובע הרשאות גישה לחומרה וברוב האתרים שלא צריכים גישה הוא יהיה:

    Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()";
    • רועי יוסף 17 יוני 2021, 13:06

      תודה רבה על המידע חתול 🙂

      אתה כנראה צודק וההגדרות מחמירות למרבית האתרים. אני אשנה את הפוסט בהתאם, אך האם תוכל לשלוח גם את השינויים שהצעת לשרתי apache? (התגיות אמורות לעבוד עכשיו).

      • חתול 17 יוני 2021, 13:47

        הקוד כללי ונכון גם ל־apache. ב־nginx צריך להוסיף לפניו add_header וב־apache צריך להוסיף Header set
        אבל למה בכלל להשתמש ב־apache?

  • מאיר סיבים 19 יוני 2021, 18:03

    מעניין, תודה.

  • חנה 22 דצמבר 2021, 14:53

    פוסט מצויין! אני חוזרת אליו שוב ושוב.

    עזר לי לסיים בקלות כמה דוחות אבטחת מידע על פרויקטים שונים.

    תודה!

    • רועי יוסף 22 דצמבר 2021, 15:03

      כיף לשמוע 🙂

      אם יש לך טיפים משלך את מוזמנת לשתף…

      • חנה 6 פברואר 2022, 13:22

        היי,

        אני משתמשת בפוסט הזה שוב ושוב בהצלחה רבה. אין מילים!!!
        יש כמה HEADER'ים נוספים שהייתי שמחה להרחבה אודותיהם ועל התחביר הנכון:

        Header set Permissions-Policy
        Access-Control-Allow-Credentials

        תודה!

השאירו תגובה

הוסיפו קוד באמצעות הכפתורים מטה. למשל, בכדי להוסיף PHP לחצו על הכפתור PHP והוסיפו את הקוד בתוך השורטקוד. מצאתם שגיאה בפוסט? עדכנו אותנו...

Savvy WordPress Development official logo