Agent Sandboxing — איך מאפשרים לסוכן להריץ קוד בלי לסכן את המערכת

מאת צוות מדיה דיל · 12.08.2026 · AI Security · 5 דק׳

מדריך טכני להרצת קוד שנוצר על ידי Agent בבידוד אמיתי - gVisor, Firecracker, WASI, מגבלות רשת וקבצים, ומתי בכלל מותר להריץ אוטומטית בלי אישור אנושי.

צוות פיתוח שהטמיע Agent שמייצר ומריץ קוד Python לצורך ניתוח נתונים גילה תוך שבועיים שהוא בעצם בנה שרת הרצת קוד מרוחק (RCE) לכל דורש - רק עם שכבת שיווק של "AI Assistant" מעליו. ה-Agent קיבל בקשה בשפה טבעית, כתב קוד, קיבל אישור אוטומטי, והריץ אותו על אותה מכונה שבה רץ גם ה-Backend הראשי, עם גישה לאותו קובץ סביבה (.env) שמכיל את כל מפתחות ה-API של החברה. איש לא תכנן את זה ככה במכוון - זו התוצאה הטבעית של להוסיף "יכולת הרצת קוד" ל-Agent בלי לעצור ולשאול: איפה בדיוק זה רץ, ומה זה יכול לגעת בו. Sandboxing נכון הוא לא Feature אופציונלי ל-Agent שמריץ קוד - הוא תנאי סף.

מודל האיום: מה בדיוק אנחנו מפחדים ממנו

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

יש גם ממד זמן שקל לפספס: איום שרלוונטי רק לרגע ההרצה הבודד. אם ה-Sandbox נשאר "חם" בין הרצות כדי לחסוך זמן אתחול (למשל Container שממתין לבקשה הבאה של אותו משתמש), כל מידע שנשאר בזיכרון או בדיסק שלו מהרצה קודמת - כולל תוצאות חישוב, קבצים זמניים, ואפילו state של תהליכים - עלול לדלוף להרצה הבאה, גם אם היא שייכת למשתמש אחר לגמרי. זו לא תיאוריה: מחקרים על סביבות Serverless משותפות הראו דליפת נתונים בין Invocations שנועדו להיות מבודדים. המשמעות המעשית היא ש"Sandbox חם" ו"Sandbox מבודד מבחינת נתונים" הם שני יעדים שסותרים זה את זה, וצריך להחליט במפורש על איזה מהם מוותרים - בדרך כלל מוותרים על החימום ומשלמים במחיר Cold Start גבוה יותר, כי מחיר הדליפה גבוה בהרבה.

שכבות הבידוד בפועל

אין "פתרון Sandboxing" אחד - יש היררכיה של מנגנוני בידוד, וכל אחד עוצר סוג אחר של בריחה. Container רגיל (Docker סטנדרטי) משתף את ה-Kernel של המארח, ולכן פגיעות ב-Kernel (Container Escape דרך CVE ב-syscalls) עוקפת אותו כמעט לגמרי. gVisor מוסיף שכבת Kernel מדומה בין הקונטיינר לבין ה-Kernel האמיתי, ומיירט syscalls - זה סוגר משמעותית את משטח התקיפה במחיר של Overhead בביצועים. Firecracker microVMs (המנוע שמאחורי AWS Lambda) הולך צעד רחוק יותר ומריץ כל הרצה בתוך VM אמיתי וזעיר, עם Virtualization חומרתית מלאה - זו כרגע רמת הבידוד הכי חזקה שסבירה מבחינת עלות תפעולית להרצת קוד שנוצר דינמית. לחלופין, WebAssembly (WASI) מציע מודל אחר לגמרי: הקוד רץ בתוך VM בעל capability-based sandbox מובנה, שבו לקוד אין שום גישה למשאבי מערכת מלבד מה שהוענק לו במפורש - גישה שמזכירה את העקרונות שמתוארים במדריך על אבטחה מבוססת יכולות.

