Back to skill

Security audit

WeChat Studio

Security checks for vulnerabilities and agentic risk

Overview

This skill has a coherent WeChat publishing-workbench purpose, but its local server exposes serious file, preview-rendering, and network-request risks that require review before installation.

Install only after reviewing or patching the local server. At minimum, add API authentication, enforce filesystem containment, sandbox and sanitize previews, restrict reference URLs to trusted public HTTPS hosts, avoid storing complete presigned URLs, and treat SK/WeChat credentials as secrets. Use it only with article content and reference URLs you trust.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (4)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
frontend/server.py:194
Finding

Workspace Path Traversal Enables Arbitrary Local File Disclosure

Content
View full analysis
str: path = Path(value).expanduser() if path.is_absolute(): try: return str(path.resolve().relative_to(ROOT)) except ValueError as error: raise FileNotFoundError("Only paths inside the workspace are allowed.") from error return str(path) def resolve_workspace_path(value: str) -> Path: relative = ensure_relative_path(value) path = (ROOT / relative).resolve() if not path.exists(): raise FileNotFoundError(f"Path not found: {relative}") return path ``` The resolver is exposed through the asset API: ```python if path == "/api/assets": self.serve_asset(str(query.get("path", [""])[0])) return ``` The resolved path is subsequently returned without another containment check: ```python def serve_asset(self, relative_path: str) -> None: clean_path = str(relative_path or "").strip() if not clean_path: self.send_error_json("Missing asset path.", status=HTTPStatus.BAD_REQUEST) return try: asset_path = resolve_workspace_path(clean_path) except FileNotFoundError as error: self.send_error_json(str(error), status=HTTPStatus.NOT_FOUND) return if not asset_path.is_file(): self.send_error_json("Asset path is not a file.", status=HTTPStatus.BAD_REQUEST) return content_type, _encoding = mimetypes.guess_type(str(asset_path)) body = asset_path.read_bytes() self.send_response(HTTPStatus.OK) self.send_header("Content-Type", content_type or "application/octet-stream") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) ``` ...[truncated 1649 chars]
Remediation
View remediation
Path: root = ROOT.resolve() candidate = (root / value).resolve(strict=True) try: candidate.relative_to(root) except ValueError as error: raise FileNotFoundError("Path escapes the workspace.") from error return candidate ``` 2. Reject absolute paths and paths containing traversal components before resolution. 3. Restrict `/api/assets` to explicit asset directories instead of the entire workspace. 4. Account for symlink escapes by checking the fully resolved path. 5. Require an unpredictable session token or equivalent authorization for all local API endpoints. 6. Add tests for raw, percent-encoded, double-encoded, mixed-separator, and symlink traversal attempts. 7. Return generic errors that do not reveal resolved filesystem paths. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
frontend/extract_live_reference.js:44
Finding

Unrestricted Reference URL Processing Enables Server-Side Request Forgery

