Back to skill

Security audit

Reaction Processor

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent logging purpose, but it uses administrative database access to write persistent audit and trigger records with weak scoping and validation.

Review before installing. Use this only in a trusted local OpenClaw/Supabase environment where the caller is allowed to write audit and trigger metadata. Prefer a narrower database role or reviewed stored procedure, require explicit user confirmation for writes, and add validation so it records only verified workflow outcomes.

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
scripts/reaction-processor.sh:3
Finding

Database Operations Execute Through an Administrative PostgreSQL Role

Content
View full analysis

Vulnerability Details

File Location: scripts/reaction-processor.sh, lines 3-5, 18, and 83
Vulnerability Type: Violation of least-privilege database access
Risk Level: High

Vulnerable Code

sh
DB_CONTAINER="supabase-db"
DB_USER="postgres"
DB_NAME="postgres"
sh
docker exec -i "$DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" <<SQL

The same administrative connection pattern is used by both supported commands.

Technical Analysis

The script enters the database container and invokes psql as the PostgreSQL administrative role. Its intended functionality only requires narrowly defined permissions to:

  • Read the applicable trigger rule and stale mission records.
  • Insert rows into public.openclaw_agent_events.
  • Insert rows into public.openclaw_agent_reactions.
  • Update limited fire metadata in public.openclaw_trigger_rules.

Using the postgres role grants substantially broader database authority than these operations require. The script therefore violates least privilege and turns modification or substitution of this file into a path for arbitrary administrative SQL execution.

Exploitation requires the ability to modify the script or otherwise influence the SQL supplied to this administrative psql invocation. It also requires permission to invoke Docker against the target container. No direct command-injection path from the script's documented command-line argument was identified.

Attack Path

  1. An attacker gains the ability to modify or replace scripts/reaction-processor.sh.
  2. The attacker adds arbitrary SQL to either existing heredoc.
  3. A user or automated workflow invokes one of the documented commands.
  4. The script enters supabase-db and runs the modified SQL as postgres.
  5. The injected SQL can access or alter database objects beyond the tables needed by this Skill.

Impact Assessment

Successful exploitation can provide admini ...[truncated 491 chars]

Remediation
View remediation

Remediation Suggestions

  1. Create a dedicated database role for this Skill rather than using postgres.
  2. Grant only the required privileges:
    • SELECT on the specific trigger and mission fields.
    • INSERT on the event and reaction tables.
    • A tightly constrained mechanism for updating only the applicable trigger metadata.
  3. Prefer a security-reviewed stored procedure that performs the complete operation and grant the Skill role only EXECUTE on that procedure.
  4. If a security-definer procedure is used, fix its search_path, schema-qualify every object, validate all inputs, and revoke unnecessary public execution privileges.
  5. Avoid Docker-mediated administrative database access. Use an authenticated connection with the dedicated role and protected credentials.
  6. Restrict write access to the script and verify its integrity before privileged automated execution.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/reaction-processor.sh:116
Finding

Outcome Records and Trigger Counters Are Updated Without Verifying the Claimed Workflow Outcome

Content
View full analysis

Vulnerability Details

File Location: scripts/reaction-processor.sh, lines 6, 51-72, and 116-166
Vulnerability Type: Unauthenticated attribution and missing workflow-state validation
Risk Level: Medium

Vulnerable Code

sh
AGENT_ID="c61b873f-354c-431f-9dd7-f627120d576c"

The duplicate-skipped command directly records the claimed outcome:

sql
INSERT INTO public.openclaw_agent_events (
  agent_id,
  kind,
  title,
  summary,
  tags,
  metadata
) VALUES (
  '$AGENT_ID'::uuid,
  'duplicate_skipped',
  'stale_missions_alert',
  'Se detectó una propuesta pending equivalente y no se creó duplicado. Misiones: ' || v_titles,
  ARRAY['trigger','heartbeat','duplicate_skipped'],
  jsonb_build_object(
    'trigger_name', v_trigger.name,
    'stale_count', v_stale_count,
    'titles', v_titles
  )
)
RETURNING id INTO v_event_id;

INSERT INTO public.openclaw_agent_reactions (
  source_event_id,
  source_agent_id,
  target_agent_id,
  reaction_type,
  context,
  status
) VALUES (
  v_event_id,
  '$AGENT_ID'::uuid,
  '$AGENT_ID'::uuid,
  'duplicate_skipped',
  jsonb_build_object(
    'trigger_name', v_trigger.name,
    'stale_count', v_stale_count,
    'titles', v_titles
  ),
  'skipped'
);

The proposal-created command similarly records success and increments trigger metadata without validating a proposal record:

sql
INSERT INTO public.openclaw_agent_events (
  agent_id,
  kind,
  title,
  summary,
  tags,
  metadata
) VALUES (
  '$AGENT_ID'::uuid,
  'trigger_fired',
  'stale_missions_alert',
  'Se detectaron ' || v_stale_count || ' misión(es) stale. Misiones: ' || v_titles,
  ARRAY['trigger','heartbeat','missions_stale'],
  jsonb_build_object(
    'trigger_name', v_trigger.name,
    'stale_count', v_stale_count,
    'titles', v_titles
  )
)
RETURNING id INTO v_event_id;

INSERT INTO public.opencla
...[truncated 2693 chars]
Remediation
View remediation

Remediation Suggestions

  1. Require a concrete source identifier for every operation, such as a proposal ID, duplicate proposal ID, or authenticated workflow execution ID.
  2. Validate the claimed state in the database before inserting audit records:
    • Confirm that the equivalent pending proposal exists for duplicate_skipped.
    • Confirm that the referenced proposal was created successfully for proposal_created.
    • Confirm that the proposal and trigger belong to the expected workflow.
  3. Derive the agent identity from authenticated execution context rather than a hardcoded UUID.
  4. Add database constraints or idempotency keys that prevent the same workflow outcome from being recorded more than once.
  5. Update fire_count and last_fired_at only when a newly validated proposal outcome is recorded.
  6. Lock or conditionally update the relevant trigger row to prevent concurrent calls from producing inconsistent counters.
  7. Reject proposal-created recording when no stale missions exist, unless zero-count firings are explicitly valid.
  8. Preserve atomicity by performing validation, event insertion, reaction insertion, and the conditional trigger update in one constrained transaction or stored procedure.
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code file executes a subprocess that writes to the database by inserting records, and in one branch later updates trigger metadata as well. The script provides only usage syntax and lacks any confirmation prompt, warning comment, or user-facing disclosure that it will modify persistent state.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The record-proposal-created branch runs docker exec/psql and both inserts new event/reaction rows and updates openclaw_trigger_rules. There is no visible confirmation prompt, safety notice, or explanatory comment disclosing that this command changes persistent database records.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script contains user-visible natural-language strings in Spanish, including exception and notice text, while the rest of the interface does not indicate a Spanish-only scope or provide language selection. That can violate language/locale policy when a skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This summary string is stored/generated as natural-language output in Spanish, and similar Spanish-only strings appear elsewhere in the script. Without offering a locale choice or documenting a justified regional constraint, the skill imposes a fixed language on users.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.