q3alique 3fe6011162 Rename --llm flag to --review and review_exporter
- cli.py: --llm -> --review, param and output key updated
- orchestrator.py: generate_llm -> generate_review, output .llm.md ->
  .review.md, import llm_exporter -> review_exporter
- llm_exporter.py renamed to review_exporter.py; internal header and
  section titles updated to remove tool-name references
- .gitignore: report.llm.md / *.llm.md -> report.review.md / *.review.md
- README.md, demo/README.md: all --llm flags and report.llm.md references
  updated to --review and report.review.md
2026-06-08 01:43:37 +02:00
2026-06-08 00:55:14 +02:00
2026-06-08 00:55:14 +02:00
2026-06-08 00:55:14 +02:00
2026-06-08 00:55:14 +02:00
2026-06-08 00:55:14 +02:00
2026-06-08 00:55:14 +02:00

codeflow

Static taint-analysis and visualization tool for source code security review.
Traces user-controlled input from sources (HTTP parameters, headers, body, files) through the call graph to sinks (SQL queries, shell commands, file writes, deserializers, template engines) and produces an interactive HTML report, plus a Markdown review document for assisted triage.


Demo

codeflow demo

VulnBank is an intentionally vulnerable Flask app covering the most common sink types. Run codeflow against it and open the report to see taint paths highlighted in the interactive graph.

pip install flask
python demo/app.py          # start VulnBank at http://127.0.0.1:5001
python run.py analyze demo --output demo/report.html --review

See demo/README.md for exploitation hints and a full vulnerability table.


Supported languages

Language Support level Frameworks detected
Python Deep Flask, FastAPI, Django (partial), Click, argparse
JavaScript / TypeScript Deep Express, Fastify, Koa
Java Deep Spring Boot (@RestController), raw Servlet
Go Deep net/http, Gin, Echo, Chi, gorilla/mux
C# Deep ASP.NET Core, ASP.NET MVC, WebAPI
Ruby, PHP, Rust, Kotlin, Swift Structural — (function/class graph, no taint)

Deep = dedicated extractor with entry-point detection, source/sink patterns, taint propagation.
Structural = generic extractor — call graph and module structure only, no taint tracking.


What it detects

Sources (user-controlled input)

  • URL path parameters (/user/<id>)
  • Query string (?q=…)
  • Request body — JSON (request.get_json(), @RequestBody, req.body), form fields, file uploads, raw body
  • HTTP headers and cookies
  • CLI arguments (sys.argv, argparse, click, os.Args, flag.*)
  • Environment variables (os.getenv, System.getenv, os.Getenv, Environment.GetEnvironmentVariable)

Sinks (dangerous operations)

Sink type Severity Examples
command_execution 🔴 CRITICAL subprocess.run, exec, os.system, exec.Command, Process.Start
code_execution 🔴 CRITICAL eval, exec, compile, newInstance, Activator.CreateInstance
template_injection 🟠 HIGH render_template_string, Template.render, .process(), Engine.Razor.Run
database 🟠 HIGH execute, executeQuery, ExecuteNonQuery, db.Query, FromSqlRaw
deserialization 🟠 HIGH pickle.loads, readObject, JsonConvert.DeserializeObject, json.Unmarshal
file_write 🟡 MEDIUM open(…, 'w'), Files.write, File.WriteAllText, os.WriteFile
file_read 🟡 MEDIUM open(…, 'r'), send_file, Files.readAllBytes, os.ReadFile
http_request 🔵 LOW requests.get, http.Get, HttpClient.GetAsync

Quick start

No virtual environment required. On first run, dependencies are installed automatically into a local vendor/ folder.

python run.py analyze <repo_path> --output report.html

Flags

Flag Default Description
--output / -o required Path for the HTML report
--review off Also generate report.review.md — Markdown taint review document
--burp off Also generate report.burp.json — structured JSON of endpoints and taint paths
--cluster-threshold 5 Collapse sibling nodes into clusters above this count (0 = off)
--max-file-size 5 Skip files larger than N MB
--verbose / -v off Print per-phase progress

Examples

# HTML report only
python run.py analyze ./target-app --output report.html

# HTML + taint review document
python run.py analyze ./target-app --output report.html --review

# HTML + Burp JSON
python run.py analyze ./target-app --output report.html --burp

# All three outputs
python run.py analyze ./target-app --output report.html --review --burp

Output files

report.html

Interactive single-file report. Features:

  • Overview panel — module dependency graph, all flows at a glance
  • Per-flow panels — one panel per entry point, showing the full taint graph
  • Nodes colour-coded by type: 🟣 entry point, 🔴 tainted sink, 🟠 source, 🟡 function, 🔵 boundary
  • Pan, zoom, drag
  • Severity filter sidebar
  • PDF-printable (SVG viewBox is recomputed on beforeprint)

report.review.md

