Skip to main content

Static checker for unsafe Piccolo raw SQL construction

Project description

piccolo-sql-guard

A community-maintained static checker for unsafe Piccolo raw SQL construction.

What it checks

Rule Name Description
PQS001 raw-sql-fstring Flags f-strings passed into Table.raw()
PQS002 raw-sql-string-formatting Flags concatenation, % formatting, and .format() passed into Table.raw()
PQS003 querystring-unsafe-template Flags the same unsafe patterns for QueryString()
PQS004 unsafe-sql-token-builder Flags uncontrolled SQL tokens in helper builders

PQS004 — unsafe SQL token builders

PQS004 performs cross-function analysis to find SQL builder functions that interpolate parameters of unsafe type and are reachable from a Piccolo raw SQL sink. A parameter is safe when its type annotation constrains it to a finite set of values:

  • Literal["ASC", "DESC"] — explicitly enumerated strings
  • bool — Boolean (maps to e.g. " WHERE active" / "")
  • int / float — numeric constants
  • A local Enum / StrEnum subclass

A plain str parameter is unsafe and triggers PQS004.

# PQS004 fires — sort_col is unconstrained str
def build(sort_col: str) -> str:
    return f"SELECT * FROM my_model ORDER BY {sort_col}"

# Safe — Literal constrains the set of allowed values
def build(direction: Literal["ASC", "DESC"]) -> str:
    return f"SELECT * FROM my_model ORDER BY id {direction}"

PQS004 also follows simple helper-call chains and common string-building patterns such as f-strings, string concatenation, and str.join() over literal containers.

Quick start

pip install piccolo-sql-guard
piccolo-sql-guard src/

Usage

piccolo-sql-guard [PATH ...]                  # scan paths
piccolo-sql-guard --format json src/          # JSON output
piccolo-sql-guard --select PQS001,PQS002 src/ # enable specific rules
piccolo-sql-guard --ignore PQS004 src/        # disable specific rules
piccolo-sql-guard --statistics src/           # print file/violation counts
piccolo-sql-guard --profile src/              # print per-phase timing
piccolo-sql-guard --version

Unknown rule codes passed to --select or --ignore are treated as configuration errors so CI does not accidentally run with an empty ruleset.

Development

This project uses uv for the local development environment and lockfile. The package supports Python 3.11 through 3.14.

uv sync --extra dev
uv run --extra dev pytest
uv run --extra dev ruff check .
uv run --extra dev mypy src

Configuration

piccolo-sql-guard.toml or pyproject.toml:

[tool.piccolo-sql-guard]
include = ["src"]
exclude = ["migrations", ".venv"]
select = ["PQS001", "PQS002", "PQS003", "PQS004"]
ignore = []
builder_allowlist = ["build_*_sql"]
piccolo_modules = ["piccolo"]
output_format = "text"
pqs004_max_iterations = 5   # fixed-point iteration cap for recursive builders

builder_allowlist

A list of glob patterns matching builder function names that are assumed safe and excluded from PQS004 analysis. Use this for third-party or generated builders you cannot annotate.

pqs004_max_iterations

Maximum number of fixed-point iterations for recursive or mutually-recursive builder groups (default: 5). Increase if you have deeply recursive builders; decrease if scan time is a concern.

Limitations

piccolo-sql-guard is a best-effort static checker. Dynamic dispatch, complex container mutation, runtime imports, and values assembled outside the scanned source tree may be treated as unknown or missed. Treat a clean run as a lint signal, not as proof that every raw SQL path is injection-safe.

Exit codes

Code Meaning
0 No violations
1 Violations found
2 Config or usage error
3 Internal checker error

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

piccolo_sql_guard-0.1.0.tar.gz (64.2 kB view details)

Uploaded Source

Built Distribution

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

piccolo_sql_guard-0.1.0-py3-none-any.whl (43.6 kB view details)

Uploaded Python 3

File details

Details for the file piccolo_sql_guard-0.1.0.tar.gz.

File metadata

  • Download URL: piccolo_sql_guard-0.1.0.tar.gz
  • Upload date:
  • Size: 64.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for piccolo_sql_guard-0.1.0.tar.gz
Algorithm Hash digest
SHA256 190e5bba337f0a0849c57f408fadac29bc69a57ad2f2e01e73bf668de95598d9
MD5 327719a93eadf756acb23efa226c74ac
BLAKE2b-256 71bac884baf64d1136fe116b5cecca7cfc50b63b4f24a467e78687267223e59f

See more details on using hashes here.

Provenance

The following attestation bundles were made for piccolo_sql_guard-0.1.0.tar.gz:

Publisher: release.yml on atkei/piccolo-sql-guard

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

File details

Details for the file piccolo_sql_guard-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for piccolo_sql_guard-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 31e1e5ed2da584ff19165791b8d80bba86cdb14e5f5df2320508dadf177d9825
MD5 4058d5aaf0b6552b6b1e4f4f18a7a68e
BLAKE2b-256 32cb2fe3a014806e7167c082d5ed4b28c56c3c4675d5459de1a762d226965353

See more details on using hashes here.

Provenance

The following attestation bundles were made for piccolo_sql_guard-0.1.0-py3-none-any.whl:

Publisher: release.yml on atkei/piccolo-sql-guard

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