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

POST אחד ללא אימות ל-Management API של Bifrost הפעיל פקודה בתור משתמש ה-Gateway

מחבר

Magnus Corvin

תאריך פרסום

מודלים אחרונים · 20צפו בכל המודלים →
בנצ'מרקים: Artificial Analysis · מתעדכן יומית
חזרה לכל הפוסטים

ב-14 בספטמבר 2026 פרסמה JFrog Security Research CVE-2026-90898, פגיעות הרצת פקודות בBifrost — שער ה-AI בקוד פתוח שמתוחזק על ידי Maxim — והעניקה לה ציון 9.8 מתוך 10. המתקפה הייתה בקשת HTTP אחת. קריאה לא מאומתת לPOST /api/mcp/client רושמת לקוח stdio MCP, שאותו Bifrost מפרש כשם תוכנית בתוספת רשימת ארגומנטים ומפעיל מיד, לפני כל לחיצת יד של MCP, בתור המשתמש שמריץ את השער; בתמונה הרשמית המשתמש הזה הוא appuser. שער הוא גם המקום שבו נמצאים מפתחות הספק והמפתחות הווירטואליים של מפעיל, כך שתהליך שרץ שם מגיע לאישורי גישה. מה שהפך את הבקשה לאנונימית היה ברירת מחדל שהופצה עם המוצר: governance.auth_config.is_enabled הוא false, ובניסוח של JFrog, "כיבוי אימות פירושו שכל קורא הוא מנהל מקומי." אף מקור מצוטט אינו מדווח שהפגיעות נוצלה אי פעם. המקורות של הרשומה עצמה, דירוג החומרה והערכת המהימנות נמצאים בארכיון אירועי ה-AI, לצד פגיעויות ה-AI-gateway וה-MCP המתועדות האחרות של השנה האחרונה.

Bifrost הוא שירות יחיד שיושב בין אפליקציה לבין מודלי השפה שאליהם היא קוראת. המאגר שלו מתאר אותו כשער בקוד פתוח ברישיון Apache-2.0 ש"מאחד גישה ל-23+ ספקים ... דרך API יחיד תואם OpenAI", עם פרוקסי MCP, מפתחות וירטואליים, תקציבים ואיזון עומסים לפי ספק בין תכונותיו, והיו לו בערך 9,150 כוכבי GitHub ב-28 באוקטובר 2026. השילוב הזה הוא כל הסיבה שגישה ל-shell במארח המסוים הזה שווה ציון קריטי: התהליך שמנתב את הבקשות הוא גם התהליך שמחזיק את פרטי הגישה לכל יעד במעלה הזרם שאליו הוא מנתב. Hacker News, שדיווח על הפגם ב-22 בספטמבר, ניסח את התוצאה בבירור — מכיוון שהשער מאחסן מפתחות API לכל ספק מחובר, הפעלת פקודות בתהליך השער מעניקה לתוקף גישה לאותם פרטי גישה.

המתקפה כולה הייתה POST בודד

התרעת האבטחה של JFrog, שפורסמה תחת אסמכתא JFSA-2026-001686326, מתארת נקודת קצה שקיימת כדי לאפשר למנהל מערכת להוסיף שרת MCP. לקוח stdio במפרט MCP אינו URL; הוא פקודה והארגומנטים שלה, שאותם תוכנית המארחת אמורה להפעיל. Bifrost מקבל את התצורה הזו דרך API הניהול ומפעיל את התוכנית ברגע שהלקוח נוסף. אין משא ומתן על יכולות, אין בדיקת זהות שרת, אין לחיצת יד שחייבת להצליח קודם — ההתרעה מפורשת בכך שלחיצת היד אינה מה שמתחיל את התהליך.

הוכחת ההיתכנות בהתראת האבטחה היא גוף JSON קצר שנשלח בשעתר (gateway) כאשר האימות נותר בברירת המחדל שלו. היא רושמת לקוח שהפקודה שלו היא /bin/sh והארגומנטים שלו כותבים קובץ סימון, ואז קוראת את קובץ הסימון בחזרה. JFrog מוסיפה פרט תפעולי שחשוב במהלך תגובה לאירוע: ייתכן שבקשת ה-HTTP תסתיים בפסק זמן בעוד Bifrost ממתין ל-handshake שלא מגיע, ופסק זמן ביומנים אינו אומר שהפקודה לא החלה לפעול. התהליך כבר רץ בשלב הזה.

