# Security Policy ## Reporting a Vulnerability 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. ## Security Considerations 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 EXTENSION` privileges to trusted users. - Review index configurations before deployment in multi-tenant environments. `pg_tre.match_timeout_ms` bounds 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_states` rejects patterns whose compiled automaton is too large *before* any match runs. `pg_tre.compile_timeout_ms` bounds 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. ## Known Sharp Edges - 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_ms` **is 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 a `query_canceled` error (`pg_tre: regex match exceeded pg_tre.match_timeout_ms`). Enforcement granularity is one NFA position-step (effectively sub-millisecond for normal inputs). The legacy `tre_amatch*` / `tre_distance` / `tre_similarity` UDFs arm this deadline automatically. Do not raise the timeout for untrusted callers. - `pg_tre.max_nfa_states` **is 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_ms` **is 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 a `query_canceled` error (`pg_tre: regex compilation exceeded pg_tre.compile_timeout_ms`). This closes the compile-time DoS lever (pathological nested bounded repetitions such as `a{80}{80}{80}` can expand for seconds before `max_nfa_states` is 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 by `pg_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. ## Disclosure Acknowledgements Reporters of confirmed vulnerabilities are credited in `CHANGELOG.md` under `### Security` for the release that fixes the issue, unless the reporter requests anonymity.