Back to skill

Security audit

Critical Debater Suite

Security checks for vulnerabilities and agentic risk

Overview

This debate skill is not clearly malicious, but it grants broad web, file-writing, external-agent, and optional persistence capabilities without enough scoping or user-control detail.

Review this skill before installing if you work with sensitive topics or private workspaces. It can search the web, fetch pages, write debate artifacts, run local scripts, invoke Claude or Codex CLIs, and may set up recurring cron refresh if approved. Use it only in a constrained workspace and avoid giving it confidential subjects unless the external search and local agent runtime permissions are acceptable.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/debate_orchestrator_generic.py:160
Finding
Untrusted Parameters Are Embedded Directly into Tool-Capable Agent Prompts## Vulnerability Details **File Location**: `scripts/debate_orchestrator_generic.py:160-181`, with vulnerable prompt construction at `scripts/debate_orchestrator_generic.py:282-285`, `344-348`, and `367-375` **Vulnerability Type**: Prompt injection through unsanitized topic and workspace parameters **Risk Level**: High ### Vulnerable Code ```python if runtime == "claude": cmd = [ "claude", "-p", prompt, "--model", model, ] elif runtime == "codex": cmd = [ "codex", "-p", prompt, "--model", model, ] result = subprocess.run( cmd, capture_output=True, text=True, timeout=timeout_sec, ) ``` The prompts passed to these tool-capable runtimes are constructed using caller-controlled values: ```python dispatch_agent( "source_ingest_round_0", f"Execute source-ingest.md: topic={opts.topic}, mode=broad, round=0, " f"depth={opts.depth}, num_queries={num_queries}. " f"Workspace: {workspace}", model_tier="balanced", ) ``` ```python dispatch_agent( f"source_ingest_round_{round_num}", f"Execute source-ingest.md: topic={opts.topic}, mode=focused, " f"round={round_num}, search_focus={search_focus}. Workspace: {workspace}", model_tier="balanced", ) ``` ```python pro_prompt = ( f"Execute debate-turn.md: side=pro, round={round_num}, topic={opts.topic}, " f"mode={opts.mode}, speculation={opts.speculation}, depth={opts.depth}. " f"{prev_round_context}. Workspace: {workspace}" ) con_prompt = ( f"Execute debate-turn.md: side=con, round={round_num}, topic={opts.topic}, " f"mode={opts.mode}, speculation={opts.speculation}, depth={opts.depth}. " f"{prev_round_context}. Workspace: {workspace}" ) ``` ### Technical Analysis The debate topic can originate directly from the command line or from a configuration file. Both the topic and workspace path are interpo ...[truncated 1897 chars]
Remediation
## Remediation Suggestions 1. Pass all parameters in a strict JSON envelope rather than interpolating them into free-form control text. 2. Delimit each untrusted value and explicitly instruct the runtime that content inside those fields is data, not executable instructions. 3. Reject control characters, unexpectedly large topics, and invalid workspace paths before prompt construction. 4. Resolve the workspace to a canonical path and require it to remain under an approved workspace root. 5. Run delegated agents with a restricted working directory and a filesystem allowlist limited to that workspace. 6. Disable shell execution and unrelated tools for roles that only need search, read, and structured write operations. 7. Apply network restrictions and destination allowlists where possible. 8. Log tool operations independently and require confirmation for access outside the workspace. 9. Add adversarial tests containing instruction-like topics to confirm that they remain inert data.

T09 · Insecure Skill Coding Practices