רשומת ה-CVE, שהוקצתה על ידי JFrog כרשות מספור CVE, ממפה את הפגם ל-CWE-306, אימות חסר לפונקציה קריטית, ול-CWE-284, בקרת גישה לא נאותה, ומציינת את שני הקבצים שמכילים את ה-handler ואת ה-middleware שלו: transports/bifrost-http/handlers/mcp.go ו-transports/bifrost-http/handlers/middlewares.go. המודול המושפע הוא github.com/maximhq/bifrost/transports, ב-Linux וב-macOS, עבור כל גרסה נמוכה מ-2.1.0.

ברירת המחדל שהפכה את הבקשה לאנונימית

שום דבר מזה לא היה ניתן לניצול ללא תנאי שני, והתנאי השני הוא ברירת המחדל של המוצר עצמו. שכבת ה-middleware לאימות ניהול של Bifrost נשלטת על ידי governance.auth_config.is_enabled, שמגיע כברירת מחדל כ-false. כשהוא כבוי, ה-middleware מתייחס לכל קורא כמנהל מקומי — הסיכום של הייעוץ עצמו הוא שאימות כבוי פירושו שכל קורא הוא מנהל מקומי — כך שהבדיקה שהייתה אמורה לעצור את הבקשה מעולם לא הייתה בנתיב.

התיקון, בקשת המשיכה #6757, מוזג לפרויקט ב-2 בספטמבר 2026, שנים עשר יום לפני פרסום ה-CVE ושישה ימים לפני הגרסה שנושאת אותו. תיאורו גלוי באופן יוצא דופן לגבי צורת הבעיה: בקשת המשיכה סוגרת שני פרימיטיבים לגישה לא מאומתת באותו API רישום, ולא אחד. הראשון הוא לקוח stdio. השני הוא לקוח MCP מסוג http או sse שמצביע על כתובת loopback או כתובת ברשת פרטית, שאותה הבקשה מכנה פרימיטיב SSRF נגד שירותים פנימיים, "כולל נקודת הקצה של מטא-נתוני הענן 169.254.169.254". שניהם נדחים כעת עם HTTP 403 כאשר הבקשה מגיעה ל-handler ללא בדיקת אישורים אמיתית. מנהלים מאומתים שומרים על שתי היכולות, ומפעילים עדיין יכולים להקצות לקוחות stdio דרך config.json.

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

היכן ש-API הניהול היה למעשה מאזין

נגישות היא החלק בתיעוד שהמקורות מתארים באופן העקבי ביותר, ומודדים אותו הכי מעט. הודעת האבטחה של JFrog נותנת את ברירת המחדל של הבינארי הסטנדרטי כ-localhost:8080, מה שמגביל תוקף למארח עצמו. הודעת האבטחה של אותו צוות עבור הפגם הנלווה קובעת שתמונת ה-Docker הרשמית מאזינה על 0.0.0.0 במקום, ו-The Hacker News חוזר על כך: התמונה הופכת את ה-API לניהול לנגיש מחוץ לקונטיינר אם הפורט מפורסם. ה-README quick start של Bifrost עצמו מריץ "docker run -p 8080:8080 maximhq/bifrost", והאפשרות -p של Docker מפרסמת פורט של קונטיינר בכל ממשק מארח אלא אם ניתנת כתובת. הודעת האבטחה ב-GitHub על הפגם מתעדת שהנתיב שדווח אומת מול התמונה maximhq/bifrost:latest שפורסמה, שבה בקשה לא מאומתת הפעילה /bin/sh וכתבה סמן בתור appuser.

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

נקודת קצה אחת, שני פגמים, סיבת שורש אחת

שמונה ימים לפני הודעת הייעוץ של MCP, ב-6 בספטמבר 2026, אותו צוות מחקר פרסם את CVE-2026-86242, נתיב שני ללא אימות אל אותו תהליך. הוא נמצא על ידי אור פלס וקיבל ציון 8.1, והוא מנצל לרעה את POST /api/plugins: Bifrost מקבל תוסף מותאם אישית מופעל שנתיבו הוא כתובת HTTP, טוען האובייקטים המשותפים מתייחס לנתיב עם קידומת http כאל הורדה, כותב את גוף התגובה לקובץ .so זמני ומוסר את הקובץ הזה ל-plugin.Open של Go. אם הטעינה מצליחה, פונקציית Init אופציונלית רצה מיד עם התצורה של התוקף, בתור משתמש ה-gateway.

