Back to skill

Security audit

书本学习助手

Security checks for vulnerabilities and agentic risk

Overview

This book-learning skill is mostly aligned with its purpose, but it needs review because it may write generated notes to synced note apps without clear confirmation and has under-scoped local ebook parsing risks.

Review before installing if you use Notion, Obsidian, or synced notes. Confirm where notes will be written before allowing any write action, avoid processing untrusted large ebooks, and install optional PDF dependencies in a constrained environment with a pinned version if you need PDF support.

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 (2)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/read_book.py:45
Finding

Unbounded Decompression and Parsing of Untrusted Ebook Files

Content
View full analysis
str: """Read a file from the ZIP archive and attempt several decodings.""" raw = z.read(fpath) for enc in ('utf-8', 'utf-8-sig', 'gbk', 'latin-1'): try: return raw.decode(enc) except Exception: continue return raw.decode('utf-8', errors='ignore') ``` ```python with zipfile.ZipFile(epub_path, 'r') as z: html_files = [f for f in z.namelist() if f.endswith(('.html', '.xhtml', '.htm'))] print(f"[search] Total HTML files: {len(html_files)}; keyword: {keyword}", file=sys.stderr) for f in html_files: try: content = _read_file(z, f) if keyword not in content: continue text_len = len(re.sub(r'<[^>]+>', ' ', content)) if text_len < 2000: print(f"[skip] {f} -> only {text_len} characters", file=sys.stderr) continue kw_count = content.count(keyword) density = kw_count * 1000 / max(text_len, 1) matches.append((f, text_len, kw_count, density, content)) ``` ```python reader = PdfReader(pdf_path) full_text = '' for i, page in enumerate(reader.pages): full_text += (page.extract_text() or '') full_text += f'\n--- Page {i + 1} ---\n' ``` ### Technical Analysis The script accepts locally supplied EPUB and PDF files and processes them without resource budgets. For EPUB files, every HTML member is read with `ZipFile.read()`, which decompresses the complete member into memory. The script does not validate: - The number of archive members. - The compressed or uncompressed size o ...[truncated 2070 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
EBOOK_README.md:7
Finding

Unpinned Third-Party PDF Parsing Dependency

Content
View full analysis
dict: try: from pypdf import PdfReader except ImportError: return {'error': 'pypdf is not installed; run pip install pypdf'} reader = PdfReader(pdf_path) ``` ### Technical Analysis The project directs users to install `pypdf` without specifying a reviewed version, cryptographic hash, lockfile, package index, or isolated environment. Consequently, the dependency resolved during installation can change independently of the audited skill. The package name is consistent across the project, and the audit found no evidence of typosquatting, dependency confusion, or an intentionally malicious package source. The risk is therefore limited to mutable supply-chain resolution, unexpected upstream changes, or incompatible future releases rather than a confirmed malicious dependency. Because Python packages execute code in the local environment when imported—and may execute build-related code during installation—an upstream compromise could affect the user with the privileges used to run `pip` or the skill. ### Attack Path 1. A user attempts to enable the documented PDF functionality. 2. The script reports that `pypdf` is missing or the user follows `EBOOK_README.md`. 3. The user runs the unpinned `pip install pypdf` command. 4. The package manager resolves the package version available at installation time. 5. If a future release or upstream dis ...[truncated 783 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

该代码块的实际职责是一个底层文档提取脚本,而不是描述中的“书本系统学习助手”。它处理本地 EPUB/PDF 文件,使用 ZIP 读取 EPUB、正则清洗 HTML、按关键词密度选择章节、列出章节目录,并返回截断文本。这可以作为上层学习助手的一个支持组件,但单看该代码,其主要行为与宣称的高层功能严重不一致。尤其是:没有任何外部搜索、没有根据书籍元信息获取全书框架、没有生成结构化学习内容、没有案例改写、没有时效性评估、没有事实核查机制。此外,代码还提供了未在描述中强调的 PDF 支持。因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The README instructs the workflow to write generated reading notes into Obsidian and Notion without any mention of explicit user consent, destination confirmation, or sync/privacy implications. This can cause unintended modification of external note stores and propagation of potentially sensitive book-derived content to synced services, especially when local ebook paths may reveal private files or reading habits.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill instructs processing user-supplied EPUB files by extracting internal files, TOC metadata, and chapter text, but it does not clearly disclose that uploaded book contents may be parsed and surfaced in outputs. This creates a privacy and data-handling risk: users may provide copyrighted, sensitive, or personal annotations embedded in ebooks without understanding the extent of extraction and exposure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file presents all user-facing example output exclusively in Chinese, including headings and instructional framing, with no indication that users can choose another language. Under the policy rule for language/locale constraints, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest describes two trigger modes, and the file-based mode explicitly specifies a reference e-book file in EPUB format. This script implements full PDF ingestion and text extraction as an additional supported format, which expands behavior beyond the stated skill description rather than serving as an obvious implementation detail.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The file presents all user-facing instructions solely in Chinese and does not indicate that users may choose another language or locale. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy issue unless the constraint is documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module docstring and all CLI-facing messages are written in Chinese, and the script's behavior presents this language choice as fixed rather than optional. The policy explicitly calls for flagging language or locale constraints when the skill forces a specific language without user opt-in.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The module docstring states a specific core strategy: scan all HTML files, sort by text length, and treat the longest as the chapter content. However, the actual chapter-selection logic in _find_chapter_in_epub filters by keyword presence and length, then sorts matches by keyword density, so the documentation actively misdescribes the behavior.

Content

No source excerpt is available for this finding.