Skip to content

Getting Started

Hugo edited this page Sep 25, 2026 · 1 revision

Getting Started

Install

pip install coretrace-python-analyzer

No runtime dependency, and the analysis runs offline.

First check

coretrace-python-analyzer --check src/

Every .py file under src/ is analysed as one project, and findings are printed one per line, followed by a count and a coverage line:

src/app.py:44:26: high command-injection: Command injection: http input reaches python.os.system through services.run_command [command_injection]
src/app.py:71:14: high dangerous-eval: call to python.builtins.eval executes dynamically built code [code_injection]
2 findings
coverage: 2/2 files, 12/12 functions

The coverage line matters: it tells "no findings" apart from "nothing analysed".

Exit status

Status Meaning
0 Nothing was reported
1 Findings were reported
2 Usage or analysis error

So the command gates a pipeline as it is. --fail-on high keeps reporting every finding but fails only from that severity up.

What gets analysed

Given a directory, every .py file below it is a module of one project, named after its package (app/views.py is app.views).

Skipped: hidden directories, node_modules, __pycache__, build, dist, and any virtual environment — recognised by its pyvenv.cfg whatever its name.

Also read: dependency files at the root (requirements*.txt, pyproject.toml, poetry.lock, uv.lock) build a dependency graph; configuration files under the root (.env, YAML, TOML, JSON, INI, properties) are scanned for secrets.

Analysed as functions: functions and methods, but also the module body and the bodies of top-level classes, as <module> and Cls.<body>. So application = get_asgi_application() in asgi.py, email = forms.EmailField() in a form class, and a module-level os.system(input()) are all seen.

When something cannot be analysed

The analyzer says so rather than staying silent:

  • A function using syntax outside the supported subset is reported as an unsupported-syntax note, and the other functions are still analysed.
  • A file Python itself cannot parse is reported as a syntax-error.
  • The coverage line and the JSON report's per-file detail distinguish the two from a clean run.

Where attacker input comes from

HTTP input is recognised for Flask, FastAPI, Django, aiohttp, Tornado and Bottle: route handlers, class-based views and registered URL patterns. A method a handler class inherits from its framework base — self.get_argument, self.request — denotes the base's.

Further sources: click and Typer commands (argv), input(), sys.argv, environment variables, the output of local processes, and the responses of HTTP clients.

Three of those are operator-controlled and deliberately do not carry the matching kinds: a command-line tool opens the paths it is given, a command or path built from the environment is the operator's own doing, and a path read from a local process is not a traversal. A downloaded script piped into a shell remains a command injection.

Next

Clone this wiki locally