Back to skill

Security audit

Book Reader - Learn & Grow Every Day

Security checks for vulnerabilities and agentic risk

Overview

This book-reader skill is mostly coherent, but it contains a real unsafe input-handling flaw that can turn a page-count argument into local command execution.

Review before installing. Use public-domain or owned books, avoid untrusted download URLs, install Python dependencies in a pinned virtual environment, and do not let untrusted content choose command arguments such as --pages until the arithmetic input validation issue is fixed.

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

Error
Location
book-reader.sh:154
Finding

Command Injection Through Unvalidated Arithmetic Input

Content
View full analysis

Vulnerability Details

File Location: book-reader.sh:154-155, 211-216
Vulnerability Type: Bash arithmetic expression injection
Risk Level: High

Vulnerable code:

bash
# Calculate chunk
local chunk_size=$((pages * chars_per_page))
local end_offset=$((offset + chunk_size))

The pages value reaches the arithmetic expression from command-line input without validation:

bash
read)
    pages=50
    if [[ "$3" == "--pages" ]]; then
        pages="${4:-50}"
    fi
    read_book "${2:-}" "$pages"
    ;;

Technical Analysis

The fourth command-line argument is assigned directly to pages and subsequently evaluated by Bash inside an arithmetic expansion:

bash
$((pages * chars_per_page))

Bash recursively interprets variable values referenced in arithmetic contexts as arithmetic expressions. Arithmetic syntax can include variable and array references whose subscripts may cause additional shell expansion. Consequently, treating untrusted text as an arithmetic operand can allow crafted input containing command substitution to execute shell commands.

Quoting the assignment does not prevent this issue because the dangerous interpretation occurs later, when the value is processed by the arithmetic expansion. The implementation does not verify that pages contains only a bounded positive decimal integer.

Attack Path

  1. An attacker obtains the ability to invoke book-reader.sh or influence arguments supplied by an Agent.
  2. The attacker supplies an existing supported book file and a malicious value after --pages.
  3. The command dispatcher assigns that value directly to pages at line 214.
  4. read_book references pages in the arithmetic expansion at line 154.
  5. Bash evaluates the attacker-controlled arithmetic expression, potentially executing embedded command substitution.
  6. The injected command runs with the same operating-system identity, environm ...[truncated 667 chars]
Remediation
View remediation

Remediation Suggestions

Validate the page count before it reaches any arithmetic context:

bash
if [[ ! "$pages" =~ ^[0-9]+$ ]]; then
    echo "Invalid page count: expected a positive integer" >&2
    exit 1
fi

if (( 10#$pages < 1 || 10#$pages > 1000 )); then
    echo "Invalid page count: allowed range is 1-1000" >&2
    exit 1
fi

pages=$((10#$pages))

Apply equivalent validation to every value loaded from external state before using it in arithmetic. In particular:

  • Accept only ASCII decimal digits.
  • Enforce practical upper bounds to prevent excessive memory or processing consumption.
  • Use the 10# prefix after validation to force decimal interpretation.
  • Reject malformed values rather than passing them to Bash arithmetic evaluation.
  • Add tests with shell metacharacters, arithmetic variable references, array subscripts, negative values, and excessively large integers.

T08 · Insecure Dependencies

Warning
Location
README.md:46
Finding

Unpinned Python Dependencies Installed from a Mutable Package Source

Content
View full analysis

Vulnerability Details

File Location: README.md:46-50; also documented in SKILL.md:51-57
Vulnerability Type: Unpinned third-party dependency installation
Risk Level: Medium

Vulnerable installation guidance:

bash
# Or use Python (alternative)
pip3 install ebooklib beautifulsoup4 lxml

The same unsafe installation pattern appears in SKILL.md:

bash
pip3 install ebooklib beautifulsoup4 lxml

Technical Analysis

The installation instructions retrieve the latest package versions available under the specified names from the active Python package index. No exact versions, artifact hashes, lock file, reviewed index, or isolated environment are specified.

Python package installation can execute package build-system code and install executable components. Because the selected artifacts can change after this skill has been audited, the effective installed code is not reproducible from the repository contents alone.

This creates supply-chain exposure if a dependency release or distribution account is compromised, if a malicious artifact is served by a configured package index, or if an incompatible or vulnerable future release is selected. The audit did not find evidence that the named packages are currently malicious; the issue is the unsafe and mutable dependency acquisition process.

Attack Path

  1. A user or Agent follows the documented installation command.
  2. pip3 resolves package versions using the environment's configured package index.
  3. The selected package artifacts and transitive dependencies are downloaded without repository-controlled version or hash verification.
  4. A compromised, substituted, or malicious artifact can execute build or installation logic and place code in the target Python environment.
  5. The installed package code is subsequently imported by the EPUB-processing path and executes with the privileges of the user running the skill.

Impact Ass

...[truncated 600 chars]

Remediation
View remediation

Remediation Suggestions

Replace the unconstrained command with a reproducible dependency process:

  1. Pin every direct and transitive dependency to a reviewed version.
  2. Record cryptographic hashes for all approved distributions.
  3. Install with pip --require-hashes from a committed requirements file.
  4. Use a dedicated virtual environment rather than the system Python environment.
  5. Document the approved package index explicitly and require HTTPS.
  6. Regularly scan and deliberately update pinned dependencies after security review.
  7. Prefer prebuilt, verified wheels where practical to reduce execution of arbitrary build logic.

Example workflow:

bash
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install --require-hashes -r requirements.txt

The requirements.txt file should contain exact versions and SHA-256 hashes for the approved artifacts.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (7)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 46)May include surrounding context.

bash
# Install dependencies (choose one)
sudo apt-get install pandoc          # Debian/Ubuntu/Raspberry Pi OS
brew install pandoc                  # macOS

# Or use Python (alternative)

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 54)May include surrounding context.

bash
# Install dependencies (choose one)
sudo apt-get install pandoc          # Debian/Ubuntu/Raspberry Pi OS
brew install pandoc                  # macOS

# Or use Python (alternative)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly points users to Anna's Archive for newer books while only adding a minimal 'check local laws' disclaimer. That guidance can facilitate access to copyrighted or untrusted content sources, creating legal exposure and potential safety risk from downloading files from unofficial repositories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill explicitly stores reading progress in a persistent JSON file containing book titles, file paths, bookmarks, and free-form notes, but it does not clearly warn users about this data collection/retention or discuss access controls. That can expose sensitive interests, local filesystem structure, and personal annotations to other local users, backups, or downstream tooling that reads the workspace memory directory.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The shell invokes python3 with a here-document only, but the embedded code accesses sys.argv[1] as if the EPUB filename had been supplied. This contradicts the surrounding implementation intent to extract text from the requested EPUB file and means the fallback path cannot do what the code indicates.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The script downloads content from arbitrary URLs and writes it directly to a chosen path, with no confirmation before overwrite and no validation that the destination is confined to the books directory. In this skill context, that creates a low-severity file integrity risk: a user or upstream workflow could accidentally overwrite local files or persist untrusted content in sensitive locations.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

At L169-L177, the script writes the current file path, reading offset, total characters, and timestamp into a JSON state file under the workspace. This is a data-affecting file write, but there is no user warning in the script's help text or nearby messaging that reading activity will be stored locally.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.