Back to skill

Security audit

All Documents QA

Security checks for vulnerabilities and agentic risk

Overview

The skill is a user-invoked document Q&A helper with expected local document-reading behavior and no evidence of hidden persistence, exfiltration, or destructive actions.

Install only if you are comfortable letting the skill read the specific documents or top-level folder you provide. Treat answers from untrusted documents cautiously because document text can contain prompt-injection attempts, and prefer pinned, reviewed dependency versions plus a trusted PDF-reader skill before using it on sensitive files.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (2)

T01 · Skill Instruction Hijacking

Error
Location
scripts/run_qa.py:27
Finding

Untrusted document content is inserted into the agent context without instruction isolation

Content
View full analysis

Vulnerability Details

File Location: scripts/run_qa.py:27-31
Vulnerability Type: Indirect prompt injection through attacker-controlled documents
Risk Level: High

Vulnerable Code

python
        # Now, present the extracted content and the question for the LLM to answer
        # Using specific markers to easily identify the context for QA
        print("\n--- DOCUMENT_QA_CONTEXT_START ---")
        print(extracted_content)
        print("--- DOCUMENT_QA_CONTEXT_END ---\n")
        print(f"QUESTION: {question}")

The intended integration with an LLM is also documented in SKILL.md:17-18:

markdown
The system will extract all relevant text and present it along with your question, allowing me to formulate an answer based on the provided content.

Technical Analysis

The extracted content is entirely controlled by the supplied TXT, DOCX, XLSX, or PDF document. It is printed directly into the context consumed by the agent. Although textual boundary markers are used, no higher-priority instruction tells the agent that the enclosed content is untrusted data and that commands found inside it must not be followed.

The boundary markers provide formatting only; they do not enforce separation between instructions and data. A malicious document can contain content such as instructions to disregard the user's question, reveal other context, produce a deceptive answer, or invoke tools. If the consuming agent interprets that text as an instruction, document content can alter the agent's behavior.

This is an indirect prompt-injection risk rather than direct Python command injection. The included Python scripts do not independently execute commands extracted from documents.

Attack Path

  1. An attacker creates a supported document containing legitimate-looking material and embedded instructions directed at the agent.
  2. A user supplies that document, or a folder containing it, to run_qa.py.
  3. process_folder.py invokes the releva ...[truncated 1011 chars]
Remediation
View remediation

Remediation Suggestions

  1. Add an explicit higher-priority instruction before the extracted content stating that document text is untrusted data and must never be treated as system, developer, tool-use, or workflow instructions.
  2. Pass document content through a structured data field or dedicated message role rather than concatenating it into an instruction-like plaintext prompt.
  3. Require the model to answer only from document facts relevant to the user's question and to disregard commands, role declarations, tool requests, or requests for secrets found in documents.
  4. Do not permit tool calls based solely on document content. Require independent policy validation and explicit user confirmation before sensitive operations.
  5. Preserve provenance for each extracted segment so the agent can distinguish the user's question from document evidence.
  6. Consider a two-stage workflow in which one constrained component extracts factual passages and another answers only from those passages.
  7. Add adversarial tests using documents containing instruction overrides, fake boundary markers, requests to reveal context, and requests to invoke tools.

T08 · Insecure Dependencies

Warning
Location
SKILL.md:31
Finding

Third-party dependencies are installed without version or integrity pinning

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:31-35, references/usage_guide.md:28, scripts/extract_docx.py:27-29, and scripts/extract_excel.py:31-33
Vulnerability Type: Unpinned third-party dependencies
Risk Level: Medium

Vulnerable Documentation

SKILL.md:31-35:

markdown
**Note:**
*   For PDF support, ensure the `iyeque-pdf-reader-1.1.0` skill is installed in your workspace.
*   For Excel support, you might need to install the `pandas` and `openpyxl` libraries if they are not already installed in your environment:
    `pip install pandas openpyxl`

references/usage_guide.md:28:

markdown
*   **Dependencies:** Ensure that the necessary Python libraries (`PyPDF2`, `python-docx`) are installed in your environment for PDF and DOCX extraction to work correctly. You might need to run `pip install PyPDF2 python-docx`.

scripts/extract_docx.py:27-29:

python
# NOTE: This script requires the python-docx library.
# If running in a new environment, you might need to install it:
# pip install python-docx

scripts/extract_excel.py:31-33:

python
# NOTE: This script requires the pandas library.
# If running in a new environment, you might need to install it:
# pip install pandas openpyxl

Technical Analysis

The project recommends installing packages by name without exact versions, hashes, or a reviewed lockfile. Consequently, the resolved package set can change between installations. Transitive dependencies are also unconstrained.

No evidence was found that the named packages are currently malicious. The security issue is that the installation procedure does not provide reproducibility or integrity verification. If a package release, maintainer account, distribution channel, or transitive dependency is compromised, users following these commands may install attacker-controlled code.

The usage guide additionally recommends PyPDF2, while the included implementation delegates PDF handling to an external s ...[truncated 1097 chars]

Remediation
View remediation

