Back to skill

Security audit

小说创作

Security checks for vulnerabilities and agentic risk

Overview

This novel-writing skill mostly matches its stated purpose, but needs review because unsafe path handling and custom API settings could overwrite local files or send drafts and API keys to the wrong service.

Review before installing. Run it in an isolated workspace or virtual environment, keep backups before using regeneration, avoid untrusted title or character names, and only set NOVEL_API_BASE_URL to a trusted HTTPS provider because drafts, outlines, character notes, summaries, and the API key are sent there during generation.

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
core.py:70
Finding

Path Traversal Through Unsanitized Project and Character Names

Content
View full analysis
dict: """加载记忆上下文""" context_file = self.project_dir / "meta" / "context.json" if context_file.exists(): with open(context_file, 'r', encoding='utf-8') as f: ctx = json.load(f) logger.info(f"Loaded context for: {self.novel_title}") return ctx def _save_context(self): """保存记忆上下文""" context_file = self.project_dir / "meta" / "context.json" context_file.parent.mkdir(parents=True, exist_ok=True) self.context["updated_at"] = datetime.now().isoformat() with open(context_file, 'w', encoding='utf-8') as f: json.dump(self.context, f, ensure_ascii=False, indent=2) def _init_project_dir(self): """初始化项目目录""" dirs = ["characters", "world", "outline", "chapters", "meta"] for d in dirs: (self.project_dir / d).mkdir(parents=True, exist_ok=True) config_file = self.project_dir / "config.json" if not config_file.exists(): with open(config_file, 'w', encoding='utf-8') as f: json.dump({ "title": self.novel_title, "style": self.context["style"], "created_at": datetime.now().isoformat() }, f, ensure_ascii=False, indent=2) def set_character(self, name: str, profile: str) -> str: """设定人物""" self.context["characters"][name] = profile self._save_context() char_file = self.project_dir / "characters" / f"{ ...[truncated 2387 chars]
Remediation
View remediation
Path: if not name or Path(name).is_absolute(): raise ValueError("Invalid path component") destination = (base / name).resolve() resolved_base = base.resolve() if destination != resolved_base and resolved_base not in destination.parents: raise ValueError("Path escapes the permitted directory") return destination ``` 4. Perform the containment check again on complete file destinations, including character and outline filenames. 5. Consider rejecting symbolic links within project storage or opening files with operating-system protections against symlink following. 6. Run the application under a dedicated, unprivileged account with write access limited to the intended working directory. 7. Add tests covering absolute paths, nested traversal, mixed separators, symbolic links, and platform-specific path forms. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
config_models.py:18
Finding

API Credentials and Manuscript Data Can Be Sent to an Unvalidated Endpoint

Content
View full analysis
str: return os.environ.get("NOVEL_API_KEY", v) @field_validator("base_url", mode="before") @classmethod def get_base_url_from_env(cls, v: str) -> str: return os.environ.get("NOVEL_API_BASE_URL", v) ``` ```python def _init_client(self): """初始化 LLM 客户端""" if OPENAI_AVAILABLE and self.config.validate_api_key(): self.client = OpenAI( base_url=self.config.api.base_url, api_key=self.config.api.api_key ) ``` ```python response = self.client.chat.completions.create( model=self.config.api.model, messages=[ {"role": "system", "content": system_prompt}, {"role": "user", "content": user_prompt} ], temperature=self.config.api.temperature, max_tokens=self.config.api.max_tokens ) ``` ### Technical Analysis `NOVEL_API_BASE_URL` is accepted without validating its scheme, hostname, port, resolved address, or trust relationship. The OpenAI-compatible client is then initialized with the API key and sends authorization data and generated prompts to that endpoint. The prompts can include the novel title, character profiles, world-building information, chapter outlines, and summaries of previous chapters. If the endpoint uses plaintext HTTP or points to an attacker-controlled service, both credentials and manuscript information can be disclosed. This is not covert exfiltration: external API use is documented. The vulnerability is the absence of safeguards against unsafe or malicious endpoint configuration. ### Attack Path 1. An attacker influences deployment configuration, a wrapper script, or the environment used to launch the ski ...[truncated 890 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
README.md:19
Finding

Runtime Dependencies Are Installed Without Version or Integrity Pinning

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (22)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The prompt requirement explicitly says '2200-2500 字(中文)', which enforces a specific language. Under the policy, forcing a language without offering the user a language or locale choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
80% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · LESSONS_LEARNED.md (reported line 118)May include surrounding context.

md
## 🔗 相关文件

