רשת המלכודות של חברת המחקר watchTowr קלטה את הבקשות הראשונות ב-11 בספטמבר 2026, בשעה 06:00 UTC. יום קודם לכן, ב-10 בספטמבר, פרסמה GitLab את גרסאות 19.3.2, 19.2.6 ו-19.1.8, ובתוכן תיקון ל-CVE-2026-85706, חולשה בציון CVSS של 10.0 שמאפשרת לפונה בלי חשבון כלל לקרוא קבצים מהשרת עצמו. בין רגע הפרסום לבין הבקשות הראשונות שנראות כמו ניסיון לשחזר אותה עברו פחות מיממה.

חוקרי watchTowr כותבים שהם עצמם שחזרו את החולשה מתוך הפרטים הטכניים ש-GitLab פרסמה, ובדקו מול סביבות של לקוחות מי מהן חשוף. הבקשות שהגיעו למלכודות שלהם הן, לדבריהם, סימן שגם מישהו אחר כבר עשה את אותו תרגיל. CISA לא חיכתה לראיה חזקה יותר: באותו יום היא הכניסה את CVE-2026-85706 לקטלוג החולשות המנוצלות בפועל, עם מועד אחרון לתיקון ב-14 בספטמבר. שלושה ימים.

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

למה דווקא שרת GitLab

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

ג'ייק נוט, ראש מודיעין האיומים ב-watchTowr, ניסח את זה בהצהרה שנמסרה ל-The Hacker News: "המשיכה של GitLab לתוקפים ברורה, כי גישה לא מורשית מאפשרת לתוקף להגיע לקוד המקור, לסודות של ה-CI/CD, לפרטי אימות, וליכולת להזריק קוד לתוך שרשרות הבנייה, ומשם להשיג גישה לכל מה שנמצא במורד הזרם או להרעיל אותו". הוא מוסיף שזה בדיוק מה שתוקפים עשו שוב ושוב השנה.

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

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

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

לפי הפרסום של GitLab, שני הדברים האלה כשלו באותו endpoint: "הגבלת נתיב לא תקינה ואכיפת אימות חסרה בממשק ה-API של הקומיטים במאגר". במילים אחרות, הבקשה נענתה גם בלי שהפונה הזדהה, וערך שהגיע מתוך הבקשה הצליח להוציא את הקריאה מהתיקייה שאליה היא הייתה אמורה להיות כלואה. לכשל השני, זה של הנתיב, קוראים path traversal.

כל אחד מהשניים לבדו הוא באג. יחד הם הופכים את ה-endpoint לקורא קבצים כללי שכל אחד באינטרנט יכול לפנות אליו. GitLab מציינת שהחולשה קיימת "בתנאים מסוימים" ולא מפרטת אילו, ונוט ממלא את החסר: לדבריו, הדרישה היחידה היא שעל השרת יהיה לפחות פרויקט ציבורי אחד. זו אמירה של watchTowr, לא של GitLab, וכדאי לקרוא אותה ככזאת.

אז למה הציון הוא בדיוק 10.0 ולא 9.8? הווקטור ש-GitLab פרסמה הוא AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N. ארבעת המרכיבים הראשונים הם הצירוף שמייצר ציונים גבוהים: מעל הרשת, במורכבות נמוכה, בלי הרשאות מוקדמות ובלי שאף אחד בצד השני צריך ללחוץ על משהו. אותם ארבעה, בתוספת פגיעה מלאה בכל שלושת ממדי ההשפעה וכשהכול נשאר בתוך גבולות הרכיב, מייצרים את 9.8 המוכר. מה שמעלה מכאן ל-10.0 הוא S:C, סימון שאומר שההשפעה של החולשה חורגת מגבול הרכיב שבו היא יושבת. כאן זה מדויק: הבקשה נשלחת לשירות אחד, והמידע שיוצא ממנה שייך למערכות אחרות לגמרי, אלה שהמפתחות בקבצים האלה פותחים.

יש בווקטור פרט שראוי לשים לב אליו. השדה של שלמות המידע מסומן I:H, פגיעה גבוהה, למרות שכל התיאור של GitLab מדבר על קריאה בלבד. החברה לא מסבירה את הפער הזה בשום מקום בפרסום, ואנחנו לא נשלים אותו בניחוש. CISA, מצידה, סיווגה את הבעיה כ-CWE-35, וריאנט של path traversal שמתאר מעבר בין תיקיות דרך רצפי נקודות ולוכסנים, בעוד שהרשומה ב-NVD מסווגת אותה כ-CWE-22, המשפחה הכללית יותר. ההבדל אינו מעשי, אבל הוא מזכיר שהסיווגים האלה נכתבים בידי גופים שונים ולא תמיד נפגשים.