Error
Location
capabilities/source-ingest.md:31
Finding
Fetched Web Content Is Processed Without Indirect Prompt-Injection Isolation## Vulnerability Details **File Location**: `capabilities/source-ingest.md:31-35`; affected downstream consumption also occurs at `capabilities/debate-turn.md:21-24`, `63-69`, and `capabilities/judge-audit.md:30-36` **Vulnerability Type**: Indirect prompt injection through web evidence **Risk Level**: High ### Vulnerable Code ```markdown ### 2. Execute Searches For each query: 1. `search(query)` → collect result URLs and snippets 2. For top results: `fetch(url)` → extract full content 3. If fetch fails on JS-heavy page: retry once, then skip with `fetch_skipped` note ``` The retrieved material is subsequently exposed to other tool-capable roles: ```markdown ## Context Files to Read 1. `evidence/evidence_store.json` — all available evidence 2. `claims/claim_ledger.json` — all claims and their statuses 3. **Round 2+**: `rounds/round_{N-1}/pro_turn.json`, `con_turn.json`, `judge_ruling.json` 4. **NEVER** read current round opponent's turn file ``` ```markdown ### 4. Search for Supplementary Evidence If evidence_store is insufficient for the arguments being constructed: 1. Use `search` to find additional sources 2. Normalize to EvidenceItem format 3. Include in `new_evidence[]` array in the turn output 4. Tag: `discovered_by` = side, `search_context` = "{side}_supplement" ``` ### Technical Analysis The source-ingestion capability retrieves arbitrary public web pages and asks an AI agent to extract content from them. The instructions do not establish a trust boundary between page content and operational instructions. There is no requirement to: - Treat all retrieved text strictly as untrusted evidence. - Ignore instructions embedded in pages, metadata, comments, or hidden text. - Perform extraction in a non-tool-capable context. - Restrict URL schemes, hosts, redirects, or private network destinations. - Remove active, hidden, or instruction-like content before storage. - Limit excerp ...[truncated 1606 chars]
Remediation
## Remediation Suggestions 1. Add an explicit invariant stating that all remote content is untrusted data and that instructions within it must never be followed. 2. Separate retrieval and deterministic text extraction from tool-capable reasoning. 3. Convert fetched pages to bounded plain-text excerpts while removing scripts, styles, comments, hidden elements, metadata instructions, and active content. 4. Restrict URLs to approved schemes such as HTTPS and reject credentials, local files, loopback addresses, link-local addresses, private networks, and unsafe redirects. 5. Limit response sizes, excerpt lengths, redirect counts, and retrieval time. 6. Preserve provenance, including the final URL, retrieval time, publisher, and exact quoted excerpt. 7. Validate evidence with a real JSON Schema that enforces types, enums, length limits, URL formats, and rejection of unexpected fields. 8. Prevent evidence text from being inserted into system or control-message positions. 9. Require an independent verification stage before retrieved evidence can become verified or influence high-impact conclusions. 10. Test the pipeline against direct, indirect, encoded, metadata-based, and multilingual prompt-injection payloads.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/init-workspace.sh:6
Finding
Workspace Writes Follow Attacker-Controlled Symbolic Links## Vulnerability Details **File Location**: `scripts/init-workspace.sh:6-25`; related unsafe writes occur at `scripts/append-audit.sh:12-18` and `scripts/debate_orchestrator_generic.py:100-103` **Vulnerability Type**: Arbitrary file overwrite through symbolic-link traversal **Risk Level**: Medium ### Vulnerable Code ```bash WORKSPACE_DIR="${1:?Usage: $0 <workspace_dir> <topic> <rounds>}" TOPIC="${2:?Usage: $0 <workspace_dir> <topic> <rounds>}" ROUNDS="${3:-3}" TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") mkdir -p "$WORKSPACE_DIR"/{evidence,claims,rounds,reports,logs} for i in $(seq 1 "$ROUNDS"); do mkdir -p "$WORKSPACE_DIR/rounds/round_$i" done cat > "$WORKSPACE_DIR/config.json" <<EOF { "topic": $(printf '%s' "$TOPIC" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))'), "round_count": $ROUNDS, "current_round": 0, "status": "initialized", "created_at": "$TIMESTAMP", "updated_at": "$TIMESTAMP" } EOF echo '[]' > "$WORKSPACE_DIR/evidence/evidence_store.json" echo '[]' > "$WORKSPACE_DIR/claims/claim_ledger.json" ``` The audit helper similarly follows the supplied path: ```bash touch "$AUDIT_FILE" TEMP_FILE=$(mktemp "${AUDIT_FILE}.XXXXXX") cp "$AUDIT_FILE" "$TEMP_FILE" echo "$JSON_LINE" >> "$TEMP_FILE" mv "$TEMP_FILE" "$AUDIT_FILE" ``` Python updates also use ordinary path-following file operations: ```python def write_json(filepath: str, data): with open(filepath, "w") as f: json.dump(data, f, indent=2, ensure_ascii=False) ``` ### Technical Analysis The workspace directory is caller-controlled and can already exist. Neither initialization nor subsequent writes canonicalize the path, reject symbolic links, or verify that all path components remain beneath an approved root. Shell redirection, `touch`, `cp`, and Python `open(..., "w")` follow symbolic links. An attacker who can prepare a workspace can replace expected files or dire ...[truncated 1788 chars]
Remediation
## Remediation Suggestions 1. Require workspaces to be newly created beneath a fixed, administrator-approved root. 2. Resolve the canonical parent path and verify that it remains under the approved root before every write. 3. Reject symbolic links in the workspace and in every path component using `lstat` or equivalent checks. 4. Open files with `O_NOFOLLOW`, `O_CREAT`, and appropriate exclusive-creation semantics. 5. Refuse to overwrite pre-existing output files unless the caller explicitly requests a safe reset. 6. Create the workspace with restrictive permissions, such as mode `0700`, and output files with mode `0600` where appropriate. 7. Use atomic writes to a securely created same-directory temporary file, verify the destination again, and then rename it. 8. Avoid running the orchestrator as root or under accounts with access beyond the required debate workspace. 9. Validate the round count and other path-derived components before creating directories. 10. Add tests covering symlinked files, symlinked directories, path traversal, race conditions, and pre-existing workspace entries.
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
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (30)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This manifest declares a debate/reporting skill but also explicitly signals external agent runtimes, internet access, and generic read/write/spawn mappings without surfacing those execution capabilities as user-facing permissions. Even if the deeper implementations are elsewhere, the mismatch between declared purpose and operational power can mislead users and reviewers about the true attack surface.

