T05 · Unauthorized Access and Privilege Escalation
Error
- Location
- references/security-and-operations.md:9
- Finding
- Spoofable Row-Level Security Identity Context## Vulnerability Details **File Location**: `references/security-and-operations.md`, lines 9–14 **Vulnerability Type**: Trusting a user-settable PostgreSQL configuration parameter as an authenticated identity **Risk Level**: High **Vulnerable Code**: ```sql -- Set session context (generic, no extensions needed) SET app.current_user_id = '123'; CREATE POLICY orders_user_policy ON orders FOR ALL USING (user_id = current_setting('app.current_user_id')::bigint); ``` ### Technical Analysis The documented RLS policy derives the effective user identity from the custom PostgreSQL configuration parameter `app.current_user_id`. The example sets that parameter through an ordinary `SET` statement but does not establish a trusted mechanism that binds the value to an authenticated application identity. A database role capable of issuing queries can potentially assign an arbitrary value to this custom parameter. The RLS policy then treats that attacker-selected value as authoritative when deciding which rows can be accessed. Consequently, the policy can become an identity-selection mechanism rather than an access-control boundary. The example also uses session-level `SET` rather than transaction-local `SET LOCAL`. With connection pooling, a value may remain attached to a reused database connection and affect a subsequent request if the application does not reliably reset session state. ### Attack Path 1. An attacker obtains the ability to execute SQL through a compromised application path, overly permissive database role, SQL injection flaw, or direct database session. 2. The attacker selects a victim identifier and executes: ```sql SET app.current_user_id = '<victim-user-id>'; ``` 3. The attacker queries or modifies the `orders` table. 4. The RLS policy evaluates `current_setting('app.current_user_id')` using the attacker-controlled value. 5. Rows belonging to the selected v ...[truncated 732 chars]
- Remediation
- ## Remediation Suggestions - Do not treat a freely mutable custom configuration parameter as authenticated identity. - Derive identity from a trusted database role where practical, or expose a narrowly scoped server-side setter that validates identity against trusted authentication context. - Use transaction-local context, such as `SET LOCAL`, inside an explicit transaction to prevent identity values from leaking across pooled connections. - Ensure untrusted application roles cannot arbitrarily select another identity through exposed SQL interfaces. - Revoke direct table access where appropriate and expose only constrained functions or views designed around least privilege. - Add both positive and negative RLS tests. Specifically verify that an untrusted role cannot set the context to another user's identifier and gain access. - Configure the application to reset or discard session state before returning connections to a pool. - Where a privileged context-setting function is used, apply the `SECURITY DEFINER` hardening controls described in the second finding.