Remediation Suggestions

  1. Add a reviewed dependency manifest with exact versions, such as a locked requirements.txt generated from a controlled environment.
  2. Use package hashes and install with hash verification, for example through pip install --require-hashes.
  3. Pin transitive dependencies, not only direct dependencies.
  4. Retrieve packages exclusively from an approved index over authenticated TLS and prevent fallback to untrusted indexes.
  5. Remove PyPDF2 from the documentation unless it is actually required by the implementation.
  6. Document the exact, audited version and integrity source for the external PDF-reader skill.
  7. Run dependency vulnerability and provenance checks in CI, and review lockfile changes before release.
  8. Install and execute document parsers in a least-privileged, isolated environment because document-processing libraries handle attacker-controlled input.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (16)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose describes a broader document-question-answering skill over multiple file types and possibly folders. The actual code only performs basic text extraction from one DOCX file using python-docx and prints the result. While DOCX extraction could be a supporting component of such a skill, this code chunk by itself does not implement the core declared behavior and omits several stated capabilities, so the description does not accurately represent this code chunk.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is a document question-answering skill over uploaded PDF, DOCX, and TXT files or folders. The actual code only reads an Excel file using pandas, converts each sheet to a string, and prints the extracted content. There is no logic for answering questions, handling uploaded documents, processing folders, or supporting the declared file types. This is a material mismatch in primary purpose and supported resources.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The declared description promises a document question-answering skill across multiple file types and scopes. The actual code chunk is a narrow utility that extracts text from one TXT file and outputs it. While text extraction from TXT could be a supporting subcomponent of such a system, this chunk alone does not implement the primary declared purpose and lacks several claimed capabilities (Q&A, PDF/DOCX handling, folder support). Therefore, the description does not accurately represent what this supplied code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The code shown is a preprocessing/extraction utility. It accepts a file or directory path, invokes helper scripts to extract content from PDF, DOCX, TXT, and XLSX files, and prints or aggregates the extracted text. This does align partially with the document-ingestion aspect of the description, including support for individual files and folders. However, the declared purpose says the skill answers questions based on uploaded documents, while this code does not implement any question-answering behavior; it only extracts content. Additionally, the code supports .xlsx files, which are not mentioned in the declared description. These are material mismatches in primary behavior and supported capability.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
92% confidence
Finding

The skill instructs users to invoke a local Python script on arbitrary file or folder paths, which implies shell execution and file-reading capability, but the manifest does not declare any tool scope or permissions. This creates a trust and review gap: operators cannot accurately assess what the skill can access, and the skill could be used to read sensitive local content without clear upfront disclosure.

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 supports folder inputs yet does not warn that this may recursively or broadly read large amounts of document content, including potentially sensitive files. In a local-workspace context, that increases the risk of accidental data overcollection, privacy exposure, and performance/resource exhaustion if pointed at large or sensitive directories.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The implementation supports .xlsx files even though the skill description only advertises PDF, DOCX, and TXT. This mismatch can hide an unexpectedly larger attack surface from reviewers and users, especially because spreadsheet parsers often have distinct parsing risks and dependency chains when handling untrusted content.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/process_folder.py (reported line 41)May include surrounding context.

python
all_extracted_text.append(f"Error: PDF reader script not found at {pdf_reader_script_path}\n")
                    continue
                try:
                    result = subprocess.run([sys.executable, pdf_reader_script_path, "extract", file_path], capture_output=True, text=True, check=True)
                    all_extracted_text.append(f"--- Content from {filename} ---\n")
                    all_extracted_text.append(result.stdout)
                    all_extracted_text.append("\n")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
86% confidence
Finding

The skill executes other Python scripts as part of document processing, including a cross-skill dependency for PDFs. In a document-QA context, this increases risk because untrusted documents are being handed off to additional parser code, broadening the trusted computing base and making dependency compromise, parser RCE, or unsafe script replacement more impactful.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/process_folder.py (reported line 56)May include surrounding context.

python
script_path = os.path.join(current_script_dir, script_name)
                
                try:
                    result = subprocess.run([sys.executable, script_path, file_path], capture_output=True, text=True, check=True)
                    all_extracted_text.append(f"--- Content from {filename} ---\n")
                    all_extracted_text.append(result.stdout)
                    all_extracted_text.append("\n")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/process_folder.py (reported line 94)May include surrounding context.

python
print(f"Error: PDF reader script not found at {pdf_reader_script_path_main}", file=sys.stderr)
                    sys.exit(1)
                try:
                    result = subprocess.run([sys.executable, pdf_reader_script_path_main, "extract", target_path], capture_output=True, text=True, check=True)
                    print(result.stdout)
                except subprocess.CalledProcessError as e:
                    print(f"Error processing {target_path}: {e.stderr}", file=sys.stderr)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/process_folder.py (reported line 112)May include surrounding context.

python
if script_name:
                    script_path = os.path.join(current_script_dir, script_name)
                    try:
                        result = subprocess.run([sys.executable, script_path, target_path], capture_output=True, text=True, check=True)
                        print(result.stdout)
                    except subprocess.CalledProcessError as e:
                        print(f"Error processing {target_path}: {e.stderr}", file=sys.stderr)

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/run_qa.py (reported line 18)May include surrounding context.

python
try:
        # Execute process_folder.py to get all text content
        print(f"Extracting text from: {document_path}")
        result = subprocess.run(
            [sys.executable, process_folder_script_path, document_path],
            capture_output=True,
            text=True,

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description and opening documentation state the skill answers questions over PDF, DOCX, and TXT documents, but the supported-types section later claims .xlsx support as well. This creates a semantic mismatch about the actual scope of document formats the skill is supposed to handle.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The description says the skill 'answers questions based on the content of uploaded documents' and the usage section broadly instructs users to run it on a file or folder, but it does not define any trigger phrases, exclusions, or negative examples. In a markdown skill description, this can make activation scope ambiguous because it is unclear what kinds of document-questioning requests should or should not invoke this skill.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest says the skill answers questions based on uploaded documents in PDF, DOCX, and TXT formats, but this script extracts text from Excel files via pandas. Supporting spreadsheet ingestion is a meaningful behavior expansion beyond the listed document types in the manifest.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.