Back to skill

Security audit

AIML Сontent Moderation

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward AIMLAPI moderation wrapper, but users should treat its results as advisory because it sends submitted text to a third party and uses weak response parsing.

Install only if you are comfortable sending checked text and your AIMLAPI key to AIMLAPI. Do not rely on this skill as a sole enforcement gate for moderation decisions without improving its strict response validation and clarifying the unsupported image claim.

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/check_safety.py:45
Finding
Fail-Open Safety Classification Caused by Substring Matching## Vulnerability Details **File Location**: `scripts/check_safety.py`, lines 45–47 **Vulnerability Type**: Fail-open validation of an untrusted API response **Risk Level**: Medium ### Vulnerable Code ```python answer = result['choices'][0]['message']['content'].strip().lower() is_safe = "unsafe" not in answer status = "SAFE" if is_safe else "UNSAFE" ``` ### Technical Analysis The script treats every model response that does not contain the exact substring `unsafe` as a safe classification. The remote model output is untrusted, free-form text rather than a locally validated structured value. This negative substring test fails open. Ambiguous, malformed, unexpected, or alternative responses such as `not safe`, a refusal, an unsupported label, or unrelated text are classified as `SAFE`. Adversarial content may also influence the guard model to return wording that avoids the literal substring while not affirmatively establishing that the submitted content is safe. The application should only approve content after receiving and validating an explicit, allowlisted safe result. Any unknown or malformed response should produce an error or conservative unsafe result. ### Attack Path 1. An attacker submits adversarial content through the `--content` argument. 2. The script sends that content to the configured AIMLAPI guard model. 3. The guard returns free-form output that does not contain the exact substring `unsafe`, whether due to ambiguity, refusal, malformed output, or model manipulation. 4. The expression `"unsafe" not in answer` evaluates to `True`. 5. The script prints `Status: SAFE`, allowing downstream users or automation to treat unverified harmful content as approved. ### Impact Assessment Successful exploitation does not grant operating-system privileges, access to credentials, or code execution. Its scope is the moderation decision produced by this Skill. An attacker may cause harmful or policy-violating content to be incorrectly marked safe, b ...[truncated 253 chars]
Remediation
## Remediation Suggestions 1. Require a strict response format, preferably a JSON schema containing a fixed classification enum such as `SAFE` or `UNSAFE`. 2. Validate the complete normalized classification using exact equality rather than searching for the absence of a substring. 3. Fail closed on missing fields, unknown labels, refusals, malformed JSON, and unexpected response structures. 4. Keep transport or parsing failures distinct from a positive safe decision and return a nonzero process exit code for such failures. 5. If structured model output is unavailable, parse only an explicitly documented first-line label and reject every other format. 6. Add regression tests covering `safe`, `unsafe`, `not safe`, empty output, refusals, malformed responses, missing `choices`, and adversarial text. A conservative implementation should follow this pattern: ```python answer = result["choices"][0]["message"]["content"].strip().lower() if answer == "safe": status = "SAFE" elif answer == "unsafe" or answer.startswith("unsafe\n"): status = "UNSAFE" else: raise ValueError("Unexpected safety-model response") ``` A validated structured API response is preferable to this textual fallback.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (8)

Harmful Content Injection

Critical
Category
Prompt Injection
Content
## Quick start

```bash
export AIMLAPI_API_KEY="sk-..."
python scripts/check_safety.py --content "How to make a bomb"
```

## Tasks

### Check Text Safety
Confidence
95% confidence
Finding
This content may contain harmful instructions that could cause physical harm if followed. CRITICAL: Review carefully before use.

Tainted flow: 'headers' from os.getenv (line 25, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
}

    try:
        response = requests.post(url, json=payload, headers=headers)
        response.raise_for_status()
        data = response.json()
        return data
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding
The skill is advertised as performing general text-or-image safety classification, but the documented behavior only shows text handling and external API submission, with no declared permissions. This mismatch is security-relevant because operators may trust the skill for moderation coverage or data-handling guarantees it does not actually provide, leading to unsafe deployment decisions, privacy exposure, or moderation bypasses.

Lp3

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding
The skill declares use of an API key and describes behavior that sends user content to an external service, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a transparency and governance gap: users or orchestrators may invoke a network-capable skill without clear authorization boundaries, increasing the risk of unintended data exfiltration to a third party.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script sends arbitrary user-supplied content to a third-party API for moderation, but it provides no explicit disclosure, consent prompt, or safeguards for sensitive data. In a safety-checking skill, users may submit highly sensitive text expecting local analysis, so silent external transmission increases privacy and compliance risk.

External Transmission

Medium
Category
Data Exfiltration
Content
print("Error: AIMLAPI_API_KEY environment variable not set.")
        return None

    url = "https://api.aimlapi.com/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
print("Error: AIMLAPI_API_KEY environment variable not set.")
        return None

    url = "https://api.aimlapi.com/v1/chat/completions"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    try:
        response = requests.post(url, json=payload, headers=headers)
        response.raise_for_status()
        data = response.json()
        return data
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.