T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/wechat/api_client.py:84- Finding
Server-Side Request Forgery Through Unvalidated Image URLs
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This WeChat publishing skill is mostly purpose-aligned, but it has material safety issues around uploading local files, fetching arbitrary image URLs, and exposing WeChat tokens in logs.
Review carefully before installing. Use a dedicated low-privilege WeChat account, avoid passing secrets on the command line, do not upload untrusted Markdown or image paths, and patch token logging plus local-file and URL validation before using this with sensitive files or networks.
scripts/wechat/api_client.py:84Server-Side Request Forgery Through Unvalidated Image URLs
scripts/wechat/api_client.py:91Arbitrary Local File Read and External Upload
scripts/wechat/api_client.py:70WeChat Access Token Disclosed Through Debug Logging
scripts/cli.py:163App Secret Is Echoed During Input and Stored in Plaintext
requirements.txt:1Unbounded Dependency Versions Permit Non-Reproducible Package Resolution
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
}
try:
response = requests.get(url, params=params, timeout=10)
data = response.json()
if data.get("errcode") == 0:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
params = {"access_token": access_token}
files = {"media": (filename, io.BytesIO(image_data), "image/jpeg")}
response = requests.post(url, params=params, files=files, timeout=30)
return response.json()
def upload_permanent_image_from_url(self, image_url: str, access_token: str = None) -> dict:
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
params = {"access_token": access_token, "type": "image"}
files = {"media": ("cover.jpg", io.BytesIO(response.content), "image/jpeg")}
upload_resp = requests.post(url, params=params, files=files, timeout=30)
result = upload_resp.json()
print(f"upload_permanent_image_from_url: result = {result}")
return result
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.
# 手动序列化 JSON,确保中文不转义(关键修复)
draft_json = json.dumps({"articles": articles}, ensure_ascii=False)
headers = {"Content-Type": "application/json; charset=utf-8"}
response = requests.post(
url,
params=params,
data=draft_json.encode("utf-8"),
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# 编辑 .env 文件,填入你的微信公众号 AppID 和 AppSecret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# 编辑 .env 文件,填入你的微信公众号 AppID 和 AppSecret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# 编辑 .env 文件,填入你的微信公众号 AppID 和 AppSecret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# 编辑 .env 文件,填入你的微信公众号 AppID 和 AppSecret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# 编辑 .env 文件,填入你的微信公众号 AppID 和 AppSecret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# 编辑 .env 文件,填入你的微信公众号 AppID 和 AppSecret
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.
cp .env.example .env
# 编辑 .env 文件,填入你的微信公众号 AppID 和 AppSecret
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The skill text explicitly states that local images will be automatically uploaded and implies network interaction, but it does not fully disclose constraints around remote fetching, default external resources, or that the workflow only saves drafts rather than publishing. In a content-publishing skill, undeclared outbound transfers and mismatched user expectations can lead to unintended data disclosure and unsafe automation.
The CLI advertises support for crawling arbitrary URLs and AI-based rewriting of third-party content, but that capability is not disclosed in the skill metadata. Hidden network-fetch and content-transformation behavior increases the risk of users unknowingly sending URLs/content to external systems and can facilitate plagiarism, unreviewed data exfiltration, or unsafe downstream processing.
This file implements a local security-audit utility that enumerates sensitive files, reads configuration files, and inspects dependency metadata, which is unrelated to the stated skill purpose of publishing WeChat public-account articles. In a skill package, unrelated host-inspection logic increases the attack surface and creates an unnecessary capability to access local secrets and repository state.
Scanning for .env files causes the skill to probe for common secret containers on the host. Because this is outside the expected scope of a publishing tool, it creates unnecessary access to locations likely to contain API keys and passwords.
print("📁 检查敏感文件...")
sensitive_files = [
'.env',
'config.local.json',
'credentials.json',
'*.pem',
Referencing credentials.json as a target for filesystem inspection is part of a broader pattern of enumerating sensitive credential material on the local machine. In a skill whose purpose is content publishing, this unnecessary awareness of credential files increases the risk of secret discovery and misuse if the code is extended or abused.
sensitive_files = [
'.env',
'config.local.json',
'credentials.json',
'*.pem',
'*.key',
]
Including .env and config.json in permission checks requires the skill to inspect metadata of files that may contain secrets. In this skill context, that is unnecessary host introspection and broadens access to sensitive material beyond what is needed to publish an article.
"""检查文件权限"""
print("🔐 检查文件权限...")
config_files = ['config.json', '.env']
for filename in config_files:
file_path = self.project_root / filename
Requiring .gitignore to contain .env indicates the script is specifically concerned with locating and managing secret-bearing files in the repository. While not direct exfiltration, this is still unnecessary credential-oriented inspection for a publishing tool and contributes to excessive access to local project security posture.
with open(gitignore_path, 'r', encoding='utf-8') as f:
content = f.read()
required_patterns = ['.env', 'config.local.json', '*.log', '__pycache__']
for pattern in required_patterns:
if pattern not in content: