slug אחד, שבע מהדורות: איך תוסף SSO לוורדפרס נשאר פרוץ בזמן שכל הסורקים הציגו אותו כמתוקן
ב-16 באוגוסט נחסם באחת ממערכות DigitalOcean ניסיון להיכנס לממשק הניהול של אתר וורדפרס מכתובת שאינה חלק מהרשת המהימנה של החברה. עד כאן שגרה. מה שהתברר בבדיקה שבאה אחר כך פחות שגרתי: לתוקף כבר הייתה עוגיית התחברות תקפה של משתמש אדמין. הוא לא ניחש סיסמה, לא גנב אחת, ולא עקף אימות דו-שלבי. הוא ביקש מהאתר להנפיק לו עוגייה, והאתר הנפיק.
הדרך פנימה עברה דרך תוסף ה-SAML Single Sign On של miniOrange, שמקשר אתרי וורדפרס למערכת הזדהות ארגונית. צוות האבטחה של DigitalOcean שחזר את התקיפה מקצה לקצה, ירד לשורות הקוד שאחראיות לה, ומסר את הניתוח ל-Patchstack, שפרסמה אותו ב-21 באוגוסט בכתבה של דייב יונג, ראש מחקר האבטחה שלה. שתי החולשות שנוצלו כבר היו מתוקנות באותו רגע. זה לא עזר לאף אחד. נעבור על שני הבאגים עצמם, ומשם על החלק שהופך את המקרה לחריג: הסיבה ששום מסד נתוני חולשות בעולם לא ידע להגיד לבעלי האתרים החשופים שהם חשופים.
מה תוסף SSO אמור לעשות
במקום שהאתר עצמו ישמור סיסמאות ויבדוק אותן, הוא מעביר את העבודה לגורם חיצוני שכבר מזהה את העובדים בארגון, נניח Okta או Entra ID. הגורם החיצוני מאמת את המשתמש אצלו, ואז שולח לאתר מסמך XML חתום דיגיטלית שאומר, בגדול, "האדם הזה הוא dana@company.com, אני ערב לו". האתר בודק את החתימה מול המפתח הציבורי של אותו גורם, ואם היא תקינה, מחבר את המשתמש לחשבון המתאים. לתקן הזה קוראים SAML, למסמך החתום קוראים assertion, ולגורם שמאמת קוראים Identity Provider, או בקיצור IdP.
כל הביטחון של המנגנון יושב על משפט אחד: החתימה תקינה. אם אפשר לזייף אותה, השאר הוא פורמליות.
התוקף בוחר איך תיבדק החתימה שלו
התוסף קרא מתוך המסמך הנכנס באיזה אלגוריתם הוא נחתם, ובדק לפי מה שכתוב שם. זה נשמע סביר עד שנזכרים מי כותב את המסמך הנכנס.
תוקף שמציב בשדה SignatureMethod את הערך HMAC-SHA1 מבקש מהתוסף לעבור מבדיקה א-סימטרית לבדיקה סימטרית, וזה הבדל מהותי. ב-RSA יש מפתח פרטי שחותם ומפתח ציבורי שמאמת, ולכן זה בסדר גמור שהציבורי גלוי לכל. ב-HMAC אין הפרדה כזאת: אותו סוד בדיוק גם חותם וגם מאמת. התוסף לקח את המפתח הציבורי של ה-IdP, בפורמט PEM, והעביר אותו כמות שהוא לפונקציית hash_hmac בתור הסוד המשותף. מכאן זו כבר לא עבודת מחקר אלא רשימת שלבים: מושכים את המפתח מ-endpoint המטא-דאטה של ה-IdP, שפתוח לכל דורש, חותמים איתו assertion שאומר שאתם המנהל של האתר, ושולחים. התוסף בודק, ומאשר.
לטכניקה הזאת קוראים בלבול אלגוריתמי חתימה, והיא מתועדת כ-CVE-2026-61979. ברשומת ה-NVD היא מופיעה בציון CVSS של 8.1, שהעניקה לה Patchstack בתפקידה כגוף שהקצה את המזהה, והדיווח עליה נזקף שם לחוקר בכינוי sequence_X0. במהדורה החינמית היא נסגרה בגרסה 5.4.4, ובמהדורת Standard בגרסה 17.0.5.
כשגיאה של OpenSSL נחשבת לאישור
הבאג השני קל יותר להסבר ומטריד יותר. הפונקציה openssl_verify ב-PHP מחזירה שלושה ערכים אפשריים: 1 כשהחתימה תקינה, 0 כשהיא אינה תקינה, ומינוס 1 כש-OpenSSL עצמו נתקל בשגיאה פנימית ולא הצליח להכריע בכלל. התוסף בדק את התוצאה הזאת כאילו היא כן או לא. ב-PHP, מינוס 1 נחשב ערך אמיתי לכל דבר.
התוצאה היא שחתימה מעוותת מספיק כדי להפיל את OpenSSL לנתיב השגיאה שלו אינה נדחית, אלא מתקבלת כתקינה. רשומת ה-NVD של CVE-2026-15981 מפרטת שהפונקציה האחראית בתוסף היא mo_saml_validate_signature, ושמיד אחרי ה"אימות" המוצלח האתר קורא ל-wp_set_auth_cookie עבור המשתמש שהתוקף נקב בשמו בתוך המסמך. את הרשומה הקצתה Wordfence, שנתנה לחולשה ציון 9.8. היא פורסמה כבר ב-23 ביולי, ותוקנה בגרסה 5.4.5 של המהדורה החינמית ובגרסה 17.0.6 של Standard.
עד כאן שני באגים בקוד, שניהם עם מזהה CVE, שניהם מתוקנים כבר יותר מחודש. הצד השני של הסיפור הוא זה שהשאיר אתרים פתוחים למרות זה.
אז למה אף סורק לא סימן את זה?
התוסף מופיע בקטלוג של WordPress.org תחת מזהה אחד, miniorange-saml-20-single-sign-on. מאחורי המזהה הזה miniOrange מפיצה שבע מהדורות מוצר נפרדות, לכל אחת מספור גרסאות משלה, ואף אחת מהן לא חולקת מספר עם אחרת. החינמית נעה בין 3.x ל-5.x, ה-Premium בין 11.x ל-13.x, ה-Standard בין 15.x ל-17.x, ומשם זה ממשיך ל-20.x, 26.x, 32.x ו-35.x במהדורות הרב-אתריות וב-VIP. מספר גרסה לבדו לא מספיק כדי לדעת באיזו מהדורה מדובר.
ההודעות הפומביות על שתי החולשות התייחסו רק למהדורה החינמית, זו שכל אחד יכול להוריד מהקטלוג. רשומה של חולשה בוורדפרס בנויה משלושה שדות: מזהה התוסף, טווח הגרסאות החשוף, והגרסה שבה תוקן. רשומה אחת, טווח אחד. כאן נכנס לתמונה החישוב שהכשיל את כולם: אתר שמריץ את מהדורת Standard בגרסה 16.1.9 מחזיק מספר גבוה בהרבה מ-5.4.5, ולכן כל סורק שמשווה מספרים סימן אותו כמעודכן. אותו דבר בדיוק קרה לאתרים על 13.x, 20.x, 26.x, 32.x ו-35.x.
למתוח את הטווח לא היה עוזר. אם מרחיבים את הרשומה עד 17.0.5 כדי לתפוס את 16.1.9, כל אתר חינמי שכבר עודכן ל-5.4.5 מתחיל להיצבע כחשוף, כי 5.4.5 הוא המספר הקטן יותר. "טווח אחד לא יכול להיות נכון לשבעה קווי גרסאות בו זמנית", כתב יונג. מאז, לפי Patchstack, הרשומה במסד הנתונים שלה מחזיקה שבעה טווחים נפרדים במקום אחד.
לפי אותה כתבה, שש המהדורות בתשלום תוקנו בלי שורת changelog פומבית ובלי הודעת אבטחה, והמטריצה המלאה של הגרסאות התקבלה מ-miniOrange רק ב-18 באוגוסט, יומיים אחרי שהתקיפה נחסמה. הקו החינמי, לשם ההגינות, כן קיבל שורות changelog, אם כי לקוניות: בעמוד התוסף בקטלוג גרסה 5.4.4 מתוארת כהסרת תמיכה באלגוריתמי חתימה לא בטוחים, ו-5.4.5 כתיקון של בעיית גישה לא מורשית ב-SAML SSO. מי שקרא את השורות האלה בלי הקשר לא היה מנחש שמדובר בעקיפת אימות מלאה לחשבון מנהל.
אפילו מי שגילה בכוחות עצמו שהוא חשוף נתקל בקיר. DigitalOcean שחזרו את שתי החולשות על גרסה 16.1.9 של מהדורת Standard, והתיקון לקו הזה יושב ב-17.0.6. אין תיקון ל-16.x, ולא צפוי כזה. מנגנון העדכונים של וורדפרס לא מציע קפיצה בין קווי גרסאות כאלה, ולכן בממשק הניהול של אתר חשוף פשוט לא מופיעה שום הודעת עדכון ממתינה. המעבר נעשה בהעלאה ידנית של קובץ התוסף, וצריך לדעת לבד שצריך לעשות אותו.
חברו את זה יחד ותקבלו אתר שבו כל מנגנון התרעה שקיים אמר בדיוק את אותו הדבר: הכול בסדר. ההודעה הפומבית לא כיסתה את המהדורה, מסד הנתונים סימן מתוקן, והדשבורד לא הציע כלום.
מי כבר סורק אתכם
Patchstack פרסמה שש כתובות IP שמהן נצפתה סריקה נגד ה-endpoints של התוסף: שתיים מבריסל שמזוהות כ-VPN או דאטה-סנטר, אחת מאבוג'ה שבניגריה על רשת סלולרית, אחת מפרנקפורט, ושתיים מספקי ענן בארצות הברית. הפיזור הזה, לפי Patchstack, מצביע על סריקה אופורטוניסטית ולא על קמפיין ממוקד. מי שמריץ אותה זורק את הניצול לכל אתר שבו התוסף מותקן, בלי לבדוק איזו מהדורה רצה שם. וזאת בדיוק הנקודה שהופכת תיקון שקט למסוכן: לתוקף לא משנה איזו מהדורה יש לכם, לכם כן.
קוד הדגמה למהדורות החינמיות כבר זמין בגיטהאב. Patchstack בחרה לא לפרסם את שלבי הניצול עצמם, בנימוק שהם לא מוסיפים כלום להגנה מעבר לניתוח שכבר פורסם. בקטלוג של WordPress.org רשומות למהדורה החינמית לבדה יותר מ-10,000 התקנות פעילות, וזה מספר שלא כולל אף אחת משש המהדורות בתשלום, שהן דווקא אלה שהיו שקופות למסדי הנתונים.
מה זה אומר בפועל
אם התוסף הזה מותקן אצלכם, המספר שמופיע בדשבורד לא אומר כלום כל עוד אתם לא יודעים באיזו מהדורה מדובר. אתרו את המהדורה, השוו אותה לטבלה המלאה שפרסמה Patchstack, והניחו שתצטרכו להעלות את הקובץ ידנית במקום ללחוץ "עדכן". שווה גם לאמץ את הסימן שתפס את התקיפה מלכתחילה: סשן של משתמש אדמין שנפתח מכתובת שלא אמורה לפתוח סשנים כאלה. הסימן הזה לא תלוי במספר גרסה, לא במסד נתונים, ולא בהודעה מהיצרן.
תגובות