Back to skill

Security audit

Gitea Repo Ingest

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its stated repository-ingestion purpose, but it handles Gitea credentials and untrusted repository files in ways that could expose tokens or local files.

Review before installing. Only run this skill with trusted backend payloads and trusted repositories, use a tightly scoped Gitea bot token, require the Gitea URL to come from trusted configuration, block symlink traversal during sampling, avoid embedding tokens in git URLs, and clean or sanitize worktrees after use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
Findings (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/repo_reader.py:431
Finding

Repository Symlink Escape Allows Reading Files Outside the Cloned Worktree

Content
View full analysis
= max_total_chars: break content = read_text_limited(repo_dir / path, max_chars=max_sample_chars) if not content.strip(): continue samples.append({"path": path, "chars": len(content), "content": content}) total += len(content) return samples ``` ```python # scripts/utils.py:77-84 def read_text_limited(path, max_chars=12000): candidate = Path(path) if not candidate.exists() or not candidate.is_file(): return "" raw = candidate.read_bytes() if b"\x00" in raw[:4096]: return "" return raw.decode("utf-8-sig", errors="replace")[:max_chars] ``` ### Technical Analysis Git repositories can contain symbolic links. After checkout, a repository-controlled path may resolve to a target outside the cloned worktree. The sampler joins a repository-controlled path to `repo_dir`, but it does not resolve the resulting path and verify that the canonical target remains inside `repo_dir`. The calls to `Path.exists()`, `Path.is_file()`, and `Path.read_bytes()` follow symbolic links. An attacker can give the symbolic link a filename or extension selected by `_important_files()` or `_should_sample()`, such as `requirements.txt`, `.env`, or another recognized source filename. The linked host file may then be read and included in `samples[]`. The path filtering performed by `safe_relpath()` only detects textual `..` traversal. It does not protect against filesystem-level symlink traversal. ### Attack Path 1. An attacker controls or contributes to a repository that will be ingested. 2. The attacker commits a symbolic link with a high-priority sampling name, for example: ...[truncated 1336 chars]
Remediation
View remediation
``` This avoids following worktree symlinks. 5. Reject non-regular Git tree entries during sampling. Use `git ls-tree` metadata to distinguish blobs from symbolic links before reading them. 6. Add regression tests covering: - Absolute symlinks - Relative symlinks escaping with `../` - Multi-hop symlink chains - Symlinks using important filenames - Symlinks targeting files inside the repository, according to the chosen policy ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/gitea_api.py:11
Finding

Payload-Controlled Gitea Endpoint Receives the Environment Bot Token

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/repo_reader.py:208
Finding

Bot Token Is Exposed Through Git Command Arguments and Persisted Clone Configuration

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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 (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The supplied code chunk is a local catalog utility. It loads catalog JSON, derives page types from paths, merges catalog entries, normalizes inter-page relations, and renders a markdown knowledge-base index. While catalog/index updates are mentioned in the description, the broader declared purpose centers on repository ingestion and source analysis workflows. None of those core capabilities appear here: there is no network access, no Git/Gitea API usage, no repository cloning or reading, no commit diffing, and no code analysis. Therefore the actual behavior is materially narrower and different from the declared description.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
92% confidence
Finding

The declared description emphasizes ingesting Git/Gitea repositories into a Research KB and supporting higher-level source analysis tasks. This code chunk does not perform repository ingestion or analysis. Instead, it is a helper client for the Gitea contents API that reads and upserts text files in a configured repository using authentication credentials. While this may be a supporting component for KB updates on Gitea, on its own its behavior is materially narrower and different from the declared primary purpose.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · scripts/repo_reader.py (reported line 45)May include surrounding context.

python
}

TEXT_EXTENSIONS = {
    ".c", ".cc", ".cfg", ".clj", ".cpp", ".cs", ".css", ".dockerfile", ".env",
    ".go", ".gradle", ".graphql", ".h", ".hpp", ".html", ".java", ".js", ".json",
    ".jsx", ".kt", ".lock", ".md", ".mjs", ".php", ".properties", ".py", ".rb",
    ".rs", ".rst", ".scss", ".sh", ".sql", ".swift", ".toml", ".ts", ".tsx",

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
60% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · scripts/repo_reader.py (reported line 210)May include surrounding context.

python
def _git(args, cwd=None, timeout=120):
    command = ["git"] + list(args)
    env = os.environ.copy()
    env["GIT_TERMINAL_PROMPT"] = "0"
    env["GCM_INTERACTIVE"] = "never"
    completed = subprocess.run(

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill instructs the agent to use shell, network, environment variables, and file read/write operations against repositories and a knowledge base, but it declares no explicit tool scope or permission boundaries. In an adversarial setting, this over-broad implicit capability increases the chance of unauthorized file modification, secret exposure via environment access, and unintended network interactions because there is no machine-readable restriction layer limiting what the skill may touch.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill instructions and operational guidance are written as if the skill must operate in Chinese, starting with the section heading and detailed responsibilities in Chinese. There is no indication that users may choose another language or that the locale restriction is required for a region-specific or compliance-specific purpose.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code writes content to a remote Gitea repository via a PUT request in upsert_text, but there is no confirmation prompt, logging, print statement, or explanatory comment/docstring disclosing that user-provided content will be transmitted and committed remotely. Because this is a code file, remote modification of repository contents is a safety-relevant operation that should have some visible user disclosure unless clearly documented elsewhere in the skill.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

This code embeds Chinese-only natural-language strings for relation labels, generated page titles, and manifest/rendered content, which forces a specific locale in outputs. The file does not provide any user opt-in, configuration, or documented justification for restricting output language to Chinese.

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/repo_reader.py (reported line 213)May include surrounding context.

python
env = os.environ.copy()
    env["GIT_TERMINAL_PROMPT"] = "0"
    env["GCM_INTERACTIVE"] = "never"
    completed = subprocess.run(
        command,
        cwd=str(cwd) if cwd else None,
        text=True,

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The client reads GITEA_BOT_TOKEN from the environment and later uses it in authenticated API requests, but the file contains no user-facing warning, comment, or docstring explaining that credentials are consumed for outbound network access. Access to sensitive environment variables and use in network calls is within the missing-warning scope for code files when undisclosed.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.