Tp4

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding
This manifest declares a debate/reporting skill but also explicitly signals external agent runtimes, internet access, and generic read/write/spawn mappings without surfacing those execution capabilities as user-facing permissions. Even if the deeper implementations are elsewhere, the mismatch between declared purpose and operational power can mislead users and reviewers about the true attack surface.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This manifest declares a debate/reporting skill but also explicitly signals external agent runtimes, internet access, and generic read/write/spawn mappings without surfacing those execution capabilities as user-facing permissions. Even if the deeper implementations are elsewhere, the mismatch between declared purpose and operational power can mislead users and reviewers about the true attack surface.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
This manifest declares a debate/reporting skill but also explicitly signals external agent runtimes, internet access, and generic read/write/spawn mappings without surfacing those execution capabilities as user-facing permissions. Even if the deeper implementations are elsewhere, the mismatch between declared purpose and operational power can mislead users and reviewers about the true attack surface.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding
This manifest declares a debate/reporting skill but also explicitly signals external agent runtimes, internet access, and generic read/write/spawn mappings without surfacing those execution capabilities as user-facing permissions. Even if the deeper implementations are elsewhere, the mismatch between declared purpose and operational power can mislead users and reviewers about the true attack surface.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# Expected: SHA-256 hash string

# 9. Cleanup
rm -rf /tmp/test-debate
```

## Full Debate (via Claude Code)
Confidence
90% 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).

Tool Parameter Abuse

High
Category
Tool Misuse
Content
# Expected: SHA-256 hash string

# 9. Cleanup
rm -rf /tmp/test-debate
```

## Full Debate (via Claude Code)
Confidence
90% 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).

External Model or Provider Selection