גרסת הבנייה קובעת מה התוקף משיג. בבניות מקושרות דינמית שהפרויקט מתעד עבור תוספי Go מותאמים אישית, הטעינה צפויה להצליח, מה שהייעוץ מכנה הרצת קוד מרחוק ללא אימות. בתמונת Docker מקושרת סטטית שפורסמה, plugin.Open נכשל עם "Dynamic loading not supported", כך שאותה בקשה הופכת לזיוף בקשה בצד השרת. תוסף שניתן לטעון חייב גם להתאים לגרסת Go של המארח, למערכת ההפעלה, לארכיטקטורה ולסוג הקישור, וזהו אילוץ ממשי ולא פורמליות. התיקון הוא transports/v2.0.0, דרך pull request #5763, וטווח המושפע הוא כל מה שמתחתיו.

המלכודת היא סדר השחרורים. v2.0.0 מתקנת את נתיב התוסף ואינה מתקנת את נתיב ה-MCP — The Hacker News אומרת זאת במפורש, ומודעת ה-MCP של JFrog מאשרת ש-v2.0.0 עדיין מאפשרת את רישום ה-stdio ללא אימות. מפעיל שתיקן במהירות לאחר מודעת ה-6 בספטמבר היה, בנקודה זו בלבד, עדיין חשוף עד ש-transports/v2.1.0 יצאה ב-8 בספטמבר. שני הפגמים מצטמצמים לאותו משפט בשתי המודעות ובבקשת המשיכה של הספק עצמו: אימות מושבת הוא ברירת המחדל.

מה שהמקורות מבססים, ומה שהם אינם מבססים

המנגנון, טווח הגרסאות, התיקון והקרדיט מוסכמים בהודעה, ברשומת ה-CVE ש-JFrog הקצתה, בבקשת ה-pull request ובהערות השחרור של הפרויקט עצמו, וב-The Hacker News. המחלוקת שנותרה היא בשאלת החומרה, והיא אמיתית.

הציון 9.8 הוא הציון של JFrog בתור ה-CNA המקצה, והוא הציון ש-NVD נושאת — רשומת NVD מפרטת את reefs@jfrog.com כמקור המדד, ונכון ל-28 באוקטובר 2026 היא עדיין מציגה את הרשומה בסטטוס "Awaiting Analysis", כלומר NVD פרסמה את הווקטור של המקצה ולא את הניתוח שלה עצמה עליו. הערכת ה-SSVC של רכז CISA המצורפת לאותה רשומה, עם חותמת זמן של 14 בספטמבר 2026, קובעת ניצול "none", אוטומטיות "yes" והשפעה טכנית "total". מודל EPSS של FIRST העמיד את ההסתברות לניצול ב-30 הימים הבאים על 2.3 אחוזים ב-27 באוקטובר 2026, באחוזון ה-83 מבין כל ה-CVEים שקיבלו ציון, ואף לא ה-CVE הזה ולא CVE-2026-86242 מופיעים בקטלוג CISA Known Exploited Vulnerabilities מתאריך 27 באוקטובר 2026.

לעומת זאת, Maxim חולקת על הדירוג. בהצהרה ל-The Hacker News, אקשאיי דאו, מנהל הטכנולוגיה הראשי ומייסד-שותף של החברה, אמר כי הסיכון המעשי נמוך מכפי שמשתמע מציון הקריטי, משום שניצול דורש שממשק הניהול יהיה נגיש מרשת לא מהימנה ושהמפעיל ישאיר את האימות לא מוגדר; פריסת ברירת המחדל והמתועדת, אמר, ממקמת את השער בתוך רשת פרטית. The Hacker News מדווח כי Maxim רואה בפגם חומרה נמוכה ומשתפת פעולה עם JFrog, שהקצתה את ה-CVE, בעדכון ההערכה. הצהרה זו מופיעה בכלי התקשורת האחד הזה; לא נמצא פרסום שני שמצטט את עמדתה של Maxim, ולא פורסמה גרסה מתוקנת נכון ל-28 באוקטובר 2026 — רשומת ה-CVE עודכנה לאחרונה ב-14 בספטמבר והערך ב-NVD ב-18 בספטמבר, ושניהם עדיין על 9.8.

