מי שמריץ Argo CD נותן לו את כל מה שצריך כדי להקים סביבה: פרטי אימות למאגרי הקוד, מפתחות פרטיים, token-ים של Kubernetes. לפי הרשומה, החולשה הזאת מאפשרת למי שמחזיק הרשאת צפייה אחת במערכת לקרוא בדיוק את הקבצים האלה מתוך השרת שמחזיק אותם. הציון 9.9 מתוך 10, והתיקון נכנס בגרסאות 3.3.15, 3.4.10, 3.5.4 ו-3.6.0-rc2.

מה החולשה?

ב-Argo CD יש רכיב בשם repo-server, ותפקידו לקחת את מה שיושב במאגר הקוד ולהפוך אותו להגדרות שאפשר להחיל על Kubernetes. בין השאר הוא יודע לעבד קובצי jsonnet, שפה שמייצרת קובצי הגדרות ויש בה פקודות ייבוא: import, importstr ו-importbin, שמביאות תוכן מקובץ אחר אל תוך התוצאה.

לפי הרשומה, מנגנון הייבוא הזה לא היה מוגבל לתיקיית השורש של המאגר. קובץ jsonnet יכול היה לבקש נתיב מוחלט, לטפס מעלה בעזרת הפניה לתיקיית האב, או להצביע דרך קישור סימבולי שנמצא במאגר, ולקבל כל קובץ שה-repo-server מורשה לקרוא. השם המקובל למצב הזה הוא path traversal, מעבר בין תיקיות, וברשומה הוא מופיע כ-CWE-22.

הרשומה גם מונה למה אפשר להגיע כך, וזאת הרשימה שהופכת את הציון למובן: משתני הסביבה של התהליך עצמו דרך /proc/self/environ, token-ים של service account שמוזרקים אל הפוד, מפתחות פרטיים שמחוברים אליו, ופרטי האימות של מאגרי הקוד.

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

מה שצריך בשביל כל זה מתואר ברשומה בשתי דרכים. האחת היא לדחוף קובץ jsonnet למאגר שאפליקציה קיימת משתמשת בו. השנייה היא להעלות את הקובץ ישירות דרך הקריאה POST /api/v1/applications/manifestsWithFiles, שחשופה גם דרך הפקודה argocd app diff עם הדגלים --local ו--server-side-generate. הדרך השנייה דורשת הרשאת get על אפליקציה קיימת מסוג directory, ולא דורשת הרשאת update, לא sync ולא הרשאת כתיבה למאגר.

ובאפליקציות מסוג directory, מוסיפה הרשומה, ה-repo-server מעבד כל קובץ jsonnet שנמצא בתיקייה.

לאותו כשל יש גם שימוש שני: importstr שמצביע על התקן שאינו נגמר, כמו /dev/zero, ממצה את הזיכרון של ה-repo-server.

מי מושפע?

כל גרסה מ-0.9.0 ואילך, עד הגרסאות שהתיקון נכנס בהן: 3.3.15, 3.4.10, 3.5.4 ו-3.6.0-rc2. בפועל זה כמעט כל התקנה שלא עודכנה.

Argo CD הוא כלי של צוותי DevOps בסביבות Kubernetes, ולא מוצר שנוגע לגולש הפרטי. בארץ הוא מוכר בחברות תוכנה שמריצות Kubernetes, ושם הוא בדרך כלל יושב בלב תהליך ההקמה, מה שמסביר למה הרשומה מסמנת חריגה מעבר לגבולות הרכיב הפגיע.

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

האם מנוצלת בפועל?

הקטלוג של CISA לחולשות שתוקפים משתמשים בהן בפועל, ה-KEV, אינו כולל אותה. לא ידוע על ניצול, והרשומה עלתה ל-NVD ב-20 באוקטובר 2026.

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

מה עושים?

עדכנו לגרסה שמתקנת את הקו שאתם עליו: 3.3.15, 3.4.10, 3.5.4 או 3.6.0-rc2. הודעת השחרור של 3.3.15 היא נקודת הפתיחה.

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

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

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