-
Notifications
You must be signed in to change notification settings - Fork 0
ARGUS A23
| Meta Field | Specification |
|---|---|
| Rule Code | ARGUS-A23 |
| Identifier | TRANSACTION_TIMEOUT_CONFIG |
| Severity | HIGH |
| Category | Database Availability, Transaction Governance & Engine Modernization |
| Analysis Layer | Layer 2 - Go-AST Structural & Configuration Scope |
| CWE Mapping | CWE-400: Uncontrolled Resource Consumption |
| OWASP ASVS | OWASP ASVS v4.0.3/v5.0 §V1.4.3, §V12 (Denial of Service & Connection Pool Governance) |
| PostgreSQL Target | PostgreSQL 17/18+ (Cumulative Wall-Clock transaction_timeout GUC Parameter) |
| Default Status | enabled |
Database connection pool configurations (pgxpool.Config) targeting PostgreSQL 17/18+ must explicitly configure the transaction_timeout GUC parameter in RuntimeParams or DSN connection strings (recommended 30,000ms - 60,000ms for OLTP web applications).
┌─────────────────────────────────────────────────────────────────────────────┐
│ ARCHITECTURAL INVARIANT │
│ │
│ PostgreSQL 17/18+ connection pool initializations MUST configure a │
│ positive `transaction_timeout` GUC parameter in `RuntimeParams` or DSN. │
│ │
│ Standard Solutions: │
│ 1. `cfg.ConnConfig.RuntimeParams["transaction_timeout"] = "30000"` (30s) │
│ 2. Append `&transaction_timeout=30000` to DSN connection URI │
│ 3. Use central repository pool configuration helper │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ THE 4-TIER TIMEOUT DEFENSE MATRIX │
│ │
│ [ BEGIN Transaction ] │
│ │ │
│ ├─► statement_timeout (10s-15s) : Bounds single query execution │
│ ├─► lock_timeout (3s-5s) : Bounds lock acquisition wait │
│ ├─► idle_in_tx_timeout (10s) : Bounds idle wait between statements │
│ │ │
│ └─► transaction_timeout (30s) : CAPSTONE CUMULATIVE WALL-CLOCK CAP │
│ (Prevents 10 x 8s chained queries 80s!)│
│ │ │
│ [ COMMIT Transaction ] │
└─────────────────────────────────────────────────────────────────────────────┘
-
statement_timeout: Only limits individual statement runtime. A transaction issuing 10 sequential 8-second queries easily evades a 10-secondstatement_timeoutwhile hogging database resources for 80 seconds. -
idle_in_transaction_session_timeout: Only measures the gap between statement completions and new arrivals. Rapid continuous queries bypass idle timeouts completely.
Introduced in PostgreSQL 17 and standardized in PostgreSQL 18, transaction_timeout measures total cumulative wall-clock time from BEGIN to COMMIT/ROLLBACK. If the threshold is breached, the PostgreSQL backend terminates the transaction with:
ERROR: canceling statement due to transaction timeout (SQLSTATE 25P03)
Zombie transactions left open by orphaned client connections hold back the oldest transaction ID (relfrozenxid in ProcGlobal->xids). This prevents autovacuum from vacuuming dead tuples, leading to table bloat and eventually triggering an emergency read-only shutdown. Client-level transaction_timeout ensures zombie transactions are terminated deterministically.
flowchart TD
A["pgxpool Configuration Initialization"] --> B{"Is transaction_timeout Configured in RuntimeParams or DSN?"}
B -- "No" --> C["FAIL: ARGUS-A23 Missing transaction_timeout Configuration"]
B -- "Yes" --> D{"Is transaction_timeout == 0 (Disabled)?"}
D -- "Yes" --> E["FAIL: ARGUS-A23 Unbounded transaction_timeout Violation"]
D -- "No" --> F["PASS (4-Tier Timeout Matrix Complete)"]
Argus AST visitor inspects:
-
RuntimeParamsMap Analysis: Evaluates composite literals and map index assignments for"transaction_timeout". -
DSN Parsing: Checks connection strings passed to
pgxpool.Newfortransaction_timeout=<non-zero>. -
Pool Initialization Checks: Verifies that
pgxpool.NewWithConfiginvocations have a correspondingtransaction_timeoutsetup inRuntimeParams. -
Exemptions:
- Explicit setting of
transaction_timeoutto positive integer duration. - Declarations with
// argus:ignore ARGUS-A23 <reason>.
- Explicit setting of
// VIOLATION: Missing transaction_timeout allows long-running cumulative transactions
cfg, _ := pgxpool.ParseConfig(connString)
cfg.ConnConfig.RuntimeParams = map[string]string{
"statement_timeout": "10000",
"lock_timeout": "3000",
"idle_in_transaction_session_timeout": "10000",
// Missing: "transaction_timeout"
}// VIOLATION: Disabling transaction_timeout (set to 0)
cfg.ConnConfig.RuntimeParams["transaction_timeout"] = "0"// COMPLIANT: Explicit 4-tier timeout matrix protecting PostgreSQL 18
cfg, err := pgxpool.ParseConfig(connString)
if err != nil {
return nil, err
}
if cfg.ConnConfig.RuntimeParams == nil {
cfg.ConnConfig.RuntimeParams = make(map[string]string)
}
cfg.ConnConfig.RuntimeParams["statement_timeout"] = "15000" // 15s
cfg.ConnConfig.RuntimeParams["lock_timeout"] = "5000" // 5s
cfg.ConnConfig.RuntimeParams["idle_in_transaction_session_timeout"] = "10000" // 10s
cfg.ConnConfig.RuntimeParams["transaction_timeout"] = "30000" // 30s Capstone
return pgxpool.NewWithConfig(ctx, cfg)// COMPLIANT: Configured via DSN connection string
const dsn = "postgres://user:pass@localhost:5432/app_db?sslmode=disable&transaction_timeout=30000"
pool, err := pgxpool.New(ctx, dsn)-
Configure in
RuntimeParams: SetRuntimeParams["transaction_timeout"] = "30000"(30 seconds) on pool startup. -
Do Not Set in
postgresql.conf: Avoid settingtransaction_timeoutglobally in cluster-wide configs to prevent aborting backup utilities (pg_dump) or data migrations. -
Align with HTTP Deadlines: Ensure
transaction_timeoutis shorter than the ingress gateway / HTTP request timeout (e.g. 30s DB transaction timeout under a 60s HTTP timeout).
rules:
ARGUS-A23:
enabled: true
recommended_timeout_sec: 30// argus:ignore ARGUS-A23 administrative migration runner requires unbounded transaction
cfg.ConnConfig.RuntimeParams["transaction_timeout"] = "0"
// argus:ignore TRANSACTION_TIMEOUT_CONFIG legacy postgres 16 compatibility mode
pool, err := pgxpool.New(ctx, legacyDSN)