Back to skill

Security audit

Local Document Ingest

Security checks for vulnerabilities and agentic risk

Overview

The skill matches its stated KB-ingestion purpose, but unsafe trust in payload-supplied paths and Gitea settings could expose local files, overwrite writable files, or leak the Gitea bot token.

Install only in a controlled backend where task payloads are trusted or normalized. Before use, require fixed allowlisted Gitea origins, restrict storagePath and resultFile to approved directories after resolving symlinks, use a narrowly scoped bot token, run the skill under a low-privilege account, and pin dependencies with hashes.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gitea_api.py:13
Finding

Payload-Controlled Gitea Endpoint Exposes the Bot Authentication Token

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/local_file_reader.py:152
Finding

Unrestricted storagePath Enables Arbitrary Local-File Read and Exfiltration

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/task_io.py:30
Finding

Payload-Controlled resultFile Permits Arbitrary Writable-File Overwrite

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding

Non-Reproducible Dependency Installation Without Hash Verification

Content
View full analysis
=4.3,<6 ``` ```bash #!/usr/bin/env bash set -euo pipefail cd "$(dirname "$0")" test -f SKILL.md test -f scripts/run_task.py python3 -m pip install -r requirements.txt python3 -m py_compile scripts/*.py echo "local_document_ingest skill is ready" ``` ### Technical Analysis The setup script installs any `pypdf` release satisfying `>=4.3,<6`. No exact version or package hash is specified, and the script does not select a trusted package index explicitly. As a result, the code reviewed during one installation may differ from the dependency installed later. Package installation can execute package build or installation logic, so compromise of the selected package release or configured package index can affect the host before the Skill is used. This is a supply-chain hardening issue rather than evidence that the current `pypdf` package is malicious. ### Attack Path 1. The environment runs `setup.sh`. 2. Pip queries its configured package index and resolves the newest matching `pypdf` release. 3. A compromised index, compromised matching release, or unsafe index configuration supplies an altered distribution. 4. Pip downloads and installs that distribution without comparing it against a project-approved hash. 5. Malicious installation logic or runtime code executes with the privileges of the setup or Skill process. 6. Subsequent PDF ingestion imports the installed package through: ```python import pypdf ``` ### Impact Assessment A compromised dependency could execute code with the setup process's privileges and gain access to: - Gitea environment credentials. - Uploaded documents. - The shared task directory. - Writable pro ...[truncated 210 chars]
Remediation
View remediation
``` 2. Generate and verify hashes for every accepted distribution, then install with: ```bash python3 -m pip install --require-hashes -r requirements.txt ``` 3. Use a lockfile or fully resolved requirements file for all direct and transitive dependencies. 4. Configure a trusted internal or explicitly approved package index rather than relying on ambient pip configuration. 5. Prefer prebuilt, reviewed wheels and prohibit unexpected source builds in production. 6. Run dependency installation in an isolated build stage without production credentials, then deploy the resulting immutable environment. 7. Add automated dependency vulnerability and provenance scanning to the release process. ]]>
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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (19)

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

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

Content

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

md
---
name: local_document_ingest
description: Ingest desktop-uploaded local files into the Research KB. Use for local folder scan tasks where OpenClaw must read backend shared-file paths, understand each changed file, create a type-specific entity wiki page for every readable file, archive originals under source_files, update related pages, synthesize concept/resource pages, maintain links/catalog/index metadata, and return backend task JSON.
---

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill directs the agent to create and update repository content, archive files, and modify catalog/index metadata, but it does not include a clear user-facing acknowledgement that it will perform persistent writes to the knowledge base. In an agent setting, silent repository modification increases the risk of unintended data changes, accidental overwrites, and surprise side effects from processing uploaded local files.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The manifest does not prominently warn that the skill archives local source files and writes content to Gitea, even though those are significant side effects involving persistence and potential data exfiltration from a local desktop context. Without explicit disclosure, users or orchestrators may invoke the skill assuming analysis-only behavior, causing confidential files to be copied and published unexpectedly.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The upsert_bytes method performs a remote file create/update via a PUT request to the Gitea contents API, which can modify repository data. The code contains no confirmation prompt, print/log message, or explanatory comment/docstring warning the user that repository contents will be written.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The inline intent signals repeatedly frame the operation as local document ingestion (for example the ValueError messages at L055/L065 and generatedBy at L308), which implies a narrower ingest/registration role. In practice, apply_pages not only ingests local source files but also creates or updates arbitrary KB markdown pages under multiple content roots, merges catalog entries, and rewrites top-level catalog.json and index.md, which is materially broader than the documented intent.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This function archives all source files and then writes multiple repository files via upsert_text, which affects user data and persists content remotely. In this code file there is no confirmation prompt, print/log disclosure, or comment/docstring warning explaining that readable local inputs will be copied into source_files/, catalog.json, and index.md.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The function reads arbitrary local file bytes from paths supplied in input metadata and uploads them to the remote Gitea client without validating that the path is within an approved local workspace. If an attacker can influence storagePath or item metadata, this can exfiltrate sensitive local files to the repository, turning the agent into a local file disclosure channel.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

The function reads repository content through GiteaClient and combines it with data derived from local uploads, meaning local-derived metadata can influence network-backed retrieval and expand the scope of accessed content beyond the uploaded files. In a local document ingestion context, this is more sensitive because users may expect processing to stay local to selected files, while the code also fetches index and catalog data from a remote repository without any trust boundary checks or disclosure in this layer.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The code derives tokens from uploaded item titles and paths, then uses those tokens to search catalog pages and fetch related page contents from the repository. This creates a cross-boundary data flow where local input influences remote content access, potentially revealing sensitive filenames/topics to the repository service and broadening the context with unrelated or overprivileged content. The skill context makes this more dangerous because it is framed as local-folder ingestion, so users may not anticipate this remote enrichment step.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code extracts text from arbitrary local files and places previews, structure, and metadata into the returned payload, which can expose user data from uploaded documents. There is no confirmation prompt, user-facing log/print, or inline comment/docstring warning that local file contents will be read and propagated for downstream processing.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructions and headings are presented in Chinese, and no alternative language option or opt-in is offered. Under the stated policy, forcing a specific language without user choice is a natural-language policy concern unless clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The manifest describes a skill that processes local folder contents and performs downstream repository writes, but it does not define clear activation boundaries or usage constraints. In an agentic environment, vague invocation criteria can cause the skill to be selected in inappropriate contexts, leading to unintended ingestion of sensitive local files and unauthorized publication into the knowledge base.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pypdf has 16 known advisory(ies) (CVE-2026-84310 (pypdf: Possible long runtimes/large memory usage when retrieving outlines); CVE-2026-48156 (pypdf: Possible long runtimes for zero-only width values in cross-reference stre); CVE-2026-24688 (pypdf has possible Infinite Loop when processing outlines/bookmarks) +13 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is only range-pinned as pypdf>=4.3,<6, so the actual installed version may vary and could include releases affected by known advisories. For a document-ingest skill that processes untrusted PDFs, this matters because several cited issues involve denial-of-service conditions such as excessive CPU, memory use, or infinite loops during PDF parsing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code reads GITEA_BOT_TOKEN from the environment and later uses it for authenticated API requests. There is no nearby comment, docstring, or user-facing notice explaining that the skill consumes a credential from environment variables.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

The _request method sends HTTP requests to a configured Gitea server, transmitting repository paths, commit messages, and authenticated requests. The code does not include a confirmation, log/print statement, or explanatory comment/docstring indicating that external network communication occurs.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

The relation labels are hard-coded in Chinese, which forces generated content into a specific language regardless of user preference. The file does not provide any user opt-in, locale selection, or documented region-specific justification for this language constraint.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

append_relation_section inserts Chinese headings such as 关联页面, and render_source_registration emits Chinese explanatory text, creating user-visible output in a fixed language. Because no locale choice or explicit justification is present, this conflicts with the language/locale policy criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
71% confidence
Finding

The sample output uses the fixed title pattern "论文:Example", which suggests a Chinese-language labeling convention for generated content. There is no nearby indication that language is user-selectable or that the locale is intentionally constrained for a region-specific use case.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

The function writes JSON output to an arbitrary filesystem path and creates parent directories if needed, but there is no confirmation prompt, logging, print statement, or explanatory comment/docstring disclosing this behavior. For a code file, file writes should have some visible warning unless the behavior is otherwise documented.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.