Back to skill

Security audit

微信创作

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its WeChat publishing purpose, but it handles account/API credentials and can send an AI bearer token to an arbitrary configured endpoint without enough guardrails or disclosure.

Review before installing. Use only trusted WeChat and AI provider credentials, avoid putting secrets directly in examples or committed .env files, do not point AI_IMAGE_BASE_URL at an untrusted or plaintext endpoint, prefer the base64 AI image path over URL downloads, and expect article content, prompts, covers, and publishing metadata to be sent to external services.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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 (3)

T09 · Insecure Skill Coding Practices

Error
Location
cover_generator.py:53
Finding

Configurable AI Endpoint Can Receive Bearer Credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
cover_generator.py:127
Finding

Unvalidated Image URL Fetch Permits Server-Side Request Forgery

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Dependency Versions Are Not Reproducibly Pinned

Content
View full analysis
=2.28.0 markdown2>=2.4.0 Pillow>=9.0.0 ``` The installation command in `README.md` line 5 is less restrictive: ```bash pip install requests markdown2 Pillow ``` ### Technical Analysis The dependency declarations specify only minimum versions and do not include upper bounds, exact pins, integrity hashes, or a lock file. Consequently, identical installations performed at different times can resolve to different package versions. The reviewed package names appear consistent with the libraries imported by the code; no typosquatting or dependency-confusion package was identified. The risk is that future compromised, incompatible, or insufficiently reviewed releases can enter the environment automatically. ### Attack Path 1. A future release of a declared dependency is compromised, malicious, or incompatible. 2. A user installs the Skill using the documented command or `requirements.txt`. 3. The package resolver selects the newer release because it satisfies the open-ended version constraint. 4. The dependency's installation or runtime code executes in the user's Python environment. 5. Any resulting impact occurs with the permissions of the user or service running the installation or Skill. ### Impact Assessment A compromised dependency could potentially access files, environment variables, network resources, and process privileges available to the Python process. There is no evidence that the currently declared packages or versions are malicious; this finding concerns avoidable supply-chain exposure and lack of reproducibility. ]]>
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (25)

Tainted flow: 'url' from os.getenv (line 113, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
96% confidence
Finding

The request target is built from a configurable base URL taken from an environment variable or function parameter, and the Authorization bearer token is sent to that endpoint. If an attacker can influence base_url or the environment, they can redirect requests and exfiltrate the API key to an attacker-controlled server, making this an SSRF-style secret leakage issue rather than a harmless configuration feature.

Content

Scanner excerpt · cover_generator.py (reported line 70)May include surrounding context.

python
"response_format": "b64_json"
    }

    response = requests.post(url, headers=headers, json=payload, timeout=120)
    response.raise_for_status()

    data = response.json()

Tainted flow: 'url' from os.getenv (line 113, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
97% confidence
Finding

This second image-generation path has the same problem: it sends the API key in an Authorization header to a URL derived from environment input or caller-supplied base_url. A malicious or misconfigured endpoint could capture credentials and request contents, so the risk is real in agent or shared execution environments.

Content

Scanner excerpt · cover_generator.py (reported line 126)May include surrounding context.

python
"response_format": "url"
    }

    response = requests.post(url, headers=headers, json=payload, timeout=120)
    response.raise_for_status()

    data = response.json()

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

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

Content

Scanner excerpt · template.env (reported line 2)May include surrounding context.

text
# 微信公众号配置模板
# 复制此文件为 .env 并填写实际值

# 微信公众号 AppID
WECHAT_APP_ID=

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The README explicitly instructs users to send prompts and an API key to an external AI image service, but it provides no warning about third-party data handling, prompt sensitivity, retention, or billing exposure. This creates a real security/privacy risk because users may unknowingly transmit proprietary content or secrets to an outside provider under the assumption the feature is self-contained.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
85% confidence
Finding

This example shows configuration of an external endpoint for AI image generation, which implies user prompts and credentials will be transmitted off-system. In context, external transmission is expected functionality rather than covert exfiltration, but it is still security-relevant because sensitive prompts or mishandled API keys could be disclosed to a third party.

Content

Scanner excerpt · README.md (reported line 72)May include surrounding context.

md
generate_cover_with_ai(
    output_path="./cover_ai.png",
    prompt="A modern tech blog cover with blue gradient and abstract shapes",
    base_url="https://api.openai.com/v1",
    api_key="your_api_key",
    model="dall-e-3"
)

External Transmission

Medium
Category
Data Exfiltration
Confidence
88% confidence
Finding

The environment variable example configures a third-party API endpoint and secret for outbound requests, confirming the skill depends on external data transmission. This is not inherently malicious, but without accompanying warnings it can lead to accidental disclosure of sensitive prompts or insecure secret management practices.

Content

Scanner excerpt · README.md (reported line 90)May include surrounding context.

bash
# AI 图片生成配置
export AI_IMAGE_BASE_URL="https://api.openai.com/v1"
export AI_IMAGE_API_KEY="your_api_key"
export AI_IMAGE_MODEL="dall-e-3"

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructs users to configure公众号凭据 and an optional AI image API, but it does not warn that article content and API credentials may be transmitted to third-party services during operation. In this context, users may unknowingly send unpublished content or sensitive tokens to external providers, creating confidentiality and supply-chain risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
89% confidence
Finding

The documented default AI_IMAGE_BASE_URL points to an external API endpoint, indicating that generated prompts and possibly article-derived input will be transmitted off-host. This is not inherently malicious, but without clear disclosure and validation controls it can expose unpublished content, metadata, or secrets to a third party and normalize use of external services in a publishing workflow.

Content

Scanner excerpt · SKILL.md (reported line 26)May include surrounding context.

md
| WECHAT_APP_ID | 公众号 AppID | - |
| WECHAT_APP_SECRET | 公众号 AppSecret | - |
| WECHAT_ACCOUNT_NAME | 作者署名 | - |
| AI_IMAGE_BASE_URL | AI 图片 API 地址 | https://api.openai.com/v1 |
| AI_IMAGE_API_KEY | AI 图片 API 密钥 | - |
| AI_IMAGE_MODEL | AI 图片模型 | dall-e-3 |

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This Python file contains only Chinese natural-language descriptions in its module docstring, presenting the skill as Chinese-only without any indication that users can choose another language or locale. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy concern.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · cover_generator.py (reported line 17)May include surrounding context.

python
# ==================== 配置区域 ====================

# AI 图片生成配置(从环境变量读取)
AI_IMAGE_BASE_URL = os.getenv("AI_IMAGE_BASE_URL", "https://api.openai.com/v1")
AI_IMAGE_API_KEY = os.getenv("AI_IMAGE_API_KEY", "")
AI_IMAGE_MODEL = os.getenv("AI_IMAGE_MODEL", "dall-e-3")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · cover_generator.py (reported line 250)May include surrounding context.

python
# ==================== 配置区域 ====================

# AI 图片生成配置(从环境变量读取)
AI_IMAGE_BASE_URL = os.getenv("AI_IMAGE_BASE_URL", "https://api.openai.com/v1")
AI_IMAGE_API_KEY = os.getenv("AI_IMAGE_API_KEY", "")
AI_IMAGE_MODEL = os.getenv("AI_IMAGE_MODEL", "dall-e-3")

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · template.env (reported line 15)May include surrounding context.

text
# ==================== 配置区域 ====================

# AI 图片生成配置(从环境变量读取)
AI_IMAGE_BASE_URL = os.getenv("AI_IMAGE_BASE_URL", "https://api.openai.com/v1")
AI_IMAGE_API_KEY = os.getenv("AI_IMAGE_API_KEY", "")
AI_IMAGE_MODEL = os.getenv("AI_IMAGE_MODEL", "dall-e-3")

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · cover_generator.py (reported line 70)May include surrounding context.

python
"response_format": "b64_json"
    }

    response = requests.post(url, headers=headers, json=payload, timeout=120)
    response.raise_for_status()

    data = response.json()

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · cover_generator.py (reported line 126)May include surrounding context.

python
"response_format": "b64_json"
    }

    response = requests.post(url, headers=headers, json=payload, timeout=120)
    response.raise_for_status()

    data = response.json()

Tainted flow: 'image_url' from requests.post (line 130, network input) → requests.get (network output)

Medium
Category
Data Flow
Confidence
91% confidence
Finding

The code downloads from image_url returned by the remote API without validating the destination host, scheme, or content type. If the upstream service, custom base URL, or response is malicious, this can be abused to trigger server-side requests to arbitrary locations and store unexpected content locally.

Content

Scanner excerpt · cover_generator.py (reported line 132)May include surrounding context.

python
data = response.json()
    image_url = data["data"][0]["url"]

    image_response = requests.get(image_url, timeout=60)
    image_response.raise_for_status()

    os.makedirs(os.path.dirname(output_path) if os.path.dirname(output_path) else ".", exist_ok=True)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Natural-language policy violations apply to all file types, including code comments, docstrings, and user-facing print strings. This file presents its description and user-facing messages only in Chinese, which effectively forces a specific language without indicating that the user can choose another locale.

Content

No source excerpt is available for this finding.

Tainted flow: 'data' from requests.get (line 131, network input) → requests.post (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · publisher.py (reported line 168)May include surrounding context.

python
'introduction': ''
                }, ensure_ascii=False)
            }
            response = requests.post(url, params=params, files=files, data=data)
        
        result = response.json()
        if 'media_id' in result:

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The README content, headings, and usage guidance are presented only in Chinese, which can amount to a language policy issue when no user opt-in or alternative language is offered. There is also no note explaining that the skill is intentionally limited to Chinese-speaking users or a region-specific audience.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

This code accesses WECHAT_APP_ID and WECHAT_APP_SECRET from environment variables, which falls under sensitive credential access for code files. Although the variables are named clearly, there is no nearby warning, comment, or runtime notice explaining that the script consumes account credentials beyond a generic configuration note.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The dependency specification for requests uses a lower-bound constraint instead of pinning to a specific version. This makes builds non-reproducible and can allow installation of a vulnerable or unexpected release if the environment resolves to an unsafe version.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
requests>=2.28.0
markdown2>=2.4.0
Pillow>=9.0.0

Unverifiable Dependency: requests has 16 known advisory(ies) (CVE-2014-1830 (Exposure of Sensitive Information to an Unauthorized Actor in Requests); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2024-35195 (Requests `Session` object does not verify requests after making first request wi) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
90% confidence
Finding

Requests has multiple known advisories, and because the manifest does not pin a version, there is no way to verify from this file whether the installed release is affected. The danger is not that requests is always vulnerable, but that the project permits ambiguous resolution to versions that may include credential leakage or other known flaws.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

The markdown2 dependency is not pinned to an exact version, so different installations may resolve to different releases. Because markdown parsers have a history of XSS and ReDoS issues, this increases supply-chain and patch-management risk.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
requests>=2.28.0
markdown2>=2.4.0
Pillow>=9.0.0

Unverifiable Dependency: markdown2 has 8 known advisory(ies) (CVE-2009-3724 (Cross-site scripting in markdown2 for python); CVE-2020-11888 (XSS in python-markdown2); CVE-2021-26813 (markdown2 Regular Expression Denial of Service ) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
91% confidence
Finding

Markdown2 has a history of security advisories, including XSS and denial-of-service issues, and the lack of version pinning prevents verification that a safe release will be installed. If this skill processes untrusted markdown, the practical risk increases because vulnerable parser behavior may be reachable.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Pillow is specified with only a minimum version, which leaves room for unsafe or inconsistent dependency resolution across environments. Since image-processing libraries often receive security fixes for memory and parsing flaws, unpinned installation can expose deployments to avoidable risk.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
requests>=2.28.0
markdown2>=2.4.0
Pillow>=9.0.0

Unverifiable Dependency: Pillow has 16 known advisory(ies) (CVE-2016-2533 (Pillow buffer overflow in ImagingPcdDecode); CVE-2023-50447 (Arbitrary Code Execution in Pillow); CVE-2021-27922 (Pillow Uncontrolled Resource Consumption) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding

Pillow has numerous historical vulnerabilities, including image parsing issues that can lead to denial of service or worse, and the unpinned requirement means the deployed version cannot be verified as safe. This is more concerning than a typical utility library because image-processing code often handles complex attacker-controlled file formats.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.