Back to skill

Security audit

Devils Advocate Suite

Security checks for vulnerabilities and agentic risk

Overview

This skill is a disclosed decision-review framework with local helper scripts, though users should treat its outputs as facilitation aids and avoid feeding hostile JSON into its CLI.

Install only if you want a structured business-decision review aid. Use it as a facilitation checklist, not as expert legal, financial, safety, or operational approval. When using premortem_aggregator.py, provide small trusted JSON inputs with 1-5 likelihood and impact values, because hostile or oversized input could produce excessive terminal output or misleading control-character display.

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 (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/premortem_aggregator.py:19
Finding

Unvalidated risk data enables resource exhaustion and terminal output injection

Content
View full analysis

Vulnerability Details

File Location: scripts/premortem_aggregator.py, lines 19–43
Vulnerability Type: Missing input bounds and unsafe terminal output
Risk Level: Medium

Vulnerable Code

python
def aggregate_failures(failure_list):
    """
    Input: List of dicts {"reason": str, "likelihood": 1-5, "impact": 1-5}
    Output: Aggregated report sorted by risk severity.
    """
    report = []
    for item in failure_list:
        score = calculate_risk_score(item["likelihood"], item["impact"])
        report.append(
            {
                "reason": item["reason"],
                "likelihood": item["likelihood"],
                "impact": item["impact"],
                "score": score,
                "category": categorize_risk(score),
            }
        )

    return sorted(report, key=lambda x: x["score"], reverse=True)


def print_risk_matrix(report):
    """Pretty-print the risk matrix to stdout."""
    print("\n=== RISK MATRIX ===\n")
    for item in report:
        bar = "█" * item["score"]
        print(f"[{item['category']:8}] Score {item['score']:2}/25 {bar}")
        print(f"           L={item['likelihood']} x I={item['impact']}: {item['reason']}\n")

Technical Analysis

The script documents likelihood and impact as integers in the range 1–5, but it never enforces their types or bounds. Their product is passed directly to Python string multiplication:

python
bar = "█" * item["score"]

An attacker who controls standard input can therefore provide values far above the intended range. This causes the process to attempt to allocate and print a string proportional to the supplied score, potentially consuming excessive memory, CPU time, and output capacity.

The attacker-controlled reason field is also written directly to a terminal without rejecting control characters. ANSI escape sequences and other terminal control bytes can a ...[truncated 1983 chars]

Remediation
View remediation

Remediation Suggestions

  1. Validate that the top-level JSON value is a list and impose a maximum number of entries.
  2. Require every entry to be an object containing exactly the expected fields.
  3. Reject booleans and non-integer values for likelihood and impact, then enforce the documented range of 1 through 5.
  4. Require reason to be a string and impose a reasonable maximum length.
  5. Reject or visibly escape control characters before writing attacker-controlled text to a terminal.
  6. Cap the rendered bar length independently of the calculated score as defense in depth.
  7. Report invalid input to standard error and exit with a nonzero status.
  8. Apply memory, CPU, and output limits when the CLI is exposed through a service or shared automation environment.

Example validation logic:

python
import unicodedata

MAX_ITEMS = 100
MAX_REASON_LENGTH = 1000

def validate_failure_list(data):
    if not isinstance(data, list):
        raise ValueError("Input must be a JSON array")
    if len(data) > MAX_ITEMS:
        raise ValueError(f"At most {MAX_ITEMS} risks are allowed")

    validated = []
    for index, item in enumerate(data):
        if not isinstance(item, dict):
            raise ValueError(f"Item {index} must be an object")

        reason = item.get("reason")
        likelihood = item.get("likelihood")
        impact = item.get("impact")

        if not isinstance(reason, str) or len(reason) > MAX_REASON_LENGTH:
            raise ValueError(f"Item {index} has an invalid reason")

        if any(unicodedata.category(char) == "Cc" for char in reason):
            raise ValueError(f"Item {index} contains control characters")

        for name, value in (("likelihood", likelihood), ("impact", impact)):
            if isinstance(value, bool) or not isinstance(value, int):
                raise ValueError(f"Item {index} field {name} must be an integer")
            if not 1 <= value &l
...[truncated 326 chars]
Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • 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 (2)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a broad high-stakes decision-review capability centered on adversarial analysis, risk discovery, and assumption-challenging. The supplied code does not perform those functions. Instead, it provides a static lookup tool for a small set of predefined business contradictions and returns associated TRIZ principles, with a generic fallback list. There is no logic for evaluating decisions, identifying risks, conducting pre-mortems, reviewing PR/FAQs, detecting groupthink, or stress-testing assumptions. While TRIZ could support brainstorming around trade-offs, that is only loosely related and far narrower than the declared purpose. No suspicious undeclared resource access appears, but the primary purpose is materially different, so this should be flagged as a mismatch.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The activation guidance is broad enough to trigger on many vague or high-stakes situations, which can cause over-invocation and unintended delegation to this skill. In a decision-support context, that increases the chance the agent applies an incomplete or mis-scoped methodology to sensitive business or operational choices, potentially displacing more appropriate safeguards or expert review.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.