כותרת Penligent

אשליית המסנן: הפיכת מנגנון המסנן של JavaScript לנשק והגנה עליו

בארכיטקטורה הטהורה של פיתוח אתרים מודרני, ה- מסנן javascript פונקציה (Array.prototype.filter()) נחשב לאבן יסוד בתכנות פונקציונלי. הוא מאפשר למפתחים לכתוב קוד הצהרתי ונקי כדי לעבד מערכי נתונים.

עם זאת, עבור מהנדסי אבטחה יריבים וחברי צוות אדום, המושג "מסנן" ב-JavaScript מייצג דיכוטומיה מסוכנת. מצד אחד, הוא מהווה את הגורם העיקרי להתפשטות בקרת גישה בצד הלקוח פגיעויות. מצד שני, הגמישות של שפת JavaScript עצמה הופכת את שיטות הסינון לכלי רב עוצמה. גאדג'טים לעקיפת חומות אש של יישומים אינטרנטיים (WAF) ומטהרי קלט.

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

מסנן javascript Penligent

הפגם האדריכלי: מלכודת מסנן JavaScript בצד הלקוח

הפגיעות הנפוצה ביותר הקשורה ל- מסנן javascript אינו באג בשפה, אלא באג ביישום של מודלים אבטחה. בעידן של יישומי דף בודד (SPAs) ולקוחות עבים (React, Vue, Angular), מפתחים לעתים קרובות מבלבלים בין מצגת עם אבטחה.

הדפוס "אבטחה באמצעות עמימות"

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

JavaScript

// התבנית הפגיעה fetch('/api/v1/users') .then(response => response.json()) .then(data => { // המפתח משתמש במסנן javascript כדי "לאבטח" את התצוגה const visibleUsers = data.filter(user => user.role !== 'admin' && user.status === 'active'); renderTable(visibleUsers); });

לסורק DAST כללי, יישום זה נראה מאובטח. ממשק המשתמש אינו מציג נתוני מנהל. עם זאת, מהנדס אבטחה המשתמש ב-Burp Suite או ב-DevTools פשוט יודע את האמת.

וקטור התקיפה: IDOR ודליפת PII

ה מסנן javascript פועל בדפדפן המשתמש, שהוא סביבה לא מהימנה. הפגיעות כאן היא שה- מאגר נתונים מלא הועבר דרך הכבלים.

שלבי הניצול:

  1. יירוט: התוקף מתווך את התעבורה.
  2. בדוק: התגובה הגולמית ב-JSON מכילה אובייקטים כמו { "id": 42, "role": "admin", "pii_ssn": "xxx-xx-xxxx" }.
  3. עוקף: התוקף מתעלם לחלוטין מהלוגיקה של ממשק המשתמש.

זוהי כישלון של צמצום נתונים. יישום נכון מבצע סינון ברמת שאילתת מסד הנתונים (SQL איפה סעיף), ומבטיח שביטים רגישים לעולם לא יעזבו את מרכז הנתונים.

שימוש בתחביר כנשק: מסנן Javascript כגאדג'ט XSS

כאשר אנו מעבירים את המיקוד ל-Cross-Site Scripting (XSS), המונח מסנן javascript מקבל משמעות חדשה: המסננים ההגנתיים (WAFs/Sanitizers) שמנסים לחסום קוד זדוני.

התוקפים מחפשים ללא הרף "גאדג'טים" — שיטות סטנדרטיות וזמינות בסביבת ההפעלה של JavaScript, שניתן לנצל לרעה כדי להריץ קוד שרירותי מבלי להשתמש במילות מפתח חסומות כמו eval(), פונקציה(), או <script>.

מסנן javascript Penligent

עקיפת שרשרת הקונסטרוקטורים

WAFs לעתים קרובות מחפשים מקורות ברורים. אבל JavaScript הוא דינמי. ה- Array.prototype.filter שיטה היא פונקציה, ולכל פונקציה ב-JavaScript יש קונסטרוקטור. הקונסטרוקטור של פונקציה הוא פונקציה אובייקט, הפועל באופן דומה ל- eval().

אם WAF חוסם eval() אך מאפשר שיטות מערך, תוקף יכול לבנות מטען באמצעות מסנן השיטה עצמה.

הלוגיקה העוקפת:

  1. [] יוצר מערך.
  2. [].filter ניגש לפונקציית הסינון.
  3. [].filter.constructor ניגש לגלובלי פונקציה קונסטרוקטור.
  4. פונקציה('קוד')() מבצע את הקוד.

המטען:

JavaScript

// מטען סטנדרטי (נחסם על ידי WAF) eval(‘alert(1)’)

// התחמקות באמצעות גאדג'ט מסנן javascript [].filter.constructor(‘alert(1)’)()`

טבלה: טכניקות נפוצות לעקיפת מסנני Javascript

