T09 · Insecure Skill Coding Practices
- Location
scripts/reply_comment.js:220- Finding
Untrusted Reply Text Is Inserted into an Authenticated Page as HTML
- Content
View full analysis
{ // eslint-disable-next-line no-new-func const resolve = new Function(src + '; return resolveCard(' + JSON.stringify(id) + ');'); const card = resolve(); if (!card) return { ok: false, reason: 'card-gone' }; const ce = Array.from(card.querySelectorAll('[contenteditable="true"]')) .find(el => /^回复\s/.test((el.getAttribute('placeholder') || el.getAttribute('aria-placeholder') || ''))); if (!ce) return { ok: false, reason: 'no-input' }; ce.focus(); // ★ 用 innerHTML 而不是 innerText,保留 emoji / 多行结构 ce.innerHTML = text; // ★ 派发 InputEvent 触发 React 状态更新(已实测:disabled 翻转为 false) ce.dispatchEvent(new InputEvent('input', { bubbles: true, inputType: 'insertText', data: text, })); return { ok: true, len: ce.innerText.length }; }, { id: target.id, src: resolveSrc, text } ); ``` ### Technical Analysis The reply value is assigned to `innerHTML`, causing the browser to parse it as markup rather than treating it as plain reply text. No HTML sanitization or character allowlist is applied beforehand. The value can originate from CLI input or from LLM-generated output. Under the documented automatic-reply workflow, the LLM reads untrusted public comments and generates text that is sent without an approval stage. A malicious comment could therefore attempt to influence the generated reply into containing HTML. Elements with executable event attributes or network-loading behavior may become active when parsed inside the authenticated Douyin Creator Center page. The nearby `new Function` use was also reviewed. Its source is locally generated by `makeResolveCardJS()`, while the identifier is JSON-escaped, so it does not provide the primary attacker-cont ...[truncated 1691 chars]- Remediation
View remediation
`, and HTML entities as literal text rather than markup. 4. Add tests with payloads such as HTML tags, quoted attributes, multiline content, emoji, and angle brackets. Verify that the editor displays the exact literal text and creates no additional DOM elements. 5. Add an optional review or dry-run stage for LLM-generated replies. This reduces the likelihood that malicious comment content can influence an automatically posted response. ]]>
