Skip to main content

A static analyzer using AI

Project description

vulnAI

Python Package Analysis Benchmark License: MIT

vulnAI is a Python static application security testing tool built around interprocedural taint analysis. It parses Python code, builds function-level summaries, resolves calls across a code graph, and reports source-to-sink vulnerability flows with CWE labels.

It is designed to answer a harder question than simple pattern matching:

Did attacker-controlled data move across functions, returns, aliases, and callsites before reaching a dangerous sink?

vulnAI analysis pipeline

Highlights

  • Interprocedural taint propagation across function call boundaries.
  • Custom codebase indexing, import resolution, call graph construction, CFG construction, use-def analysis, and fixed-point dataflow iteration.
  • Per-callsite context isolation to avoid mixing taint from unrelated calls.
  • Rule support for common Python web/security vulnerability classes.
  • CLI workflow for scanning codebases and scoring OWASP Benchmark Python.
  • Measured against OWASP Benchmark Python ground truth and compared with Bandit 1.9.4 on the same supported benchmark scope.

Demo

CLI Scan

vulnAI CLI scan demo

vulnai scan ./benchmarks/external/pygoat

Example output shape:

[*] Starting vulnAI scan on: ./benchmarks/external/pygoat
[-] Building CodebaseIndex...
[-] Building CallGraph edges...
[-] Building function summaries...
[-] Running interprocedural taint analysis...
[+] Scan complete.

Vulnerabilities found: 65

Cross-Function Taint Tracking

vulnAI cross-function taint flow

vulnAI does not stop at the local function. If a value enters through a web request, passes through helper functions, returns into another scope, and then reaches a sink, the analyzer can preserve the flow through the call graph.

def route(request):
    name = request.args.get("name")
    value = normalize(name)
    return render(value)

def normalize(x):
    return x.strip()

def render(html):
    return HttpResponse(html)

In this shape, the important fact is not just that HttpResponse exists. The important fact is that attacker-controlled input reached it.

Installation

After publishing to PyPI:

pip install vulnai

From source:

git clone https://github.com/shayaan09/vulnAI.git
cd vulnAI
python -m pip install -e .

Verify the CLI:

vulnai --help

Usage

Scan a Python project:

vulnai scan ./path/to/python-project

Run OWASP Benchmark Python scoring:

vulnai benchmark ./benchmarks/external/OWASPBenchmarkPython ./benchmarks/external/OWASPBenchmarkPython/expectedresults-0.1.csv

Run the local recall corpus:

python ./tests/cwe_recall_check.py --strict

Supported Vulnerability Classes

CWE Vulnerability class Detection style
CWE-22 Path traversal Taint flow
CWE-78 OS command injection Taint flow
CWE-79 Cross-site scripting Taint flow
CWE-89 SQL injection Taint flow
CWE-327 / CWE-328 Weak cryptography / weak hash Pattern-based
CWE-330 / CWE-338 Insecure randomness / weak PRNG Pattern-based
CWE-502 Insecure deserialization Taint flow + sink rules
CWE-611 XML external entity injection Taint flow + parser rules
CWE-798 Hardcoded credentials/secrets Pattern-based
CWE-918 Server-side request forgery Taint flow

The OWASP Benchmark Python score below uses the 8 currently supported OWASP Benchmark categories: command injection, deserialization, hash, path traversal, SQL injection, weak randomness, XSS, and XXE.

Benchmark Results

Measured on OWASP Benchmark Python using the benchmark's expected-results CSV. The table below reports the supported vulnAI categories only, covering 852 labeled test cases.

Tool TP FP FN TN Precision Recall F1
vulnAI 267 50 43 492 0.84 0.86 0.85
Bandit 1.9.4 192 50 118 492 0.79 0.62 0.70

Interpretation:

  • vulnAI detected 75 more true positives than Bandit at the same false-positive count on the supported OWASP Benchmark Python scope.
  • Bandit remains strong on local risky APIs such as hashlib.md5, random.getrandbits, pickle.loads, eval, and exec.
  • vulnAI's advantage comes from resolving source-to-sink dataflow across function boundaries rather than only matching local AST patterns.

Reproduce vulnAI's benchmark run:

vulnai benchmark ./benchmarks/external/OWASPBenchmarkPython ./benchmarks/external/OWASPBenchmarkPython/expectedresults-0.1.csv

How It Works

vulnAI runs the scan in phases:

  1. Parse Python files into ASTs.
  2. Build a codebase index of modules, imports, functions, classes, and nested definitions.
  3. Build a code graph with containment, import, call, and external-call edges.
  4. Build a CFG for each function.
  5. Run reaching-definition and use-def analysis.
  6. Build function summaries that describe parameter-to-return and parameter-to-sink behavior.
  7. Run fixed-point interprocedural taint propagation over the call graph.
  8. Replay local sink checks once new return taint is discovered.
  9. Emit CWE-labeled findings with caller, callee, sink, line, and context data.

On OWASP Benchmark Python, the analyzer builds a graph with more than 5,400 nodes, 19,700 edges, and 3,700 indexed functions.

Example Finding

[1] Tainted Flow to Sink: SQL Injection
    CWE: CWE-89
    Caller: views.search
    Callee: database.run_query
    Via Parameter: query
    Sink Reached: cursor.execute(sql)
    Line: 42
    Context: views.search -> database.run_query

The goal is to make the report explain both the dangerous operation and how tainted data reached it.

Development

Install in editable mode:

python -m pip install -e .

Run tests:

python -m pytest

Run the positive-only CWE recall matrix:

python ./tests/cwe_recall_check.py --strict

Build the package:

python -m build
python -m twine check dist/*

Project Status

vulnAI is a research/portfolio SAST engine. It is useful for exploring static analysis architecture and catching many common Python vulnerability patterns, but it is not a replacement for a professional security review.

Known limitations:

  • Python 3 AST parsing only. Python 2 projects should be converted before scanning.
  • Highly dynamic Python features can hide calls or dataflow from static analysis.
  • Framework-specific source/sink modeling is rule-dependent and should be expanded over time.
  • Benchmark metrics are reported for supported OWASP Benchmark Python categories only.

Responsible Use

Only scan code you own or are authorized to test. Static analysis findings should be reviewed before being treated as confirmed vulnerabilities.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vulnai-0.0.1.tar.gz (76.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vulnai-0.0.1-py3-none-any.whl (84.1 kB view details)

Uploaded Python 3

File details

Details for the file vulnai-0.0.1.tar.gz.

File metadata

  • Download URL: vulnai-0.0.1.tar.gz
  • Upload date:
  • Size: 76.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for vulnai-0.0.1.tar.gz
Algorithm Hash digest
SHA256 ebe2f37b7efe837b2aa3b1af888f11172af5f103ff2c8e07a53575c64db36905
MD5 f9624de849a49591b69a8defe073fa3f
BLAKE2b-256 ccb1a423a37be6de9bf2566fe7ec8e1ee86b654a47c09e857ddca535404038ee

See more details on using hashes here.

File details

Details for the file vulnai-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: vulnai-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 84.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for vulnai-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 91c2261fb9daf6b15ce582533b7c9b3311840ca4680dae145e3d11cc25471ff2
MD5 2d97f6fac07699be0a5218ff2e24378a
BLAKE2b-256 71fa7d27dc708f4acd56dee45deecc3acf6f5430eef14f999915b73d6e923c37

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page