High
Category
Excessive Agency
Content
"""
    Execute a step via the detected agent runtime.

    Claude Code  → claude -p <prompt> --model <model>
    Codex        → codex -p <prompt> --model <model>
    None         → ERROR, returns False
Confidence
90% confidence
Finding
Selecting and invoking whichever external agent runtime is present in PATH (`claude` or `codex`) delegates sensitive orchestration steps to an external model/tooling surface without trust validation or capability restriction. Because this skill is specifically an adversarial debate orchestrator that repeatedly feeds model-generated context back into later prompts, the context increases the danger of prompt injection, data leakage, and unintended actions across rounds.

Lp3

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding
The skill advertises compatibility with bash, python3, jq, shasum, and web access and defines generic write/shell-adjacent tool mappings, but it does not declare any explicit tool scope such as allowed-tools or permissions. That omission weakens least-privilege controls and can let a routed capability inherit broader file-write or shell execution rights than users would reasonably expect.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrase "analyze from multiple perspectives" is broad and likely to match ordinary user requests that were not intended to invoke a multi-step skill with web access and delegated role behavior. Over-broad activation increases the chance of unintended network use, file creation, or role-spawning in contexts where the user expected a simple local response.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The manifest states that internet access is required for web search but does not clearly tell users that their prompts, topics, or evidence queries may be sent to external services. This creates a meaningful privacy and data-governance risk, especially when users provide sensitive organizational, legal, or personal subjects for analysis.

Vague Triggers

Medium
Confidence
86% confidence
Finding
The routing rule "full topic for debate" is ambiguous and leaves too much discretion to the router about what counts as debate invocation. Ambiguous routing can accidentally activate more powerful capability chains, including web search and file/output generation, on generic analytical prompts.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The skill instructs the agent to create a recurring 6-hour cron job, which introduces persistent system modification unrelated to the core task of conducting a debate. Even though it says 'If user agrees,' the capability text lacks explicit safety constraints, scope limits, removal guidance, or a requirement for a clearly informed confirmation before establishing ongoing execution.

Missing User Warnings

Medium
Confidence
92% confidence
Finding
The scheduled task is presented as an optional continuation, but the skill does not require a prominent warning that this causes ongoing automated system changes beyond the immediate debate session. That makes it easy for an agent or user to trigger persistent background behavior without fully appreciating the operational and security implications, such as repeated network access or resource consumption.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The phrase "verify evidence" is presented as a manual invocation intent without any scope constraints, examples, or exclusions. In a debate or research workflow, this wording is generic enough that normal user requests could unintentionally activate the capability.

Natural-Language Policy Violations

Medium
Confidence
97% confidence
Finding
The markdown instructs the agent to always produce a bilingual report and specifically requires a complete Chinese translation of all sections. This forces a specific locale/language behavior without user opt-in, which matches the language-policy violation criteria.

Missing User Warnings

Medium
Confidence
93% confidence
Finding
The capability explicitly instructs the agent to overwrite `evidence/evidence_store.json`, but the skill text provides no requirement to notify the user or obtain confirmation before modifying persisted workspace data. In a multi-agent debate workflow, silent mutation of stored evidence can change future outputs, erase prior freshness states, or unexpectedly alter user-maintained records, making the behavior unsafe even if it is operationally intended.

Missing User Warnings

Medium
Confidence
91% confidence
Finding
The capability instructs the agent to write `judge_ruling.json` and execute `scripts/validate-json.sh` without any user-facing disclosure or consent boundary. In a workspace-oriented skill, silent file modification and script execution can create integrity and transparency risks, especially if the workspace or script contents are attacker-controlled or unexpected.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
This capability explicitly performs `search(query)` and `fetch(url)` using topic-derived queries, which can transmit user-provided debate topics, focus areas, and potentially sensitive research intent to external services without any user-facing disclosure or consent step. In a multi-agent debate workflow, repeated broad and focused searches amplify the privacy exposure because the system may send nuanced or controversial user topics to multiple third-party endpoints over several rounds.

Description-Behavior Mismatch

Medium
Confidence
91% confidence
Finding
The evals introduce capabilities beyond the skill’s stated debate scope, including source-ingest, judge-audit, and final-synthesis. This matters because routing and permission expectations are typically derived from the manifest; undocumented capability expansion can cause the skill to activate in contexts users and reviewers did not anticipate.

Vague Triggers

Medium
Confidence
94% confidence
Finding
The trigger phrase 'search evidence about ...' is broad enough to match ordinary research requests that are not asking for a debate workflow. In this skill context, that can over-trigger the suite, causing unintended source-ingest behavior and expanding the skill’s operational scope beyond adversarial debate initiation.

Vague Triggers

Medium
Confidence
91% confidence
Finding
The phrase 'generate the final report' is generic workflow language that could appear in many non-debate tasks. In a multi-capability skill, such a broad trigger risks accidental invocation of final-synthesis behavior, potentially overriding user intent and producing outputs from the wrong workflow context.

Missing User Warnings

Medium
Confidence
94% confidence
Finding
The markdown includes `rm -rf /tmp/test-debate` as a cleanup step, which is a destructive filesystem operation. The surrounding text does not provide any warning that the command permanently deletes the workspace or caution users to verify the target path before running it.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
def run_script(script: str, args: list[str], cwd: str) -> subprocess.CompletedProcess:
    script_dir = Path(__file__).parent
    script_path = script_dir / script
    result = subprocess.run(
        ["bash", str(script_path)] + args,
        cwd=cwd,
        capture_output=True,
Confidence
70% confidence
Finding
subprocess module calls execute external commands. Without careful input validation, this enables command injection.

subprocess module call

Medium
Category
Dangerous Code Execution
Content
return False

    try:
        result = subprocess.run(
            cmd,
            capture_output=True,
            text=True,
Confidence
90% confidence
Finding
The orchestrator forwards dynamically constructed prompts containing untrusted topic, workspace, and prior-round content to external agent CLIs (`claude`/`codex`) and treats exit-code success as sufficient. In a multi-agent skill, this creates a prompt-injection and unsafe-agent-execution boundary where adversarial input can steer downstream agents to read, modify, or exfiltrate files accessible from the current environment.

Static analysis

No suspicious patterns detected.