Back to skill

Security audit

Prompt injection detection skill

Security checks for vulnerabilities and agentic risk

Overview

The skill is a disclosed moderation wrapper, but its shell script has unsafe configuration and mode handling that can bypass checks and may allow code execution if configuration is attacker-controlled.

Install only if you can run it in a constrained environment, trust who controls its environment variables and direction argument, and are allowed to send moderated text to Hugging Face and OpenAI. Fix or sandbox the shell script before using it as an automated security gate.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/moderate.sh:39
Finding
Arbitrary Python Code Execution Through INJECTION_THRESHOLD<![CDATA[ ## Vulnerability Details **File Location**: `scripts/moderate.sh`, lines 39-65 **Vulnerability Type**: Environment-variable code injection **Risk Level**: High ### Vulnerable Code ```bash THRESHOLD="${INJECTION_THRESHOLD:-0.85}" ``` ```bash INJ_FLAGGED=$(python3 -c "print('true' if float('$INJ_SCORE') >= float('$THRESHOLD') else 'false')") ``` ### Technical Analysis The script reads `INJECTION_THRESHOLD` from the process environment and interpolates it directly into Python source passed to `python3 -c`. The value is placed inside a single-quoted Python string, but the shell does not validate or escape it as Python data. An attacker who can influence this environment variable can terminate the Python string and insert arbitrary Python expressions. For example, a value shaped like the following can cause a command to execute while preserving a syntactically valid expression: ```text 0') or __import__("os").system("id") or float('0 ``` The resulting Python expression executes `os.system("id")`. Exploitation occurs only on the input-processing path when `HF_TOKEN` is configured and the Hugging Face request returns a response from which `INJ_SCORE` is calculated. Although control of the complete process environment is already a strong capability, configuration values are commonly supplied through deployment manifests, CI/CD variables, wrappers, or orchestration interfaces. Treating a documented numeric configuration value as executable source unnecessarily turns limited configuration influence into code execution. ### Attack Path 1. The attacker obtains the ability to set or influence `INJECTION_THRESHOLD`, such as through an exposed deployment setting, CI/CD variable, wrapper process, or unsafe multi-tenant configuration. 2. The attacker assigns a value that closes the Python string and injects a Python expression invoking `os.system`, `subprocess`, or another execution primitive. 3. `HF_TOKEN` is present and the Skill processes a message in the ...[truncated 769 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Never interpolate environment values into executable Python source. Pass both values as positional arguments and parse them strictly as data: ```bash INJ_FLAGGED=$( python3 -c ' import sys score = float(sys.argv[1]) threshold = float(sys.argv[2]) if not 0.0 <= threshold <= 1.0: raise ValueError("Threshold must be between 0 and 1") print("true" if score >= threshold else "false") ' "$INJ_SCORE" "$THRESHOLD" ) ``` Additional hardening should include: 1. Validate `INJECTION_THRESHOLD` before making any external request and reject nonnumeric, non-finite, or out-of-range values. 2. Avoid dynamically generated source code for all configuration handling. 3. Run the script under a dedicated, least-privileged account with a restricted filesystem and network policy. 4. Keep API credentials scoped to the minimum necessary permissions. 5. Add tests using quotes, newlines, Python expressions, `NaN`, infinity, and malformed numeric values. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/moderate.sh:21
Finding
Moderation Bypass and Verdict Corruption Through Unvalidated Direction<![CDATA[ ## Vulnerability Details **File Location**: `scripts/moderate.sh`, lines 21-45 **Vulnerability Type**: Input validation failure and unsafe JSON construction **Risk Level**: Medium ### Vulnerable Code ```bash DIRECTION="${1:-input}" shift 2>/dev/null || true ``` ```bash THRESHOLD="${INJECTION_THRESHOLD:-0.85}" MODEL="${HF_MODEL:-protectai/deberta-v3-base-prompt-injection}" RESULT="{\"direction\":\"$DIRECTION\"" ``` ```bash if [ "$DIRECTION" = "input" ] && [ -n "${HF_TOKEN:-}" ]; then ``` The same unvalidated value later controls whether input-specific moderation is performed: ```bash elif [ "$DIRECTION" = "input" ] && [ -z "${HF_TOKEN:-}" ]; then RESULT="$RESULT,\"injection\":{\"flagged\":false,\"score\":0,\"error\":\"HF_TOKEN not set\"}" fi ``` ### Technical Analysis The documented direction values are `input` and `output`, but the script accepts any first argument. Prompt-injection detection runs only when the value is exactly `input`. Consequently, any other value causes the entire Hugging Face prompt-injection layer to be skipped without reporting a direction-validation error. The direction is also concatenated directly into a JSON string without JSON escaping: ```bash RESULT="{\"direction\":\"$DIRECTION\"" ``` A direction containing quotation marks or JSON delimiters can corrupt the result or introduce attacker-selected fields. Depending on the supplied value, later JSON parsing may fail and fall back to `FLAGGED="false"`, or downstream consumers may receive misleading or malformed verdict metadata. The content-moderation layer may still run when `OPENAI_API_KEY` is configured, but it is not a replacement for the skipped prompt-injection classifier. If OpenAI moderation is not configured, an invalid direction can result in no substantive moderation layer being applied while the script emits an overall unflagged result. ### Attack Path 1. An attacker controls the direction argument directly or through an integration that forwards an ...[truncated 1285 chars]
Remediation
<![CDATA[ ## Remediation Suggestions Validate the direction immediately and fail closed for every unsupported value: ```bash DIRECTION="${1:-input}" case "$DIRECTION" in input|output) ;; *) printf '%s\n' '{"error":"Direction must be input or output","flagged":true}' >&2 exit 2 ;; esac shift || true ``` Construct the complete response with a JSON serializer instead of shell string concatenation. For example, pass values to Python through arguments or standard input and use `json.dumps()` to encode every field. Additional controls should include: 1. Treat classifier errors, malformed API responses, and internal JSON parsing failures as an explicit indeterminate or fail-closed state rather than silently setting `flagged` to `false`. 2. Return a stable error field when a required moderation layer was skipped or unavailable. 3. Ensure callers use a fixed, trusted direction value rather than forwarding user-controlled data. 4. Add tests for unsupported modes, quotation marks, backslashes, control characters, newlines, and attempted JSON field injection. 5. Define whether unavailable optional services should produce `flagged`, `error`, or `indeterminate`, and document that behavior for downstream consumers. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Ae1

High
Category
analysis-evasion
Content
Two safety layers via `scripts/moderate.sh`:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Two safety layers via `scripts/moderate.sh`:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
Two safety layers via `scripts/moderate.sh`:
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Lp3

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding
The skill invokes a shell script (`scripts/moderate.sh`) and requires external API tokens, but the manifest does not declare any tool scope or allowed-tools restrictions. That omission weakens isolation and reviewability: an agent platform may permit broader shell access than intended, making misuse or unexpected command execution harder to constrain and audit.

External Transmission

Medium
Category
Data Exfiltration
Content
# ── Layer 1: Prompt injection detection (input only) ──

if [ "$DIRECTION" = "input" ] && [ -n "${HF_TOKEN:-}" ]; then
  HF_RESPONSE=$(curl -sf \
    "https://router.huggingface.co/hf-inference/models/$MODEL" \
    -X POST \
    -H "Authorization: Bearer $HF_TOKEN" \
Confidence
97% confidence
Finding
This script transmits the full user-provided input text to a third-party Hugging Face inference endpoint for prompt-injection detection. In a content-moderation skill, inputs are explicitly likely to come from untrusted, public, or sensitive contexts, so sending raw text off-platform can expose confidential user data, internal prompts, secrets, or regulated content without minimization or consent.

External Transmission

Medium
Category
Data Exfiltration
Content
# ── Layer 2: Content moderation (both directions, optional) ──

if [ -n "${OPENAI_API_KEY:-}" ]; then
  OAI_RESPONSE=$(curl -sf \
    "https://api.openai.com/v1/moderations" \
    -X POST \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
Confidence
98% confidence
Finding
The script sends raw text to the OpenAI moderation API, which is an external service. Because this skill is designed to process adversarial and potentially highly sensitive input/output, this creates a meaningful data-exfiltration and privacy boundary issue if the text includes secrets, personal data, hidden instructions, or confidential conversation content.

External Transmission

Medium
Category
Data Exfiltration
Content
if [ -n "${OPENAI_API_KEY:-}" ]; then
  OAI_RESPONSE=$(curl -sf \
    "https://api.openai.com/v1/moderations" \
    -X POST \
    -H "Authorization: Bearer $OPENAI_API_KEY" \
    -H 'Content-Type: application/json' \
Confidence
94% confidence
Finding
This finding is the concrete external endpoint used for moderation, confirming that moderated content is transmitted to api.openai.com. In this skill’s context, that is more dangerous than in ordinary tooling because the whole purpose is to inspect suspicious or policy-sensitive content, which may contain exactly the high-risk data that should not leave the trust boundary unredacted.

Static analysis

No suspicious patterns detected.