Back to skill

Security audit

Rewrite Question

Security checks for vulnerabilities and agentic risk

Overview

This skill is presented as simple question rewriting, but it can send business queries, SQL templates, and credentials to external endpoints with weak disclosure and unsafe defaults.

Review this before installing in any environment with real business data or secrets. It should not receive broad .env files or production credentials, and its LLM endpoint should be fixed to an approved HTTPS host before use. Rotate or remove the embedded token, avoid caller-supplied endpoints, and document the Milvus, SQL, subprocess, and workflow file behavior.

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)

T09 · Insecure Skill Coding Practices

Error
Location
index.js:84
Finding

Caller-Controlled LLM Endpoint Enables Credential and Sensitive Data Exfiltration

Content
View full analysis
str: start = time.time() with httpx.Client(timeout=self.llm_timeout) as client: resp = client.post(self.api_url, json=payload, headers=headers) resp.raise_for_status() ``` ### Technical Analysis The JavaScript entry point accepts `gemini_api_url` directly from Skill input without validating its scheme, hostname, port, or resolved address. It then combines that caller-s ...[truncated 2868 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
rewrite_question.py:559
Finding

Hardcoded Administrative Token and Plaintext Default API Endpoint

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
rewrite_question.py:537
Finding

Recursive Parent-Directory Environment Loading Crosses the Skill Configuration Boundary

Content
View full analysis
None: """Search for and load .env files from the current directory or parent directories""" from pathlib import Path try: from dotenv import load_dotenv search_path = Path(__file__).resolve().parent for _ in range(8): for name in (".env", ".env.dev", ".env.local"): env_file = search_path / name if env_file.exists(): load_dotenv(env_file, override=False) print(f"[Configuration] Loaded: {env_file}") return search_path = search_path.parent print("[Configuration] No .env file found; using system environment variables") except ImportError: print("[Warning] python-dotenv is not installed; run pip install python-dotenv") ``` ### Technical Analysis The standalone entry point searches the Skill directory and up to seven additional ancestor levels for `.env`, `.env.dev`, or `.env.local`. It loads the first matching file without checking whether the file belongs to this Skill, whether its owner and permissions are trusted, or whether the discovered directory is an approved configuration boundary. In a shared workspace, monorepo, archive extraction directory, or nested deployment, an ancestor environment file may belong to another project. Loading it can import unrelated Gemini, Milvus, or other process configuration. Relevant values can alter network destinations, grant database access, or become request credentials. The issue compounds the arbitrary-endpoint weakness: credentials discovered outside the Skill directory can subsequently be selected by `_get_gemini_config` and sent in LLM request headers. It also allows an attacker who can create a nearer ...[truncated 1592 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (23)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared purpose is only query rewriting, but the detected behavior includes QA-to-SQL matching, external LLM-driven SQL rewriting, Milvus retrieval, and calls to an external Gemini API. This mismatch is dangerous because reviewers and calling agents may trust the skill with benign text-processing input while it actually performs data access and outbound transmission, increasing the risk of unauthorized query execution, sensitive data exposure, and hidden side effects.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

The explicit loading of ../.env gives this skill access to locally stored credentials, which is credential exposure behavior. In a question-rewriting skill, this is more dangerous because the capability is unrelated to its stated purpose, so compromise of the Python runner or misuse of inherited environment variables could disclose API keys or tokens.

Content

Scanner excerpt · index.js (reported line 31)May include surrounding context.

