העוזר המונע על ידי AI שלך מציית להוראות שלו בערך ב-99% מהזמן, אך ה-1% החסר הוא המקום שבו תוקפים מכהים. על ידי הזנת פרומפט מתוכנן, משתמש זדוני יכול לגרום למודל להפעיל פונקציות שהוא לא אמור להפעיל, לגנוב נתונים או לבצע פעולות בעלות הרשאות גבוהות. התיקון אינו ניסוח מנומס יותר — אלא התייחסות לליקוי כבעיית הרשאות והסרת הכלים המסוכנים מהישג ידו של המודל.
למה הזרקת פרומפטים היא לא רק בעיית ניסוח
מפתחים מנסים לעיתים קרובות לחזק סוכנים (agents) באמצעות אזהרות באותיות גדולות, כללים ממוספרים או סעיפים כמו "אל תקרא לפונקציות מנהל". הגנות אלו מניחות שהמודל יצוית למשפט שאומר "אל תעשה X". בפועל, ניתן לשכנע את המודל להתעלם מההוראה על ידי ניסוח מחדש של הבקשה, משחק תפקידים של דמות אחרת, או פשוט הוספת הקשר נוסף. הגבול הלשוני הוא ניתן למשא ומתן; הפרומפט של התוקף הוא בלתי מוגבל ואינו עולה דבר בניסוי.
הפגיעות האמיתית טמונה ברשימת הכלים שהסוכן מקבל. כאשר סכימת הפרומפט מכילה פונקציה המעניקה הרשאות מנהל, למודל יש כעת מפה לכוח הזה. גם אם הפרומפט אומר "אל תשתמש בזה עבור לקוחות", עדיין ניתן לשכנע את המודל לקרוא לה מכיוון שהפונקציה קיימת בסביבת ההרצה שלו. לכן, הבעיה היא פער הרשאות: המערכת חושפת יכולות בעלות הרשאה למזמן שאין לו זכות להשתמש בהן.
אבטחת סוכנים על ידי הגבלת החשיפה
הדרך הפשוטה ביותר לסגור את הפער היא להפסיק לתת למודל גישה לכלים שאינו מורשה להשתמש בהם. חשבו על רשימת הכלים כמפתח API: אם המפתח אינו נוכח, הקריאה לא יכולה להתבצע. שום ניסוח חכם לא יוכל לזמן פונקציה שאינה נמצאת בהקשר הנוכחי.
הדרך הלא נכונה
Prompt: “You are an assistant. Do not use the adminDeleteUser function for regular customers.”
המודל עדיין רואה את adminDeleteUser בתיבת הכלים שלו ויכול להישפן להפעיל אותו.
הדרך הנכונה
Prompt schema for a regular customer: { “functions”: [ “searchCatalog”, “placeOrder” ] }
adminDeleteUser לעולם לא מופיע, ולכן למודל אין נתיב לקרוא לו.
שלושה כללים מעשיים למפתחים
- בנו רשימות כלים לפי בקשה – צרו את קטלוג הפונקציות בצורה דינמית, בהתבסס על ההרשאות של המזמן המאומת. לקוח רואה רק את הפונקציות שהוא צריך; מנהל רואה את הסט המלא.
- Fail closed – אם לא ניתן לאמת את זהות המשתמש, החזירו רשימה ריקה במקום ברירת מחדל גנרית של "כל הכלים זמינים". זה מבטיח שבקשה לא מאומתת לעולם לא תשיג כוח בלתי צפוי.
- הימנעו משימוש במצב משותף (shared state) – בעת שמירת הגדרות כלים בזיכרון מטמון (caching), לעולם אל תכתבו נתונים ספציפיים למשתמש על אובייקט משותף. השתמשו ב-copy-on-write או בעותקים לכל סשן (per-session) כדי שההרשאות של משתמש אחד לא יזלגו לבקשה של משתמש אחר.
אם הסכימה המוצגת למשתמש רגיל נראית זהה לזו המוצגת למנהל, גבול האבטחה הוא עדיין טקסט הפרומפט, ופרומפטים אינם מנגנון אבטחה אמין.
מה הוביל אותנו לכאן
הזרקת פרומפטים צצה כאשר מפתחים החלו לחבר מודלי שפה גדולים (LLMs) לתהליכי עבודה בייצור (production) שדרשו מהמודל לקרוא ל-APIs חיצוניים, להריץ קוד או לשנות מסדי נתונים. ה"הסקה" (reasoning) של המודל מונחית על ידי פרומפט שכולל גם רשימה של כלים זמינים. אבות-טיפוס מוקדמים הניחו שהמודל יצוית לכלל בשפה טבעית כמו "אל תמחק רשומות עבור משתמשים שאינם מנהלים". תוקפים הוכיחו במהירות שמעט משפטים נוספים יכולים לעקוף את הכללים הללו, ולגרום למודל לקרוא לאותה פונקציית מחיקה בכל זאת.
תגובת הקהילה הראשונה הייתה להדק את שפת הפרומפט, להוסיף סעיפים של "לעולם אל תעשה X", או להטמיע מסנני regex שמסירים טוקנים חשודים. צעדים אלו הפחיתו שימוש שגוי מקרי, אך לא עצרו יריב נחוש שיכול פשוט לנסח מחדש את הבקשה. הגורם הבסיסי — חשיפת פונקציות בעלות הרשאה למזמן שאינו מהימן — נותר בעינו.
מי מרוויח, מי מפסיד
ארגונים המאמצים הגדרת כלים לפי בקשה (per-request tool scoping) מרוויחים גבול ברור וניתן לאכיפה. ניתן לפרוס את הסוכנים שלהם בקנה מידה רחב מבלי לחשוש שפרומפט אחד מעוות ישחרר יכולות מנהל. צוותי ציות (compliance) מעריכים גם את עקבות הביקורת (audit trail): רשימת הפונקציות שנשלחה למודל היא תוצר מוחשי שניתן לתעד ולבדוק.
מפתחים המסתמכים על הגנות מבוססות פרומפט בלבד ממשיכים להתמודד עם מטרה נעה. הסוכנים שלהם עשויים להיראות תקינים בבדיקות, אך עלולים להיפרץ בשטח, מה שמוביל לדליפות נתונים, עסקאות לא מורשות או הפרות ציות. עלות הפריצה עולה בהרבה על המאמץ הנדרש לבניית רשימת כלים דינמית.
טיעון נגד: "פרומפטים טובים יותר הם מספיקים"
יש הטוענים כי באמצעות הנדסת הנחיות (instruction engineering) מספקת — פרומפטים בשכבות, הודעות מערכת ולמידת חיזוק ממשוב אנושי (RLHF) — ניתן לגרום למודל לכבד סעיפי "אל תעשה". המציאות היא שמודלי שפה הם מחוללים הסתברותיים; הם שוקלים את ההמשך הסביר ביותר, ולא כלל אבטחה נוקשה. גם עם מעקות בטיחות (guardrails) מכויינים, ניסוח חדשני עלול לחמוק, במיוחד כאשר התוקף יכול לבצע איטרציות אינסופיות ללא עלות. מעקות בטיחות שימושיים להפחתת רעש, אך הם לא צריכים להיות קו ההגנה היחיד.
מה כדאי לעקוב אחריו בהמשך
- Frameworks החושפים tool scoping כ-API ברמה ראשונה – צפו לספריות חדשות שיאפשרו לכם להצהיר על יכולות מבוססות-משתמש ולצמצם באופן אוטומטי את רשימת הפונקציות לפני בניית הפרומפט.
- "מניפסטים של פונקציות" (function manifests) סטנדרטיים – קבוצות בתעשייה עשויות להגדיר סכימת JSON המפרידה בין פונקציות ציבוריות לפונקציות בעלות הרשאות גבוהות, מה שיקל על יצירת מניפסטים ספציפיים לבקשה.
- אכיפה בזמן ריצה (Runtime enforcement) – פלטפורמות מסוימות מתנסות בהרצה בסביבת ארגז חול (sandboxed execution) הבודקת את הטוקן של הקורא מול הפונקציה שנקראת, ובכך מוסיפה שכבה שנייה מעבר להגדרת היקף הפרומפט (prompt scoping).
השורה התחתונה ברורה: התייחסו להזרקת פרומפטים (prompt injection) כאל פגם בהרשאות (authorization flaw). על ידי הסרת כלים לא מורשים מתיבת הכלים של המודל, אתם מבטלים את שטח התקיפה שפרומפט מנוסח בחוכמה מנסה לנצל. פרומפטים יכולים להנחות התנהגות; הם אינם יכולים להחליף בקרת גישה תקינה.