- **技能文档**:`/app/working/customized_skills/novel_writer/SKILL.md`
- **核心代码**:`/app/working/customized_skills/novel_writer/core.py`
- **配置文件**:`/app/working/customized_skills/novel_writer/config.json`
- **小说项目**:`/app/working/novels/废柴至尊:踏破九天/`

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README instructs users to configure an external API endpoint and use generation/import features, but it does not clearly disclose that user-provided novel text, outlines, and related content may be transmitted to a third-party service. This creates a real privacy and data-handling risk because users may unknowingly upload sensitive drafts, proprietary story material, or personal data embedded in the content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill explicitly advertises persistent memory and automatic chapter file output, but it does not provide a clear, user-facing privacy warning that prompts and generated content will be written to disk and retained over time. In a writing assistant, users may include unpublished manuscripts, personal notes, or sensitive ideas; silent persistence increases the risk of unintended disclosure, cross-session data exposure, and mishandling of confidential content.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The documentation says generated chapters must strictly use first-person perspective and include specific stylistic elements. This imposes a language/output policy by default rather than offering it as a configurable preference, which can conflict with organizational requirements to avoid forced language or locale constraints without user choice.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains natural-language strings such as the module docstring and multiple field descriptions exclusively in Chinese. Under the policy for all file types, forcing a specific language without offering user choice or documenting a justified locale constraint is a language/locale policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

Natural-language strings in the file describe the functionality as using improved Chinese summarization and the operational prompts and defaults are Chinese-oriented, but no opt-in or language selection policy is mentioned. This can constitute a language/locale policy issue because the skill appears to enforce a specific language context by default.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The code sends user-authored content and accumulated novel context to an external LLM API via self.client.chat.completions.create(...) without any consent prompt, privacy notice, or option to avoid remote transmission in this file. Because characters, world-building notes, summaries, and prior chapter content may contain sensitive or proprietary material, this creates a real data exfiltration/privacy risk if users assume processing is local.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The regeneration path writes directly to the existing chapter file and the comment indicates it overwrites the old version, making the operation destructive for prior content. There is no confirmation prompt or user-visible warning in the CLI flow before replacing the chapter text.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The file title and all instructional content are written in Chinese, and there is no indication that users may choose another language or that the skill is intentionally limited to a Chinese-language audience. Under the policy, a fixed language/locale without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The system prompt explicitly requires output in Chinese at L030 and further imposes strict output constraints at L055-L057, but the file provides no option for the user to choose another language or locale. Under the policy, forcing a specific language without opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring is entirely in Chinese and presents the skill's purpose only in that language. Under the policy, forcing a specific language without user opt-in or documented locale justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

All printed status, warning, and error messages are emitted only in Chinese, which enforces a single language at runtime. There is no indication of user language selection or a documented reason for limiting the skill to Chinese.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The instruction '严格保持“我”的视角' is a language-specific constraint embedded in the skill guidance. While stylistic constraints can be valid, this one hard-codes a Chinese-specific expression and does not indicate user opt-in or configurability.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Natural-language instructions, command descriptions, and feature explanations are presented only in Chinese, which can impose a language constraint without user opt-in. The file does not mention that the skill is Chinese-only or provide an alternative language option.

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 instructions and usage guidance exclusively in Chinese. Under the policy rule for natural-language violations, forcing a specific language without user opt-in can be a locale policy issue when no alternative or opt-in is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
77% confidence
Finding

This JSON file contains user-facing narrative content entirely in Chinese, and there is no indication that the skill offers language selection or that the locale restriction is intentionally documented as region-specific. Under the stated policy, forcing a specific language without user opt-in 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
89% confidence
Finding

This JSON embeds all user-facing content in a single language, which may violate language/locale policy if the skill assumes Chinese output without offering opt-in or documenting that it is region-specific. The file does not indicate that Chinese is optional, configurable, or justified by a locale-specific use case.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

The file’s headings and instructions are entirely in Chinese, which creates a language-specific constraint in the skill content. There is no indication that Chinese is optional, user-selected, or required for a documented region-specific purpose, so this appears to impose a locale/language preference without opt-in.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown template appears to require Chinese as the interaction/documentation language, and there is no indication that users may choose another language. Under the policy criteria, forcing a specific language without user opt-in 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
86% confidence
Finding

This markdown template uses Chinese as the default interaction language and does not indicate that users may choose another language. Under the stated policy, forcing a specific language without user opt-in 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
87% confidence
Finding

The module name and class/docstring language are entirely in Chinese, which imposes a specific language/locale in the skill's user-facing natural-language text without indicating user opt-in or a documented region-specific requirement. Under the stated policy, forced language constraints should either offer choice or be clearly justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.