Back to skill

Security audit

Document Learning

Security checks for vulnerabilities and agentic risk

Overview

The skill has a coherent document-learning purpose, but it asks agents to persist document-derived notes into long-term memory with too little scoping or user control.

Review this skill before installing if you may use it on private, proprietary, regulated, or prompt-bearing documents. Use it only with documents you are comfortable having summarized into persistent memory, and manually inspect or avoid MEMORY.md and memory/YYYY-MM-DD.md entries unless the skill is updated with confirmation, redaction, source labeling, and deletion controls.

Vulnerability Patterns
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T02 · Agent Memory Poisoning

Error
Location
SKILL.md:43
Finding

Untrusted Document Content Can Poison Persistent Agent Memory

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:43-56; references/memory_integration.md:21-36
Vulnerability Type: Persistent storage of untrusted document-derived content
Risk Level: High

Vulnerable Content

SKILL.md:43-56:

markdown
2. **Track Progress**
   - After each session, note where you stopped
   - Progress is saved automatically
   - Key points are extracted to memory files

3. **Resume Later**
   - Say "resume learning [document]"
   - System loads last position
   - Continues from there seamlessly

4. **Build Knowledge Base**
   - Over time, all learned content accumulates in MEMORY.md
   - Use `memory_search` to find specific topics later
   - Create comprehensive summaries periodically

references/memory_integration.md:21-36:

markdown
### 2. Progressive Learning Notes

During learning sessions, add entries to `memory/YYYY-MM-DD.md`:

