Handlebars היא ספריית תבניות ל-JavaScript, מהסוג שבונה דף מתוך שלד טקסט ונתונים, והיא תלות נפוצה בפרויקטי Node.js. בגרסאות שלפני 4.7.10 אפשר להעביר לה לא רק תבנית כטקסט אלא גם אובייקט מפורסר, ודרך האובייקט הזה אפשר להחדיר קוד JavaScript שירוץ בתהליך השרת. הציון שניתן לחולשה הוא 9.8 מתוך 10, והיא עוקפת את התיקון שיצא בגרסה 4.7.9 לחולשה קודמת באותו מקום.
מה החולשה?
תבנית היא שלד של טקסט עם מקומות ריקים שמתמלאים בנתונים, וזה מה ש-Handlebars עושה: היא לוקחת את השלד, מתרגמת אותו לקוד JavaScript, ומריצה את הקוד כדי לקבל את הפלט. כל עוד השלד מגיע כמחרוזת, הספרייה יודעת מה לעשות איתו.
אבל לפי הרשומה, Handlebars.compile() ו-Handlebars.precompile() מקבלות גם אובייקט מוכן שמייצג את התבנית אחרי פירסור, מה שנקרא AST. בגרסה 4.7.9 נוספה בדיקה על האובייקט הזה, אחרי חולשה קודמת שסומנה CVE-2026-33937. הבדיקה ההיא היא מה שהחולשה הנוכחית עוקפת, מפני שהיא כיסתה רק חלק מהערכים בעץ: PathExpression, NumberLiteral ו-BooleanLiteral נבדקו, והשאר לא.
מי שיכול להעביר אובייקט כזה במקום מחרוזת שם ביטוי JavaScript באחד השדות שנשארו בלי בדיקה. הרשומה מונה אותם: אורך blockParams ב-Program, עומק של פרמטר שאינו PathExpression, ערך של StringLiteral שאינו מחרוזת, וערך original של PathExpression שאינו מחרוזת. הקומפיילר כותב את הערכים האלה אל הקוד שהוא מייצר, בלי מרכאות ובלי סינון, והקוד רץ. זה קורה בתהליך השרת, כשהפלט של compile מרונדר, או בכל מקום שבו נטען הפלט של precompile.
לסוג הכשל הזה קוראים הזרקת קוד. הערך שהיה אמור להיות נתון הופך לפקודה.
מי מושפע?
לפי הרשומה, Handlebars מגרסה 4.0.0 ועד 4.7.10, כלומר כל הגרסאות שלפניה.
והנה הפרט שחשוב כאן יותר מטווח הגרסאות: לפי הרשומה, אפליקציה שמעבירה ל-Handlebars רק מחרוזות תבנית אינה מושפעת. החולשה נוגעת למי שמעביר אובייקט מפורסר, ובמיוחד למי שהאובייקט הזה מגיע אליו מקלט חיצוני. זה אינו השימוש הרגיל בספרייה, וזאת הסיבה שציון 9.8 אינו מתאר כאן את מצבו של כל מי שהספרייה מותקנת אצלו.
בישראל זה אינו עניין של גולש אלא של מי שמפתח ומתחזק שירותי צד שרת. Handlebars יכולה להיכנס לפרויקט גם בלי שבחרתם בה ישירות, כתלות של חבילה אחרת, ולכן שווה לבדוק מה מותקן בפועל ולא רק מה רשום בקובץ התלויות.
האם מנוצלת בפועל?
אין דיווח ידוע על ניצול בפועל. החולשה אינה מופיעה בקטלוג ה-KEV של CISA, סוכנות הסייבר האמריקאית, שמרכז את החולשות שידוע כי תוקפים משתמשים בהן, נכון לעדכון הרשומה. הרשומה פורסמה ב-6 באוקטובר 2026, כך שאין מכאן מה להסיק לכאן או לכאן.
מה שכן, מדובר בעקיפה של תיקון קיים. הפרטים של החולשה הקודמת ושל הבדיקה שנוספה בעקבותיה כבר פומביים, וזה מקצר את הדרך למי שמחפש את הפערים שנשארו בה.
מה עושים?
עדכנו את Handlebars לגרסה 4.7.10. זאת הגרסה שסוגרת את החולשה לפי הרשומה, והיא פורסמה ב-GitHub.
אם אתם על 4.7.9 ומניחים שהתיקון הקודם מכסה אתכם, הוא אינו מכסה. הבדיקה שנוספה באותה גרסה היא בדיוק מה שהחולשה הזאת עוקפת.
בדקו איזו גרסה מותקנת בפועל. הרצה של npm ls handlebars בתיקיית הפרויקט מראה גם את הגרסה שבחרתם וגם גרסאות שנכנסו כתלות של חבילות אחרות, וזה המקום שבו בדרך כלל מסתתרת גרסה ישנה.
ואם אינכם יכולים לעדכן מיד, חפשו בקוד קריאות ל-Handlebars.compile() ול-Handlebars.precompile() ובדקו מה הן מקבלות. קריאה שמקבלת מחרוזת תבנית אינה בטווח לפי הרשומה. קריאה שמקבלת אובייקט, ובמיוחד אובייקט שנבנה מקלט שהגיע מבחוץ, היא המסלול שצריך לחסום. ההתראה של הפרויקט מתארת את הפרטים.