T09 · Insecure Skill Coding Practices
- Location
scripts/gitea_api.py:13- Finding
Payload-Controlled Gitea Endpoint Exposes the Bot Authentication Token
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
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.
scripts/gitea_api.py:13Payload-Controlled Gitea Endpoint Exposes the Bot Authentication Token
scripts/local_file_reader.py:152Unrestricted storagePath Enables Arbitrary Local-File Read and Exfiltration
scripts/task_io.py:30Payload-Controlled resultFile Permits Arbitrary Writable-File Overwrite
requirements.txt:1Non-Reproducible Dependency Installation Without Hash Verification
Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.
---
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.
---
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
No suspicious patterns detected.