Skip to main content

Static analysis engine for Python web applications

Project description

flawed

A static-analysis engine for Python web applications. flawed builds a framework-aware model of a Python web app — its routes, request inputs, state effects, call graph, and value flow — and exposes that model as a Python library and a command-line tool.

Python API

The top-level flawed package is the analysis API — the same surface the bundled rules are built on, usable directly from a REPL or a script. open_repo() loads a repository's model:

from flawed import open_repo
from flawed.route import POST

repo = open_repo("path/to/app")          # build (or load cached) the model
repo.routes                              # RouteCollection(75) [Route(GET / → index, …), …]
repo.routes.count_by(lambda r: "/".join(sorted(m.name for m in r.methods)))
                                         # Counter({'GET': 35, 'POST': 28, 'GET/POST': 12, ...})

# Which POST routes write state but declare no guard in their handler stack?
for route in repo.routes.accepting(POST):
    if route.reachable.effects() and not route.full_stack.checks():
        print(route)

load_findings() is its mirror image — comb through a scan you already ran:

from flawed import load_findings

findings = load_findings("scan.json")               # a --json or --sarif capture
findings.count_by("rule_id").most_common(5)         # which rules fired most
findings.min_severity("high").in_dir("auth/")       # high-sev findings under auth/
findings.diff(load_findings("baseline.json")).added # new findings vs a baseline

Both return immutable, chainable collections (group_by / count_by / tabulate / | / slicing). See Python API for the full surface.

Command line

flawed is also a command-line scanner that runs rule modules over a repository:

flawed                       # orientation dashboard (does not scan)
flawed .                     # scan the current directory
flawed scan path/to/repo     # scan a repository: L1 index + L2 semantic + L3 rules
flawed scan . --rules-dir ./my_rules   # run your own rule modules instead of the built-ins

Findings stream to stdout, progress and diagnostics to stderr. See CLI for output formats (--json, --sarif), exit codes, baseline diffing, and the full command list.

Documentation

End-user docs live in docs/:

  • Writing rules — the rule-authoring guide: the @detector contract, the objects a rule navigates, and running your own rules with --rules-dir.
  • The analysis model — what the engine models (routes, inputs, effects, call graph, value flow) and how to think about it.
  • CLI — running scans, output formats, and configuration.
  • Python API — querying the model interactively from a REPL or script.
  • Provider authoring — teaching the engine a new framework so your rules see its routes, inputs, and effects.

Setup

flawed uses mise for project tools and task entry points, and uv for Python dependency resolution.

mise install   # Python + uv, pinned in mise.toml
mise deps      # uv sync --all-extras

Development

mise run install-hooks         # install the version-controlled pre-commit gate
mise run check                 # full gate: lockfile + lint + format + mypy + layers + framework/dep/subprocess checks + tests
mise run check -- PATH...      # scope the gate to specific files or directories
mise run test                  # run affected tests (testmon)
mise run test -- tests/unit/   # scope tests to a directory or file

The pre-commit hook is tracked at tools/hooks/pre-commit; mise run install-hooks copies it into the repository's git hooks directory (idempotent, and worktree-aware). Edit the tracked file and reinstall — never edit the copy under .git/hooks/ directly.

Configuration

Global config: ~/.config/flawed/config.yaml

data_dir: <path>          # where L1 cache artifacts are stored
repo_local: false         # true = store cache next to each repo
observability_enabled: true   # local run/scan metrics; set false to opt out
type_enrichment:
  enable_mypy_batch: false  # opt-in experimental mypy oracle

By default each scan appends local observability records — a runs.jsonl plus a per-repo scan_metrics.jsonl under the data dir. These are written locally only (no network, no telemetry); set observability_enabled: false to turn them off.

Per-repo cache uses <data_dir>/owner__name/ layout. The index is cached after the first run; subsequent scans skip L1 extraction.

License

flawed is released under the Apache License 2.0.

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

flawed-0.7.2.tar.gz (562.0 kB view details)

Uploaded Source

Built Distribution

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

flawed-0.7.2-py3-none-any.whl (675.3 kB view details)

Uploaded Python 3

File details

Details for the file flawed-0.7.2.tar.gz.

File metadata

  • Download URL: flawed-0.7.2.tar.gz
  • Upload date:
  • Size: 562.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for flawed-0.7.2.tar.gz
Algorithm Hash digest
SHA256 4492cc1d8926a1ddb79dae6a1a6d613071c2cb0b7ec4190c4e0dffdea8905662
MD5 03c36dc43aedbfea98748c259a070596
BLAKE2b-256 bb514b8fb5f2492c834e01b02d7c78a5315f3ce1eda6babb8c4faeb8a6a42157

See more details on using hashes here.

Provenance

The following attestation bundles were made for flawed-0.7.2.tar.gz:

Publisher: publish.yml on execveat/flawed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flawed-0.7.2-py3-none-any.whl.

File metadata

  • Download URL: flawed-0.7.2-py3-none-any.whl
  • Upload date:
  • Size: 675.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for flawed-0.7.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0f0ad360b9c8ff4d82284e5cff2e1fa81fed3500d3c3c6ec5c559a96da1facfc
MD5 bb2253851152f731062450fd60e802d9
BLAKE2b-256 f489e9b312f76d69fead727d7c6c0af52b204acb1061cfb5950c56697daee588

See more details on using hashes here.

Provenance

The following attestation bundles were made for flawed-0.7.2-py3-none-any.whl:

Publisher: publish.yml on execveat/flawed

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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