JSFuck היא טכניקת כתיבה ב-JavaScript בעזרתה ניתן לכתוב קוד בעזרת שישה תווים בלבד [], (), !, +
. טכניקה זו פופולרית עבור בודקי חדירה ליישומי אינטרנט, לעקיפת מנגנוני אבטחה כנגד התקפות XSS ולהטמעת קוד. שמה של הטכניקה נגזר משמה של שפת התכנות Brainfuck המשתמשת אך ורק בסימני פיסוק כתחליף לאותיות, אלא שבשונה מ-Brainfuck, עבורה קיים מהדר משלה, הרי ש-JSFuck הוא קוד JavaScript לכל דבר ועניין וניתן להפעילו בעזרת כל יישום אינטרנט או מנוע JavaScript.
הספרייה נוצרה לראשונה ביולי 2009, כאשר יוסקה הסוואגה יצר יישום אינטרנט בשם jjencode שיכל לקודד קוד JavaScript בעזרת 18 תווים בלבד[1]. מאוחר יותר, בינואר 2010, התקיימה תחרות בלתי פורמלית בפורום "Obfuscation" של אתר אבטחת יישומי האינטרנט sla.ckers.org (אורכב 23.12.2010 בארכיון Wayback Machine), כדי למצוא דרך להשיג את המספר המינימלי של התווים הנדרשים עד לפחות משמונת התווים - [] () /, ! +
תורמים לשרשור הצליחו למצוא דרך לוותר על שימוש בתווים / וְ־ , ובכך להעמיד את מספר התווים הנדרשים על שישה[2]. בסוף שנת 2010, העמידה Hasegawa קידוד חדש זמין בשם JSF * ck, אשר השתמש רק בששת התווים המינימליים. בשנת 2012, מרטין קלפה יצר פרויקט בשם "jsfuck" בGitHub[3] וכן יצר את אתר JSFuck.com עם יישום אינטרנט המאפשר קידוד אונליין בטכניקה זו[4].
ניתן להשתמש ב-JSFuck כדי לעקוף איתור של קוד זדוני על ידי מנגנוני אבטחת אתרים, למשל בהתקפות XSS. לדוגמה, פרצת האבטחה שנמצאה על ידי חוקר האבטחה הישראלי רומן זאיקין מצ'ק פוינט בחנות המסחר המקוון eBay, התבססה על טכניקה זו[5]. זאיקין ניסה להכניס לממשק המוכרים ב-eBay קוד JavaScript סטנדרטי ונתקל בחסימה של הקוד (blacklist), לאחר שניסה להכניס את קוד ה-JavaScript במסגרת ה-oneror בקוד html המציג תמונה (onerror - תגית HTML המאפשרת לבצע פעולה כולשהי אם הייתה שגיאה בהעלאת התמונה) וראה שקוד ה-enerror עצמו לא נחסם, אלא רק קוד ה-JS, ניסה זאיקין להכניס את קוד ה-JavaScript עם טכניקת JSfuck ואכן הצליח[6]. שימוש פוטנציאלי נוסף ב-JSFuck הוא עבור הטמעת קוד.
קוד JSFuck הוא ארוך באופן קיצוני ביחס לקוד JavaScript סטנדרטי, לדוגמה: בקוד JavaScript המקורי, אורכה של הפקודה ;("!alert("Hello World הגורמת לקפיצת חלון עם צמד המילים שלום עולם, היא 21 תווים. ב-JSFuck לעומת-זאת, לאותו קוד יש אורך של 22,948 תווים. בשורות הבאות נסביר את הטכניקה מאחורי JSFuck וממילא, מה גורם לריבוי שורות הקוד בה, ביחס לקוד JavaScript סטנדרטי.
המספר 0 נוצר ב-JSFuck על ידי כתיבת []+
, כאשר []
הוא המערך הריק ו +
הוא הפלוס האריתמטי, המשמש להמרת הצד הימני לערך מספרי. המספר 1 נוצר כ []!!+
או []+!+
, כאשר הערך הבוליאני true
(מבוטא כ []!!
או []+!
ב-JSFuck) מומר לערך המספרי 1 על ידי סימן הפלוס המוגמר. הספרות 2 עד 9 נוצרות על ידי סיכום true
למספר הפעמים המתאים. למשל ב- true + true
= 2 ו- true
ב-JSFuck נכתב כ[]!!
או []+!
, ולכן אפשר לכתוב 2 כ- []!!+[]!!
או []+!+[]+!
, 3 כ-[]!!+[]!!+[]!!
או כ []+!+[]+!+[]+!
וכן הלאה. המרות אחרות מתבצעות בעזרת דפוס דומה: מספרים שלמים המורכבים משתי ספרות או יותר נכתבים, כמחרוזת, על ידי שרשור מערכים חד ספרתיים עם מפעיל הפלוס. לדוגמה, המחרוזת "10"
יכולה לבוא לידי ביטוי ב-JavaScript כ [1] + [0]
, לצד המרת הספרות ב-JSFuck לטקסט. לדוגמה: [[]+]+[[]+!+]
או [[]+]+[[]!!+]
יניבו את המספר 10 כמחרוזת (על מנת לגרום ל-JSfuck להבין שמדובר בפעולה של הוספת ערך ולא לפעולת אריתמטית סטנדרטית, יש לתחום כל מספר בסוגריים מרובעות). כדי לקבל ערך מספרי במקום מחרוזת, עלינו לסגור את הביטוי הקודם בסוגריים עגולות או בסוגריים מרובעות לצד הוספת פלוס, מה שיניב 10
מטיפוס מספר שלם = ([[]+]+[[]+!+])+
את חלק מהאותיות ב-JSfuck ניתן לכתוב על ידי כתיבת האינדקס (ציון מיקום האות בסוגריים מרובעים) של ביטויים בוליאניים שונים כגון true, false, NaN, undefined. לדוגמה, בשביל לכתוב את התו r, נוכל לפנות לאינדקס של r במילה true, כלומר, הספרה 1 (בשפות תכנות מתחילים לספור מ-0), וכך זה ייראה: [[]!!+]([]+[]!!)
(שים לב שעל-מנת שנוכל לגרום ל-JSfuck להבין שאנו מדברים על פעולת אינדוקס, יש להוסיף []+. ניתן גם להכניס את המחרוזת 1e1000 לתוך מספר, מה שיצור לנו משתנה עם ערך Infinity (ערך המבטא מספר שחרג מהגבול של המספרים הניתנים לאחסון ב-JavaScript, גם בעזרת נקודה צפה ועומד על 1.79e + 308 או 2¹⁰²⁴), שגם אליו נוכל לגשת בעזרת האינדקס הרלוונטי.
הערך | צורת הכתיבה בJSFuck |
---|---|
True | []!! או []+!
|
False | []!
|
NaN | [[]!]+
|
undefined | [[]][]
|
infinity | ([[]+]+[[]+]+[[]+]+[[]+!+]+[[]+!+[]+!+[]+!]([]+[]+!)+[]+!+)+
|