כל שפת תכנות מגיעה עם סט משל פגיעות אבטחה משל עצמה, ו-JavaScript אינה חריגה. פיצוץ פגיעות אבטחה של JavaScript עשוי לגרום להשפעת נתונים, לתפיסת מפגרות, לגישה לנתונים לא מורשים ועוד. אף שנהוג לקשר אותו בעיקר עם פונקציות צד לקוח, פגיעות אבטחה של JavaScript עשויות גם להוטיב איומים משמעותיים בסביבות צד שרת.
לכל יישום, אמון הלקוח חשוב ביותר. ניהול האמון הזה מחייב שמירה על נתוני הלקוח והבטיחות של היישומים. למרבה המזל, יישום ההגנות הראוי עשוי להוזיל את הסיכונים הללו ולשפר את הבטיחות של היישום שלך.
במאמר זה, נסקור חלק מהאיומים המצוים ביישומי JavaScript הנפוצים ביותר ונדון בכלים ובאסטרטגיות יעילים להגנת היישום שלך מהתקפות אפשריות.
פריצת קרוס-סייט סקריפטינג
פריצת קרוס-סייט סקריפטינג (XSS) היא פגיעת אבטחה שמאפשרת לתוקף להכניס קוד צד לקוח זדיתי לאתר. לפי פרויקט אבטחת יישומי רשת האינטרנט הפתוח (OWASP) העשירייה העליונה של פגיעות אבטחה ב-2021, XSS דורגת ככיוון לתקפה השלישית ביותר נפוצה.
איך להוזיל את XSS
אימות קלט
וודא שקלט המשתמש עומד בסוגי נתונים, פורמטים וטווחים צפויים. הסר או הפינוי של תווים פוגעניים פוטנציאליים כדי למנוע פלישה.
function validateInput(input) {
return input.replace(/[^a-zA-Z0-9]/g, ''); // Allow only alphanumeric characters
}
קידוד פלט
המרה של תווים מיוחדים בפלט למקבילים של יישות HTML כדי לנטרל סקריפטים זדוניים בטרם הצגתם.
function encodeHTML(input) {
return input.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
Clickjacking
Clickjacking הוא התקפת מעיות שמטעה משתמשים ללחיצה על אלמנט שהם לא מתכוונים לפעול איתו. הטכניקה משתמשת בהטמעת אתר תקין בתוך אתר זדוני — לעתים קרובות באמצעות <iframe>
HTML מוסתר או במיקום מטעה — על מנת לחטוף פעולות משתמש. כתוצאה, מתקפים יכולים לגנוב פרטי כניסה, לרכוש הרשאות בלתי מורשות, או אפילו להטעות משתמשים להתקנת תוכנות זדוניות ללא ידיעתם.
דרך אחת נפוצה להשיג זאת היא להשתמש ב־CSS להוספת כפתור חופף שמגדיל או מקטין את השקיפות (opacity
) עד כמעט 0. זה מטעה את המשתמש ללחיצה על כפתור או קישור לא רצוי.
כיצד למנוע Clickjacking
האפשרויות X-Frame-Options מציינות לדפדפן האם האתר יכול להיות מוטבע בתוך iframe. יש לה שלוש אפשרויות:
- DENY – מונע מהעמוד להופיע באופן מוטבע בכלל בתוך iframe
- SAMEORIGIN – מאפשר לעמוד להיות מוטבע רק אם הבקשה מגיעה מהתחום השורשי
- ALLOW-FROM – מאפשר לעמוד להיות מוטבע רק על ידי דומיין מסוים ומהימן
ב־Node.js ניתן להשתמש ב־helmet
כדי להגדיר את האפשרויות הללו כפי שמוצג למטה:
const helmet = require("helmet");
const app = express();
app.use(
helmet({
xFrameOptions: { action: "sameorigin" },
}),
);
מגנה יעיל נגד Clickjacking הוא ליישם את הכותרת מדיניות אבטחת תוכן (CSP). CSP מספק שליטה גרנולרית על אופן ומקום בו ניתן להטביע תוכן, מונע חפיפת מסגרת לא מורשית.
כדי להפחית את סיכוני ה־clickjacking, כלול את ההוראה frame-ancestors
בכותרת ה־CSP שלך. לדוגמה:
Content-Security-Policy: frame-ancestors 'self' https://www.example.org;
מדיניות זו מבטיחה כי המסמך שמוגן יכול להיות מטבע על ידי מקורו העצמי ('self'
) ודומיינים שאושרו באופן מפורש, כמו example.org
. זה מונע את כל הניסיונות הלא מורשים להטביע את התוכן, מגנה על המשתמשים מפני התקפות clickjacking.
הערה: אם frame-ancestors ו־X-Frame-Options מוגדרים גם, אז דפדפנים שתומכים ב־frame-ancestors יתעלמו מ־X-Frame-Options.
גניבת בקשת אתר מצד צד (CSRF)
CSRF (לפעמים נקרא גם XSRF) מנצל את האמון של אתר בדפדפן של המשתמש על ידי ביצוע בקשות לא מורשות בשמו של המשתמש. התוקפים מטעים משתמשים לבצע פעולות בלתי ידועות להם, שעשויות להוביל לפריצות נתונים או עסקאות לא רצויות. כמה דוגמאות הן עדכון פרטי המשתמש האישיים של הקורבן, התחלת העברת כספים מחשבון הבנק של הקורבן, או אפילו הפניית משלוח חבילה לכתובת שונה.
בואו נבחן דוגמה ספציפית לתופעה זו. אתם בוקרים באתר הבנק שלכם ונכנסים למערכת. נניח שאתם מקבלים אימייל על תחרות בהשגחת הבנק שמתחזה להיות הבנק שלכם. הקישור מביא אתכם לעמוד אינטרנט שמראה כאילו אינו פוגע. מאחורי הקלעים, בקשת POST מתפעלת ונשלחת לאפליקציית הבנק החוקית.
curl --location --request POST 'https://acmebank.com/transfer?routing=852363&fromAccountNumber=123456789&toAccountNo=987654321' \
--header 'Cookie: session=acmebanksessionvalue'
בצידו של אפליקציית acmebank.com, התג "script" מגיש את הטופס כשהמשתמש טוען את העמוד, ללא אימות משתמש או אפילו הבנה מצד המשתמש למה שקורה, כפי שמוצג למטה.
<html>
<body>
<form action="https://acmebank.com/transfer" method="POST">
<input type="hidden" routing="852363" fromAccountNo="123456789" toAccountNo="987654321" amount="5000" />
</form>
<script>
window.addEventListener("DOMContentLoaded", () => {
document.querySelector("form").submit();
});
</script>
</body>
</html>
הטופס מעלה קריאה בקשת הבאה לאפליקציית הבנק האמיתית, acmebank. הבקשה מכילה את עוגיית הסשן החוקית של המשתמש, אך מכילה את מספר חשבון הבנק שלנו! מאחר והסשן שלכם עם הבנק עדיין פעיל, ההעברה לסכום תתבצע אם אין במקום אימות נוסף.
איך להגן עצמכם מ-CSRF
הגדירו את ה-SameSite ל-Strict. זה ישליט באם עוגייה תשלח עם בקשות צד-אתר.
- עוגיות הסשן צריכות להיות בעלות תוקף קצר. דרושה הפעלת מחדש לפעולות רגישות כדי להפחית סיכונים.
השתמש באסימוני ייחודיות של סשן למניעת CSRF. אז ניתן לכלול את האסימון הזה בטופס שנשלח על ידי הדפדפן. לכל בקשה, השרת משווה את האסימון שנשלח מהלקוח עם הערך השמור שלו עבור הסשן. השתמש בספריית csrf-csrf כדי להגדיר אסימוני ייחודיות.
גניבת נתוני הסשן
גניבת הסשן מתרחשת כאשר תוקף גונב את אסימון הסשן של המשתמש, מאפשרת לו להתחזות למשתמש ולקבל גישה לא מורשית לחשבונם.
איך למנוע גניבת סשן
השתמש בעוגיות מאובטחות
הגדר את הדגלים Secure
ו־HttpOnly
על עוגיות הסשן כדי למנוע גישה לא מורשית. הגדרת המאפיין Secure מונעת מעוגית הסשן להיות משודרת בטקסט ברור ומאפשרת רק להעביר אותה על חיבורי HTTPS בלבד. הגדרת המאפיין Http-Only
מאפשרתלדפדפן לא לאפשר גישה לעוגית מה-DOM מה שמונע התקפות מבוססות סקריפט מצידה של הלקוח מלגשת לנתונים הרגישים שמאוחסנים בעוגיות אלה.
הפעל אימות רב-גורמי (MFA)
הוסף שכבת אבטחה נוספת לאימות משתמשים. זהו שיטה נפוצה מאוד שתיתקל בה ביישומים מאובטחים רבים. ניתן לשלב בקלות עם ספקים כגון Okta ו־Duo.
יישם פקיעת חיבור
פקודה של פקיעת חיבורים רקמים להפחתת חלונות התקפה.
שיטות קידוד וכלים לאבטחה ברמה גבוהה
סריקת שורשים.
סורק התקינות שומר על אבטחת היישום שלך. סריקת הספריות, הרשת, היישומים והמכשירים שלך עוזרת לגלות נקודות חולשה שמתקפים עשויים לנצל. כלים כמו Snyk ו־Sonarqube יכולים להיות משולבים בקלות בבסיסי קוד JavaScript. כלים אלה עובדים במקביל עם רשימות מוכרות של נקודות חולשה שמתוחזקות על ידי OWASP. עם שילוב חלקי כחלק מתהליך הפיתוח, סורקים אלה מספקים למפתחים וצוותי אבטחה תראות בזמן אמת ומדויקות לתוך נקודות חולשה בקוד ופתרונות לתיקון עימם.
בדיקות חדירה והערכות
מפתחים יכולים לאמץ את פרקטיקות בדיקת החדירה כדי לחקור בצורה פעילה נקודות חולשה פוטנציאליות ביישום. האתגרים האתיים מדמו תקיפות בעולם האמיתי כדי להעריך את סטטוס האבטחה של יישומי האינטרנט על ידי שינוי קוד JavaScript ואינטראקציות משתמש.
כדי לבצע זאת, מפתחים יכולים לכתוב קוד JS מותאם אישית כדי לדמות את התרחילים, או להשתמש בכלים מתקדמים לבדיקת חדירות שמשתמשים ב-JavaScript כדי לאוטומטיזציה של תהליך סריקה לאי-אבטחות נפוצות כמו XSS, באמצעות OWASP ZAP. מידע נוסף על בדיקות חדירה זמין ב-מדריך הרשמי של OWASP.
Web Application Firewall (WAF)
ככל שיישומים גדלים, כך גדל גם תעבורת הרשת, מה שמגביר את חשיפתם לתקיפות. התקנת חומת אש ליישום אינטרנט (WAF) עוזרת להגן על היישום מפני תעבורת זדונית על ידי סינון ומעקב אחר בקשות HTTP. זה כולל שילוב עם ספקי WAF צד שלישי כמו Cloudflare או AWS WAF. עם WAF, ניתן להגדיר כללים כגון:
- מדינה או מיקום גיאוגרפי ממנו מגיעות הבקשות.
- כתובת IP, טווחי CIDR ושמות דומיין ממנו מגיעות הבקשות.
- הגבלת אורכי בקשות ופרמטרים שאותם כדאי למנוע תקיפות הכנסה באמצעותם.
- קוד SQL המכיל סיכוי להיות זדוני. תוקפים מנסים לחלץ נתונים ממסד הנתונים שלך על ידי הטמעת קוד SQL זדוני בבקשת האינטרנט. זה נקרא הכנסת SQL.
- איתור וחסימת סקריפטים מוטבעים שעשויים להיות חלק מתקיפות XSS.
גם WAF יכול לעזור בהפחתת התקפות של שירות דחויות מבוזרות (DDoS), ולוודא זמינות של היישום.
לשמירה על תקינות הנתונים
יש ליישם אמצעים חזקים לשמירה על תקינות הנתונים כשמאוחסנים או נגישים מידע מאובטח. הפעולות המומלצות כוללות:
- לאכוף מדיניות סיסמאות חזקה ולקדם שימוש במנהל סיסמאות. בנוסף, עליך לעודד את המשתמשים שלך להשתמש במנהל סיסמאות כדי שיהיה באפשרותם להשתמש בסיסמאות מורכבות יותר ולא יצטרכו לדאוג לזכור אותן (השתמש ב־LastPass או ב־1Password).
- להגן על האתר מהתקפות כוח גולמיות על דפי התחברות עם הגבלת קצב, נעילת חשבונות לאחר מספר מסוים של ניסיונות כושלים, ואתגרי CAPTCHA.
- בשימוש בכותרות HTTP כגון:
- HTTP Access-Control-Allow-Origin לשליטה על אילו מקורות יכולים לגשת למשאבים.
- HTTP X-Content-Type-Options למניעת סיכוני אבטחת סוג MIME.
- Subresource integrity (SRI) להבטחת שמשאבים מ-CDN אינם נערפים.
מסקנה
אבטחת JavaScript היא תהליך מתמשך שדורש גישה פרואקטיבית כדי להגן על אפליקציות מפני איומים מתפתחים. יישום פרקטיקות מיטביות כמו אימות קלט, כותרות CSP, ניהול מושבים בטוח, וסריקות פגיעות יכול להפחית באופן משמעותי את הסיכון להתקפות כמו XSS, CSRF, וחטיפת מושבים.
בנוסף, שימוש בכלי אבטחה כמו WAFים, בדיקות חדירה, ו-MFA מחזק את עמידות האפליקציה. מתן עדיפות לאבטחה בכל שלב של הפיתוח יאפשר למפתחים לבנות אפליקציות חזקות, מהימנות מצד המשתמש, אשר נשארות מוגנות מפני איומי סייבר מודרניים.
Source:
https://dzone.com/articles/enhancing-security-in-javascript