שני פערים נוספים ראויים לציון מפורש ולא להחלקה. הודעות האבטחה של הפרויקט ב-GitHub, שפורסמו ב-23 בספטמבר 2026 ומייחסות לחוקר של JFrog את הדיווח, עדיין נושאות 9.8 עבור פגם ה-MCP ו-8.1 עבור פגם התוסף, בלי כל סימן לעדכון שמקסים תיאר. והטווחים המושפעים בהודעות אלה כתובים ביחס לגרסאות מודול של Go — מתחת ל-1.5.27 ומתחת ל-1.6.3 — ולא ביחס לתגי השחרור של transports שבהם משתמשות הודעות האבטחה של JFrog, כך שמפעיל שמצליב מסמך אחד עם השני צריך ליישב שתי שיטות מספור לפני שיוכל להחליט אם בנייה מושפעת.

Rendered two-column card with the kicker 'BIFROST · CVE-2026-90898' and the title 'What the sources establish — and what they do not', subtitled 'Sources: JFrog JFSA-2026-001686326 (14 September 2026), the CVE record assigned by JFrog, NVD, FIRST EPSS, the CISA KEV catalogue, and the project's pull request 6757 and release tags.' The left column, headed 'ESTABLISHED' in blue, lists eight items: score 9.8 with the vector AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H supplied by the CNA; CWE-306 missing authentication with CWE-284 access control; unauthenticated POST /api/mcp/client starting a program as the gateway user; affected below transports 2.1.0 when management auth is disabled, the default; fixed in transports 2.1.0, PR 6757 merged 2 September, released 8 September 2026; CISA SSVC of 14 September 2026 with exploitation none, automatable yes, impact total; EPSS 2.3 percent at the 83rd percentile on 27 October 2026; and not in the CISA KEV catalogue dated 27 October 2026. The right column, headed 'NOT ESTABLISHED, OR CONTESTED' in amber, lists eight items: no exploitation reported, and the archive records real harm as false; no count of exposed or affected deployments in any cited source; severity contested, the vendor's CTO telling The Hacker News it is low; no published revision to the score as of 28 October 2026; NVD still Awaiting Analysis, so the 9.8 is the assigner's and not NVD's; affected ranges stated in two numbering schemes across the advisories; no detection or triage guidance in either advisory; and no evidence tying the flaw to any intrusion. A footer reads 'Card rendered by OrcaRouter'. The OrcaRouter logo is composited in the bottom-right corner.

מה השתנה, ומה נאמר למפעילים לעשות

הכרונולוגיה נעה לאחור מן החשיפה, וזה החלק הכי פחות אינטואיטיבי בתיעוד. בקשת משיכה #6757 מוזגה ב-2 בספטמבר 2026. transports/v2.1.0, הגרסה שהייעוץ מציין כראשונה שמכילה את התיקון, פורסמה ב-8 בספטמבר — שישה ימים לפני ש-CVE-2026-90898 פורסם ב-14 בספטמבר. התיקון לתוסף של הפרויקט קדם לייעוץ האבטחתי של עצמו באותו אופן: transports/v2.0.0 יצאה ב-26 באוגוסט, אחד עשר ימים לפני ה-CVE של 6 בספטמבר. מפעילים שעוקבים אחרי גרסאות ששוחררו ולא אחרי פידים קיבלו את התיקונים לפני שקיבלו את האזהרות.

מה שהשדרוג מעניק הוא צר וספציפי. ב-2.1.0 ואילך, רישום stdio לא מאומת מחזיר 403 והפקודה אינה מופעלת; מנהלים מאומתים שומרים על היכולת, והקצאה באמצעות config.json עדיין עובדת. פתרון הביניים של הייעוץ למי שאינו יכול לעבור הוא לקבוע את governance.auth_config.is_enabled ל-true, להשתמש בפרטי מנהל חזקים ולהרחיק את מאזין הניהול מרשתות לא מהימנות. ההנחיה של JFrog לגבי מופעים שפעלו חשופים עם אימות מושבת היא לא לחקור ולקוות: יש להתייחס אליהם כאל מערכות שנפרצו, ולבצע רוטציה של מפתחות וירטואליים ושל פרטי התחברות של ספקים.