Content
View full analysis
tuple[Any, dict[str, Any]]: script = FRONTEND_DIR / "extract_live_reference.js" if not script.exists(): raise FileNotFoundError(f"Live extractor not found: {script}") result = subprocess.run( ["node", str(script), reference_url, str(REFERENCE_SHOTS_DIR)], check=True, capture_output=True, text=True, cwd=str(FRONTEND_DIR), ) payload = json.loads(result.stdout) ``` The URL is accepted whenever a reference is supplied: ```python clean_reference = reference_url.strip() if clean_reference: theme_name_for_file = f"{article_dir.name}-reference" try: theme_obj, extraction_meta = extract_live_reference_theme(clean_reference, theme_name_for_file, theme) except Exception: theme_obj, extraction_meta = extract_reference_theme( clean_reference, theme_name=theme_name_for_file, base_theme=theme, ) ``` The headless browser navigates to it and records a screenshot: ```javascript const [, , url, outputDirArg] = process.argv; if (!url) { throw new Error("Usage: extract_live_reference.js [output-dir]"); } const outputDir = path.resolve( outputDirArg || path.join(process.cwd(), "..", "AI", "reference-shots") ); fs.mkdirSync(outputDir, { recursive: true }); const screenshotPath = path.join(outputDir, `${slugify(url)}.png`); const browser = await chromium.launch({ headless: true }); const page = await browser.newPage({ viewport: { width ...[truncated 2327 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
frontend/app.js:477
Finding

Unsafe Dynamic HTML Rendering Creates Stored DOM XSS Exposure

Content
View full analysis
{ const card = document.createElement("article"); card.className = "history-card"; const isCurrent = item.localPath === candidatePath; card.innerHTML = `
${item.styleLabel || `封面候选 ${index + 1}`} ${item.createdAt || "未知时间"}
${isCurrent ? "当前封面" : (item.preset || "cover")}
${ assetUrl(item) ? `${item.styleLabel || ` : "" } ${renderPathDisclosure(item.localPath)}
${isCurrent ? "当前已使用" : "设为当前封面"} 删除
`; refs.coverHistoryGallery.appendChild(card); }); ``` Editor HTML is assigned directly: ```javascript blocks.forEach((block) => { if (block.kind === "image-slot") { body.appendChild(renderEditorImageSlotBlock(detail, block)); return; } if (block.kind === "list") { body.appendChild(renderEditorListBlock(block)); return; } const tagName = block.kind === "heading" ? `h${Math.min(Math.max(Numb ...[truncated 2835 chars]
Remediation
View remediation
``` 6. Do not add `allow-scripts` or `allow-same-origin` unless strictly necessary. Never combine both for untrusted content. 7. Apply a restrictive Content Security Policy to the main application and preview document. 8. Treat dynamically imported formatter output as untrusted input. 9. Add regression tests covering script tags, SVG handlers, malformed attributes, `javascript:` URLs, iframe payloads, and event-handler attributes. 10. Add API authentication and CSRF protections so frontend XSS cannot freely invoke sensitive publishing and deletion actions. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
content/articles/2026-03-28-ai-art-advantage/studio-state.json:39
Finding

Persisted Presigned URLs Expose Temporary Security Tokens and Publishing Metadata

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Memory PoisoningPersistent Context Injection, Context Window Stuffing, Memory Manipulation
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (84)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

If the skill actually performs content modification, local deletion/persistence, external API image generation, subprocess execution, remote theme extraction, and WeChat publishing operations while being described only as a manual preview workbench, that concealment materially increases security risk. Users and agents may authorize the skill under false assumptions, leading to unintended code execution, data loss, credential use, or exfiltration through publishing and remote integrations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

If the skill actually performs content modification, local deletion/persistence, external API image generation, subprocess execution, remote theme extraction, and WeChat publishing operations while being described only as a manual preview workbench, that concealment materially increases security risk. Users and agents may authorize the skill under false assumptions, leading to unintended code execution, data loss, credential use, or exfiltration through publishing and remote integrations.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

If the skill actually performs content modification, local deletion/persistence, external API image generation, subprocess execution, remote theme extraction, and WeChat publishing operations while being described only as a manual preview workbench, that concealment materially increases security risk. Users and agents may authorize the skill under false assumptions, leading to unintended code execution, data loss, credential use, or exfiltration through publishing and remote integrations.

Content

No source excerpt is available for this finding.

Memory Manipulation

High
Category
Memory Poisoning
Confidence
80% confidence
Finding

Skill manipulates agent memory, state, or stored context. Memory corruption can alter personality, override safety rules, or cause unpredictable behavior.

Content

Scanner excerpt · frontend/app.js (reported line 1008)May include surrounding context.

js
async function saveEditorBlock(blockId, text) {
  if (!state.selectedId || !blockId) return;
  delete state.editorSaveTimers[blockId];
  const result = await requestJson(`/api/articles/${encodeURIComponent(state.selectedId)}/editor/text`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },

Missing User Warnings

High
Category
Not specified by scanner
Confidence
95% confidence
Finding

The interface offers a one-click 'push to draft box' action without an explicit warning that article content, images, and metadata may be transmitted to an external WeChat service. In a publishing workbench, this can cause unintended disclosure of unpublished or sensitive content because users may treat the action as a local save rather than outbound transmission.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · tmp_wechat_edit.html (reported line 1)May include surrounding context.

html
<link href="https://res.wx.qq.com/mpres/zh_CN/htmledition/js/layout/error.97102178.css" rel="stylesheet"><!DOCTYPE html><html><head>  <link href="https://res.wx.qq.com/mpres/zh_CN/htmledition/js/default~layout/base/base_css_4web2~layout/base/meta~layout/base/meta_bak~layout/base_badjs.97101585.css" rel="stylesheet"><link href="https://res.wx.qq.com/mpres/zh_CN/htmledition/js/default~layout/base/meta~layout/base_badjs.97101587.css" rel="stylesheet"><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta name="renderer" content="webkit"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0"><!-- <meta name="referrer" content="origin-when-crossorigin"> --><meta charset="utf-8"><script type="text/javascript">
//上报测速 --初始点
window._points = [+new Date()];

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · tmp_wechat_edit.html (reported line 82)May include surrounding context.

html
</script><script src="https://res.wx.qq.com/mpres/zh_CN/htmledition/js/default~layout/base/base_css_4web2~layout/base/meta~layout/base/meta_bak~layout/base_badjs_fe.c2df1d11.js" onerror="wx_loaderror(this)" crossorigin="anonymous"></script><script src="https://res.wx.qq.com/mpres/zh_CN/htmledition/js/default~layout/base/meta~layout/base_badjs_fe.73866e04.js" onerror="wx_loaderror(this)" crossorigin="anonymous"></script><script src="https://res.wx.qq.com/mpres/zh_CN/htmledition/js/layout/base/meta_fe.e25e4fa4.js" onerror="wx_loaderror(this)" crossorigin="anonymous"></script>  <!-- <link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/mpres/zh_CN/htmledition/comm_htmledition/style/page/page_error.css" /> -->  </head><body class="zh_CN weui-desktop-page_simple page_error page_timeout">  <div class="mp-head" id="header">    <link href="https://res.wx.qq.com/mpres/zh_CN/htmledition/js/layout/base/head-box.97102168.css" rel="stylesheet"><script type="text/javascript">
    //上报测速 --css加载完成点
    window._points&&(window._points[1]=+new Date());
</script><div class="weui-desktop-head" id="mp_header">    <div class="weui-desktop-head__inner">      <div class="weui-desktop-layout">        <a id="m_open" href="javascript:;" class="weui-desktop-btn__head-opr weui-desktop__unfold-menu-opr">展开</a>        <div class="weui-desktop-layout__side">          <h1 class="weui-desktop-logo">                        <a href="/" title="公众号" class="weui-desktop-logo__inner"></a>                      </h1>        </div>        <div class="weui-desktop-layout__extra">          <!-- 企业号不显示顶部的所有的链接 -->                      <!-- inside -->                        <div class="weui-desktop-account">              <!-- 如果是小程序就不出现了 -->                                                                          </div>                      <!-- 给企业号加退出按钮 -->                  </div>      </div>    </div></div><script type="text/javascript">
(function() {
  // 初始化消息未读
  var eleHeadBoxAccountNum = do
...[truncated 24 chars]

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

This section implements account/session timeout messaging and constructs a login redirect URL to WeChat endpoints, which is outside the stated role of a local article editing and preview tool. In skill context, embedding authentication flow behavior increases the chance of credential phishing, session handling confusion, or unintended navigation to live platform endpoints from what should be a local QA surface.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · tmp_wechat_edit.html (reported line 162)May include surrounding context.

html
}else if(ret=="430002"){//视频原创申诉过期
                document.getElementById('info').innerHTML="申诉已过期";
        }
        </script>                  </div>                </div>              </div>            </div>          </div>        </div>      </div>    </div>  </div>  </div>  </div>  </div>  <div class="mp-foot" id="footer">  <div class="weui-desktop-foot">    <div class="weui-desktop-foot__info">      <div class="weui-desktop-links weui-desktop-link-group weui-desktop-link-group_split">                <a class="weui-desktop-link" href="http://www.tencent.com/zh-cn/index.shtml" target="_blank">关于腾讯</a>        <a class="weui-desktop-link" href="/cgi-bin/readtemplate?t=home/agreement_tmpl&type=info&lang=zh_CN&token=" target="_blank">服务协议</a>        <a class="weui-desktop-link" href="/webpoc/ruleCenter?type=oa " target="_blank">规则中心</a>         <!--<a class="weui-desktop-link" href="/cgi-bin/opshowpage?action=dispelinfo&lang=zh_CN&begin=1&count=9" target="_blank">辟谣中心</a>-->        <a class="weui-desktop-link" href="http://kf.qq.com/product/weixinmp.html" target="_blank">腾讯客服</a>                        <!-- <a class="weui-desktop-link" href="mailto:weixinmp@qq.com" target="_blank">联系邮箱</a> -->                <a class="weui-desktop-link" href="/acct/infringementlogin?action=getkey_brand&lang=zh_CN" target="_blank">侵权投诉</a>                      </div>    </div>    <div class="weui-desktop-foot__extra">      <!--#00002#-->      <p class="weui-desktop-link">Copyright &copy; 2012-2026 Tencent. All Rights Reserved.</p>      <!--%00002%-->    </div>  </div></div><script type="text/javascript">
//上报测速 --dom加载完成点
window._points&&(window._points[2]=+new Date());
</script>    <!-- mp 不再支持 ie浏览器 -->  <script type="text/javascript">

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · tmp_wechat_edit.html (reported line 162)May include surrounding context.

html
}else if(ret=="430002"){//视频原创申诉过期
                document.getElementById('info').innerHTML="申诉已过期";
        }
        </script>                  </div>                </div>              </div>            </div>          </div>        </div>      </div>    </div>  </div>  </div>  </div>  </div>  <div class="mp-foot" id="footer">  <div class="weui-desktop-foot">    <div class="weui-desktop-foot__info">      <div class="weui-desktop-links weui-desktop-link-group weui-desktop-link-group_split">                <a class="weui-desktop-link" href="http://www.tencent.com/zh-cn/index.shtml" target="_blank">关于腾讯</a>        <a class="weui-desktop-link" href="/cgi-bin/readtemplate?t=home/agreement_tmpl&type=info&lang=zh_CN&token=" target="_blank">服务协议</a>        <a class="weui-desktop-link" href="/webpoc/ruleCenter?type=oa " target="_blank">规则中心</a>         <!--<a class="weui-desktop-link" href="/cgi-bin/opshowpage?action=dispelinfo&lang=zh_CN&begin=1&count=9" target="_blank">辟谣中心</a>-->        <a class="weui-desktop-link" href="http://kf.qq.com/product/weixinmp.html" target="_blank">腾讯客服</a>                        <!-- <a class="weui-desktop-link" href="mailto:weixinmp@qq.com" target="_blank">联系邮箱</a> -->                <a class="weui-desktop-link" href="/acct/infringementlogin?action=getkey_brand&lang=zh_CN" target="_blank">侵权投诉</a>                      </div>    </div>    <div class="weui-desktop-foot__extra">      <!--#00002#-->      <p class="weui-desktop-link">Copyright &copy; 2012-2026 Tencent. All Rights Reserved.</p>      <!--%00002%-->    </div>  </div></div><script type="text/javascript">
//上报测速 --dom加载完成点
window._points&&(window._points[2]=+new Date());
</script>    <!-- mp 不再支持 ie浏览器 -->  <script type="text/javascript">

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The document declares lang="en" while the title and body content are clearly written in Chinese. This imposes an incorrect language/locale setting without user choice or justification, which can violate language/locale policy expectations and affect accessibility or downstream processing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

This file declares lang="zh-CN" and all visible content is written in Chinese, which imposes a specific language/locale on users. Under the stated policy, locale-specific behavior should either offer user choice or be clearly justified as region-specific; neither is present here.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding

The skill documentation instructs users to install dependencies, run a Python server, and interact with local content and remote services, but it does not declare any explicit tool scope or permission boundaries. In an agent-skill ecosystem, missing scope makes filesystem, shell, environment, and network access implicit and harder to audit, increasing the chance of overbroad execution or unintended data access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The documentation tells users to obtain an SK token and place it into a token field without any warning about secret handling, storage, reuse, phishing risk, or least-privilege practices. In a skill that already involves local servers and possible remote integrations, this raises the likelihood of credential leakage through logs, screenshots, browser autofill, copied configs, or accidental check-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The title and summary are entirely in Chinese, which indicates a language-specific output or content policy. In this manifest file there is no indication that the user can choose a language or that the locale restriction is intentionally limited to a Chinese-speaking audience.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file presents all user-facing content in a single language and does not indicate that Chinese is optional, selectable, or required for a documented regional purpose. Under the language/locale policy rule, forcing one language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The title and summary are entirely in Chinese, and the summary describes producing a publishable long-form article for a WeChat public account audience. There is no indication that the language/locale is optional, user-selectable, or justified as a region-specific skill, which may violate the policy against forcing a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The warning string at L07 is written entirely in Chinese and provides operational instructions to the user, but this JSON file does not indicate any user language selection, opt-in, or region-specific justification. Under the policy, forcing a specific language in user-facing content without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown file contains only Chinese-language content and metadata, including the title and all substantive sections, with no indication that users may choose another language. Under the policy rule, forcing a specific language without user opt-in can be a natural-language policy violation unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The title explicitly specifies '中文语境' (Chinese-language context), which imposes a locale/language constraint in natural language. The file does not indicate that this is optional, user-selected, or justified as a region-specific requirement, so it appears to violate the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file contains user-facing natural language exclusively in Chinese, including the title, research question, conclusions, and references context. Under the policy rule, forcing a specific language without user opt-in can be a locale-policy violation when no choice or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The filename string explicitly embeds "中文语境" (Chinese-language context), indicating the skill state is scoped to a specific language context. In this JSON there is no accompanying language-selection field, opt-in mechanism, or justification that this locale restriction is required for a region-specific tool.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The title and summary are written entirely in Chinese, indicating the skill/content is presented in a fixed language. There is no accompanying note that this is a China-focused or Chinese-only artifact, and no indication that users can opt into another language, which can violate the language/locale choice policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The warning string at L07 is presented entirely in Chinese, and the file also includes Chinese text in other user-facing fields. For a general studio-state JSON, this appears to force a specific language/locale without any visible opt-in or justification, which matches the policy-violation category for language or locale constraints.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code assigns backend-supplied HTML directly to iframe.srcdoc, which causes that HTML to execute in the page context of the iframe. If the preview HTML contains script, event handlers, malicious forms, or active content derived from imported Markdown or compromised backend output, this becomes a client-side XSS/trusted-preview issue that can run arbitrary code and potentially interact with the parent depending on sandboxing and origin behavior. In this publishing workbench context, users are expected to preview untrusted article content, which makes direct rendering substantially more dangerous.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.