Markdown review document for assisted triage. Contains:

  • Reviewer instructions explaining what codeflow can and cannot detect
  • Summary table of tainted flows by severity
  • Per-flow sections with:
    • Sources table (param name, input type, file:line)
    • Tainted sinks table
    • One ⚠️ Taint path block per source→sink pair, with real code snippets (±3 lines) at every hop, >>> markers on focal lines
    • Explicit review question per path (TRUE POSITIVE / FALSE POSITIVE classification)

Use this file to review each taint path and dismiss false positives without sharing the entire codebase.

report.burp.json (opt-in)

Machine-readable JSON listing all endpoints, user-controlled parameters, sink node IDs, and taint paths as node-ID chains. Intended for custom tooling or Burp extension integration.


How taint works

  1. Source nodes are created for every place user input enters the code.
  2. Taint propagates forward through CALLS and DATA_FLOW edges — every function that receives or passes tainted data becomes tainted.
  3. Taint stops at sanitizer calls (html.escape, shlex.quote, hashing functions, etc.).
  4. When tainted data reaches a sink node the path is recorded as a flow and scored by severity.

Known limitations

  • No conditional-branch awarenessif x not in allowed: abort() does not stop taint. Validation guards will appear as false positives.
  • No type-coercion modellingint(user_input) eliminates injection risk in practice but taint still propagates.
  • No parameterised-query detectioncursor.execute("SELECT … WHERE id = ?", (x,)) is safe but flagged the same as string concatenation.
  • No inter-procedural data-flow inside structs/maps — field-level taint after json.Unmarshal(&obj) is not tracked.

These limitations make the tool deliberately conservative — it over-reports and expects a human reviewer second pass to dismiss false positives.


Architecture

codeflow/
├── run.py                        # Self-bootstrapping launcher (no venv needed)
├── requirements.txt
├── codeflow/
│   ├── cli.py                    # Click CLI entry point
│   ├── orchestrator.py           # Pipeline coordinator
│   ├── discovery/
│   │   ├── file_scanner.py       # Recursive file discovery
│   │   └── language_detector.py  # Extension → language mapping
│   ├── analysis/
│   │   ├── ast_parser.py         # tree-sitter wrapper (all languages)
│   │   ├── base_extractor.py     # Extractor base class + ExtractionResult
│   │   ├── python_extractor.py   # Deep: Flask, FastAPI, Click, argparse
│   │   ├── js_extractor.py       # Deep: Express, Fastify, Koa
│   │   ├── java_extractor.py     # Deep: Spring Boot, Servlet
│   │   ├── go_extractor.py       # Deep: net/http, Gin, Echo, Chi, gorilla/mux
│   │   ├── csharp_extractor.py   # Deep: ASP.NET Core, MVC, WebAPI
│   │   ├── generic_extractor.py  # Structural: all other languages
│   │   ├── graph_builder.py      # Assembles CodeGraph from extractor results
│   │   ├── taint_tracker.py      # Forward taint propagation
│   │   ├── boundary_marker.py    # Promotes BOUNDARY → SINK for dangerous calls
│   │   ├── flow_identifier.py    # BFS per entry point → Flow objects
│   │   ├── severity_scorer.py    # Assigns CRITICAL/HIGH/MEDIUM/LOW/INFO
│   │   └── clusterer.py          # Collapses sibling nodes above threshold
│   ├── models/
│   │   ├── node.py               # Node, NodeType
│   │   ├── edge.py               # Edge, EdgeType
│   │   ├── graph.py              # CodeGraph (networkx wrapper)
│   │   └── flow.py               # Flow dataclass
│   └── renderer/
│       ├── layout_engine.py      # Sugiyama-style DAG layout
│       ├── svg_renderer.py       # SVG generation (nodes, edges, lanes)
│       ├── html_builder.py       # Packages SVGs into single-file HTML
│       ├── review_exporter.py    # Markdown taint review document
│       └── burp_exporter.py      # JSON endpoint + taint-path export
└── tests/
    ├── unit/                     # Per-module unit tests
    ├── integration/              # Multi-file fixture tests
    ├── smoke/                    # End-to-end smoke test
    └── fixtures/                 # Flask, Express, CLI sample apps

Corporate / offline use

run.py is self-bootstrapping:

  • First run — installs dependencies into vendor/ using pip --target (no admin rights, no venv)
  • Subsequent runs — skips bootstrap, loads from vendor/ directly
  • Proxy — set CODEFLOW_PIP_ARGS=--proxy http://proxy.corp:8080 before first run
  • Offline — copy vendor/ from a machine with internet access; subsequent runs need no network
# First run (needs internet once)
python run.py analyze ./app --output report.html

# All subsequent runs (instant, offline)
python run.py analyze ./app --output report.html --review

Dependencies

Package Version Purpose
tree-sitter 0.21.3 AST parsing core
tree-sitter-languages 1.10.2 Pre-compiled grammars for all supported languages
networkx 3.3 Graph data structure and path algorithms
click 8.1.7 CLI framework
jinja2 3.1.4 HTML report templating
pathspec 0.12.1 .gitignore-style file exclusion patterns
S
Description
Automated archival mirror of github.com/q3alique/codeflow
Readme 2.2 MiB
Languages
Python 100%