ניתוח תוך-פרוצדורי לעומת ניתוח בין-פרוצדורי

ניתוח תוך-פרוצדורלי לעומת ניתוח בין-פרוצדורלי: מדוע ההבדל קובע את מה שתמצא

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

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

ראה את גרף השיחות המלא, לא רק קובץ אחד

SMART TS XL עוקב אחר זרימות נתונים ב-COBOL, Java, Python וכל שפה שאתם מספקים.

מידע נוסף

מהי אנליזה תוך-פרוצדורלית?

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

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

פִּיתוֹן

def process_input(user_data):
    # Intraprocedural analysis sees: user_data used here
    query = "SELECT * FROM users WHERE id = " + user_data  # flagged: string concat in SQL
    return query

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

פִּיתוֹן

def get_user_id(request):
    return request.args.get("id")  # untrusted input

def build_query(user_id):
    return "SELECT * FROM users WHERE id = " + user_id  # looks safe in isolation

def handle_request(request):
    uid = get_user_id(request)
    query = build_query(uid)    # vulnerability spans three functions
    db.execute(query)

כעת מקור הנתונים המוכתמים (request.args.get("id")) נמצא בפונקציה שונה מהכיור המסוכן (db.execute(query)אף פונקציה אינה מכילה מספיק מידע כדי שכלי תוך-פרוצדורלי יוכל לזהות את הפגיעות. get_user_id נראה בסדר, זה פשוט קורא מתוך בקשה. build_query נראה בסדר, זה לוקח פרמטר ובונה מחרוזת. handle_request נראה בסדר, הוא קורא לפונקציות ומבצע שאילתה. הזרקת SQL אמיתית, ניתנת לניצול ובלתי נראית לכל כלי שאינו חוצה גבולות פונקציות.

במה אנליזה תוך-פרוצדורלית טובה

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

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

הכלים בקטגוריה זו כוללים את ESLint, Pylint, Clippy (Rust), golangci-lint, Checkstyle, ורוב כלי הלינטר. הם חיוניים ובעלי ערך עבור סוג הבעיות שהם יכולים לראות. מגבלתם היא מבנית, לא ליקוי איכות.

מהי ניתוח בין-פרוצדורלי?

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

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

שלוש פונקציות הזרקת ה-SQL לעיל הן דוגמה פשוטה. ניתוח בין-פרוצדורלי אמיתי מטפל ב:

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

תאווה

// Interprocedural vulnerability: three-hop taint flow
public class UserController {
    public String handleRequest(HttpServletRequest request) {
        String userId = request.getParameter("id");    // source: untrusted input
        User user = userService.getUser(userId);       // taint flows through call
        return generateReport(user);                   // taint reaches sink
    }
}

public class UserService {
    public User getUser(String id) {
        // id is tainted -- passed to repository
        return userRepository.findByRawId(id);         // taint propagates
    }
}

public class UserRepository {
    public User findByRawId(String id) {
        String query = "SELECT * FROM users WHERE id = " + id;  // sink: SQL injection
        return db.execute(query);
    }
}

כלי תוך-פרוצדורי הבוחן UserRepository.findByRawId רואה בבידוד פרמטר id משורשר לשאילתת SQL. זה נראה אולי לא בטוח, אבל לכלי אין דרך לדעת היכן id אם מגיע ממנו, זה יכול להיות ערך מהימן ומאומת מקוד פנימי. לכן, כלי תוך-פרוצדורי מסמן אותו כבעיה אפשרית (מייצר תוצאות חיוביות שגויות בכל שאילתה שעברה פרמטרים אך מובנית בבסיס הקוד) או מתעלם ממנו (מייצר תוצאות שליליות שגויות על פגיעויות אמיתיות). ניתוח כתמים בין-פרוצדורי מזהה אם נתונים לא מהימנים זורמים דרך פונקציות לפעולות רגישות. הוא עוקב אחר הנתונים מ request.getParameter("id") דרך userService.getUser(), דרך userRepository.findByRawId(), כדי db.execute(query), המייצר ממצא מדויק עם נתיב זרימת הזיהום המדויק, ללא תוצאה חיובית כוזבת, ללא תוצאה שלילית כוזבת.

שלוש רמות הניתוח: ספקטרום מעשי

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

רמת ניתוחהיקףמה שהוא רואהמה זה מפספסכלים
לקסיקלי / תחביריאסימונים בודדים ותחבירעיצוב, מתן שמות, תחביר בסיסיהכל סמנטייפה יותר, חלודה יותר, גמורה
תוך-פרוצדוריפונקציה בודדתזרימת נתונים מקומית, מורכבות, זרימת בקרה בתוך הפונקציהפגיעויות חוצות-פונקציות, בעיות ארכיטקטוניותESLint, Pylint, Clippy, golangci-lint
בין-פרוצדורה רדודהרמה אחת של עומק שיחהקשרים ישירים בין מתקשר לקוראזרימות עמוקות מרובות קפיצותכמה כללי Semgrep, כללי SAST בסיסיים
בין-פרוצדורה מלאהחציית גרף שיחות מלאהזרימות זיהום מרובות-הופות, ניתוח תלוי-הקשרפולימורפיזם בזמן ריצה (חלקי), קריאות רפלקטיביותCodeQL, הסקת מסקנות של פייסבוק, SMART TS XL
תוכנית שלמה / סמנטיתסמנטיקה מלאה של התוכניתתכונות הניתנות להוכחה פורמליתמדרגיות על בסיסי קוד גדולים מאודהסקה, קאני (חלודה), כלי אימות פורמליים

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

כיצד פועל ניתוח בין-פרוצדורלי: שלוש גישות מרכזיות

1. ניתוח מבוסס סיכום

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

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

2. גישת מחרוזת קריאה (ניתוח רגיש להקשר)

ניתוח תלוי-הקשר מבחין בין אתרי קריאה שונים של אותה פונקציה. אם sanitize(input) כאשר נקראת עם נתונים מהימנים במקום אחד ונתונים לא מהימנים במקום אחר, ניתוח תלוי-הקשר מייצר תוצאות שונות עבור כל אתר קריאה במקום להניח באופן שמרני את התרחיש הגרוע ביותר עבור כולם. זה מפחית משמעותית תוצאות חיוביות שגויות בהשוואה לניתוח שאינו תלוי-הקשר.

מסגרת IFDS (בין-פרוצדורלית, סופית, חלוקתית, תת-קבוצה) מנסחת זאת כבעיית נגישות גרפים. במסגרת IFDS, זרימת הגורמים המזהמים מתוארת על ידי פונקציות חלוקה על פני תחום סופי של עובדות, וההתפשטות הבין-פרוצדורלית מצטמצמת לנגישות גרפים. ניסוח זה הופך את ניתוחי IFDS למדויקים ויעילים מבחינה אלגוריתמית, כלים כמו FlowDroid (לאנדרואיד) ומספר שאילתות CodeQL משתמשים ב-IFDS באופן פנימי.

3. בניית גרף שיחות

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

שיגור סטטי (קריאות לא וירטואליות בג'אווה, קריאות לפונקציות C, קריאות ברמת מודול של פייתון): פשוט למידול, f() שיחות f.

שיגור דינמי (מתודות וירטואליות של Java, קריאות מסוג duck-typed של Python): דורש ניתוח היררכיית מחלקות (CHA) או אלגוריתמים מדויקים יותר לבניית גרף קריאות (RTA, VTA) כדי לקבוע אילו יישומים של מתודה עשויים להיקרא בפועל באתר קריאה נתון.

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

הדיוק של גרף הקריאה קובע ישירות את דיוק הניתוח הבין-פרוצדורלי. גרף קריאה הכולל יותר מדי קצוות (קירוב יתר) מייצר תוצאות חיוביות שגויות; גרף קריאה שמפספס קצוות מייצר תוצאות שליליות שגויות.

מה ניתוח בין-פרוצדורלי מוצא שניתוח תוך-פרוצדורלי לא יכול

פגיעויות אבטחה (ניתוח כתם)

רוב עשרת הפגיעויות המובילות של OWASP דורשות ניתוח זיהומים בין-פרוצדוריים כדי לזהות באופן אמין:

  • הזרקת SQLקלט לא אמין זורם דרך מספר פונקציות לשאילתת מסד נתונים
  • XSSHTML לא אמין זורם דרך פונקציות רינדור להקשר פלט
  • הזרקת פיקודנתונים הנשלטים על ידי המשתמש מגיעים אליהם exec() or system() באמצעות פונקציות ביניים
  • חציית נתיבנתיבי קבצים הנגזרים מקלט משתמש מגיעים לפעולות מערכת הקבצים
  • SSRFכתובות URL הנשלטות על ידי המשתמש זורמות לקריאות לקוח HTTP

פִּיתוֹן

# Intraprocedural tool: sees no issue in any individual function
# Interprocedural tool: traces the full taint path and reports SSRF

def get_target_url(request):
    return request.json().get("url")              # source: attacker-controlled

def fetch_resource(url):
    return requests.get(url)                      # sink: SSRF

def api_endpoint(request):
    target = get_target_url(request)
    data = fetch_resource(target)                 # full path: source -> sink
    return data

בעיות בטיחות של מצביע ריק וזיכרון

Facebook Infer הוא הכלי הבין-פרוצדורלי הקנוני לניתוח בטיחות null. הוא משתמש ב-bi-abduction, סוג של חשיבה בין-פרוצדורלית, כדי לגלות תנאים מוקדמים ותנאי המשך של פונקציות, ולאחר מכן לבדוק שהקוראים עומדים בתנאים מוקדמים אלה. ביטול הפניה של null הדורש ידיעה שפונקציה יכולה להחזיר null בתנאים מסוימים אינו נראה לכלי תוך-פרוצדורליים.

תאווה

// Intraprocedural tool: no issue in either function
// Infer: finds that processResult() can receive null from fetchData()

String fetchData(boolean condition) {
    if (condition) return getData();
    return null;                    // can return null
}

void processResult(String result) {
    System.out.println(result.length());  // NPE if result is null
}

void run() {
    String data = fetchData(false);   // passes false: fetchData returns null
    processResult(data);              // null dereference
}

שימוש לאחר שחרור ודליפות משאבים

ב-C וב-C++, באגים מסוג "use-after-free" כוללים לעתים קרובות זיכרון שהוקצה בפונקציה אחת ומשוחרר באחרת, כאשר פונקציה שלישית שומרת הפניה. אף ניתוח של פונקציה בודדת אינו יכול לזהות סוג שגיאה זה. ניתוח בין-פרוצדורלי מנתח את שלמות זרימת הבקרה: מוודא שקריאות לפונקציה עוקבות אחר דפוסים צפויים כדי למנוע פרצות.

הפרות של צימוד אדריכלי ותלות

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

כאשר אתה זקוק לניתוח בין-פרוצדורלי

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

אתה זקוק לניתוח בין-פרוצדורי כאשר:

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

ניתוח תוך-פרוצדורי מספיק כאשר:

  • המטרה היא אכיפת סגנון, עמידה במוסכמות וזיהוי טעויות מקומיות ברורות
  • אתם זקוקים למשוב מהיר המשולב בלולאת הפיתוח (pre-commit, IDE, CI per-PR)
  • בסיס הקוד קטן מספיק כדי שמפתחים ידעו את כל קשרי הקריאה
  • האבטחה נאכפת בשכבה שונה (מסגרת מאומתת, מערכת מסוג) והסיכון לפגיעויות חוצות-פונקציות נמוך.

התשובה המעשית עבור רוב הצוותים: להשתמש בשניהם. כלים תוך-פרוצדוריים (ESLint, Pylint, Clippy) רצים על כל קומיט לקבלת משוב מהיר. כלים בין-פרוצדוריים (CodeQL, Infer, Semgrep עם כללי טאיינט) רצים על בקשות משיכה או בלוח זמנים לילי לניתוח יסודי. שתי השכבות משלימות זו את זו, אינן מתחרות.

כלי ניתוח בין-פרוצדורליים: מה כל אחד מהם מכסה

כליגישת הניתוחשפותמקרה שימוש ראשוני
CodeQLניתוח בין-פרוצדורי מלא, מבוסס IFDSC/C++, ג'אווה, JS/TS, פייתון, גו, רוביזיהוי פגיעויות אבטחה
הסקת מסקנות של פייסבוקחטיפה דו-שלבית, בין-פרוצדוריג'אווה, C, C++, Objective-Cבטיחות ריק, דליפות זיכרון, תנאי מרוץ
Semgrep (מצב כתמים)כתם בין-פרוצדורי רדוד30 + שפותהתאמת דפוסי אבטחה עם זרימת נתונים
קוד סניקבין-פרוצדורלי מבוסס MLג'אווה, JS/TS, פייתון, C#אבטחה עם משוב ידידותי למפתחים
פוליספייספרשנות מופשטתC, C++, עדהמערכות משובצות קריטיות לבטיחות
פרמה-סיבין-פרוצדורה מלאה + פורמליתCאימות רשמי, אישור בטיחות
SMART TS XLחוצה שפות, חוצה מערכותCOBOL, JCL, ג'אווה, פייתון, RPG, SQLניתוח השפעה על הארגון, מיפוי תלות

ניתוח בין-פרוצדורלי חוצה גבולות שפה

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

SMART TS XL"S ניתוח קוד סטטי מבצע ניתוח תלות בסגנון בין-פרוצדורלי בו זמנית בכל שפה בסביבת הארגון. כאשר שירות Java קורא לתוכנית COBOL שקוראת מטבלת DB2 שמשימת JCL אחרת ממלאת, SMART TS XL עוקב אחר השרשרת הזו ומייצג אותה כמודל תלות מאוחד. ניתוח השפעות לאחר מכן, capability מיייש את גרף הקריאה בין-לשוני הזה כדי לענות על: אם תוכנית COBOL זו משתנה, אילו שירותי Java, אילו עבודות JCL ואילו צרכנים במורד הזרם מושפעים?

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

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

פשרה בין חיובי כוזב לשלילי כוזב

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

היתרון של ההשקעה הוא שיעורים נמוכים משמעותית של תוצאות חיוביות ושליליות שגויות:

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

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