Skip to content
בדיקת אבטחה לקוד שנכתב על ידי AI במוצרי SaaS בפרודקשן8 minOct 3, 2026

שער האבטחה שאני מריץ לפני שקוד של AI עולה לאוויר

AI כותב את רוב הקוד שלי, ולפני כל מרג׳ רץ שער אבטחה אחד. מה הוא בודק, איפה Claude Code טועה בהרשאות, ואיך מקימים את זה באותו יום.

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

קוד של AI לא נופל במקומות מפתיעים, הוא נופל בהרשאות

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

ב-Brainers Club יש יותר מ-10,000 חברים. The Next Level הוא פורק white-label של אותה פלטפורמה. זה אומר קודבייס אחד שבו כל קריאה צריכה לענות על שאלה שהקוד עצמו לא כותב במפורש: באיזה מועדון האדם הזה נמצא, והאם השיעור הזה שלו. הסוכן קורא את הסכמה, רואה עמודה בשם club_id, וכותב משהו שנראה הגיוני. זה עובר את הטסטים שלי, כי הטסטים שלי מתחברים כמשתמש אחד. הפספוס מתגלה רק כשיש מועדון שני במערכת, וזה בדיוק המצב שבפרודקשן קיים תמיד ובסביבה מקומית כמעט לא. זו לא רשלנות, זה סוכן שממקסם את הבקשה שמונחת לפניו, בלי לדעת איזו טבלה היא זו שדליפה ממנה מסיימת קשר עם לקוח. את הפער הזה לא סוגרים עם פרומפט טוב יותר. סוגרים אותו עם בדיקה שרצה בין אם מישהו זכר לשים לב באותו יום ובין אם לא.

שלוש הבדיקות, ומתי כל אחת רצה

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

  • טסטים של הפרדה בין לקוחות, מול Postgres אמיתי עם לפחות שני ארגונים ושני תפקידים בדאטה. כל טסט בודק שמשתמש של ארגון אחד מקבל אפס שורות מהארגון השני, ולא שהבקשה מחזירה שגיאה. תוצאה ריקה בשקט היא ההתנהגות הנכונה, והיא היחידה שלא מספרת לתוקף מה קיים.
  • מעבר ביקורת שעוסק בהרשאות בלבד. אני נותן לסוכן את הדיף והוראה אחת: תתעלם מסטייל, תתעלם מביצועים, תן לי כל שורה שבה קורא יכול להגיע לנתונים של מישהו אחר, ותגיד איזו בדיקה עוצרת אותו. שאלה צרה מחזירה תשובה שאפשר לעבוד איתה. ״תעשה ריוויו״ מחזיר סיכום של מה הקוד עושה.
  • סריקת תלויות וסודות על הדיף, כי הדרך הכי מהירה שסוכן שובר מוצר היא להוסיף חבילה למשהו שהספרייה הסטנדרטית כבר עשתה, או להכניס מפתח לתוך קומפוננטה שנשלחת לדפדפן.
  • קריאה ידנית של כל מה שנוגע בהתחברות, בחיוב או ב-row level security. אני הריוויוער היחיד במוצרים האלה, ולכן שם אני שם את הראש במקום לפזר אותו על כל הדיף.

למה הפסקתי לתת לסוכן לבדוק את האבטחה של עצמו

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

// רץ ב-CI על כל pull request, מול דאטבייס עם דאטה מוכנה
test('חבר במועדון A לא יכול לקרוא שיעורים של מועדון B', async () => {
  const client = await signInAs(members.clubA)

  const { data, error } = await client
    .from('lessons')
    .select('id')
    .eq('club_id', clubs.clubB.id)

  expect(error).toBeNull()
  expect(data).toEqual([])
})

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

כמה זה עולה, בכל הכנות

הכנת הטסטים לקחה לי אחר צהריים אחד והם רצים בשניות. מעבר הביקורת עולה קריאת סוכן אחת נוספת לכל פול ריקווסט. זה כל המחיר, והוא קונה בחזרה בדיוק מה שחסר כשמפתחים לבד: אדם שני שקורא את הדיף עם אינטרס אחר. את זה אני מלמד את 600 התלמידים שאני מנטור שלהם ב-nCode ואת בעלי העסקים שעוברים את סדנת Claude Code, וההתנגדות תמיד זהה: אין לי זמן להקים את זה. יש עוד פחות זמן להעביר לקוח מפלטפורמה שדלפו ממנה החברים שלו.

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

FAQ

קוד שנכתב על ידי AI פחות מאובטח מקוד שמפתח כותב בעצמו?

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

מה הבדיקה המינימלית שכדאי להוסיף אם עושים רק דבר אחד?

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

אפשר לבקש מ-Claude Code לעשות ריוויו אבטחה לקוד שהוא עצמו כתב?

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

איך עושים ריוויו לקוד של AI כשאני המפתח היחיד במוצר?

מפסיקים לקרוא את כל הדיף באותה רצינות ומעבירים את הראש לנתיבים שיכולים לעלות בלקוח: התחברות, הרשאות, חיוב ו-row level security. כל השאר עובר לאוטומציה. טסטים מכסים הפרדה בין לקוחות, סריקה מכסה תלויות חדשות ומפתחות שנחשפו, וסשן סוכן נפרד עונה על שאלת הרשאות אחת לכל פול ריקווסט. ככה כמה מוצרים חיים עם אלפי משתמשים משלמים נשארים ניתנים לביקורת של אדם אחד.

עוד מהבלוג