OpenAI

16 במרץ 2026

מוצראבטחה

למה Codex Security לא כולל דוח SAST

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

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

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

הבעיה: SAST מותאם לניתוח זרימת נתונים

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

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

זו, כשלעצמה, אינה הסיבה לכך ש-Codex Security לא מתחיל מדוח SAST.

הבעיה העמוקה יותר היא מה קורה אחרי שמצליחים לעקוב אחר הנתונים מהמקור ליעד.

היכן הניתוח הסטטי מתקשה: אילוצים וסמנטיקה

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

האם ההגנה באמת עבדה?

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

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

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

דוגמה: בדיקת תקינות לפני פענוח

הנה דפוס שחוזר שוב ושוב במערכות אמיתיות.

יישום אינטרנט מקבל מטען נתונים בפורמט JSON, מחלץ ממנו redirect_url, בודק אותו מול ביטוי רגולרי שמגדיר רשימת ערכים מותרים, מפענח את קידוד ה-URL ומעביר את התוצאה לרכיב המטפל בהפניות.

דוח קלאסי של מעקב מהמקור ליעד יכול לתאר את הזרימה:

untrusted input → regex check → URL decode → redirect

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

אם הביטוי הרגולרי נבדק לפני הפענוח, האם הוא באמת מגביל את כתובת ה-URL המפוענחת כפי שמפרש אותה הרכיב המטפל בהפניות?

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

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

זה לא רק דפוס תיאורטי. ב-CVE-2024-29041⁠(נפתח בחלון חדש), התגלתה ב-Express בעיית הפניה פתוחה: כתובות URL פגומות יכלו לעקוף מימושים נפוצים של רשימות ערכים מותרים, בשל האופן שבו יעדי ההפניה קודדו ולאחר מכן פורשו. זרימת הנתונים הייתה פשוטה וברורה. השאלה הקשה יותר — וזו שקבעה אם הבאג קיים — הייתה אם בדיקת התקינות עדיין תקפה לאחר שרשרת הטרנספורמציות.

הגישה שלנו: מתחילים בהתנהגות, ואז מאמתים

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

כש-Codex Security נתקל בגבול שנראה כמו ״בדיקת תקינות״ או ״ניקוי״, הוא לא מסתפק בסימון וי. הוא מנסה להבין מה הקוד מבקש להבטיח — ואז מנסה להפריך את ההבטחה הזו.

בפועל, לרוב מדובר בשילוב של הפעולות הבאות:

  • קריאת מסלול הקוד הרלוונטי בהקשר המלא של המאגר, כפי שחוקר אבטחה היה עושה, וחיפוש פערים בין הכוונה למימוש. זה כולל גם הערות, אבל המודל לא בהכרח מאמין להן, כך שהוספת //Halvar says: this is not a bug מעל הקוד לא תבלבל אותו אם באמת יש בו באג.

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

  • ביצוע reasoning על אילוצים לאורך הטרנספורמציות, במקום להתייחס לכל בדיקה בנפרד. כשמתאים, זה יכול לכלול גם ניסוח פורמלי כבעיית ספיקות. במילים אחרות, אנחנו נותנים למודל גישה לסביבת Python עם z3-solver, והוא יודע להשתמש בה היטב בעת הצורך — בדיוק כפי שאדם היה נדרש לעשות כדי לפתור בעיית אילוצי קלט מורכבת במיוחד. זה שימושי במיוחד לבחינת גלישות של מספרים שלמים או באגים דומים בארכיטקטורות לא סטנדרטיות.

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

זה השינוי המרכזי: במקום לעצור ב-״קיימת בדיקה״, המערכת חותרת ל-״האינווריאנט מתקיים (או לא מתקיים), והנה הראיות״. והמודל בוחר את הכלי המתאים ביותר למשימה.

למה אנחנו לא נותנים ל-Codex Security דוח SAST כנקודת מוצא

תגובה מתבקשת היא: למה לא לשלב בין השניים? להתחיל מדוח SAST, ואז להשתמש בסוכן כדי לנתח לעומק.

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

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

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

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

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

כלי SAST עדיין חשובים מאוד

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

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

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

מבט קדימה

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

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

למידע נוסף על האופן שבו Codex Security סורק מאגרים, מאמת ממצאים ומציע תיקונים, עיינו בתיעוד שלנו⁠(נפתח בחלון חדש).

מחבר/ת

OpenAI