js
// 加载 skills/.env(若父进程未注入则自行读取)
(function loadDotEnv() {
  const envFile = path.join(__dirname, '..', '.env');
  if (!fs.existsSync(envFile)) return;
  for (const line of fs.readFileSync(envFile, 'utf8').split('\n')) {
    const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.+?)\s*$/);

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · rewrite_question.py (reported line 114)May include surrounding context.

python
澄清指令处理:若历史末尾是系统给出的【选项列表】,用户回答"第一个"或"按月",需将其融合为完整指令。

                            # Output Rules
                            1. **严禁过度继承:如果用户已经明确提到了"全国"或"所有门店",不得将历史中的"华西区"强行塞入。
                            2. **严禁臆造**:绝对不要创造历史记录中不存在的年份或数据值。
                            3. **保持独立**:重写后的句子必须能让不知道上下文的人也能完全听懂。

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 · rewrite_question.py (reported line 538)May include surrounding context.

python
# ═══════════════════════════════════════════════════════════════════

def _load_dotenv() -> None:
    """从当前目录或各层父目录查找并加载 .env 文件"""
    from pathlib import Path
    try:
        from dotenv import load_dotenv

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 · rewrite_question.py (reported line 583)May include surrounding context.

python
# ═══════════════════════════════════════════════════════════════════

def _load_dotenv() -> None:
    """从当前目录或各层父目录查找并加载 .env 文件"""
    from pathlib import Path
    try:
        from dotenv import load_dotenv

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 · rewrite_question.py (reported line 712)May include surrounding context.

python
# ═══════════════════════════════════════════════════════════════════

def _load_dotenv() -> None:
    """从当前目录或各层父目录查找并加载 .env 文件"""
    from pathlib import Path
    try:
        from dotenv import load_dotenv

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 · rewrite_question.py (reported line 544)May include surrounding context.

python
from dotenv import load_dotenv
        search_path = Path(__file__).resolve().parent
        for _ in range(8):
            for name in (".env", ".env.dev", ".env.local"):
                env_file = search_path / name
                if env_file.exists():
                    load_dotenv(env_file, override=False)

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 · rewrite_question.py (reported line 544)May include surrounding context.

python
from dotenv import load_dotenv
        search_path = Path(__file__).resolve().parent
        for _ in range(8):
            for name in (".env", ".env.dev", ".env.local"):
                env_file = search_path / name
                if env_file.exists():
                    load_dotenv(env_file, override=False)

Missing User Warnings

High
Category
Not specified by scanner
Confidence
99% confidence
Finding

The code embeds a default authentication token and silently uses it when GEMINI_TOKEN is unset. Hardcoded credentials are dangerous because they can be extracted from source control, reused by unauthorized parties, and cause accidental sharing of a privileged backend identity across deployments.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill documentation declares no explicit tool restrictions even though the implementation reportedly uses environment access, file writes, and network connectivity. In an agent setting, missing scope declarations weaken least-privilege controls and can allow broader execution than reviewers or orchestrators expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The documented --clean option states it clears this step and all subsequent intermediate files, but the skill does not warn about deletion risk or scope. In practice, such cleanup operations can cause unintended data loss, destroy audit artifacts, or erase state needed for recovery if triggered casually or by automation.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill reads a local .env file and populates process environment variables even though its declared purpose is only to rewrite user questions. That expands the skill's access to secrets beyond its functional need and creates unnecessary exposure if the Python component, logs, or downstream code mishandles those values.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

Sensitive credentials are loaded from .env and then made available for use without any clear boundary or disclosure. In this skill context, that is risky because a text-rewriting feature does not inherently require broad secret access, so the design increases the blast radius of any downstream bug or prompt-induced leakage in the Python logic.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill executes a subprocess using a configurable interpreter from PYTHON_EXECUTABLE. If an attacker or untrusted deployment input can influence that environment variable, the skill may run an unexpected binary, turning a simple rewrite operation into arbitrary code execution within the agent environment.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
81% confidence
Finding

The skill serializes the user's query, conversation history, QA pairs, and optional credentials into a JSON payload and sends it over stdin to a subprocess. The code has no user-facing log, confirmation, or warning that these inputs—including potentially sensitive history and tokens—are being handed off to another process.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
76% confidence
Finding

The file's natural-language documentation, prompts, and examples are entirely in Chinese, and the behavior appears tailored to Chinese-language interaction without any opt-in or alternative locale path. Under the stated policy, forcing a specific language is a violation unless the skill clearly offers a language choice or documents a justified regional constraint.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Manifest 描述将该技能限定为问题补全与重写,但路径 A 中代码在 QA 精确匹配后调用 LLM 更新时间条件并返回 matched_sql,实际承担了 SQL 生成/改写职责。这超出了“重写用户提问”的语义范围,不只是实现细节。

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

对于“补全上下文并重写用户提问”这一目的,连接外部 Milvus 服务批量读取 QA 对并驱动后续 SQL 输出,不是直接且明显必需的能力。该能力更接近检索式问答/SQL 模板命中,而非单纯的提问重写。

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code retrieves QA data from Milvus and, elsewhere in the skill, sends user content to external services, yet there is no explicit disclosure, consent, or data governance control in the code path. In an enterprise BI context, both QA corpora and user questions may contain sensitive business logic or operational data, making undisclosed network/data flows more dangerous.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The natural-language description and operating instructions are presented in Chinese only, which can amount to forcing a specific language without user opt-in. There is no indication that the skill is region-specific or that users may choose another language.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill launches an external Python interpreter via child_process.spawn, which is a safety-relevant operation for code auditing. While subprocess use may be functionally necessary here, the code does not include any visible warning, prompt, or user-facing disclosure that execution depends on invoking a local Python process.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

文档注释写明 QA 精确匹配后“直接输出 SQL”,容易让人理解为技能主输出变为 SQL;但实现中 L328-L333 返回的 final_query 仍为 current_query,SQL 只是附加在 matched_sql。该注释与实际输出行为存在直接偏差。

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill sends full prompts, including user queries and formatted conversation history, to an external LLM endpoint over the network. In a context-rewrite skill, this increases data exposure risk because potentially sensitive business queries, clarification candidates, and conversation context are transmitted to a third-party or remote service without any minimization, redaction, or consent mechanism shown here.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.env_credential_access, suspicious.exposed_secret_literal

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
index.js:101

Python code POSTs credential environment variables to an environment-controlled URL.

Critical
Code
suspicious.env_credential_access
Location
rewrite_question.py:508

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
index.js:91