Back to skill

Security audit

Science Simulation Author

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent offline science-simulation generator, but it needs Review because crafted SimSpec text can be embedded into generated HTML in a way that may run unintended JavaScript.

Install only if you trust the SimSpecs you will use or if the template is fixed to escape JSON safely for inline script contexts. Avoid generating simulations from third-party or student-supplied specs until that encoding issue is remediated; no credential access, persistence, or deliberate exfiltration was found.

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

Error
Location
templates/sim_single_file_html_template.html:413
Finding

Untrusted SimSpec Strings Can Break Out of the Generated Script Block

Content
View full analysis

Vulnerability Details

File Location: templates/sim_single_file_html_template.html:413-420
Related Validation Locations: templates/sim_spec_schema.json:27-30, 132-140, 157-160, 183-186, 228-234
Vulnerability Type: Generated HTML script injection
Risk Level: High

Vulnerable Code

html
const stateDefs = {{{state_json}}};
const paramDefs = {{{params_json}}};
const initialState = {{{initial_json}}};
const equations = {{{equations_json}}};
const outputs = {{{outputs_json}}};
const worksheet = {{{worksheet_json}}};
const successCriteria = {{{success_criteria_json}}};
const readoutFields = {{{readout_fields_json}}};

The schema allows unrestricted strings in fields that can reach these placeholders. For example:

json
"title": {
  "type": "string",
  "minLength": 1
}

The same lack of content restrictions applies to multiple embedded fields, including units, descriptions, output labels, worksheet prompts, and success criteria.

Technical Analysis

The template embeds serialized SimSpec data directly into an executable <script> element through raw triple-mustache placeholders. JSON serialization alone is not sufficient contextual output encoding for an HTML script element.

A string containing the HTML parser terminator </script> can terminate the enclosing script even when the sequence appears inside a JavaScript string literal. An attacker can follow it with a new <script> element containing arbitrary JavaScript.

The schema validates these values only as non-empty strings and does not reject HTML control sequences. Although the application later displays dynamic labels and worksheet content through safe textContent assignments, the vulnerable values are processed by the HTML parser before those safe DOM operations occur.

The affected data flow is:

  1. An untrusted SimSpec supplies free-form text.
  2. The text passes schema validation.
  3. The value is serialized as JSON.
  4. The serialized JSON is inserted raw int ...[truncated 2233 chars]
Remediation
View remediation

Remediation Suggestions

  1. Use script-safe serialization for every embedded JSON value.

    After JSON.stringify, escape characters that are significant to the HTML parser:

    javascript
    function serializeForInlineScript(value) {
      return JSON.stringify(value)
        .replace(/</g, "\\u003c")
        .replace(/>/g, "\\u003e")
        .replace(/&/g, "\\u0026")
        .replace(/\u2028/g, "\\u2028")
        .replace(/\u2029/g, "\\u2029");
    }
    

    Apply this serializer to all JSON placeholders before template insertion.

  2. Prefer inert JSON containers.

    Store configuration in <script type="application/json"> elements and parse their textContent. Script-closing sequences must still be escaped because the HTML parser recognizes </script> regardless of the script type.

  3. Apply context-specific encoding to non-JSON placeholders.

    HTML-escape values inserted into element text and attribute-encode sim_id, domain, level, and renderer_kind before placing them in attributes.

  4. Add defense-in-depth validation.

    Reject or normalize dangerous HTML control sequences in all free-text fields. This should supplement, not replace, correct contextual encoding.

  5. Add regression tests for every free-text field.

    Test titles, units, descriptions, labels, worksheet prompts, success criteria, and extension metadata with payloads containing:

    text
    </script><script>alert(1)</script>
    

    Confirm that the resulting document contains no additional executable script element and that the payload is displayed only as inert text.

  6. Extend the validation checklist.

    Require verification that all SimSpec-derived values are safely encoded for their exact HTML, attribute, or JavaScript context before returning index.html.

Vulnerability Patterns
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (3)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 44)May include surrounding context.

md
4. Populate [templates/sim_single_file_html_template.html](templates/sim_single_file_html_template.html) with pre-normalized values.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 94)May include surrounding context.

md
4. Populate [templates/sim_single_file_html_template.html](templates/sim_single_file_html_template.html) with pre-normalized values.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This YAML manifest defines the skill's content and parameters but does not specify how or when the skill should be invoked, nor any constraints or exclusions on activation. For manifest files, missing specificity on trigger scope can lead to unintended invocation if external tooling infers activation from broad metadata like the title or domain.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.