טכניקהמבנה המטעןמנגנוןהקשר אבטחה
שרשור קונסטרוקטורים[].filter.constructor('code')()משתמש בשרשרת האב טיפוס כדי להגיע ל- פונקציה קונסטרוקטור.עוקף מסנני מילות מפתח ב eval.
שימוש לרעה באיטרטור[].map.constructor('code')()דומה למסנן; עובד עם כל שיטת אב טיפוס של מערך.יתירות אם מסנן נמצא תחת פיקוח מיוחד.
הסתרת מחרוזות[].filter['c'+'onstructor']מפרק את מילת המפתח "constructor" למחרוזות מחוברות.עוקף כללי WAF מבוססי regex.
קידוד Unicode\\u0061lert(1)משתמש ב-unicode escapes לשמות פונקציות.מנתחי JS מפענחים זאת; מסננים פשוטים אינם עושים זאת.

כאשר מסננים נכשלים: זיהום אב טיפוס (CVE-2019-10744)

המושג "סינון" הוא חיוני בעת מיזוג אובייקטים. אם יישום מקבל קלט JSON וממזג אותו לאובייקט קיים מבלי להקפיד על סינון המפתחות, זה פותח את הדלת לזיהום אב טיפוס.

אחת הדוגמאות המשמעותיות ביותר לכך הייתה CVE-2019-10744 בשימוש נרחב לודאש ספרייה.

האנטומיה של הפגיעות

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

הניצול:

התוקף מספק מטען JSON המכיל מאפיין קונסטרוקטור המפנה לפרוטוטיפ.

JavaScript

const payload = '{"constructor": {"prototype": {"isAdmin": true}}}'; _.defaultsDeep({}, JSON.parse(payload));

ההשפעה:

מכיוון שהקלט לא עבר סינון, ההקצאה זיהמה את Object.prototype הבסיסי. לפתע, כל אובייקט בסביבת הריצה של JavaScript ירש את המאפיין isAdmin: true.

אם ליישום היה לוגיקת אימות כגון:

JavaScript

if (user.isAdmin) { grantAccess(); }

התוקף מקבל גישה ניהולית באופן מיידי, ויוצר מניעת שירות או RCE בהתאם להקשר של Node.js.

גילוי לוגיקה אוטומטי: היתרון של Penligent

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

  • סורקים מסורתיים: בדקו אם יש קריסות, קודי שגיאה (500) או מחרוזות XSS פשוטות המשתקפות. הם לא מבינים את זה. users.filter() מסתיר נתונים רגישים.
  • פער ה-AI: כדי לאתר את הבעיות הללו, אתה זקוק למנוע שמבין סמנטיקה של קוד ו זרימת נתונים.

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

  1. בדיקת זרימת נתונים: Penligent מפקח על תגובות ה-API מול ה-DOM המוצג. אם ה-API מחזיר 50 שדות, אך ה-DOM מציג רק 5, ה-AI מסיק כי קיים פוטנציאל ל מסנן javascript פגם לוגי ומסמן אותו כסיכון לדליפת נתונים.
  2. דור הגאדג'טים: במקום להשתמש ברשימה סטטית של מטעני XSS, Penligent מייצר מטענים באופן דינמי בהתבסס על האובייקטים הזמינים בסביבה. אם הוא מזהה ש- Array.prototype.filter זמין אך eval נחסם, הוא בונה את הספציפי [].filter.constructor עוקף את המטען.

באמצעות אוטומציה של "אינטואיציית ההאקר", Penligent מאפשר לצוותי אבטחה לזהות פגמים לוגיים עמוקים, אשר בדרך כלל מצריכים בדיקה ידנית של הקוד.

הגנה מעמיקה: חיזוק זמן הריצה

להגן מפני נשק מסנן javascript גאדג'טים ופגמים לוגיים, עלינו לאמץ אסטרטגיית הגנה רב-שכבתית.

  1. אימות בצד השרת: לעולם אל תסתמך על לוגיקה בצד הלקוח לצורך אבטחה. הסינון חייב להתבצע ברמת מסד הנתונים. השתמש ב-DTO (אובייקטי העברת נתונים) ב-backend כדי להסיר שדות רגישים לפני הסידור הסדרתי.
  2. אבות טיפוס בלתי משתנים: JavaScript כדי לחסל את כל סוג הפגיעות של זיהום אבות טיפוס, הקפיאו את אבות הטיפוס הסטנדרטיים של האובייקטים בעת הפעלת היישום. Object.freeze(Object.prototype); Object.freeze(Array.prototype); כך מובטח שגם אם מסנן javascript לא מצליח לחסום מפתח זדוני, זמן הריצה יציג שגיאה במקום לאפשר את השינוי.
  3. מדיניות אבטחת תוכן (CSP): CSP היא אמצעי ההגנה האולטימטיבי. כדי למנוע את ניצול ה-[].filter.constructor, עליך להשבית את ביצוע מחרוזות כקוד.
    • כותרת מומלצת: מדיניות אבטחת תוכן: default-src 'self'; script-src 'self'; object-src 'none';
    • קריטי: הימנע מהוספה 'unsafe-eval'. ללא 'unsafe-eval', הדפדפן יסרב לבצע קוד שנוצר על ידי פונקציה קונסטרוקטור, מה שהופך את גאדג'ט המסנן לבלתי שמיש.

סיכום

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

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

משאבים אמינים

שתף את הפוסט:
פוסטים קשורים