Content Security Policy וה-CMP שלכם: איך גורמים ל-CSP ולהסכמה לעבוד יחד
שתי שכבות אבטחה שחייבות להסכים
Content Security Policy (CSP) אומרת לדפדפן מאילו מקורות עמוד רשאי לטעון סקריפטים, סגנונות, תמונות, פריימים ובקשות רשת. פלטפורמת ניהול הסכמה עושה את העבודה ההפוכה: היא מחליטה אילו מהסקריפטים האלה מותר להפעיל על סמך בחירת המשתמש. כששתיהן מוגדרות בנפרד, הן מתנגשות. ה-CMP נכשל בטעינה כי ה-CSP חוסמת אותו, או שה-CSP מרוככת כל כך כדי להכיל את ה-CMP ותגי הפרסום שהיא כבר לא מגינה על כלום.
מדריך זה מסביר אילו הנחיות CSP CMP בדרך כלל צריך, איך nonces מתקשרים עם הזרקת סקריפטים, ואיך להשיק שינויים בלי לשבור את הבאנר.
מה CMP בדרך כלל צריך מה-CSP
הדרישות המדויקות תלויות בספק, ולכן תמיד התחילו מהתיעוד של ה-CMP שלכם. באופן כללי, בדקו את ההנחיות האלה:
script-src— הדומיין שממנו נטען סקריפט ה-CMP, בתוספת כל קובצי סקריפט נוספים שהוא טוען.connect-src— נקודות קצה שה-CMP קורא להן עםfetchאו XHR, כגון תצורה, רשימת ספקים, מיקום גיאוגרפי ותיעוד הסכמה.style-src— דומיין גיליון הסגנון, ואולי סגנונות משולבים אם ה-CMP מזריק אלמנט<style>או מגדיר תכונות style.img-src— לוגואים, אייקונים וכל פיקסל נטול מעקב שה-CMP משתמש בו.font-src— אם הבאנר טוען גופנים משלו.frame-src— אם ה-CMP משתמש ב-iframes, למשל לשיתוף הסכמה בין דומיינים.
באתרי TCF זכרו שה-CMP יוצר גם פריים מאתר בשם __tcfapiLocator בעמוד. הפריים הזה נוצר ללא מקור מרוחק, ולכן בדרך כלל אינו זקוק לרשומת frame-src, אך כדאי לוודא זאת בבדיקות.
בעיית ה-Stub המשולב
רוב ה-CMPs מבקשים להציב סקריפט משולב קטן — ה-stub — בראש העמוד, כדי שסקריפטים אחרים יוכלו להכניס קריאות לתור לפני שה-CMP הראשי נטען. CSP מחמירה חוסמת סקריפטים משולבים אלא אם מתירים אותם במפורש. יש שלוש אפשרויות:
- nonce. צרו ערך אקראי לכל תגובה, הוסיפו אותו לכותרת ה-CSP בצורת
'nonce-...'ולתג<script>של ה-stub. זו האפשרות הגמישה ביותר לעמודים דינמיים. - hash. הוסיפו את גיבוב SHA-256 של התוכן המדויק של ה-stub אל
script-src. זה עובד היטב לאתרים סטטיים, אך כל שינוי ב-stub, אפילו רווח, שובר אותו. - אירוח עצמי של ה-stub כקובץ חיצוני בדומיין שלכם, המכוסה על ידי
'self'. זה דורש זהירות כדי שהוא ייטען מוקדם מספיק.
הימנעו מ-'unsafe-inline' כקיצור דרך. הוא מתיר כל סקריפט משולב, ומסיר חלק גדול מההגנה שה-CSP מספקת.
Nonces וסקריפטים שה-CMP מזריק
CMP שחוסם סקריפטים עד להסכמה פועל לעיתים קרובות בכך שהוא מעכב אותם ומזריק אותם מאוחר יותר. תחת CSP מבוססת nonce, צריך להתיר גם את הסקריפטים המוזרקים האלה. יש שתי גישות נפוצות:
- הפצת nonce. ה-CMP קורא את ה-nonce מתג הסקריפט שלו ומוסיף אותו לכל סקריפט שהוא מזריק. בדקו אם ה-CMP שלכם תומך בכך.
'strict-dynamic'. מילת המפתח הזו אומרת לדפדפנים תומכים לסמוך על סקריפטים שנטענו על ידי סקריפט שכבר נתמך באמון. היא מפשטת את החיים עם מנהלי תגים ו-CMPs שמזריקים סקריפטים, אך היא גם אומרת שכל סקריפט שאתם סומכים עליו יכול לטעון אחרים, ולכן סמכו בזהירות.
מנהלי תגים מעלים את אותה שאלה. אם אתם טוענים תגי פרסום ואנליטיקה דרך מנהל תגים, עקבו אחר התיעוד שלו בנוגע ל-nonces וודאו שה-CMP ומנהל התגים משתמשים בגישה עקבית.
תגי פרסום מקשים על CSP
פרסום פרוגרמטי טוען סקריפטים ופריימים מדומיינים רבים, והרשימה משתנה כששותפי הביקוש משתנים. מפרסמים בדרך כלל עושים אחת משתי בחירות:
- CSP מחמירה בעמודים ללא פרסום פרוגרמטי, ומדיניות רחבה יותר במקום שבו רצות פרסומות.
- מדיניות שמתמקדת בהנחיות שנשארות ניתנות לניהול, כגון
frame-ancestors,object-src 'none'ו-base-uri, בעוד שמקורות הסקריפטים נשארים רחבים יותר.
בכל מקרה, ה-CMP צריך להיות ברשימת ההיתרים המפורשת, ולא מכוסה רק על ידי תו כללי, כדי ששינוי ב-CSP לעולם לא יכבה את הבאנר בשקט.
השקה במצב Report-Only
השתמשו קודם בכותרת Content-Security-Policy-Report-Only. הדפדפן מדווח על הפרות בלי לחסום דבר, כך שאפשר לראות מה מדיניות חדשה הייתה שוברת.
- פרסו את המדיניות במצב report-only עם נקודת קצה לדיווח.
- טענו עמודים בפרופילי דפדפן נקיים ועברו על כל תהליך ההסכמה: ביקור ראשון, אישור הכל, דחיית הכל, בחירה מותאמת, ביטול הסכמה.
- עברו על דוחות ההפרות ועל קונסולת הדפדפן בחיפוש אחר משאבי CMP חסומים.
- התאימו את המדיניות, ואז עברו לאכיפה.
- השאירו את הדיווח פעיל גם לאחר האכיפה כדי לתפוס נסיגות.
תסמינים של התנגשות CSP
- הבאנר אף פעם לא מופיע, והקונסולה מציגה הפרת CSP עבור סקריפט ה-CMP.
- הבאנר מופיע אך ללא עיצוב, כי
style-srcחוסם את ה-CSS שלו. - בחירות לא נשמרות, כי
connect-srcחוסם את קריאת תיעוד ההסכמה. - פרסומות או אנליטיקה אף פעם לא נטענות לאחר הסכמה, כי לסקריפטים המוזרקים אין nonce.
__tcfapiלא מוגדר, כי ה-stub המשולב נחסם.
עיקרי הדברים
- בדקו את
script-src,connect-src,style-src,img-srcו-frame-srcעבור ה-CMP שלכם. - התירו את ה-stub המשולב עם nonce או hash, לא עם
'unsafe-inline'. - ודאו שסקריפטים שמוזרקים לאחר הסכמה מקבלים nonce או מכוסים על ידי
'strict-dynamic'. - בדקו כל נתיב הסכמה במצב report-only לפני האכיפה.
- השאירו את ה-CMP ברשימת היתרים מפורשת כדי ששינויי CSP לא יוכלו לכבות אותו.