If you discover a security vulnerability in pg_tre, please
report it responsibly by emailing greg@burd.me with the
subject line [pg_tre security].
Please include:
- A description of the vulnerability.
- Steps to reproduce.
- Potential impact.
- Any suggested fixes (optional).
I will acknowledge receipt within 7 days and aim to provide a fix or mitigation within 30 days for confirmed vulnerabilities.
Please do not disclose the vulnerability publicly until a fix has shipped or 90 days have passed since the initial report, whichever comes first.
pg_tre is a PostgreSQL extension that runs as part of the backend process and has the same privileges as the PostgreSQL server. When deploying:
- Follow PostgreSQL security best practices.
- Limit
CREATE EXTENSIONprivileges to trusted users. - Review index configurations before deployment in
multi-tenant environments.
pg_tre.match_timeout_msbounds the wall-clock time spent in a single regex match (see "Known Sharp Edges" for exactly what is and is not enforced).pg_tre.max_nfa_statesrejects patterns whose compiled automaton is too large before any match runs.pg_tre.compile_timeout_msbounds the wall-clock time spent compiling a single pattern (enforced since 1.5.6; see below). - Keep PostgreSQL and pg_tre updated to the latest versions.
- Run with
wal_consistency_checking = 'pg_tre'enabled in pre-production environments to catch any custom-rmgr WAL redo bugs before they hit production standbys.
-
The
tre_amatch(text, text, int)UDF accepts arbitrary regex patterns and runs them through a TRE backend that has documented worst-case complexity. Two guardrails bound this cost, and it is important to understand precisely what each one does:-
pg_tre.match_timeout_msis enforced for the match phase. The matcher's per-input-position NFA loop calls a progress hook (installed by the extension) that compares the current wall-clock time against a deadline armed when the match begins; once the deadline passes, the match is aborted and the query fails with aquery_cancelederror (pg_tre: regex match exceeded pg_tre.match_timeout_ms). Enforcement granularity is one NFA position-step (effectively sub-millisecond for normal inputs). The legacytre_amatch*/tre_distance/tre_similarityUDFs arm this deadline automatically. Do not raise the timeout for untrusted callers. -
pg_tre.max_nfa_statesis enforced at pattern-compile time: a pattern whose compiled automaton exceeds the limit is rejected before it can ever reach the match path. -
pg_tre.compile_timeout_msis enforced (since 1.5.6) for the pattern-compile phase. A progress hook woven into TRE's NFA-build loops (the bounded-repetition AST expansion and the tag/copy/compile worklists) compares the current wall-clock time against a deadline armed when compilation begins; once the deadline passes, compilation is aborted and the query fails with aquery_cancelederror (pg_tre: regex compilation exceeded pg_tre.compile_timeout_ms). This closes the compile-time DoS lever (pathological nested bounded repetitions such asa{80}{80}{80}can expand for seconds beforemax_nfa_statesis even evaluated, since the state cap is checked only after the automaton is built). Compilation remains additionally bounded by the 64 KiB hard pattern-length ceiling and bypg_tre.max_nfa_states. Do not raise the timeout for untrusted callers.
-
-
The per-tuple positional bloom and positional filter (tier-3.1) were removed in 3.0.0. They were lossy CPU pre-filters only; the executor recheck remains authoritative for correctness, so their removal does not change query results. The range bloom (tier-1 heap-block skip) is retained.
Reporters of confirmed vulnerabilities are credited in
CHANGELOG.md under ### Security for the release that fixes
the issue, unless the reporter requests anonymity.