הטווחים שקיבלו תיקון הם כל הגרסאות מ-18.7 עד 19.1.8, ענף 19.2 עד 19.2.6, וענף 19.3 עד 19.3.2, ב-Community Edition וב-Enterprise Edition כאחד. מי שמשתמש ב-GitLab.com או ב-GitLab Dedicated לא צריך לעשות דבר; החברה כבר עדכנה את השירות המנוהל שלה. כל השאר הוא התקנה עצמאית, ושם התיקון הוא באחריות מי שמפעיל אותה.

החולשה השנייה באותה גרסה

אותה הוצאת גרסה סגרה 18 חולשות, שתיים מהן בדירוג קריטי. השנייה היא CVE-2026-87719 בציון 9.9, ב-Enterprise Edition בלבד, והיא מעניינת מסיבה אחרת לגמרי.

כשתוכנה מקבלת בלוק נתונים מבחוץ ומשחזרת ממנו אובייקט חי בזיכרון בלי לבדוק מה בדיוק הגיע, התוקף יכול לתפור את הנתונים כך שהשחזור עצמו יעשה משהו שלא התכוונו אליו. זה deserialization לא בטוח. לפי GitLab, משתמש מזוהה שיש לו גישה ל-Duo Chat, עוזר ה-AI המשולב במוצר, יכול היה לשלוח ארגומנט בנוי במיוחד ב-subscription של GraphQL, לעקוף את שכבת ההמרה ולהגיע דרכה להגדרות של מנגנון החיפוש המתקדם ולפרטי אימות רגישים ששמורים שם.

שווה לעצור על התנאי המקדים: הרשאה לעוזר AI. פיצ'ר שברוב הארגונים חולק בנדיבות, כי הוא נראה כמו כלי פרודוקטיביות ולא כמו הרשאה רגישה, הפך כאן לתנאי הכניסה לחולשה בציון 9.9. שתי החולשות הקריטיות דווחו דרך תוכנית ה-bug bounty של GitLab ב-HackerOne, על ידי חוקרים שמזוהים שם בכינויים s3ntago ו-kyyblin.

שאר 16 התיקונים מתפרסים על הרגיל: גלישת חוצץ בהמרת Unicode, שתי חולשות XSS, כמה כשלי הרשאה בגישה למשתני CI/CD מוגנים, עקיפת אכיפה של כניסה דרך SAML, ושתי חולשות מניעת שירות במגביל המורכבות של GraphQL.

הפעם השנייה בשלושה שבועות

זו לא החולשה הקריטית הראשונה ב-GitLab בחודש האחרון. ב-21 באוגוסט דיווחה watchTowr על ניצול בשטח של CVE-2026-19478, חולשת הזרקת קוד בציון 9.4 שאפשרה לתוקף לא מזוהה לשנות או למחוק פרויקטים ציבוריים דרך דירקטיבה של GraphQL. אצלנו היא הופיעה אז כחלק ממקבץ של חמישה פרסומים קריטיים באותו שבוע. נוט אמר אז שהצוות שלו שחזר את החולשה "תוך דקות" מרגע הפרסום, והוסיף משפט ששווה לחזור עליו: "זו המציאות החדשה של שחזור וניצול חולשות, שבה תוקפים נעזרי AI מסוגלים לכווץ את הזמן מפרסום ועד ניצול, ו'לחכות למחזור העדכונים הבא' זה לרוב מאוחר מדי".

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

מה לחפש בלוגים

מי שעדיין לא עדכן, ורוצה לדעת אם כבר נגעו בו, יכול לחפש בלוגי השרת בקשות POST לנתיבים מהצורה api/v4/projects/{id}/repository/commits/ שמכילות פרמטרים בשם file.path. זו ההמלצה של watchTowr, והיא מתארת את הצורה של ניסיון הניצול, לא את תוכנו. ההמלצה השנייה שלהם פשוטה יותר: לוודא שהתקנת GitLab בכלל צריכה להיות פתוחה לאינטרנט. הרבה מהן לא צריכות.

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

מה זה אומר בפועל

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