{"record":{"id":"ddde787329829dfe","repo":"davila7/claude-code-templates","slug":"sem-e017","errorCode":"SEM_E017","errorMessage":"Inline event handler detected (XSS risk)","messagePattern":"Inline event handler detected \\(XSS risk\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli-tool/src/validation/validators/SemanticValidator.js","lineNumber":289,"sourceCode":"        this.addError(code, message, {\n          path,\n          severity,\n          matches: contexts.length,\n          examples: contexts.slice(0, 3)\n        });\n      }\n    }\n  }\n\n  /**\n   * Check for HTML/Script injection attempts\n   */\n  checkHtmlInjection(content, path) {\n    const dangerousTags = [\n      { tag: '<script', code: 'SEM_E014', message: '<script> tag detected (XSS risk)' },\n      { tag: '<iframe', code: 'SEM_E015', message: '<iframe> tag detected (injection risk)' },\n      { tag: 'javascript:', code: 'SEM_E016', message: 'javascript: protocol detected (XSS risk)' },\n      { tag: 'onclick=', code: 'SEM_E017', message: 'Inline event handler detected (XSS risk)' },\n      { tag: 'onerror=', code: 'SEM_E018', message: 'onerror handler detected (XSS risk)' }\n    ];\n\n    for (const { tag, code, message } of dangerousTags) {\n      const lowerContent = content.toLowerCase();\n      if (lowerContent.includes(tag.toLowerCase())) {\n        const index = lowerContent.indexOf(tag.toLowerCase());\n        const lineInfo = this.getLineFromIndex(content, index);\n\n        this.addError(code, message, {\n          path,\n          severity: 'critical',\n          line: lineInfo.line,\n          column: lineInfo.column,\n          position: lineInfo.position,\n          lineText: lineInfo.lineText,\n          context: this.getContext(content, index, 50)\n        });","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/davila7/claude-code-templates/blob/a0851ed10c7c60463dac8cfaaca124cf32d5804d/cli-tool/src/validation/validators/SemanticValidator.js#L271-L307","documentation":"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.","triggerScenarios":"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.","commonSituations":"Agent/command markdown containing React or HTML snippets with onClick handlers; front-end tutorial components; copy-pasted markup examples.","solutions":["Escape or paraphrase HTML examples rather than including literal 'onclick=' (e.g. describe: 'attach a click handler via addEventListener')","For React examples, note the validator lowercases content, so onClick= matches too — use addEventListener-style examples or move code to a linked external file","Remove inline handlers from real templates and bind events in referenced JS files"],"exampleFix":"# before\n<button onclick=\"doThing()\">Go</button>\n# after\n<button id=\"go\">Go</button> <!-- bind via addEventListener in app.js -->","handlingStrategy":"validation","validationCode":"if (component.content.toLowerCase().includes('onclick=')) {\n  // escape/paraphrase handler examples\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Show addEventListener-style event binding in examples","Escape HTML samples in docs","Remember matching is case-insensitive: onClick= also trips it"],"tags":["xss","inline-event-handler","static-analysis"],"backgroundTag":"xss-script-tag-detected","analyzedSha":"a0851ed10c7c60463dac8cfaaca124cf32d5804d","analyzedAt":"2026-08-28T14:11:56.058Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}