T09 · Insecure Skill Coding Practices
- Location
SKILL.md:68- Finding
Potential Stored Cross-Site Scripting Through Unescaped Diary Content
- Content
View full analysis
Vulnerability Details
File Location:
SKILL.md, lines 68–71
Vulnerability Type: Unsafe HTML construction using unescaped user input
Risk Level: MediumComplete Code Snippet:
markdown - 新内容用 `<p>` 标签包裹:`<p>用户说的文字</p>` - 若今天已有内容,直接在末尾拼接:`{existing_content}<p>新内容</p>` - 若今天没有内容,直接发:`<p>新内容</p>` - 内容原文存入,不做 AI 改写,保持用户的原始表达Technical Analysis
The Skill instructs the agent to place user-controlled diary text directly inside an HTML paragraph and concatenate it with existing HTML. It does not require HTML escaping, validation, or allowlist-based sanitization.
A malicious diary entry could close the paragraph and introduce active markup, for example:
html </p><img src=x onerror="/* attacker-controlled script */"><p>The resulting content is submitted to the TimeFriend daily-review API. If the service stores this value and later renders it as HTML without effective server-side or client-side sanitization, the payload could execute in the TimeFriend web origin. The repository does not contain the remote service implementation, so successful script execution depends on how that service sanitizes and renders the submitted HTML.
Attack Path
- An attacker persuades a user or agent to save crafted markup as diary content.
- The Skill follows its documented rule and inserts the text verbatim into a
<p>element. - The agent sends the constructed HTML to
PUT /api/daily-reviews/{date}. - The TimeFriend service stores the submitted diary content.
- A user opens a page that displays the daily review.
- If the application renders the stored value as HTML without adequate sanitization, the injected markup or script executes in the viewer's authenticated browser context.
Impact Assessment
This creates a potential stored cross-site scripting condition. Depending on the remote application's browser security controls and authentication design, exploitation could permit in ...[truncated 461 chars]
- Remediation
View remediation
Remediation Suggestions
- Treat diary text as plain text rather than trusted HTML.
- HTML-escape at least
&,<,>,", and'before placing user input inside<p>elements. - Prefer sending structured or plain-text content and let the server perform safe presentation-layer rendering.
- Apply server-side allowlist sanitization even if the client or agent already escapes input.
- Render untrusted content with safe text APIs rather than raw HTML insertion.
- If limited formatting is required, use a well-maintained HTML sanitizer and allow only necessary tags and attributes. Reject scripts, event-handler attributes, dangerous URL schemes, embedded objects, and unsafe CSS.
- Add tests covering script tags, event attributes, malformed nested tags, encoded payloads, SVG payloads, and dangerous links.
- Deploy a restrictive Content Security Policy as defense in depth, without treating it as a replacement for output encoding and sanitization.
