EitanGuard

Content-Security-Policy חסרה - מה זה ואיך מתקנים

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

למה זה מסוכן

CSP היא רשת הביטחון נגד XSS: גם כשתוקף מצליח להזריק סקריפט לדף - דרך פרמטר בכתובת, תוכן שמשתמשים מזינים או ספרייה חיצונית שנפרצה - מדיניות טובה חוסמת את ההרצה או את שליחת הנתונים החוצה. בלי CSP הסקריפט המוזרק רץ חופשי: גונב טוקנים, קורא טפסים ופועל בשם המשתמש.

מה זה CSP במילים פשוטות

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

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

איך נראית מדיניות אמיתית

זו מדיניות סבירה לאתר טיפוסי שמשתמש ב-Google Fonts ובאנליטיקס:

Content-Security-Policy: default-src 'self'; script-src 'self' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self'; frame-ancestors 'none'; object-src 'none'

מה כל חלק אומר:

השגיאות שתראה בקונסול ומה הן אומרות

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

Refused to load the script ... because it violates the following Content Security Policy directive: "script-src 'self'"

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

Refused to execute inline script because it violates the following Content Security Policy directive

התרגום: יש <script> עם קוד ישירות בתוך ה-HTML. או שמעבירים אותו לקובץ נפרד, או שנותנים לו nonce.

Refused to connect to ... because it violates the following Content Security Policy directive: "connect-src 'self'"

התרגום: הקוד מנסה לפנות ל-API חיצוני שלא הרשית - למשל Supabase או שירות תשלומים. מוסיפים את הדומיין שלו ל-connect-src.

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

למה תג meta הוא לא תחליף לכותרת

זו הטעות הכי נפוצה שאנחנו רואים. אפשר להגדיר CSP גם כתג <meta http-equiv="Content-Security-Policy"> בתוך ה-HTML, וזה נראה כאילו זה עובד - אבל זה תחליף חלקי בלבד:

לכן ההגדרה הנכונה היא תמיד בשכבת ההגשה: vercel.json ב-Vercel, netlify.toml או קובץ _headers ב-Netlify, headers() ב-Next.js, או helmet() בשרת Express.

CSP באפליקציה שנבנתה בכלי AI

כאן נמצא הפער האמיתי. כלי כמו Lovable, Bolt או v0 מייצרים אפליקציה שעובדת מצוין, אבל אף אחד לא ביקש מהם להגדיר כותרות אבטחה - ולכן הן פשוט לא שם. בסריקות שלנו זו הבדיקה שנכשלת הכי הרבה.

שתי נקודות שחשוב לדעת לפני שמוסיפים CSP לאפליקציה כזו:

אם אתה לא בטוח מאילו מקורות האפליקציה שלך באמת טוענת, אל תנחש: הרץ אותה שבוע ב-Report-Only, אסוף את הרשימה מהקונסול, ורק אז כתוב את המדיניות הסופית.

איך מתקנים

איך מוודאים שהתיקון עבד

הרץ curl -sSI https://your-domain.com וודא ש-Content-Security-Policy מופיעה, פתח את האתר וודא שאין שגיאות CSP בקונסול, ואז הרץ סריקה חוזרת.

מדריכים לפי הכלי שבנה את האפליקציה

בדיקה חינם

רוצה לדעת אם האפליקציה שלך חשופה? סרוק בחינם ב-30 שניות וקבל ציון אבטחה + הוראות תיקון.

סרוק את האפליקציה שלך בחינם