Skip to main content

Security

To report a vulnerability, email the maintainers privately, and don't open a public issue.

This page sums up a review from 2026-10-31, covering how ant builds SQL, what it logs, and how it handles secrets. It was done by the project's own tooling and authors, not an outside auditor.

SQL injection​

PathProtection
Values in queriesAlways bound as parameters, in every statement ant writes
Column and table namesCome from struct metadata, never from input, and are quoted
OrderBy, Where, joinsTake field probes, so a request can't name a column
Query comments and hintsComment delimiters are removed, so they can't close the comment
JSON pathsBound as a parameter, and each part is quoted
Migration scriptsIdentifiers are quoted, and text is escaped

These take raw SQL by design, and must never be built from input. Pass values as arguments.

A helper that takes a column or sort order from a request should map it through a fixed list.

Logs and errors​

Secrets​

Tenancy​

A global filter is a convenience, not a security boundary, because ant.Raw and IgnoreFilters bypass it. See multi-tenancy.

Migrations​

  • reset needs the database's name, typed or passed with --confirm, and refuses otherwise.
  • A checksum stops an applied file changing unnoticed. It detects mistakes, not attackers.
  • Migration files are code. Treat access to them, and to the embedded binary, like access to the database.