Free Python SAST scanner: find security bugs in Python code
DepWarden's free Python SAST scanner checks Python source code against 79 security rules (including 10 Django-specific rules). Every rule maps to a CWE and the findings span 8 OWASP Top 10 categories, and every finding comes with an explanation, a fix and a before-and-after example. Paste a file, upload a zip or connect a repository: no account, and the results stay in a private, session-isolated workspace.
Python runs web back ends (Django, Flask, FastAPI), data pipelines and automation scripts. Its dynamic features (eval, pickle, shell calls) make a small set of mistakes disproportionately dangerous.
What DepWarden checks in Python code
79 rules cover 45 distinct weakness types (14 critical, 36 high, 23 medium and 6 low severity).
| What it checks | Rules | Examples |
|---|---|---|
| Weak cryptography | 20 | MD5 used for password hashing; Null or no-op cipher used; TLS certificate validation disabled — trust all certs |
| Insecure configuration | 17 | Werkzeug/Flask debugger PIN disabled; CORS: Access-Control-Allow-Credentials with wildcard origin; Django DEBUG=True |
| Injection (SQL, command, code) | 16 | OS command injection; Dangerous eval / exec; Django QuerySet.extra() SQL injection |
| Authentication and sessions | 4 | JWT decoded without signature verification; JWT none algorithm accepted; PyJWT/python-jose decode with no signature verification |
| Hardcoded secrets | 4 | Django SECRET_KEY hardcoded; Hardcoded symmetric encryption key; JWT signed with weak or hardcoded secret |
| Insecure deserialization | 4 | Insecure deserialization (pickle / yaml); Celery configured with the pickle serializer; pickle used with user-supplied class name |
| Cross-site scripting | 3 | Django mark_safe on user-controlled data; Django mark_safe on untrusted input; Jinja2 autoescaping disabled |
| Reliability and error handling | 3 | assert used for runtime validation; Mutable default argument; Overly broad exception handler |
| Open redirect | 2 | Django redirect to user-controlled URL; Open redirect to user-controlled URL |
| Server-side request forgery | 2 | SSRF — HTTP request to user-controlled URL; Server-side request forgery (SSRF) |
| Access control | 1 | Open redirect |
| File handling | 1 | File upload without type or size restriction |
| Path traversal | 1 | Path traversal in open() |
| Privacy and data leaks | 1 | Sensitive data written to application log |
Examples from the Python rules
Django SECRET_KEY hardcoded (CWE-321, critical)
A hardcoded SECRET_KEY is shared across all deployments. Rotate it immediately and load from an environment variable.
Vulnerable:
SECRET_KEY = 'django-insecure-h8x!k2p9q...'Fixed:
SECRET_KEY = os.environ['SECRET_KEY']Use os.environ['SECRET_KEY'] or django-environ.
OS command injection (CWE-78, critical)
os.system / subprocess with shell=True executes a command built from untrusted input.
Vulnerable:
os.system("convert " + filename + " out.png")Fixed:
subprocess.run(["convert", filename, "out.png"])Use subprocess with a list of args and shell=False (the default). Never build shell strings from user input.
Insecure deserialization (pickle / yaml) (CWE-502, critical)
pickle.loads / yaml.load on untrusted data executes arbitrary code during deserialization.
Vulnerable:
data = pickle.loads(request.data)Fixed:
data = json.loads(request.data) # or yaml.safe_load(...) for YAMLUse yaml.safe_load and a safe format (JSON) for untrusted data. Never unpickle data you did not produce.
Run it
- Paste code: open the SAST scanner, choose Python and paste a file. You get findings in seconds.
- Upload a zip: files with these extensions are scanned: .py, .pyw. Dependency folders such as node_modules and vendor are skipped.
- Connect a repo: point DepWarden at a branch and it scans it once or on a schedule, with an emailed report.
- In CI: the GitHub Action runs SAST as its own step and can fail the build on severity. CI use goes through an API key and needs a plan that includes SAST.
- uses: Rushabh5000/depwarden-action@v1
with:
sast-dir: src
sast-fail-on: high
env:
APP_API_KEY: ${{ secrets.APP_API_KEY }}What it does not do
DepWarden's SAST engine uses pattern rules and taint-aware rules that require untrusted input to reach a dangerous call. It is not a full cross-file dataflow engine, so a bug that only appears when data crosses several files can be missed, and every static analyser reports some false positives. Treat findings as leads: review them, fix the real ones and suppress the rest with a written reason. SAST covers the code you write; for the packages you import, run software composition analysis too.
Frequently asked questions
Is there a free Python SAST tool?
Yes. DepWarden's Python scanner is free in the browser with no account: paste code, upload a zip or connect a repository. Running SAST from CI through an API key needs a plan that includes SAST.
Which Python files are scanned?
.py, .pyw. Configuration and secret-bearing files such as .env and key files are also checked for hardcoded credentials, whatever language the project uses.
How do I fix what it finds?
Each finding names the weakness (CWE), explains why the code is risky, shows a vulnerable and a fixed version of the pattern, and gives the remediation. Fix the code, then scan again to confirm the finding is gone.
More
Other languages: Java, JavaScript and TypeScript, PHP, Go (Golang), C#, Ruby, Kotlin, Swift, and secret scanning. Compare the options in free SAST tools compared, or start with what is SAST and SAST vs SCA.