חשבון הגרסאות הוא החלק שסביר ביותר שייקרא שלא כהלכה.‏ v2.0.0 אינו מתקן את הפגם הזה. גם קו 1.6.x עד 1.6.11 אינו מכיל את התיקון, והתג החדש ביותר בסדרת 1.6 של הפרויקט הוא transports/v1.6.11, שפורסם ב-14 באוגוסט 2026, כאשר אין קו 1.7 במאגר נכון ל-28 באוקטובר 2026 — לכן אין מהדורה מתוקנת בתוך הסדרה הזו, ומפעיל 1.6.x חייב לעבור ל-2.1.0 או מאוחר יותר במקום להמתין ל-backport. קו המהדורות הנוכחי נמצא הרבה מעבר לנקודה הזו: transports/v2.3.2 פורסם ב-20 באוקטובר 2026.

Rendered release-timeline card with the kicker 'BIFROST · RELEASE TIMELINE', the title 'The fix shipped six days before the advisory' and the subtitle 'Dates from the project's release tags and pull request metadata, the JFrog advisories and The Hacker News. Every date below is a single day.' A horizontal timeline carries seven dated markers: 26 Aug 2026, transports 2.0.0 published; 2 Sep 2026, PR 6757 merged; 6 Sep 2026, CVE-2026-86242 published, 8.1; 8 Sep 2026, transports 2.1.0, the fix; 14 Sep 2026, CVE-2026-90898 published, 9.8; 22 Sep 2026, vendor statement reported; 23 Sep 2026, GitHub advisories published. Below it, three bars show release lines: a hatched amber bar labelled '1.6.x line' reading 'affected — no patched release in the series; newest tag 1.6.11, 14 August 2026'; a bar labelled '2.0.0' split between a pale blue segment reading 'plugin flaw fixed' and a red segment reading 'MCP flaw still open'; and a solid blue bar labelled '2.1.0 and later' reading 'MCP fix — unauthenticated stdio registration returns 403'. A foot band headed 'THE PART THAT IS EASY TO GET WRONG' notes that 2.0.0 was the patched release on 6 September and did not close the MCP path, that for the two days before 2.1.0 an operator who patched on the day of the warning was still exposed, and that the 1.6.x series has no fixed release at all. A footer reads 'Card rendered by OrcaRouter'. The OrcaRouter logo is composited in the bottom-right corner.

שני דברים קרו לאחר הפרסום שאנשי הגנה יכולים להשתמש בהם. הודעות האבטחה של הפרויקט ב-GitHub — GHSA-86gf-xh3g-rvxq עבור הפגם ב-MCP ברמת חומרה קריטית ו-GHSA-2qp8-4xgm-fw6g עבור הפגם בתוסף ברמת חומרה גבוהה — פורסמו ב-23 בספטמבר 2026, ונתנו לפידי התלויות וההודעות מזהה נוסף להתאמה לפיו. וב-13 באוקטובר 2026 מוזגה תבנית זיהוי עבור CVE-2026-90898 אל מאגר nuclei-templates הציבורי, מה שאומר שהבדיקה לניסיון רישום לא מאומת היא כעת משהו שצינור סריקה יכול להריץ, ולא משהו שכל צוות צריך לכתוב בעצמו.

Abstract illustration on a dark navy field: a wide translucent slab representing a credential store, filled with evenly spaced glowing key-shaped tokens, stands behind a low wall. A narrow gateway aperture in the wall holds a fresh, brighter set of tokens, a blank card-shaped slip lies pushed aside on the ground in front of it, and a thin amber arc sweeps from the aperture around to the store. A second gateway aperture in the background remains closed and unlit. No text, no people, no organisation logos.

מה שנותר פתוח הוא חומרת הפגם, והיא תוכרע או לא תוכרע על ידי שני הארגונים שעדיין מדברים עליה. עמדתו של Maxim, כפי שדווחה, היא ש-9.8 מציג כחמור מדי פגם שתלוי במאזין חשוף ובברירת מחדל שאינה מוגדרת כדי להיות משמעותי — טענה שאפשר לבדוק אותה עקרונית אך לא נבדקה בפומבי, מפני שאיש לא פרסם כמה פריסות עמדו בשני התנאים האלה. עמדתו של JFrog היא הציון שהקצתה בתור CNA, שנותר בתוקפו ברשומת CVE וב-NVD. עד שאחד מהם יפרסם עדכון, המשמעות התפעולית זהה בכל מקרה: הפגם אמיתי ואומת מקצה לקצה על תמונת הקונטיינר שפורסמה, התיקון יצא לפני האזהרה, לסדרת 1.6 אין תיקון כלל, וכל מופע שהורץ עם אימות מושבת על מאזין נגיש יש להתייחס אליו כאירוע אישורי גישה ולא כטלאי שצריך לתזמן.