T09 · Insecure Skill Coding Practices
- Location
scripts/gitea_api.py:15- Finding
Payload-Controlled Gitea Endpoint Can Exfiltrate the Bot Token
- Content
View full analysis
- Remediation
View remediation
Security audit
Security checks for vulnerabilities and agentic risk
The skill is mostly coherent for a Gitea-backed knowledge-base assistant, but it handles powerful credentials and filesystem paths without enough containment.
Install only in an environment where backend payloads are trusted and where the bot token is tightly scoped. Before production use, require an allowlisted HTTPS Gitea host, constrain attachment and result paths to trusted directories, reject symlinks/traversal, and keep the bot account limited to the intended KB repository.
scripts/gitea_api.py:15Payload-Controlled Gitea Endpoint Can Exfiltrate the Bot Token
scripts/query_context.py:252Unvalidated Attachment Storage Paths Permit Arbitrary Local-File Reads
scripts/task_io.py:149Unconstrained Output Paths Permit Arbitrary File Overwrite
If the skill advertised as read-oriented KB answering can also write or update repository contents, that is a meaningful privilege/behavior mismatch. Operators may invoke it assuming low-risk query semantics, while the workflow includes persistent modification of KB files (qa/, catalog.json, index.md), increasing the chance of unauthorized or unintended content changes.
If the skill advertised as read-oriented KB answering can also write or update repository contents, that is a meaningful privilege/behavior mismatch. Operators may invoke it assuming low-risk query semantics, while the workflow includes persistent modification of KB files (qa/, catalog.json, index.md), increasing the chance of unauthorized or unintended content changes.
If the skill advertised as read-oriented KB answering can also write or update repository contents, that is a meaningful privilege/behavior mismatch. Operators may invoke it assuming low-risk query semantics, while the workflow includes persistent modification of KB files (qa/, catalog.json, index.md), increasing the chance of unauthorized or unintended content changes.
If the skill advertised as read-oriented KB answering can also write or update repository contents, that is a meaningful privilege/behavior mismatch. Operators may invoke it assuming low-risk query semantics, while the workflow includes persistent modification of KB files (qa/, catalog.json, index.md), increasing the chance of unauthorized or unintended content changes.
The skill describes access to environment variables, local file reads/writes, and likely network-backed repository operations, but it declares no explicit tool scope or permissions boundary. That creates an avoidable overreach risk: a caller or runtime may grant broader capabilities than intended, enabling filesystem or token exposure if the skill or its downstream scripts are abused.
The markdown explicitly states that answers must be primarily in Chinese unless the user clearly asks for another language. This imposes a default language choice without user opt-in, which matches the locale/language policy violation criteria.
The manifest description says the skill will "Answer Research KB questions" without defining specific trigger phrases, boundaries, or exclusion conditions. In a manifest file, this broad phrasing can overlap with many ordinary research/help requests and may cause unintended invocation because the scope is not narrowly constrained.
Suspicious Unicode normalization or mixed-script content
The client can write arbitrary content back into the Gitea repository via upsert_text, which exceeds a narrowly read-only KB query role. In this skill context, that is meaningful because an answering workflow with persistence can be coerced into modifying trusted knowledge-base content, creating integrity risks such as unauthorized Q&A insertion, poisoning future answers, or overwriting files if upstream path/message/content inputs are not tightly controlled.
The upsert_text method performs a remote file create/update operation against the Gitea repository, which can change persisted user or team data. The code does not include a confirmation prompt, user-facing log/print, or inline comment/docstring warning that this method writes repository contents.
The _request method sends HTTP requests to the configured Gitea server and includes an authorization token; when used by read and write paths, it transmits repository paths and potentially file contents over the network. There is no user-facing warning, logging, or explanatory comment/docstring disclosing this external network interaction.
The constants for the reference heading, source trace label, and fallback source text are fixed in Chinese, which forces generated content into a specific language. This is a natural-language locale policy concern because the file does not provide any user opt-in, configuration, or justification for restricting output language.
The manifest says the skill answers knowledge-base questions with optional high-value Q&A persistence, but this code goes beyond producing an answer by performing multiple repository write operations: creating/updating a QA page and modifying catalog.json and index.md. Those content-management side effects materially extend behavior beyond simple question answering and are only partially hinted at by the brief 'optional persistence' wording.
After persisting a QA page, the code reads and rewrites catalog.json and index.md, effectively maintaining site-wide repository metadata. While saving a high-value answer page may fit the manifest, rebuilding shared catalog and index artifacts is a broader content-administration capability than answering KB questions with citations.
The string requires answers to end with a section titled '## 参考来源', which imposes Chinese output regardless of the user's preferred language. This is a natural-language locale policy issue because the file does not offer any language choice or document a justified region-specific constraint.
This code returns a natural-language answer in Chinese when answer recovery fails, regardless of the user's preferred language or locale. That enforces a specific language without opt-in, which matches the policy-violation category for locale/language constraints.
The input field describes a "Research KB backend query payload JSON" but does not clarify what kinds of questions, systems, or contexts are in scope. For a manifest file, this leaves activation boundaries ambiguous and provides no negative examples or constraints to prevent overbroad matching.
This client loads Gitea URL, bot token, owner, and repo selection from environment variables, meaning the skill participates in credentialed repository access and target selection. For a skill framed as answering KB questions, direct credential and repo-resolution logic is not clearly justified unless explicitly declared as part of its operational scope.
The code creates parent directories and writes JSON content to an arbitrary path, which is a file-modifying operation covered by the warning requirement for code files. There is no confirmation prompt, visible logging/print, or inline documentation explaining this write behavior in this file.
No suspicious patterns detected.