Back to skill

Security audit

Book Writer

Security checks for vulnerabilities and agentic risk

Overview

This book-writing skill is not clearly malicious, but it needs review because some scripts can fetch remote content and write files outside the expected output area.

Install only in a contained environment with a virtualenv or sandbox, avoid running the installer as admin/root, use only non-sensitive prompts or approved API keys, and do not pass arbitrary output paths or image URLs unless the code is fixed to validate destinations and downloads.

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
scripts/material_searcher.py:232
Finding

Unrestricted Image Download Enables SSRF and Arbitrary File Writes

Content
View full analysis
bool: """ Download an image. Args: image_url: Image URL save_path: Save path Returns: bool: Whether the download succeeded """ try: response = requests.get(image_url, stream=True) response.raise_for_status() with open(save_path, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk) logger.info(f"Image downloaded: {save_path}") return True except Exception as e: logger.error(f"Image download failed: {e}") return False ``` ### Technical Analysis The `download_image` method accepts both `image_url` and `save_path` without applying security validation. `requests.get()` can connect to any URL supported by the Requests library. The method does not restrict schemes, hosts, resolved IP addresses, ports, or redirects. Consequently, an attacker who controls `image_url` can cause requests to loopback interfaces, private networks, link-local services, or cloud instance metadata endpoints. The destination is also passed directly to `open()` without constraining it to an intended media or temporary directory. Absolute paths and traversal sequences such as `../../` can therefore target any file writable by the current process. Symbolic links are not rejected. No request timeout or response-size limit is enforced. A remote server can hold the connection open or return an excessively large response. ### Attack Path 1. An attacker reaches a workflow or integration that passes untrusted URL and destination values to `download_image`. 2. The attacker supplies a URL targeting an internal service, such as a loopback administ ...[truncated 1348 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/book_writer.py:490
Finding

Output Path Traversal Allows Writes Outside the Generated-Books Directory

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
scripts/install_dependencies.py:10
Finding

Unpinned Dependency Installation Executes Unreviewed Upstream Package Code

Content
View full analysis
=1.0.0", "requests>=2.28.0", "pyyaml>=6.0", "python-dotenv>=0.19.0", "tiktoken>=0.3.0", "beautifulsoup4>=4.11.0", "lxml>=4.9.0" ] print("Installing Python dependencies...") for package in packages: package_name = package.split(">=")[0].split("<=")[0] cmd = f"{sys.executable} -m pip install --upgrade {package}" run_command(cmd, f"Installing {package_name}") return True ``` The same open-ended constraints appear in `requirements.txt`: ```text openai>=1.0.0 requests>=2.28.0 pyyaml>=6.0 python-dotenv>=0.19.0 tiktoken>=0.3.0 beautifulsoup4>=4.11.0 lxml>=4.9.0 ``` ### Technical Analysis Each dependency has only a minimum version an ...[truncated 2651 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (38)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The skill is presented as a book-writing tool, but the documentation also describes network-based material search using Google APIs, credential handling, and downloading remote content to local storage. This expands the risk surface to third-party data transfer and untrusted content ingestion, which is more dangerous when those behaviors are not prominently disclosed as part of the skill's core behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The skill is presented as a book-writing tool, but the documentation also describes network-based material search using Google APIs, credential handling, and downloading remote content to local storage. This expands the risk surface to third-party data transfer and untrusted content ingestion, which is more dangerous when those behaviors are not prominently disclosed as part of the skill's core behavior.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
98% confidence
Finding

This is a true tool-parameter abuse issue because the subprocess is configured with shell=True, an unsafe parameter that broadens the attack surface and can enable shell metacharacter interpretation. Although cmd is assembled from internal values in the present code, installer scripts run with user privileges and are a sensitive context, so this unsafe pattern is more dangerous than in ordinary application logic.

Content

Scanner excerpt · scripts/install_dependencies.py (reported line 19)May include surrounding context.

python
print(f"   💻 执行: {cmd}")

    try:
        result = subprocess.run(cmd, shell=True, check=True,
                              capture_output=True, text=True)
        if result.returncode == 0:
            print(f"   ✅ 成功")

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The download_image function fetches arbitrary remote content from a caller-supplied URL and writes it to a caller-supplied local path with no allowlist, path restriction, size limit, or content-type validation. This can enable SSRF-like internal network access, overwriting sensitive files, or storing malicious payloads locally under the guise of an image.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill advertises capabilities that involve shell execution, network access, filesystem reads/writes, and environment-variable use, but it does not declare any explicit tool scope or permission boundaries. This makes the effective privilege surface opaque to users and runners, increasing the chance that the skill is executed with broader access than expected.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill documentation states that it searches for materials via external APIs, but it does not warn that user prompts, manuscript content, or derived queries may be transmitted to third-party providers. This creates a privacy and data-governance risk, especially if users process confidential, unpublished, or regulated content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

