Back to skill

Security audit

omnipub-content-engine

Security checks for vulnerabilities and agentic risk

Overview

This appears to be a legitimate Chinese content publishing skill, but it needs review because it handles real publishing credentials and account actions while leaking a token fragment and under-documenting some side effects.

Review this skill before installing. Use it only if you intend to manage Chinese-language WeChat/Toutiao publishing, keep config.yaml out of version control, avoid passing secrets on the command line, remove the token-printing line, inspect all generated footers/CTAs/QR links before publishing, and confirm any draft deletion or Playwright publishing step manually.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (3)

T01 · Skill Instruction Hijacking

Error
Location
references/05-footer-styles.md:3
Finding

Default Workflow Injects Branded Advertising and Traffic-Diversion Content

Content
View full analysis
str: brand = config.get("brand", {}) footer_cfg = config.get("footer", {}) order = footer_cfg.get("order", ["recommend", "about", "community", "cta", "signature"]) ``` It then emits a follow prompt: ```python elif section == "cta": sections.append( f'
' f'

' f'关注{brand.get("name","")},获取更多增长干货

' f'
' ) ``` The example configuration enables the footer by default: ```yaml footer: enabled: true template: "default" order: ["recommend", "about", "community", "cta", "signature"] ``` ### Technical Analysis The Skill defines private-traffic conversion as a standard content-lifecycle stage rather than an explicitly requested publishing option. Its instructions prescribe QR codes, community recruitment, follow prompts, recommended links, and lead-generation calls to action. The reference also contains a fixed example promoting the Skill author's identity and ...[truncated 1843 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/cli.py:294
Finding

WeChat Access Token Fragment Is Exposed in Console Output

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/footer_builder.py:29
Finding

Unescaped Footer Configuration Permits HTML and Link Injection

Content
View full analysis
' f'' f'{a["title"]}

' for a in articles ) sections.append( f'
' f'

' f'推荐阅读

{items}
' ) elif section == "about": bio = brand.get("bio", "") name = brand.get("name", "") if bio: sections.append( f'
' f'

' f'关于{name}

' f'

{bio}

' f'
' ) elif section == "community": wechat_qr = brand.get("wechat_qr", "") community_qr = brand.get("community_qr", "") qr_html = "" if wechat_qr: qr_html += f'微信二维码' if community_qr: qr_html += f'社群二维码' if qr_html: sections.append( f'
' f'
Remediation
View remediation
str: parsed = urlparse(value) if parsed.scheme != "https" or not parsed.netloc: raise ValueError("Only absolute HTTPS URLs are permitted") return escape(value, quote=True) safe_title = escape(str(a.get("title", "")), quote=True) safe_url = safe_https_url(str(a.get("url", ""))) items += f'{safe_title}' ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (77)

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/07-publishing.md (reported line 32)May include surrounding context.

md
2. **若存储一致但视觉不同**:不是通道问题,是微信渲染器白名单限制。把本地 HTML 用 v9 白名单清洗后,本地浏览器预览就会等于微信端效果。
     3. **若存储不一致**:检查 `Content-Type: application/json; charset=utf-8` 请求头是否缺失(会导致乱码/属性丢失)。
   - ⚠️ 若终稿已按网页标准写完(flex/grid/class/渐变/阴影),用 `scripts/wechat_compat.py` 转 table 版只能救急,且**仍有 border-radius/shadow/gradient 被忽略**,视觉上不可能 1:1。
   - 推送脚本 `wechat_publish_design.py`:draft/add 接口直接建草稿(content=清洗后的 HTML、thumb_media_id=封面、author、digest),创建成功后 draft/delete 删旧草稿;凭证存于 `C:/Users/miko/AppData/Roaming/wenyan-md/credential.json`
   - ⚠️⚠️ **编码坑(2026-08-14 实测踩过)**:
     - `draft/add` 请求**必须显式带 `headers={"Content-Type": "application/json; charset=utf-8"}`**。`requests` 的 `data` 传 bytes 时不会自动设置 Content-Type,微信服务器按错误编码解析 → 整篇(标题+正文)存储为乱码,后台显示 `ä½ çæ£è...`。
     - `draft/get` 响应 `Content-Type: text/plain` 无 charset,`requests.json()` 会按 ISO-8859-1 解码 → **即使存储正常也会显示假乱码**。验证时必须用 `resp.content.decode('utf-8')` 再 `json.loads`,不要用 `resp.json()` 判断中文。

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

This code path handles highly sensitive WeChat credentials and access tokens for publishing operations, which raises real security risk in a CLI context. The surrounding function also accepts secrets via command-line flags and later exposes part of the token in console output, increasing the chance of credential leakage through shell history, logs, screenshots, or shared terminals.

Content

Scanner excerpt · scripts/cli.py (reported line 276)May include surrounding context.

python
print("Error: WeChat appid and secret required. Use --appid and --secret or set in config.yaml")
        return

    # Get access token (with retry if --retry is set)
    print("Getting access token...")
    token = None
    if args.retry:

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

The retry path continues to process appid and secret for token retrieval, so the same credential-handling exposure applies here. In a publishing skill, these credentials can authorize actions against a WeChat account, so accidental disclosure could let an attacker create, modify, or delete drafts and abuse the associated account.

Content

Scanner excerpt · scripts/cli.py (reported line 277)May include surrounding context.

python
return

    # Get access token (with retry if --retry is set)
    print("Getting access token...")
    token = None
    if args.retry:
        loop_result = push_loop(appid, secret, get_token_fn=get_access_token)

Credential Access

High
Category
Privilege Escalation
Confidence
98% confidence
Finding

Printing the first 20 characters of an access token leaks part of a live bearer credential to stdout. Even partial token disclosure is unnecessary and may aid correlation, debugging-log harvesting, or exposure in CI logs and terminal recordings; in some environments stdout is centrally collected and retained.

Content

Scanner excerpt · scripts/cli.py (reported line 295)May include surrounding context.

python
token = get_access_token(appid, secret)

    if not token:
        print("Error: Failed to get access token. Check appid/secret.")
        return
    print(f"  Token: {token[:20]}...")

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/infographic.py (reported line 82)May include surrounding context.

python
Image dimensions: 900x506px (16:9 aspect ratio).
"""

    return prompt


def generate_all_engines(title: str, subtitle: str, data_points: str,

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/theme.py (reported line 106)May include surrounding context.

python
rules[selector].update(props)
            else:
                rules[selector] = dict(props)
    return rules

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README instructs users to place platform credentials in a local configuration file and publish content to external services, but it does not warn that secrets must be protected or that article data and metadata will be transmitted to third-party platforms. This creates a realistic risk of accidental credential exposure, unsafe storage/commit of config files, and uninformed data transfer in a workflow explicitly designed for cross-platform publishing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill handles sensitive operations including publication to external platforms, browser automation, and use of stored platform credentials, yet the document lacks a prominent consolidated risk notice. Without a clear warning section, users may not fully understand that invoking the skill can cause external side effects, account actions, or content publication under their identity.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The trigger list includes broad phrases such as '内容发布', '公众号发布', and '内容同步' for a skill that can publish content and use configured platform credentials. Overly generic activation terms increase the chance of accidental or context-inappropriate invocation, which is more dangerous here because the skill performs high-impact actions like drafting or automating publication workflows.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The manifest sets the skill language to "zh-CN", which is a natural-language locale constraint. In this file there is no indication that users can choose another language or explicitly opt in to this locale, so it may violate the language/locale policy requirement.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The template and inline instructions are entirely in Chinese and include WeChat-specific constraints such as the author name length limit, indicating the skill is designed around a single language/locale. There is no natural-language indication that users may choose another language or that the Chinese locale restriction is optional or explicitly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The manifest sets language: zh-CN, which is a natural-language locale constraint. In this file there is no indication that users can choose another language or explicitly opt into this locale, so it appears to enforce a specific language by default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file presents all operational instructions in Chinese and does not indicate that language selection is optional or configurable. This can violate a language/locale policy when a skill implicitly forces 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
93% confidence
Finding

The title and stated goal prescribe a Chinese-language content generation methodology for platform-specific outputs, and nowhere in the file is there an option for the user to choose another language or locale. Under the policy, forcing a specific language without user opt-in 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
95% confidence
Finding

The section '中文 AI 生态注意点' gives guidance specifically for Chinese AI platforms and Chinese publishing channels without indicating that this is optional, user-selectable, or limited to a clearly documented region-specific use case. This can violate language/locale policy by implicitly constraining the skill to a Chinese-language ecosystem without explicit opt-in or justification.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The generated HTML explicitly sets lang="zh-CN" and all user-facing report text is hard-coded in Chinese. This imposes a specific language/locale on users without any opt-in or documented region-specific justification, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 61)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 71)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 88)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 97)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 107)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 116)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 417)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/cli.py (reported line 429)May include surrounding context.

python
cmd += ["--output", args.output]
    if args.verbose:
        cmd += ["--verbose"]
    subprocess.run(cmd)


def cmd_fact_check(args):

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The infographic command hard-codes Chinese locale expectations in user-facing arguments and defaults, including 'Main title (Chinese)', a Chinese default source string, and a Chinese default brand name. This imposes a specific language/locale behavior without offering an explicit user choice or documenting a justified region-specific constraint.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.