Back to skill

Security audit

Book Report

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it says, but it needs Review because crafted book titles can make it write report files outside its reports folder.

Review before installing. Use this only for explicit book-report requests, prefer an isolated virtual environment, avoid private PDFs unless you are comfortable with their contents being processed and persisted in reports, and patch the report filename handling to use sanitized titles with directory-containment checks.

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
lib/render.py:96
Finding

Unsanitized Book Title Permits Report Writes Outside the Intended Directory

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
book-report/README.md:40
Finding

Unpinned Global Installation of Third-Party Python Dependencies

Content
View full analysis
Remediation
View remediation
Jinja2== PyMuPDF== ``` 2. Generate and verify cryptographic hashes, then require hash validation: ```bash python -m pip install --require-hashes -r requirements.txt ``` 3. Use a lockfile generated by a dependency-management tool such as `pip-tools`, Poetry, or uv, including transitive dependencies. 4. Require installation in an isolated virtual environment: ```bash python3 -m venv .venv . .venv/bin/activate python -m pip install --require-hashes -r requirements.txt ``` 5. Replace bare `pip3` commands with `python -m pip` so installation targets the intended interpreter. 6. Add automated dependency scanning and a controlled update process. Review and test dependency changes before updating the lockfile. 7. Update the `pdf_extract.py` error message to reference the locked installation procedure rather than recommending a direct unpinned installation. ]]>
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
Findings (38)

Tainted flow: 'USE_PROXY' from os.environ.get (line 29, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · book-report/lib/fetch.py (reported line 55)May include surrounding context.

python
elif "zhihu.com" in url:
            headers["Referer"] = "https://www.zhihu.com/"

        r = requests.get(url, headers=headers, timeout=TIMEOUT,
                         proxies=PROXIES if USE_PROXY else None)
        r.raise_for_status()
        r.encoding = r.apparent_encoding or "utf-8"

Tainted flow: 'USE_PROXY' from os.environ.get (line 29, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · lib/fetch.py (reported line 55)May include surrounding context.

python
elif "zhihu.com" in url:
            headers["Referer"] = "https://www.zhihu.com/"

        r = requests.get(url, headers=headers, timeout=TIMEOUT,
                         proxies=PROXIES if USE_PROXY else None)
        r.raise_for_status()
        r.encoding = r.apparent_encoding or "utf-8"

Vague Triggers

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

The trigger words are extremely broad (e.g. "了解/研究/讲一下/聊/书/读") and can match ordinary conversation unrelated to requesting this skill. That increases the chance of unintended auto-invocation, causing unexpected web fetching, content generation, and local file creation without clear user intent.

Content

No source excerpt is available for this finding.

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
85% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · book-report/reports/README.md (reported line 21)May include surrounding context.

想清空历史产物

bash
rm reports/*.html reports/*.md

不放心的话加 -i 逐个确认。

Obfuscated Code

High
Category
Supply Chain
Confidence
50% confidence
Finding

Code contains obfuscation (base64, hex encoding with execution). This is often used to hide malicious functionality.

Content

Scanner excerpt · book-report/sources/cache/goodreads__The_Old_Man_and_the_Sea.html (reported line 15)May include surrounding context.

html
<script type="text/javascript">
    window.awsWafCookieDomainList = [];
    window.gokuProps = {
"key":"AQIDAHjcYu/GjX+QlghicBgQ/7bFaQZ+m5FKCMDnO+vTbNg96AFPL1G3oJcTFBhlx+6LwB30AAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMP1vzbmgXNG41AiMOAgEQgDtC30jfk1Uc3Cb+uYKuU7yb30Xzzha7jVC2wcUOKEE6UAFYO855l7m1kCCrRQk87/36K4+U0OGyMUlY3Q==",
          "iv":"grC9LAA/UQAAADdn",
          "context":"UUnKZqTYrFcZOPCaJm84ycLOZf9iVLaS5WUnS98/H6ymuVDIzgzx2z9PwwALmTsc1fDrVyEN/4dmU3YYpL6QLt2h6VcDSO/Wvig4/g4DIiLYJsYhWAbwfIVECA6OiK2lartgwgS27NIagXi8j3TupelTbkGsM4ZFjnZyijJDappXuRU1uXMi3TD4wW4xud3RkpcB+Wdq4F6dd4A5oOvFvuZeVpyFxMcWajGkT79AVFlqjau/Ps3chlUMMJKKqGa3zDRdTlXUyYHQB9seGU4TUwcG3Cj6pod/CyaqM7vObu0QiTIckdJEvRIrT+icZeWv+0qYStqie/kXtcrG4lD/5P0oUwutuMB3ObBV2dtCqjUqqXt0wprLOPJCyk5cF1CdM0TFBCI="
};

Obfuscated Code

High
Category
Supply Chain
Confidence
50% confidence
Finding

Code contains obfuscation (base64, hex encoding with execution). This is often used to hide malicious functionality.

Content

Scanner excerpt · book-report/sources/cache/goodreads__The_Old_Man_and_the_Sea.html (reported line 17)May include surrounding context.

html
window.gokuProps = {
"key":"AQIDAHjcYu/GjX+QlghicBgQ/7bFaQZ+m5FKCMDnO+vTbNg96AFPL1G3oJcTFBhlx+6LwB30AAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMP1vzbmgXNG41AiMOAgEQgDtC30jfk1Uc3Cb+uYKuU7yb30Xzzha7jVC2wcUOKEE6UAFYO855l7m1kCCrRQk87/36K4+U0OGyMUlY3Q==",
          "iv":"grC9LAA/UQAAADdn",
          "context":"UUnKZqTYrFcZOPCaJm84ycLOZf9iVLaS5WUnS98/H6ymuVDIzgzx2z9PwwALmTsc1fDrVyEN/4dmU3YYpL6QLt2h6VcDSO/Wvig4/g4DIiLYJsYhWAbwfIVECA6OiK2lartgwgS27NIagXi8j3TupelTbkGsM4ZFjnZyijJDappXuRU1uXMi3TD4wW4xud3RkpcB+Wdq4F6dd4A5oOvFvuZeVpyFxMcWajGkT79AVFlqjau/Ps3chlUMMJKKqGa3zDRdTlXUyYHQB9seGU4TUwcG3Cj6pod/CyaqM7vObu0QiTIckdJEvRIrT+icZeWv+0qYStqie/kXtcrG4lD/5P0oUwutuMB3ObBV2dtCqjUqqXt0wprLOPJCyk5cF1CdM0TFBCI="
};
    </script>
    <script src="https://ea457862827c.c7756a6c.ap-northeast-1.token.awswaf.com/ea457862827c/ca63136f72fb/b63fc4339d15/challenge.js"></script>

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · book-report/sources/cache/wiki_en__The_Old_Man_and_the_Sea.html (reported line 1186)May include surrounding context.

html
<li><i><a href="/wiki/Angel_Down_(novel)" title="Angel Down (novel)">Angel Down</a></i> by <a href="/wiki/Daniel_Kraus_(author)" title="Daniel Kraus (author)">Daniel Kraus</a> (2026)</li></ul>
</div></td></tr></tbody></table></div>
<div class="navbox-styles"><link rel="mw-deduplicated-inline-style" href="mw-data:TemplateStyles:r1333133064" /><link rel="mw-deduplicated-inline-style" href="mw-data:TemplateStyles:r1353707246" /></div><div role="navigation" class="navbox authority-control" aria-labelledby="Authority&#95;control&#95;databases&#95;frameless&amp;#124;text-top&amp;#124;10px&amp;#124;alt=Edit&#95;this&#95;at&#95;Wikidata&amp;#124;link=https&amp;#58;//www.wikidata.org/wiki/Q26505#identifiers&amp;#124;class=noprint&amp;#124;Edit&#95;this&#95;at&#95;Wikidata1853" style="padding:3px"><table class="nowraplinks hlist mw-collapsible autocollapse navbox-inner" style="border-spacing:0;background:transparent;color:inherit"><tbody><tr><th scope="col" class="navbox-title" colspan="2"><div id="Authority&#95;control&#95;databases&#95;frameless&amp;#124;text-top&amp;#124;10px&amp;#124;alt=Edit&#95;this&#95;at&#95;Wikidata&amp;#124;link=https&amp;#58;//www.wikidata.org/wiki/Q26505#identifiers&amp;#124;class=noprint&amp;#124;Edit&#95;this&#95;at&#95;Wikidata1853" style="font-size:114%;margin:0 4em"><a href="/wiki/Help:Authority_control" title="Help:Authority control">Authority control databases</a> <span class="mw-valign-text-top noprint" typeof="mw:File/Frameless"><a href="https://www.wikidata.org/wiki/Q26505#identifiers" title="Edit this at Wikidata"><img alt="Edit this at Wikidata" src="//upload.wikimedia.org/wikipedia/en/thumb/8/8a/OOjs_UI_icon_edit-ltr-progressive.svg/20px-OOjs_UI_icon_edit-ltr-progressive.svg.png" decoding="async" width="10" height="10" class="mw-file-element" data-file-width="20" data-file-height="20" /></a></span></div></th></tr><tr><th scope="row" class="navbox-group" style="width:1%">International</th><td class="navbox-list-with-group navbox-list n
...[truncated 26 chars]

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · book-report/sources/cache/wiki_en__The_Old_Man_and_the_Sea.html (reported line 1208)May include surrounding context.

html
Lua memory usage: 9552776/52428800 bytes
Number of Wikibase entities loaded: 1/500
-->
<!--
Transclusion expansion time report (%,ms,calls,template)
100.00%  729.094      1 -total
 16.28%  118.708      1 Template:Infobox_book

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The description states a workflow of fetching from Wikipedia, Baidu Baike, and Zhihu, but does not clearly warn users up front that the skill will contact external websites. Unexpected outbound requests may expose user interests or prompts through network activity and can violate user expectations in privacy-sensitive environments.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill is described entirely in Chinese and explicitly depends on Chinese sources such as 百度百科, 维基百科(zh), and 知乎, while also framing its usage around Chinese-language output. It does not offer a user opt-in for language/locale or explain that the limitation is an intentional region-specific constraint.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill writes artifacts to the local filesystem under reports/ but the user-facing description does not prominently disclose that side effect before activation. If invoked unintentionally, it can create persistent local files containing scraped or synthesized content, which may surprise users and create privacy, storage, or workspace-integrity concerns.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This file contains natural-language interface text exclusively in Chinese, including usage instructions, help output, and error guidance. Under the policy rule for language/locale constraints, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · book-report/README.md (reported line 44)May include surrounding context.

md
pip3 install requests jinja2

# 3. 注册 skill 到 Hermes(如果用 Hermes)
mkdir -p ~/.hermes/skills/book-report
cp SKILL.md ~/.hermes/skills/book-report/

# 4. 跑(任选一种方式)

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file contains a natural-language locale restriction: '当前是中文专用'. The policy allows locale constraints only when the skill offers user choice or the restriction is clearly justified as region-specific; here the README presents the limitation as a blanket constraint rather than an opt-in language selection.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The English mode section states "报告仍用中文样式输出(界面统一)", which imposes a specific language/locale choice even when the user requests an English-language workflow. This is a natural-language policy concern because it does not offer the user a language choice or explicit opt-in for Chinese output.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill describes extracting content from local PDFs and combining it with web-fetched data for LLM-based structuring, but it does not clearly disclose that local document contents may be transmitted to or processed by an LLM. This creates a privacy and data-handling risk, especially if users provide copyrighted, personal, or sensitive PDFs under the assumption the processing is purely local.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The trigger phrases are broad enough to match ordinary requests about learning or discussing a book, which can cause the skill to activate without clear user intent. In an agent setting, this increases the chance of unprompted web fetching, PDF processing, and report generation that the user did not explicitly ask for.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The request headers hard-code Accept-Language to prefer Chinese, and the module description emphasizes Chinese Wikipedia and Chinese sources by default. This imposes a locale/language preference at runtime rather than offering the user a clear opt-in choice for request language behavior.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script sends user-supplied book titles to multiple third-party services as part of URL construction and search queries, which can disclose potentially sensitive reading interests or research topics without an explicit privacy warning. In this skill's context, network exfiltration is the core behavior, so the main risk is privacy leakage rather than technical compromise.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The module docstrings and all user-facing CLI messages are written only in Chinese, indicating the skill is designed around a single language/locale with no visible option for user choice. Under the stated policy, forcing a specific language without opt-in is a natural-language policy concern unless the locale restriction is explicitly justified.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module documentation says step 2 is 'LLM(本进程内)结构化抽取 9 字段', implying an in-process LLM performs structured extraction. In the implementation, extract_fields merely combines existing values from sources and optional pdf_data, with no LLM invocation or model-based extraction anywhere in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The script writes fetched web content and PDF-extracted content to local report files automatically, without explicit confirmation, minimization, or sensitivity checks. In this skill context, users may provide private PDFs or search targets, so silent persistence can expose personal, copyrighted, or confidential data to other local users, backups, sync agents, or later unintended disclosure.

Content

No source excerpt is available for this finding.

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · book-report/sources/cache/wiki_en__The_Old_Man_and_the_Sea.html (reported line 742)May include surrounding context.

html
</p><p>Many critics have drawn parallels not only between Santiago and St. James, but between Santiago and <a href="/wiki/Jesus" title="Jesus">Jesus</a> himself, especially with regard to Christ's <a href="/wiki/Passion_of_Jesus" title="Passion of Jesus">Passion</a> and <a href="/wiki/Crucifixion_of_Jesus" title="Crucifixion of Jesus">crucifixion</a>. Melvin Backman outlines several, beginning with the Santiago's wish to "rest gently ... against the wood and think of nothing"; Sylvester, Grimes, and Hays also cite the preceding scene, in which Santiago is cut and bleeds from near the eye, as a <a href="/wiki/Stigmata" title="Stigmata">stigmatic</a> evocation of the wounds inflicted by the <a href="/wiki/Crown_of_thorns" title="Crown of thorns">crown of thorns</a>.<sup id="cite&#95;ref-FOOTNOTEBackman1962142SylvesterGrimesHays201869&#95;47-0" class="reference"><a href="#cite_note-FOOTNOTEBackman1962142SylvesterGrimesHays201869-47"><span class="cite-bracket">&#91;</span>47<span class="cite-bracket">&#93;</span></a></sup> An often-cited passage occurs when Santiago spots two sharks:<sup id="cite&#95;ref-FOOTNOTEBackman1962143Oliver199957,&#95;247Waldmeir1962144&#95;48-0" class="reference"><a href="#cite_note-FOOTNOTEBackman1962143Oliver199957,_247Waldmeir1962144-48"><span class="cite-bracket">&#91;</span>48<span class="cite-bracket">&#93;</span></a></sup>
</p>
<style data-mw-deduplicate="TemplateStyles:r1244412712">.mw-parser-output .templatequote{overflow:hidden;margin:1em 0;padding:0 32px}.mw-parser-output .templatequotecite{line-height:1.5em;text-align:left;margin-top:0}@media(min-width:500px){.mw-parser-output .templatequotecite{padding-left:1.6em}}</style><blockquote class="templatequote"><p>"Ay," he said aloud. There is no translation for this word and perhaps it is just a noise such as a man might make, involuntarily, feeling the nail go through his hands and into the wood.</p></blockquote>
<p>This passage was characterized by Sylvester, Grimes, and Hays as "a c
...[truncated 26 chars]

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · book-report/sources/cache/wiki_en__The_Old_Man_and_the_Sea.html (reported line 1185)May include surrounding context.

html
<li><i><a href="/wiki/James_(novel)" title="James (novel)">James</a></i> by <a href="/wiki/Percival_Everett" title="Percival Everett">Percival Everett</a> (2025)</li>
<li><i><a href="/wiki/Angel_Down_(novel)" title="Angel Down (novel)">Angel Down</a></i> by <a href="/wiki/Daniel_Kraus_(author)" title="Daniel Kraus (author)">Daniel Kraus</a> (2026)</li></ul>
</div></td></tr></tbody></table></div>
<div class="navbox-styles"><link rel="mw-deduplicated-inline-style" href="mw-data:TemplateStyles:r1333133064" /><link rel="mw-deduplicated-inline-style" href="mw-data:TemplateStyles:r1353707246" /></div><div role="navigation" class="navbox authority-control" aria-labelledby="Authority&#95;control&#95;databases&#95;frameless&amp;#124;text-top&amp;#124;10px&amp;#124;alt=Edit&#95;this&#95;at&#95;Wikidata&amp;#124;link=https&amp;#58;//www.wikidata.org/wiki/Q26505#identifiers&amp;#124;class=noprint&amp;#124;Edit&#95;this&#95;at&#95;Wikidata1853" style="padding:3px"><table class="nowraplinks hlist mw-collapsible autocollapse navbox-inner" style="border-spacing:0;background:transparent;color:inherit"><tbody><tr><th scope="col" class="navbox-title" colspan="2"><div id="Authority&#95;control&#95;databases&#95;frameless&amp;#124;text-top&amp;#124;10px&amp;#124;alt=Edit&#95;this&#95;at&#95;Wikidata&amp;#124;link=https&amp;#58;//www.wikidata.org/wiki/Q26505#identifiers&amp;#124;class=noprint&amp;#124;Edit&#95;this&#95;at&#95;Wikidata1853" style="font-size:114%;margin:0 4em"><a href="/wiki/Help:Authority_control" title="Help:Authority control">Authority control databases</a> <span class="mw-valign-text-top noprint" typeof="mw:File/Frameless"><a href="https://www.wikidata.org/wiki/Q26505#identifiers" title="Edit this at Wikidata"><img alt="Edit this at Wikidata" src="//upload.wikimedia.org/wikipedia/en/thumb/8/8a/OOjs_UI_icon_edit-ltr-progressive.svg/20px-OOjs_UI_icon_edit-ltr-progressive.svg.png" decoding="async" width="10" height="10" class="mw-file-element" data-file-width="20" data-fi
...[truncated 26 chars]

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The HTTP headers hard-code Accept-Language: zh-CN,zh;q=0.9,en;q=0.8, which imposes a specific locale preference on all requests. This is a natural-language policy concern because the skill does not offer the user a language choice or document a justified region-specific requirement.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
book-report/lib/render.py:51