Back to skill

Security audit

ia-postgresql

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent PostgreSQL guidance package, but its RLS security advice includes unsafe patterns that could weaken database access controls.

Review the PostgreSQL security guidance before installing or relying on it for RLS work. The skill is not deceptive and does not execute code, but users should not directly apply its RLS identity-context or SECURITY DEFINER patterns without adding proper trusted identity handling, transaction scoping, restricted grants, fixed search_path, least-privilege ownership, and negative access-control tests.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (2)

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.

T09 · Insecure Skill Coding Practices

Warning
Location
references/security-and-operations.md:26
Finding
Unsafe Recommendation to Use SECURITY DEFINER Helper Functions## Vulnerability Details **File Location**: `references/security-and-operations.md`, line 26 **Vulnerability Type**: Incomplete hardening guidance for privileged PostgreSQL functions **Risk Level**: Medium **Vulnerable Code**: ```text Always index columns referenced in RLS policies. For complex multi-table checks, use `SECURITY DEFINER` helper functions. ``` ### Technical Analysis The documentation recommends `SECURITY DEFINER` helper functions for RLS checks without specifying the mandatory security controls for such functions. A `SECURITY DEFINER` function executes with the privileges of its owner rather than those of its caller. If the function uses an inherited or attacker-influenced `search_path`, unqualified relation, function, operator, or type names may resolve to attacker-controlled objects in a writable schema. An attacker can exploit this object-shadowing behavior to execute their own database object under the function owner's privileges. The recommendation also omits requirements to use a minimally privileged owner, revoke default `PUBLIC` execution, restrict grants to intended roles, and schema-qualify referenced objects. These omissions are especially significant for RLS helpers because their owners may possess privileges that bypass ordinary table policies. ### Attack Path 1. A privileged owner creates an RLS helper as `SECURITY DEFINER` based on the recommendation. 2. The helper references a database object without schema qualification and does not pin a safe `search_path`. 3. An attacker with creation rights in a schema searched by the function creates a shadow relation, function, operator, or other resolvable object with the expected name. 4. The attacker invokes the helper directly or triggers it through an RLS-protected query. 5. PostgreSQL resolves the unqualified reference to the attacker-controlled object. 6. The attacker-controlled object executes within the definer's privileg ...[truncated 694 chars]
Remediation
## Remediation Suggestions Replace the recommendation with a hardened pattern that requires all of the following: - Set a fixed, trusted function search path, for example: ```sql CREATE FUNCTION trusted_schema.check_access(...) RETURNS boolean LANGUAGE sql SECURITY DEFINER SET search_path = pg_catalog, trusted_schema AS $$ -- Use schema-qualified object names here. $$; ``` - Schema-qualify every referenced table, function, type, sequence, and other database object. - Assign ownership to a dedicated, minimally privileged, non-superuser role. - Revoke default execution access: ```sql REVOKE ALL ON FUNCTION trusted_schema.check_access(...) FROM PUBLIC; GRANT EXECUTE ON FUNCTION trusted_schema.check_access(...) TO intended_application_role; ``` - Prevent untrusted roles from creating objects in every schema on the function's effective `search_path`. - Avoid giving the owner unnecessary `BYPASSRLS`, superuser, schema-creation, or unrelated table privileges. - Validate all caller-controlled arguments and avoid dynamic SQL. If dynamic SQL is unavoidable, use safe parameter binding and fixed object identifiers. - Add tests for object shadowing, unauthorized direct invocation, privilege boundaries, and behavior under RLS.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.