T09 · Insecure Skill Coding Practices
- Location
lib/adapter.py:156- Finding
Server-Side Request Forgery and Publication of Fetched Internal Data
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
This report-publishing skill does what it claims, but it needs review because its URL fetching, Cloudflare deployment, and remote sync paths are powerful and under-scoped.
Install only if you are comfortable reviewing and controlling every URL, source HTML file, and Cloudflare deployment action. Use a least-privilege Cloudflare token for one Pages project, avoid running sync against an untrusted or shared site, do not publish untrusted HTML or Markdown without separate sanitization, and avoid exposing broad environment secrets while deploying.
lib/adapter.py:156Server-Side Request Forgery and Publication of Fetched Internal Data
lib/html_lint.py:380Stored Cross-Site Scripting in Published Report Pages
lib/site.py:58Arbitrary File Write and Deletion Through Unvalidated Remote Index Paths
lib/remote_deploy.py:31Unpinned Wrangler Execution Receives Cloudflare Credentials and the Full Process Environment
lib/page.py:39Mutable Third-Party CDN Scripts Execute in Published Report Origins
This mismatch is more security-relevant because the skill explicitly includes arbitrary URL fetching while the declared purpose frames the tool mainly as report generation and CF deployment. Hidden or under-emphasized network retrieval can cause users to unintentionally authorize outbound requests to attacker-controlled URLs, potentially exposing metadata, internal network access patterns, or importing untrusted HTML into the publishing pipeline.
This mismatch is more security-relevant because the skill explicitly includes arbitrary URL fetching while the declared purpose frames the tool mainly as report generation and CF deployment. Hidden or under-emphasized network retrieval can cause users to unintentionally authorize outbound requests to attacker-controlled URLs, potentially exposing metadata, internal network access patterns, or importing untrusted HTML into the publishing pipeline.
This mismatch is more security-relevant because the skill explicitly includes arbitrary URL fetching while the declared purpose frames the tool mainly as report generation and CF deployment. Hidden or under-emphasized network retrieval can cause users to unintentionally authorize outbound requests to attacker-controlled URLs, potentially exposing metadata, internal network access patterns, or importing untrusted HTML into the publishing pipeline.
This mismatch is more security-relevant because the skill explicitly includes arbitrary URL fetching while the declared purpose frames the tool mainly as report generation and CF deployment. Hidden or under-emphasized network retrieval can cause users to unintentionally authorize outbound requests to attacker-controlled URLs, potentially exposing metadata, internal network access patterns, or importing untrusted HTML into the publishing pipeline.
Referenced artifact was not completely inspected
templates/index.html — 首页模板
Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.
token = CLOUDFLARE_API_TOKEN
project = REPORT_CF_PROJECT
env = {**os.environ, "CLOUDFLARE_API_TOKEN": token}
cmd = [
"npx", "wrangler", "pages", "deploy", str(deploy_dir),
"--project-name", project,
The skill describes capabilities that imply access to environment variables, local file reads/writes, network fetching, and shell-based deployment, but it does not declare any explicit tool scope or permission boundaries. In a skill that can publish to Cloudflare Pages and sync remote/local content, missing scope declarations increases the chance of over-broad execution, accidental destructive actions, or credential misuse without user awareness.
The manifest description and all user-facing instructions are presented exclusively in Chinese, indicating a language constraint without any stated option for other languages or user preference. SQP-3 applies to natural-language policy violations where a specific language is imposed without opt-in or clear justification.
The skill instructs users to configure a Cloudflare API token but gives no warning about credential sensitivity, storage, scope minimization, or risk of leakage through logs and shell commands. Because the skill can perform deployment actions, mishandling this token could allow unauthorized site modification or broader Cloudflare account compromise depending on token scope.
The workflow includes commands that write to dist, rebuild indexes, sync from the live site, update all pages, and publish to Cloudflare Pages, but the skill does not prominently warn that these operations mutate local state and a production-like remote site. In a deployment skill, lack of upfront mutation/publishing warnings can cause accidental overwrites, data loss, or unauthorized live changes when a user expects a dry-run style helper.
The module docstring and all user-facing CLI help text are written in Chinese, presenting the skill as a Chinese-language interface by default. There is no indication that users may choose another language, nor any documented justification that the skill is intended only for a Chinese-specific region or audience.
The module promises 'pure HTML' without script content, but _url_to_html preserves arbitrary remote body HTML after only limited tag stripping, and markdown/text conversion also injects unescaped title/body content into HTML. In a report-generation and publishing skill, this can lead to stored XSS or malicious active content being deployed to Cloudflare Pages and served to end users.
The _url_to_html function performs outbound network requests using curl and urlopen to fetch arbitrary URLs. Although the docstring states that it fetches web content, there is no confirmation prompt, user-facing log/print, or explicit warning that providing a URL will trigger network access and transmit request metadata to external hosts.
The code invokes an external subprocess (curl) to retrieve remote content. This is a safety-relevant operation under the rule, and the file provides no user-facing notice, confirmation, or logging around that shell/tool execution.
The skill is described as generating and deploying HTML report pages, and this module is documented as an input-adaptation layer. While fetching a URL is within scope, invoking an external program via subprocess is a broader execution capability that is not justified by the manifest's stated purpose and goes beyond ordinary content adaptation.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
# Try curl first
import subprocess
try:
result = subprocess.run(
['curl', '-sL', '--max-time', '30', url],
capture_output=True, text=True
)
The file contains natural-language documentation and console output in Chinese, including the top-level module docstring and later status/error messages, but there is no indication that the skill is intentionally region-specific or that users can opt into another language. This can violate language/locale policy when a skill forces one language by default.
The code scans both the user's home directory and a workspace-level TOOLS.md file to extract configuration, including CLOUDFLARE_API_TOKEN. While deploying to Cloudflare requires credentials, harvesting them from arbitrary documentation-style files in broader filesystem locations is not an obvious or declared part of a report publishing skill's purpose.
The check_config function prints all validation failures and setup instructions in Chinese only. Because these are user-facing operational messages and no alternative locale or explicit regional scope is provided, the skill appears to enforce a specific language without opt-in.
The template always emits <html lang="zh-CN">, which forces a specific locale for all generated pages. The file does not provide a language selection mechanism or explain that the skill is intentionally limited to a Chinese-language context.
The module docstring and function docstring are written entirely in Chinese, and the script's user-facing status/error messages are also Chinese-only. This imposes a specific language/locale on users without offering a choice or documenting a justified region-specific constraint, which matches the language policy violation criteria.
subprocess module calls execute external commands. Without careful input validation, this enables command injection.
for attempt in range(1, MAX_RETRIES + 2):
try:
result = subprocess.run(cmd, capture_output=True, text=True, env=env, timeout=120)
except subprocess.TimeoutExpired:
print(f"❌ 部署超时(120秒),尝试 {attempt}/{MAX_RETRIES+1}")
if attempt <= MAX_RETRIES:
The skill's purpose is to generate and publish HTML reports to Cloudflare Pages, and networked deployment itself is expected. However, implementing that by spawning npx wrangler introduces a general external-process execution capability, which is broader and more dangerous than the manifest's stated functional scope and not explicitly justified in the description.
This code contains natural-language strings exclusively in Chinese in the module docstring and later user-facing status/error messages, which effectively imposes a specific language on users and operators. The file does not indicate that Chinese is optional, configurable, or required for a region-specific purpose, so it conflicts with the policy against forced language/locale without opt-in.
manifest将技能定位为生成并部署报告到 Cloudflare Pages,且明确排除纯上传/下载类操作;但这里的 sync_from_cf 会从远端站点拉取 index、页面和静态资源回写到本地 dist,并合并本地索引。这不是部署流程中显而易见的必要实现细节,而是额外的远程恢复/镜像能力。
Detected: suspicious.dynamic_code_execution