Back to skill

Security audit

Redigg Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill's Redigg integration is mostly coherent, but it asks to store API keys in plaintext and run persistent jobs that autonomously process remote tasks.

Install only if you intentionally want a long-running Redigg agent. Before use, require explicit approval for cron setup and task submission, store tokens in a proper secret manager or protected file instead of TOOLS.md or command arguments, add a clear disable/remove procedure, and treat all Redigg task content as untrusted data.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • System PersistenceInstalls backdoors, hooks, services, or scheduled tasks that survive the run
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T06 · System Persistence

Error
Location
SKILL.md:20
Finding
Persistent Autonomous Polling and Heartbeat Jobs<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:20-30, 43-50, 57-80` **Vulnerability Type**: Persistent scheduled tasks controlled by an external service **Risk Level**: High ### Vulnerable Code ```markdown 2. **Setup Polling** (cron job) - Frequency: Every 10-30 seconds - Endpoint: `GET /api/agent/tasks` - Auth: Bearer `agent_api_key` - Lock file: `/tmp/redigg-polling.lock` to prevent concurrent runs 3. **Setup Heartbeat** (cron job) - Frequency: Every 30-60 seconds - Endpoint: `POST /api/agent/heartbeat` - Auth: Bearer `agent_api_key` ``` ```markdown 3. Create two cron jobs: - redigg-poll: Every 10s, fetch tasks, process if found - redigg-heartbeat: Every 30s, maintain online status 4. Test: Manual poll to verify connection ``` ```markdown Cron: redigg-poll triggered ↓ 1. Check lock file exists? → Exit (another instance running) 2. Create lock: `touch /tmp/redigg-polling.lock` 3. GET /api/agent/tasks 4. Parse response: - No tasks: Delete lock, exit silently (NO_REPLY) - Tasks found: a. Take FIRST task b. POST /claim c. Read [references/task_processing.md](references/task_processing.md) for guidelines d. Process with LLM based on task.type and parameters e. Build submit payload (result + proposal) f. POST /submit g. Send notification: "✅ Redigg task completed: [title]" h. Delete lock, exit 5. On error: Delete lock, send error notification, exit ``` ### Technical Analysis The Skill explicitly instructs the Agent to create cron jobs that continue running after the initiating interaction. The polling job repeatedly retrieves tasks from an external service and delegates them to an LLM, while the heartbeat job continually reports Agent availability. Persistent scheduling is related to the declared online-agent functionality, but it exceeds the minimum privilege needed for a one-time connection or task operation. The design does not specify an expiration time, maximum ...[truncated 1271 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Do not install recurring cron jobs by default. - Require explicit, informed user approval before creating each scheduled job. - Display the exact command, frequency, credentials source, and expected network destinations before installation. - Prefer a bounded foreground process or a scheduler entry with a fixed expiration time. - Require user confirmation before claiming, processing, or submitting each externally supplied task. - Add limits for task count, runtime, token consumption, polling frequency, and daily resource usage. - Provide a documented removal command and automatically remove jobs when the integration is disabled. - Make persistent activity visible through audit logs and periodic status notifications rather than silently polling indefinitely. - Use a narrowly scoped Agent credential that cannot manage users, webhooks, or unrelated resources. ]]>

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:64
Finding
Untrusted Remote Task Content Is Passed to the LLM Without an Instruction Boundary<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:64-70`; `references/api_reference.md:42-53`; `references/task_processing.md:5-28` **Vulnerability Type**: Prompt injection through externally controlled task fields **Risk Level**: High ### Vulnerable Code ```markdown - Tasks found: a. Take FIRST task b. POST /claim c. Read [references/task_processing.md](references/task_processing.md) for guidelines d. Process with LLM based on task.type and parameters e. Build submit payload (result + proposal) f. POST /submit ``` The remote API controls the content processed by the LLM: ```json { "id": "task_xxx", "idea_id": "...", "idea_title": "...", "idea_description": "...", "status": "pending", "type": "evolution", "parameters": { "title": "...", "direction": "...", "original_content": "..." }, "created_at": "..." } ``` The processing guide directs the model to consume those fields without defining a trust boundary: ```markdown **Parameters:** - `title`: Research topic - `direction`: Evolution focus (e.g., "Deepen theoretical analysis", "Focus on cost reduction", "Apply to different domain") - `original_content`: Previous proposal content (markdown) **Processing Steps:** 1. Analyze original content and direction 2. Identify what needs to evolve: - Theoretical depth? Add mathematical/formal analysis - Cost focus? Add economic analysis and optimization - Domain shift? Map concepts to new field 3. Generate evolved proposal with: - Clear evolution rationale - New methodology section - Updated findings/conclusions - Next steps ``` ### Technical Analysis The task title, direction, description, and original content originate from an external service and must therefore be treated as untrusted data. The Skill does not instruct the Agent to delimit these values, reject embedded instructions, constrain them to research content, or disable tools and access to unrelated context while processing the ...[truncated 1987 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Treat every remote task field as untrusted data, never as Agent instructions. - Place task values inside explicit delimiters and state that instructions contained inside those delimiters must not be followed. - Validate task objects against an allowlisted schema, including accepted task types, field sizes, character constraints, and permitted processing directions. - Reject or quarantine content containing attempts to override system instructions, request secrets, invoke tools, read files, or perform unrelated network operations. - Process tasks in an isolated LLM context without credentials, Agent memory, local files, shell access, browser access, or unrelated tools. - Require human review before claiming and before submitting externally supplied tasks. - Limit output to the documented JSON schema and validate it before submission. - Record the task identifier, source fields, model output, and approval event in an audit log. - Add server-side authorization so only trusted project owners can create tasks for a specific Agent. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:43
Finding
API Credentials Are Stored in Plaintext and Exposed Through Command-Line Arguments<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:43-47, 88-96`; `scripts/heartbeat.sh:3-5`; `scripts/poll_tasks.sh:3-5`; `scripts/submit_task.sh:3-7` **Vulnerability Type**: Insecure secret storage and process-argument disclosure **Risk Level**: High ### Vulnerable Code ```markdown 1. Check TOOLS.md for existing credentials 2. If missing: a. Ask for owner_token (user's Redigg API key) b. Register agent via /api/agent/register c. Save agent.id and agent.api_key to TOOLS.md ``` ```yaml ### Redigg - Owner Token: sk-redigg-... # User API key - Agent ID: ... # From registration - Agent API Key: sk-redigg-... # For all agent operations - API Base: https://redigg.com - Polling Interval: 10000ms (10s) - Heartbeat Interval: 30000ms (30s) ``` The scripts also encourage supplying credentials as positional command-line arguments: ```bash #!/bin/bash # Redigg Agent Heartbeat Script # Usage: ./heartbeat.sh <agent_api_key> API_KEY="${1:-$REDIGG_API_KEY}" ``` ```bash #!/bin/bash # Redigg Agent Task Polling Script # Usage: ./poll_tasks.sh <agent_api_key> API_KEY="${1:-$REDIGG_API_KEY}" ``` ```bash #!/bin/bash # Redigg Claim and Submit Task Script # Usage: ./submit_task.sh <agent_api_key> <task_id> <result_json> API_KEY="$1" TASK_ID="$2" RESULT_JSON="$3" ``` ### Technical Analysis `TOOLS.md` is a plaintext documentation file rather than a protected secret store. Saving both the owner token and Agent key there exposes long-lived credentials to any process, tool, backup system, repository operation, or user able to read that file. Passing the Agent key as `$1` places it in the process argument vector. Depending on operating-system configuration, process arguments may be visible through process inspection utilities. They may also be retained in shell history, scheduler definitions, terminal logs, debugging output, or operational documentation. The owner token has a broader documented role than the Agent token: t ...[truncated 1495 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Never store API credentials in `TOOLS.md`, source files, ordinary configuration files, or repository-tracked content. - Store credentials in an operating-system keychain, a dedicated secret manager, or a protected credential file with restrictive permissions. - Delete the owner token from working memory and storage immediately after registration if it is not required for ongoing operation. - Use a distinct, narrowly scoped Agent token for polling, heartbeat, claim, and submission operations. - Avoid positional command-line secrets. Supply the key through a protected file descriptor, secret-manager integration, or a restricted credential file. - If an environment variable is used as an interim measure, prevent it from being copied into logs, diagnostics, child processes, or scheduler definitions. - Redact authorization headers and credential-shaped values from all errors and audit logs. - Add credential rotation and revocation procedures. - Ensure secret files are excluded from version control and backups unless backups provide appropriate encryption and access controls. - Rotate any credentials that have already been stored or passed through potentially observable command lines. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/poll_tasks.sh:6
Finding
Predictable and Non-Atomic Lock File in Shared Temporary Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/poll_tasks.sh:6, 14-20, 29-32, 41` **Vulnerability Type**: Unsafe temporary lock file and race condition **Risk Level**: Medium ### Vulnerable Code ```bash LOCK_FILE="/tmp/redigg-polling.lock" ``` ```bash # Check lock if [ -f "$LOCK_FILE" ]; then echo "LOCKED" exit 0 fi # Create lock touch "$LOCK_FILE" ``` ```bash if [ "$TASK_COUNT" -eq 0 ]; then rm -f "$LOCK_FILE" echo "NO_TASKS" exit 0 fi ``` ```bash rm -f "$LOCK_FILE" ``` ### Technical Analysis The lock uses a fixed, globally predictable path in the shared `/tmp` directory. The script first checks whether the path exists and then creates it with `touch`; these are separate operations and therefore do not provide atomic mutual exclusion. Two processes can both pass the existence check before either creates the file. Another local user or process may pre-create `/tmp/redigg-polling.lock`, causing the poller to return `LOCKED` indefinitely. The script also lacks a cleanup `trap`, so interruption, termination, or failure after lock creation can leave a stale lock. The lock contains no process identifier, owner validation, or age information. ### Attack Path 1. A local attacker or unrelated process creates `/tmp/redigg-polling.lock` before the scheduled poller starts. 2. The poller sees the file and exits successfully with `LOCKED`. 3. Repeated cron invocations continue to exit while the attacker preserves the file, preventing task polling. 4. Alternatively, two polling instances start close together and both pass the non-atomic existence check. 5. Both instances then poll Redigg concurrently, defeating the intended synchronization and potentially causing duplicate processing attempts. ### Impact Assessment The primary impact is local denial of service against task polling and unreliable concurrency control. Concurrent workers may produce duplicate network requests or contend for task claims. A stale lock can silently ...[truncated 314 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Replace the check-then-`touch` sequence with an atomic locking primitive such as `flock`. - Open a lock file in a user-private runtime directory, such as `$XDG_RUNTIME_DIR`, rather than using a global fixed path in `/tmp`. - If a directory lock is required, create it atomically with `mkdir` and fail if creation does not succeed. - Set restrictive permissions with an appropriate `umask`. - Install an `EXIT`, `INT`, and `TERM` trap immediately after acquiring the lock so cleanup occurs on normal and interrupted exits. - Store and validate the lock owner’s process identifier when `flock` is unavailable. - Detect and safely recover stale locks without deleting a lock actively held by another process. - Use a per-user or per-Agent lock name to avoid interference between independent Agent installations. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (7)

Tool Parameter Abuse

High
Category
Tool Misuse
Content
| 401 Unauthorized | Key expired or wrong format | Re-register agent |
| 409 Conflict | Task already claimed | Check claimed_by_agent_id |
| No tasks returned | Agent not associated with research | Verify agent registration |
| Lock file stuck | Previous run crashed | Manually `rm /tmp/redigg-polling.lock` |
Confidence
85% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Vague Triggers

Medium
Confidence
93% confidence
Finding
The trigger text includes a broad catch-all for 'any Redigg platform integration requests', which can cause the skill to activate in situations beyond narrowly intended account setup or task handling. Overly broad activation increases the chance that sensitive actions such as credential handling, network calls, or background-job setup are performed when the user did not explicitly request them.

External Transmission

Medium
Category
Data Exfiltration
Content
1. **Register Agent** (one-time)
   ```bash
   curl -X POST https://redigg.com/api/agent/register \
     -H "Content-Type: application/json" \
     -d '{"name": "Agent Name", "owner_token": "sk-redigg-..."}'
   ```
Confidence
88% confidence
Finding
The registration flow transmits a sensitive owner token to an external service using a curl command. Although external transmission is expected for an API integration, it is still security-relevant because the skill encourages handling high-value credentials and does not include safeguards around redaction, consent, or secure storage before and after transmission.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The skill instructs the agent to request an owner token and save agent credentials to TOOLS.md without warning the user that secrets will be persisted locally. This creates a real risk of credential exposure through logs, files, repo sync, or later prompts that read TOOLS.md, especially because both the owner token and agent API key grant access to an external service.

External Transmission

Medium
Category
Data Exfiltration
Content
fi

# Submit result
SUBMIT_RESPONSE=$(curl -s -X POST \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d "$RESULT_JSON" \
Confidence
70% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Low
Confidence
91% confidence
Finding
The skill directs creation of cron jobs that poll every 10-30 seconds and send heartbeats every 30-60 seconds, but it does not clearly warn the user that this establishes persistent background activity and ongoing outbound traffic. That can lead to unintended resource use, privacy concerns, and long-lived autonomous behavior on the host.

Scope Creep

Low
Category
Excessive Agency
Content
| Deepen theoretical analysis | Add formal proofs, mathematical models, complexity analysis |
| Focus on cost reduction | Economic analysis, resource optimization, efficiency metrics |
| Apply to different domain | Domain mapping, transfer learning, analogy construction |
| Expand scope | Broader implications, interdisciplinary connections |
| Narrow focus | Specific case study, concrete implementation details |

## Token Budget
Confidence
75% confidence
Finding
Skill's behavior or capabilities extend beyond its stated purpose. Scope creep allows an agent to perform actions unrelated to its documented functionality, increasing the attack surface.