T09 · Insecure Skill Coding Practices
Error
- Location
- BRAIN_ARCHITECTURE.md:317
- Finding
- Context-Unaware Template Substitution Enables HTML and JSON-LD Injection<![CDATA[ ## Vulnerability Details **File Location**: `BRAIN_ARCHITECTURE.md:317-326`; injection sinks are present in `TEMPLATES/product_new_template.md:7-28` and `TEMPLATES/product_new_template.md:35-88` **Vulnerability Type**: Unescaped HTML, attribute, URL, and JSON-LD template substitution **Risk Level**: High ### Vulnerable Code `BRAIN_ARCHITECTURE.md:317-326`: ```python def inject_variables(template_text: str, variables: dict) -> str: """Replace ALL {PLACEHOLDER} text with actual values.""" return template_text.format(**variables) ``` ```text Rules: - Every {PLACEHOLDER} in the template must be replaced — no placeholder may survive into output - If a variable is missing from the dictionary → flag it, ask the user for the value, do not output {PLACEHOLDER} text - Schema variables ({SCHEMA_*}) are substituted in the same pass ``` Representative sinks from `TEMPLATES/product_new_template.md:7-28`: ```html <title>{TITLE} — {DESCRIPTION}</title> <meta name="description" content="{META_DESCRIPTION}"> <link rel="canonical" href="{URL_CANONICAL}"> <!-- Schema: Product --> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "Product", "name": "{TITLE}", "description": "{DESCRIPTION}", "brand": "{BRAND_NAME}", "offers": { "@type": "Offer", "priceCurrency": "EUR", "price": "{PRICE_CURRENCY_PRICE}", "availability": "https://schema.org/InStock" }, "aggregateRating": { "@type": "AggregateRating", "ratingValue": "{RATING_VALUE}", "ratingCount": "{RATING_COUNT}" } } </script> ``` Representative body and URL sinks from `TEMPLATES/product_new_template.md:35-88`: ```html <h1>{H1_TITLE_BRAND_PRODUCT_KEYWORD}</h1> <p>{HERO_SUBHEADLINE_TECHNICAL_BENEFITS} — Perfect for {TARGET_USE_CASES}</p> <span class="price-tag">{DISPLAY_PRICE_EUR} / unit</span> <section class="product-description"> <h2>{H2_DESCRIPTION_OVERVIEW_FEATURES}</h2> <p>{DESCRIPTION_CONTENT_400_CHARS_MAX}</p> <p> ...[truncated 2942 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions 1. Replace generic string formatting with a context-aware rendering system that enables automatic HTML escaping. 2. HTML-escape every value inserted into text nodes. 3. Attribute-encode values inserted into quoted HTML attributes. 4. Construct JSON-LD as a native object and serialize it with a standards-compliant JSON serializer. Never build JSON by interpolating strings. 5. Validate all URL values before rendering: - Permit only explicitly supported schemes, normally `https`. - Reject `javascript:`, `data:`, `file:`, and other unintended schemes. - Normalize and parse URLs before applying the allowlist. 6. Treat brand profiles, briefs, plans, search-result text, and user prompts as untrusted input. 7. Add a final structural validation step for generated HTML and JSON-LD. 8. Add adversarial regression tests containing: - Single and double quotation marks. - HTML tags and event-handler attributes. - Script-closing sequences. - Newlines and control characters. - `javascript:` and `data:` URLs. 9. Do not describe generated HTML as deploy-ready unless it has passed these security checks. ]]>
