T01 · Skill Instruction Hijacking
- Location
references/module-c-style.md:83- Finding
Remote Style Reports Can Hijack Agent Instructions and Persist Across Sessions
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This WeChat writing skill is mostly purpose-aligned, but it gives broad file, memory, network, and credential-bearing authority with several under-scoped security risks users should review before installing.
Install only if you trust the publisher and are comfortable with the skill making authenticated calls to the 100.city API, fetching external URLs, writing article/theme files, and updating persistent memory. Before use, avoid setting 100CITY_BASE_URL to untrusted hosts, do not pass internal/private URLs to style extraction, review MEMORY.md changes, and treat generated HTML as potentially active content until sanitized.
references/module-c-style.md:83Remote Style Reports Can Hijack Agent Instructions and Persist Across Sessions
scripts/render.py:376Unrestricted URL Fetching Enables Server-Side Request Forgery
scripts/render.py:52Unsanitized Theme Identifiers Permit Path Traversal Reads and Writes
scripts/render.py:69Markdown and Extracted Themes Can Inject Active Content into Generated HTML
\1", text)
text = re.sub(r"\*\*(.+?)\*\*", r"\1", text)
text = re.sub(r"\*(.+?)\*", r"\1", text)
return text
```
```python
return (
"\n\n\n"
'\n'
'\n'
f"{theme.get('name', 'Article')}\n"
"\n\n"
f"{body_html}\n"
"\n\n"
)
```
```python
def _templatize(node: _Node, frag_type: str) -> str:
"""Convert a node's HTML into a fragment template with placeholders."""
html = node.outer_html()
text = node.get_text().strip()
html = re.sub(
r'style="([^"]*)"',
lambda m: f'style="{_clean_style(m.group(1))}"',
html
)
if frag_type == "image":
html = re.sub(r'data-src="[^"]*"', 'src="{SRC}"', html)
html = re.sub(r'src="[^"]*"', 'src="{SRC}"', html)
html = re.sub(r"src='[^']*'", "src='{SRC}'", html)
html = re.sub(r'alt="[^"]*"', 'alt="{ALT}"', html)
return html
```
### Technical Analysis
`_escape_h
...[truncated 2709 chars]scripts/writer.py:56Connectivity Check Discloses API Key Material and Allows Credential Redirection
The script lets the HTTP destination be overridden by the 100CITY_BASE_URL environment variable or config.json, then sends the Bearer API key to that URL in the Authorization header. If an attacker can influence environment variables or the local config, they can redirect requests to an attacker-controlled server and exfiltrate the credential; in this skill context, that is more dangerous because the tool is specifically designed to make authenticated outbound API calls.
req = urllib.request.Request(url, data=data, headers=headers, method=method)
try:
with urllib.request.urlopen(req, timeout=120) as resp:
result = json.loads(resp.read().decode("utf-8"))
except urllib.error.HTTPError as e:
err_body = e.read().decode("utf-8", errors="replace")
The activation criteria are unusually broad and explicitly include ambiguous requests like '整理一下' when context merely hints at writing intent. This can cause the skill to trigger on unrelated user tasks, leading the agent to invoke external scripts, consume API-backed resources, and steer the interaction into a content-generation workflow the user did not clearly request.
Defaulting to WeChat Official Account output when the platform is unspecified imposes a single publishing context without confirming user intent. In practice this can misroute content into the wrong format, tone, and workflow, and may unnecessarily activate downstream modules tailored to a specific platform.
The file presents the skill entirely in Chinese and uses mandatory language such as '必须' and prescriptive response rules, but it does not state that Chinese is optional or limited to a China-specific use case. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern.
The skill instructs the agent to persist inferred user interest data into dated memory files without requiring explicit user consent, notice, retention limits, or sensitivity checks. This creates a privacy risk because the agent may silently build behavioral profiles from user activity and reuse them later in ways the user did not expect.
The entire instruction set is written as a Chinese-only module and gives no indication that language choice is optional or user-selectable. Under the policy, forcing a specific language without opt-in can be a natural-language policy violation unless clearly justified as region-specific.
The '记忆来源' section describes this module in terms of reading MEMORY.md and recent MEMORY/{日期}.md files to build understanding, which presents the module as consuming existing memory. However, L29 explicitly instructs the skill to update MEMORY.md during creation, introducing a write side effect that contradicts the earlier read-only operational description.
The skill instructs the agent to update persistent memory with newly learned user preferences, but it does not require notifying the user or obtaining consent before modifying stored profile data. This can lead to silent retention of sensitive preferences, inaccurate profile updates, or long-term privacy harms if the memory is later reused in other contexts.
The skill explicitly instructs reading persistent user preferences from MEMORY.md and using them across sessions, but it provides no requirement to disclose that retention to the user or obtain consent. This creates a privacy and transparency issue because user-linked preference data may be stored and later reused without the user's awareness, which can violate expected session boundaries and data-minimization principles.
This section directs the agent to persist an account name and style report URL into MEMORY.md for future reuse, again without any user-facing disclosure, consent flow, or retention limit. Even though the data is not highly sensitive by itself, it is still cross-session behavioral preference data tied to a user and can accumulate into a profile over time.
The activation conditions include broad natural-language phrases such as asking to "add pictures" or proceeding toward publication, which can cause the skill to trigger during ordinary conversation without a clear, scoped confirmation step. Because this module performs file modification and external image acquisition, unintended invocation could overwrite article content or initiate network-backed actions the user did not explicitly mean to authorize at that moment.
The workflow instructs the agent to overwrite the article file after replacing placeholders, but the skill does not prominently warn up front that execution is destructive and in-place. This increases the risk of accidental data loss, especially when combined with the broad activation logic, because users may not realize that invoking image handling will directly modify the source document rather than producing a preview or separate output.
The activation criteria include broad phrases such as '排版一下', which can easily match ordinary editing or formatting requests that do not necessarily imply consent to run the styling workflow. In this skill, misactivation is more dangerous because the workflow may later prompt for external links, invoke local scripts, and persist preferences to MEMORY.md, expanding behavior beyond a simple formatting request.
The skill instructs the agent to run extract-style against arbitrary article URLs and save derived themes locally, but it does not require notifying the user that this causes network access and local persistence of scraped style data. That creates a consent and data-handling issue: a user asking for styling may unknowingly trigger outbound requests and storage of content-derived assets.
The skill says the chosen theme ID is recorded to MEMORY.md for future use, but it does not instruct the agent to disclose that persistence to the user. Persistent preference storage is lower impact than network fetching, but still affects user expectations and can create privacy or cross-session behavior concerns if done silently.
The module docstring and CLI help/examples are written in Chinese, and later user-facing status/error messages are also Chinese-only. This imposes a specific language/locale on all users with no opt-in or alternative, which matches the language-policy violation criteria.
The module docstring and usage block describe the script as supporting topic search, trend/news, and image generation, but they do not mention the implemented style-by-name and style-by-url commands that analyze WeChat writing style. This is not just incomplete help text in one place: the top-level documentation presents the intended capabilities of the script while omitting a substantive analysis feature actually present in code.
This code file contains user-facing natural-language documentation and CLI help oriented entirely in Chinese, establishing a fixed language/locale experience. The policy for natural-language violations applies to all file types, and there is no indication that users can select another language or that the locale restriction is explicitly justified.
The argument parser description says the CLI provides article-creation support with topic search and trend capabilities, but the same parser also exposes style-by-name, style-by-url, and generate-image commands. Because this description summarizes the tool's purpose while excluding major implemented functions, it diverges from the actual behavior users can invoke.
This JSON manifest-style file includes a natural-language description of applicability ('适合科技、商务类公众号文章') but does not define any concrete activation phrase, scope boundary, or exclusion condition. In a manifest/context where descriptions may influence automatic selection, the wording is broad enough to create ambiguous matching for many business or technology-related articles.
This JSON manifest uses Chinese-only natural-language values for the style name, description, groups, and labels, which can amount to a language/locale constraint embedded in the skill asset. There is no indication that users can choose another language or that the locale restriction is explicitly documented as region-specific.
No suspicious patterns detected.