User-facing descriptions, prompts, logs, and CLI messages throughout the file are in Chinese, and there is no indication that the user can choose another language. This creates a language-policy concern because the skill appears to enforce a locale without opt-in or documented justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The tool sends user prompts and book content to the OpenAI API, but there is no explicit notice or consent step informing users that their data leaves the local environment. For a writing skill, prompts may contain proprietary drafts, research notes, or sensitive material, so silent third-party transmission creates a real privacy and data-handling risk.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This Python file contains natural-language strings such as the module docstring and later CLI help/output text exclusively in Chinese, which imposes a specific language on users. Under the policy, locale or language constraints should either be optional for the user or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The argparse description, argument help text, and printed status messages are all Chinese-only, which creates a language policy issue for users who have not opted into that locale. There is no visible mechanism to select another language or indication that the tool is intended only for a Chinese-language environment.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
97% confidence
Finding

The script invokes subprocess.run with shell=True, which makes command execution go through the shell and introduces command-injection risk if the command string is ever influenced by untrusted input or modified in the future. In this file the current package list is hardcoded, so exploitation is not immediate, but using shell=True in an installer script is still unsafe because dependency/setup scripts are often adapted to accept user input later.

Content

Scanner excerpt · scripts/install_dependencies.py (reported line 19)May include surrounding context.

python
print(f"   💻 执行: {cmd}")

    try:
        result = subprocess.run(cmd, shell=True, check=True,
                              capture_output=True, text=True)
        if result.returncode == 0:
            print(f"   ✅ 成功")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The code loads Google API credentials from environment variables and configuration to enable outbound search requests. For a skill presented as an AI book-writing tool, handling external search credentials is an additional operational capability that is not clearly justified or declared by the manifest text.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest describes an AI-assisted book-writing skill that generates outlines and expands content, with support for formulas, charts, and code elements. This file implements external web search for images, code examples, and statistics, and later downloads remote images, which is materially broader than content generation itself and is not mentioned in the skill description.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The function writes directly to a caller-controlled path without any confirmation, visibility, or safety checks. In an agent context, this increases the chance of silent filesystem modification, accidental overwrites, or abuse by prompting the agent to persist attacker-chosen content in sensitive locations.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The installation test enumerates whether sensitive API credentials are present and prints partially masked values to stdout. Even though the keys are not fully disclosed, revealing credential presence and fragments can leak operational details into logs, CI output, shared terminals, or support screenshots, which is unnecessary for basic installation validation and increases exposure of secrets.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

All user-facing documentation and examples are presented in Chinese, which effectively imposes a language constraint on users. The file does not state that the skill is region- or language-specific, nor does it offer an opt-in or alternative language.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This manifest contains user-facing natural language in comments such as 'OpenAI API配置', 'Google搜索API配置', and other section descriptions exclusively in Chinese. Under the policy rule for language/locale, forcing a single language without opt-in or justification can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file presents all user-facing instructional content in Chinese, and there is no indication that the user can opt into another language or that the skill is intentionally region-specific. Under the policy criteria, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The chapter title and all instructional prose in this markdown file are written exclusively in Chinese, with no indication that language selection is optional or user-configurable. Under the stated 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

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The document content is entirely written in Chinese and does not indicate that language selection is optional or user-configurable. Under the policy rule for natural-language violations, a skill that imposes a specific language without opt-in should be flagged unless the locale constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This JSON outline is entirely authored in Chinese, including the title, chapter names, and descriptions, while the metadata only states a general audience and does not indicate that the skill is region-specific or that users can opt into this locale. Under the language/locale policy criterion, this can be considered a forced language choice without explicit justification.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower bound only, so builds may resolve to different versions over time. This weakens supply-chain reproducibility and makes it harder to ensure that only reviewed, non-vulnerable versions of the OpenAI SDK are installed.

Content

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

text
openai>=1.0.0
requests>=2.28.0
pyyaml>=6.0
python-dotenv>=0.19.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

Using requests>=2.28.0 allows installation of any later version, making the environment non-reproducible and preventing verification against known advisories. Because requests has multiple historical security advisories, leaving it unpinned increases uncertainty about whether deployed instances are exposed.

Content

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

text
openai>=1.0.0
requests>=2.28.0
pyyaml>=6.0
python-dotenv>=0.19.0
tiktoken>=0.3.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
97% confidence
Finding

The manifest does not pin requests, so it is impossible to verify from this file alone whether deployment will use a version affected by known requests advisories. In a skill that may fetch remote content, uncertainty around HTTP client security increases supply-chain and runtime risk, even if the issue is not directly exploitable from this file alone.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
99% confidence
Finding

PyYAML is unpinned, so installations may pick different releases depending on when and where the package is installed. Given PyYAML's history of unsafe parsing-related advisories, this creates avoidable supply-chain risk and complicates security review.

Content

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

text
openai>=1.0.0
requests>=2.28.0
pyyaml>=6.0
python-dotenv>=0.19.0
tiktoken>=0.3.0
beautifulsoup4>=4.11.0

Static analysis

No suspicious patterns detected.