הכלל המעשי: אם הקוד שה-Agent מריץ יכול להגיע ממשתמש חיצוני או מהקשר לא מהימן, Docker רגיל לא מספיק. צריך לפחות gVisor, ועדיף microVM לכל הרצה בודדת עם Teardown מלא בסיום.

מה שקורה מסביב ל-Sandbox חשוב לא פחות

גם ה-Sandbox החזק ביותר לא עוזר אם התצורה סביבו רשלנית. שלושה כללים לא משא ומתן: ראשית, לכל הרצה יש Filesystem זמני ונקי (Overlay שנמחק בסיום) - לעולם לא Mount של תיקיית העבודה האמיתית או קבצי סביבה. שנית, גישת רשת (Network Egress) חסומה כברירת מחדל, ונפתחת רק ל-Allowlist מפורש של כתובות שהקוד באמת צריך - אחרת קוד שנוצר יכול לשלוח נתונים החוצה בקריאת HTTP פשוטה, מה שהופך את כל דיון ה-Sandboxing לחסר משמעות. שלישית, מגבלות משאבים אמיתיות ב-cgroups: CPU, זיכרון, ומספר תהליכים, כדי שקוד שנתקע בלולאה אינסופית או שמנסה Fork Bomb לא יפיל את שאר המערכת.

  • ללא גישת רשת יוצאת כברירת מחדל, עם Allowlist מפורש בלבד
  • Filesystem זמני שנמחק לחלוטין בסיום כל הרצה
  • מגבלת זמן ריצה קשיחה (Timeout) שלא ניתנת לעקיפה מתוך הקוד עצמו
  • ללא משתני סביבה של המערכת המארחת - רק מה שהוזרק במפורש להרצה הספציפית

תקציב אמון: מתי בכלל לאשר הרצה אוטומטית

גם עם Sandbox מושלם, יש שאלה נפרדת: האם בכלל להריץ קוד בלי אישור אנושי. התשובה תלויה במידת ההיפוך (Reversibility) של מה שהקוד עלול לעשות בתוך ה-Sandbox עצמו - לא רק מחוצה לו. קוד שמנתח נתונים וכותב לקובץ פלט זמני יכול לרוץ אוטומטית. קוד שמקבל אישור לגשת ל-API חיצוני עם Side Effect אמיתי (למשל שליחת בקשה שמשנה מצב במערכת צד שלישי) צריך שער אישור נפרד, גם אם ה-Sandbox עצמו אטום לחלוטין - כי הנזק לא קורה בתוך ה-Sandbox אלא דרך ה-API שהוא קורא לו. העיקרון הזה מתקשר ישירות לרעיון של Least Agency: כמה חופש פעולה עצמאית מגיע לקוד, לא רק כמה הרשאות טכניות יש לו.

ניטור ותגובה: לתפוס בריחה בזמן אמת

Sandboxing מונע חלק גדול מהתקיפות, אבל לא את כולן - יש להניח שיום אחד תתגלה שיטת בריחה חדשה. לכן חובה שכבת ניטור: לוג מלא של כל syscall חריג, התראה על ניסיון גישה לרשת חסומה, והתראה על ניסיון קריאה לנתיבי מערכת מחוץ ל-Sandbox. שילוב עם eBPF ברמת המארח מאפשר לראות בזמן אמת ניסיונות בריחה בלי להסתמך רק על הלוגים של ה-Sandbox עצמו, שעלול להיות בדיוק מה שנפרץ. כל הרצה חריגה צריכה להפעיל מסלול חירום מהיר - נושא שמפורט בהרחבה במדריך על Kill Switch לסוכני AI, שמתאר איך עוצרים פעילות של Agent בזמן אמת כשמשהו נראה לא תקין.

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

תגיות: Agent Sandboxing · gVisor · Firecracker · WASI · code execution security · container escape

← חזרה לבלוג · צור קשר