davila7/claude-code-templates · error

SEM_E017

SEM_E017

Error message

Inline event handler detected (XSS risk)

What it means

SEM_E017 is emitted by checkHtmlInjection when the content contains 'onclick=' (case-insensitive substring). Inline event-handler attributes execute JavaScript from HTML, so embedding them in distributed component markdown is flagged as an XSS risk.

Source

Thrown at cli-tool/src/validation/validators/SemanticValidator.js:289

        this.addError(code, message, {
          path,
          severity,
          matches: contexts.length,
          examples: contexts.slice(0, 3)
        });
      }
    }
  }

  /**
   * Check for HTML/Script injection attempts
   */
  checkHtmlInjection(content, path) {
    const dangerousTags = [
      { tag: '<script', code: 'SEM_E014', message: '<script> tag detected (XSS risk)' },
      { tag: '<iframe', code: 'SEM_E015', message: '<iframe> tag detected (injection risk)' },
      { tag: 'javascript:', code: 'SEM_E016', message: 'javascript: protocol detected (XSS risk)' },
      { tag: 'onclick=', code: 'SEM_E017', message: 'Inline event handler detected (XSS risk)' },
      { tag: 'onerror=', code: 'SEM_E018', message: 'onerror handler detected (XSS risk)' }
    ];

    for (const { tag, code, message } of dangerousTags) {
      const lowerContent = content.toLowerCase();
      if (lowerContent.includes(tag.toLowerCase())) {
        const index = lowerContent.indexOf(tag.toLowerCase());
        const lineInfo = this.getLineFromIndex(content, index);

        this.addError(code, message, {
          path,
          severity: 'critical',
          line: lineInfo.line,
          column: lineInfo.column,
          position: lineInfo.position,
          lineText: lineInfo.lineText,
          context: this.getContext(content, index, 50)
        });

View on GitHub (pinned to a0851ed10c)

Solutions

  1. Escape or paraphrase HTML examples rather than including literal 'onclick=' (e.g. describe: 'attach a click handler via addEventListener')
  2. For React examples, note the validator lowercases content, so onClick= matches too — use addEventListener-style examples or move code to a linked external file
  3. Remove inline handlers from real templates and bind events in referenced JS files

Example fix

# before
<button onclick="doThing()">Go</button>
# after
<button id="go">Go</button> <!-- bind via addEventListener in app.js -->
Defensive patterns

Strategy: validation

Validate before calling

if (component.content.toLowerCase().includes('onclick=')) {
  // escape/paraphrase handler examples
}

Prevention

When it happens

Trigger: validate() where content.toLowerCase().includes('onclick='). Any occurrence counts, including HTML examples in fenced code blocks, JSX/React sample code like <button onClick={...} (matches after lowercasing), or attribute listings.

Common situations: Agent/command markdown containing React or HTML snippets with onClick handlers; front-end tutorial components; copy-pasted markup examples.

Related errors


AI-assisted analysis of davila7/claude-code-templates@a0851ed10c (2026-08-28). Data as JSON: /api/errors/ddde787329829dfe. Report an issue: GitHub.