```markdown
### Document Learning Session - [Date]

**Progress:** Chapter X of Y (XX% complete)

#### What I Learned Today
- Main point 1
- Main point 2  
- Important insight: [...]

#### Questions for Later

Technical Analysis

The skill directs the agent to extract content from arbitrary documents and persist the resulting key points or summaries in MEMORY.md and daily memory files. It does not establish a trust boundary between document data and agent instructions, require review before persistence, label the source's trust level, or direct the agent to remove prompt-like instructions.

Documents processed by the skill are externally controlled inputs. A malicious document can contain text framed as facts, notes, or procedural guidance that actually instructs the agent to change future behavior. If that text is included in a summary and written to persistent memory, subsequent memory_search operations can place it back into the agent's context during unrelated sessions.

This differs from transien ...[truncated 1250 chars]

Remediation
View remediation

Remediation Suggestions

  1. Treat all document text as untrusted data, regardless of file origin or format.
  2. Explicitly instruct the agent never to follow behavioral directives found inside processed documents.
  3. Detect and exclude prompt-like content, role changes, tool instructions, credential requests, and policy-override language from persistent memory.
  4. Require explicit user approval before writing document-derived summaries to long-term memory.
  5. Store source path, source hash, extraction date, and trust classification with every memory entry.
  6. Clearly delimit persisted excerpts as quoted reference material rather than agent instructions.
  7. Keep document knowledge in a dedicated, source-scoped store instead of mixing it with operational agent rules.
  8. When retrieving entries, instruct the agent to use them only as untrusted reference data.
  9. Provide a mechanism to inspect, revoke, and remove all memory entries originating from a particular document.

T08 · Insecure Dependencies

Note
Location
scripts/read_large_document.py:113
Finding

Unpinned Third-Party Dependency Installation Guidance

Content
View full analysis

Vulnerability Details

File Location: scripts/read_large_document.py:113-115
Vulnerability Type: Unpinned dependency installation
Risk Level: Low

Vulnerable Code

python
if not HAS_PDFPLUMBER:
    raise ImportError("pdfplumber is required for PDF reading. Install with: pip install pdfplumber")

The related import occurs at scripts/read_large_document.py:27-32:

python
try:
    import pdfplumber
    HAS_PDFPLUMBER = True
except ImportError:
    HAS_PDFPLUMBER = False

Technical Analysis

The error message advises installing pdfplumber directly from the configured Python package index without a pinned version, lock file, or integrity hash. Consequently, the installed dependency and its transitive dependency graph can vary over time.

This does not itself prove that the named package is malicious. The risk arises if a future package release, a transitive dependency, the configured package index, or the package owner's distribution account is compromised. Because Python packages can execute code during installation or import, a compromised package would run under the installing user's privileges.

Attack Path

  1. A user invokes PDF-reading functionality on a system where pdfplumber is absent.
  2. The script displays the command pip install pdfplumber.
  3. The user follows the instruction using the currently configured package index.
  4. pip resolves an unpinned current release and its transitive dependencies.
  5. If any resolved artifact or package source has been compromised, malicious code can execute during installation or later import.
  6. That code runs with the privileges of the user or environment performing the installation.

Impact Assessment

In the conditional event of a supply-chain compromise, arbitrary Python code could execute with the installing user's privileges. Potential scope includes files, credentials, environment variables, and network r ...[truncated 222 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add a reviewed dependency manifest or lock file with an exact pdfplumber version.
  2. Pin all transitive dependencies where practical.
  3. Generate and verify package hashes, such as with pip --require-hashes.
  4. Install dependencies in an isolated virtual environment with minimal privileges.
  5. Use a trusted internal package mirror or an allowlisted package repository.
  6. Perform dependency vulnerability and provenance checks during release preparation.
  7. Replace the generic installation command with a reference to the project's verified installation procedure.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/multi_doc_progress.py:489
Finding

Imported Progress Store Is Accepted Without Schema or Type Validation

Content
View full analysis

Vulnerability Details

File Location: scripts/multi_doc_progress.py:489-496
Vulnerability Type: Unvalidated structured-data import
Risk Level: Medium

Vulnerable Code

python
elif args.command == 'import':
    if not os.path.exists(args.input_file):
        raise FileNotFoundError(f"Import file not found: {args.input_file}")

    with open(args.input_file, 'r', encoding='utf-8') as f:
        store = json.load(f)

    save_progress_store(store)
    print(f"✅ Progress imported from {args.input_file}")

The imported object is subsequently saved by scripts/multi_doc_progress.py:65-74:

python
def save_progress_store(data: Dict[str, Any]) -> None:
    """Save the global progress store."""
    current_dir = os.getcwd()
    store_file = os.path.join(current_dir, PROGRESS_STORE_FILE)

    data['last_updated'] = str(datetime.now())

    with open(store_file, 'w', encoding='utf-8') as f:
        json.dump(data, f, indent=2, ensure_ascii=False)

Technical Analysis

The import command parses attacker-influenced JSON and immediately treats the result as the authoritative progress store. It does not verify that the top-level value is an object, confirm the required documents structure, validate nested field types, constrain path values, reject unknown fields, enforce size or nesting limits, or preserve the existing store before replacement.

For example, a top-level array or scalar can trigger an exception when save_progress_store() attempts data['last_updated']. A syntactically valid but structurally malicious object can replace legitimate document records with misleading paths, positions, titles, statuses, or oversized values. Later code assumes specific nested keys and types, which can produce crashes or corrupted status calculations.

The JSON parser does not execute code, so this issue does not independently provide arbitrary code execution. Its direct security effects co ...[truncated 1100 chars]

Remediation
View remediation

Remediation Suggestions

  1. Define and enforce a strict schema for the complete progress-store format.
  2. Require the top-level value to be an object containing a documents object.
  3. Validate every nested field, including allowed keys, strings, integers, lists, dates, statuses, and paths.
  4. Reject negative positions, unreasonable page counts, invalid status values, excessive nesting, and oversized files or fields.
  5. Normalize document paths and clearly warn before accepting paths outside expected directories.
  6. Import into a temporary in-memory structure and only replace the active store after successful validation.
  7. Back up the existing progress file before replacement and use atomic file replacement.
  8. Present an import summary and require confirmation before overwriting or merging existing records.
  9. Handle malformed input with concise errors rather than emitting full tracebacks.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code substantially supports document reading, resume capability, and multi-document progress tracking via a local JSON store. However, a key part of the declared description is missing: there is no code that writes learned knowledge to MEMORY.md or integrates with any long-term memory system. The script only extracts key points and prints them; it does not persist them as retained knowledge. Additionally, while it does support limited chunked reading for PDFs and progress persistence, the implementation is narrower than the declared 'comprehensive document learning system' with permanent memory integration. Therefore the description overstates important capabilities the code does not actually provide.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code substantially matches the core idea of reading documents, supporting resume, and persisting basic progress. However, key parts of the declared description are not implemented. Most notably, there is no code that writes to MEMORY.md or performs any long-term memory integration, despite that being a prominent part of the declared purpose. The script does extract key points, but it only prints them or includes them in optional JSON output; it does not store them for future retention. Additionally, although the description emphasizes chunked processing for large files, the implementation reads entire text files into memory and concatenates all PDF page text, while the chunk_size parameter is effectively unused in processing. The bookmarking/progress functionality is also more limited than described, storing only a numeric last position rather than richer chapter/page bookmarks. Therefore, the description overstates important capabilities, creating a meaningful mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill advertises behavior that reads and writes files, including persistent progress and memory artifacts, but does not declare any explicit tool scope or permissions boundary. That increases the chance of overbroad file access and makes it harder for users or the runtime to understand and constrain what the skill may persist or modify.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill describes automatic storage of learned content into MEMORY.md and dated notes without warning the user that document-derived content will be retained persistently. This can cause sensitive information from private documents, filenames, or notes to be stored beyond the immediate session and later surfaced unexpectedly.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill encourages broad accumulation and later retrieval of learned document content without restricting sensitive material such as credentials, proprietary documents, regulated data, or personal information. This creates a durable secondary store of user-provided content that may be queried later out of context or exposed to other workflows.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The workflow examples normalize automatic saving of progress and summaries but omit any notice about retention of filenames, bookmarks, and extracted content. In practice, users may paste confidential manuals, internal docs, or personal files and not realize that derivative data will remain on disk for later retrieval.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The examples normalize keeping complete learning history and searchable notes across multiple documents, which increases the risk of cross-document exposure of user-supplied sensitive content. In this context, a document-learning skill is especially likely to process proprietary manuals, internal references, and personal files, so unrestricted retention materially raises privacy and confidentiality risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The guide states that progress tracking begins and an initial summary is saved to memory, but it does not warn users that data will be persisted. This can lead to silent retention of document-derived content and metadata, which is especially risky when documents contain sensitive, proprietary, or personal information.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The trigger phrase "Continue from last position" is broad and resembles normal conversational language, which can cause unintended invocation of document-learning behavior. In an agent environment, accidental activation could make the system read, resume, or update progress for documents and persist notes when the user did not intend to use this skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The reset instructions tell users to delete the progress file directly without warning that this action is irreversible. This creates a realistic risk of accidental loss of learning state, bookmarks, and notes, especially for non-technical users following the documentation literally.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill manifest describes a system that resumes learning sessions and automatically stores learned knowledge into MEMORY.md for permanent retention. In this file, the implemented behavior is limited to reading documents, extracting key points for console output, and persisting progress in .multi_doc_learning_progress.json or exported JSON; there is no MEMORY.md access or memory-integration logic.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The module docstring and manifest describe knowledge extraction for long-term memory and automatic storage into MEMORY.md, but the script only extracts key points into an in-memory result object or optional JSON output. There is no code that reads or writes MEMORY.md or performs any persistent knowledge-base integration.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The manifest and docstring advertise chunked reading for large file handling, and the CLI exposes a --chunk_size option, but text files are read entirely with f.read() and PDFs are processed page-by-page without using the chunk_size parameter. This means the core advertised large-file/chunked-processing behavior is not actually implemented.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The manifest describes reading documents, tracking progress, resuming later, and storing learned knowledge, but this guide additionally presents a broader workflow for managing multiple documents simultaneously and querying status across all tracked documents. That is a meaningful capability expansion at the documented behavior level, even though it is adjacent to the core purpose.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The status-query phrase "What's my progress on all documents?" is overly broad and could be matched during ordinary conversation. If invoked unintentionally, it may reveal tracked document names, reading history, or learning activity across documents, which is a privacy issue even if the exposed data is limited.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The module documentation says the script manages switching between documents and resuming from last position, implying maintained multi-document context. However, the 'switch' command merely looks up a document and prints its title and last position without recording an active document or changing subsequent behavior, so the documented capability overstates what the code actually does.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The script silently writes document-reading progress and document path metadata to a hidden file in the document directory. In a document-learning skill, this can expose sensitive filenames, locations, and reading history to other local users, synced folders, or repositories, especially because the behavior is not clearly surfaced to the user at runtime.

Content

No source excerpt is available for this finding.