Back to skill

Security audit

摸鱼日报和百度热搜等图片生成,持续升级中

Security checks for vulnerabilities and agentic risk

Overview

This is a poster-generation skill, but its JSON inputs can trigger overly broad local file reads and outbound network fetches that may expose data through generated outputs.

Review carefully before installing, especially if it may process JSON specs from other people. Run it with restricted filesystem and network access, avoid untrusted image_path, data_path, or api_url values, and prefer pinned dependencies plus URL and path allowlists before production use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/render_daily_poster.py:189
Finding

Unrestricted Local File Access and Server-Side Request Forgery Through Poster Specifications

Content
View full analysis
Path | None: if not path_value: return None raw = Path(os.path.expandvars(path_value)).expanduser() candidate = raw if raw.is_absolute() else base_dir / raw return candidate.resolve() if candidate.exists() else None @lru_cache(maxsize=32) def fetch_binary_payload(url: str, *, timeout: float = 8.0) -> tuple[str, bytes] | None: request = Request(url, headers={"User-Agent": "daily-poster/1.0"}) try: with urlopen(request, timeout=timeout) as response: payload = response.read() mime = response.headers.get_content_type() if not mime or mime == "application/octet-stream": guessed, _ = mimetypes.guess_type(urlparse(url).path) mime = guessed or "image/png" return mime, payload except (HTTPError, URLError, TimeoutError, OSError, ValueError): return None def load_image_asset(path_value: str | None, *, base_dir: Path) -> tuple[str, bytes] | None: source = str(path_value or "").strip() if not source: return None if source.startswith(("http://", "https://")): return fetch_binary_payload(source) path = resolve_image(source, base_dir) if path is None: return None mime, _ = mimetypes.guess_type(str(path)) return (mime or "image/png", path.read_bytes()) ``` The loaded bytes are subsequently embedded directly into the SVG: ```python mime, payload = asset data = base64.b64encode(payload).decode("ascii") fit = "xMidYMid slice" if mode == "cover" else "xMidYMid meet" self.add(f'
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/render_daily_poster.py:578
Finding

API-Controlled Secondary Image Requests Enable Indirect SSRF and Resource Exhaustion

Content
View full analysis
Path | None: asset = fetch_binary_payload(url) if asset is None: return None mime, payload = asset suffix = mimetypes.guess_extension(mime or "") or Path(urlparse(url).path).suffix or ".img" if suffix == ".jpe": suffix = ".jpg" CACHE_DIR.mkdir(parents=True, exist_ok=True) cache_path = CACHE_DIR / f"{cache_key}{suffix}" cache_path.write_bytes(payload) return cache_path ``` ```python api_url = str(note.get("api_url", "https://v2.xxapi.cn/api/heisi")).strip() payload = fetch_json_payload(api_url) if api_url else {} if not isinstance(payload, dict): if cached_image is not None: note["image_path"] = str(cached_image) return note image_url = str(payload.get("data", "")).strip() if image_url: cached_path = cache_remote_image(image_url, cache_key=cache_key) note["image_path"] = str(cached_path) if cached_path is not None else image_url ``` The Baidu renderer performs the same operation for every item returned by its API: ```python def _download_image_base64(url: str, *, timeout: float = 6.0) -> str | None: """Download an image URL and return as data URI, or None on failure.""" if not url: return None try: req = Request(url, headers={"User-Agent": "daily-poster/1.0"}) with urlopen(req, timeout=timeout) as resp: data = resp.read() b64 = base64.b64encode(data).decode("ascii") content_type = resp.headers.get("Content-Type", "image/jpeg").split(";")[0].strip() return f"data: ...[truncated 2804 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Open-Ended Dependency Version Ranges Permit Unreviewed Future Releases

Content
View full analysis
=0.2.6 Pillow>=10.0.0 ``` ### Technical Analysis Both dependencies use open-ended lower-bound constraints. A future installation can therefore resolve to any later release available from the configured package index, including a release that did not exist when the Skill was reviewed. This configuration does not establish that either named package is currently malicious. The risk is that installation behavior is not reproducible and that future compromised, malicious, or incompatible releases may be selected automatically. Both packages process complex image formats, and `resvg_py` is imported into the renderer process, so a compromised dependency would execute with the same privileges as the Skill. No lock file or package hashes were identified in the audited project structure to authenticate expected distribution artifacts. ### Attack Path 1. A user or deployment system installs dependencies from `requirements.txt` at a later date. 2. The package resolver selects newer versions satisfying the open-ended `>=` constraints. 3. A selected release is compromised, malicious, or contains a newly introduced exploitable defect. 4. Package installation, module import, or image processing activates the affected code. 5. The dependency executes or processes data with the filesystem and network privileges of the poster-rendering environment. ### Impact Assessment A compromised dependency could potentially obtain all privileges held by the Python process, including: - Reading and modifying files accessible to the Skill. - Altering generated poster output. - Accessing available network resources. - Executing code during installation or import. - Compromising every render performed by the affected environment. The exact impact depends on th ...[truncated 174 chars]
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (22)

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · scripts/render_baidu_hot.py (reported line 32)May include surrounding context.

python
星期日")
POSTER_TYPE = "baidu_hot"
DEFAULT_OUTPUT_SCALE = 2.0

BAIDU_API_URL = "https://v2.xxapi.cn/api/baiduhot"
DEFAULT_HEADER_TITLE = "百度热搜榜"
DEFAULT_HEADER_SUBTITLE = "实时热点  一手掌握"
DEFAULT_CONTENT_LIMIT = 10

# Embedded to avoid runtime PNG file dependencies in deployment targets such as Clawhub.
BAIDU_LOGO_DATA_URI = (
    "data:image/png;base64,"
    "iVBORw0KGgoAAAANSUhEUgAAAMoAAABCCAYAAAAWhkkdAAAAAXNSR0IArs4c6QAAGZNJREFUeAHtXQ18VMW1n7l3v/JFDBAIIbuBACJZikqCCmhFrRTf06et"
    "YtUW+/BVrfVHq7aWVp8F+4lIq/ZZf632WdvaWkX7+myV6qsI1icKBBFJ4FFFkg0JkgAhX/t17533n012s3f33rv3bnYTlDs/wr1zzpkzM+fOmZlz5mMJsYMt"
    "AVsCtgRsCdgSsCVgS8CWwAhJgI5QPid1NowxWn8zcdQca4K8a+X166mcjUBifOobHDU1dbSjY5OyadMFUjZ87DTWJWArinWZmU5x5nnt5aH+yA8ooZ9HIy+M"
    "J4TQmwRRuGf3Nu8f4zCj5/z5gYKuiLKKMnITI6QsifaAQOi63Q3eRygF1g55k4CtKHkS7SfmNtfJlLzAGJmol4VAyNrGHdUr9fAc7p8fGMvCbCMj7HRdOkpf"
    "LiSOzzQ0VPbr0tiIYUkA38oOuZaAv67NJ1H6kpGS8DwVQr7pnxu40Sh/FlHWGyoJT8zY4iCT/mDEx8YNTwK2ogxP

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description explicitly says the tool generates '中文信息海报', which imposes a specific output language in the skill description. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is clearly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill repeatedly defines behavior only in terms of Chinese user phrasing such as “生成图片”, “导出 PNG”, and similar prompts, and elsewhere maps activation/selection using only Chinese terms. This creates a language-policy concern because the skill appears tailored to a single language without explicit user opt-in or an offered language choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This markdown explicitly instructs the AI to interpret Chinese phrasings and prioritize Chinese aliases as the default mapping behavior. It imposes a language/locale-specific interaction pattern without stating that this is optional, user-selectable, or limited to a justified region-specific deployment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The module docstring and implementation indicate the skill renders Chinese lunar calendar text, and the formatted output later uses fixed Chinese strings. This enforces a specific language/locale without any opt-in, alternative locale handling, or justification that the skill is region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The month and day name tables are defined only with Chinese characters, and there is no parallel localization path. This means all rendered user-facing calendar text is forced into Chinese regardless of user preference.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The returned formatted string uses fixed Chinese prefixes such as "农历" and "闰". Because there is no user choice or documented opt-in, this is a natural-language locale constraint embedded directly in the code.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code defines fixed Chinese strings for visible output, including weekday labels and poster headers, and later renders them directly into the generated poster. Under the policy rule, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The file is described as a renderer, but it also performs outbound HTTP requests to third-party APIs and writes fetched data to a local cache. This mismatch is security-relevant because operators may trust or sandbox it as a pure local rendering utility, while untrusted input can trigger network access and persistent file writes, increasing the attack surface and enabling SSRF-like access to arbitrary URLs supplied via the spec.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This file embeds extensive Chinese-only UI text and labels such as weekday names, default section titles, and rendered poster text, but there is no visible mechanism for user language selection or explicit justification that the skill is intended only for a Chinese locale. That can violate language/locale policy when a skill forces a specific language without opt-in.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The code fetches arbitrary remote content via http/https and stores it under a local cache path without user-facing disclosure or consent. In a skill/agent context, this is dangerous because attacker-controlled specs can cause unexpected outbound requests, leak network metadata, consume resources, and persist untrusted files on disk.

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/svg_image_converter.py (reported line 291)May include surrounding context.

python
def _run_command(command: list[str], failure_message: str) -> None:
    try:
        completed = subprocess.run(
            command,
            check=True,
            capture_output=True,

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language metadata in the name and bio is written entirely in Chinese, which can indicate a language-specific presentation being imposed by default. The file does not offer any language choice or document a justified region-specific constraint, which may conflict with a policy requiring language or locale opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The natural-language fields for the skill persona and bio are written only in Chinese, which can imply a fixed language/locale experience. The file does not indicate that users can choose another language or that this locale restriction is intentional and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This JSON file hard-codes Chinese-language titles, holiday names, and preview labels throughout the dataset, such as the source title and countdown labels. Because the file provides no indication that the skill is China-specific or that users can opt into this locale, it may violate the language/locale policy for natural-language content.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
93% confidence
Finding

The dependency is specified with only a lower bound, which allows future installs to resolve to different versions over time. This weakens build reproducibility and can inadvertently introduce a vulnerable or breaking upstream release into the skill environment.

Content

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

text
resvg_py>=0.2.6
Pillow>=10.0.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
97% confidence
Finding

Pillow is also unpinned, so installations may pull different versions depending on when and where the skill is installed. Because Pillow has a history of security advisories, leaving it floating increases the chance of resolving to an affected release or an unreviewed future version.

Content

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

text
resvg_py>=0.2.6
Pillow>=10.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
95% confidence
Finding

The manifest references Pillow without pinning to a known-safe version, and Pillow has multiple published advisories including memory corruption, resource exhaustion, and potential code execution in some versions. Without an exact version, it is impossible to verify at review time whether deployments will receive a patched release, making the dependency risk real rather than merely theoretical.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The default value for --title is set to Chinese text ("假期倒计时"), which imposes a specific language choice by default. This can violate a language/locale policy when the skill does not explicitly offer opt-in language selection or document why a Chinese-only default is required.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This code embeds user-facing labels, holiday names, and official-source metadata entirely in Chinese, such as the holiday labels and countdown text. Because the file does not offer a language opt-in or document that the skill is intentionally China/Chinese-locale specific, it may violate the language/locale policy for natural-language content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The renderer accepts a user-supplied path, resolves it, and reads JSON from the local filesystem with no path restriction or disclosure. While it only reads files and parses JSON, in an agent setting this can expose unintended local data if an attacker can influence the input spec to reference sensitive files that happen to contain readable JSON.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This script invokes render_to_files(...), which by name and arguments clearly indicates writing rendered output to disk at output_path. Although the module docstring describes rendering posters, there is no confirmation prompt, print/log disclosure, or inline comment in this file warning the user that files will be created or overwritten.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.