Back to skill

Security audit

Recognize Intent

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly fits a Chinese business-intelligence intent parser, but its secret handling and network controls could leak credentials or user queries, so it needs review before installation.

Install only in a controlled environment after removing the hard-coded token, requiring HTTPS allowlisted LLM endpoints, preventing caller-supplied URLs from receiving environment credentials, and limiting .env loading to an explicit skill-owned configuration file. Treat workflow JSON files as sensitive because they can contain user queries, extracted metadata, and SQL-bearing fields.

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 (4)

T09 · Insecure Skill Coding Practices

Error
Location
recognize_intent.py:966
Finding

Plaintext Transmission of Credentials and Business Data to a Default Bare-IP Endpoint

Content
View full analysis
str: """Synchronously call the Gemini REST API.""" headers = { "x-goog-api-key": api_key, "token": token, "Content-Type": "application/json", "Accept": "*/*", } payload = { "contents": [{"role": "user", "parts": [{"text": prompt}]}], "generationConfig": {"thinkingConfig": {"thinkingLevel": "low"}}, } start = time.time() try: with httpx.Client(timeout=timeout) as client: resp = client.post(api_url, json=payload, headers=headers) resp.raise_for_status() result = resp.json() duration = time.time() - start content = "" candidates = result.get("candidates", []) if candidates: parts = candidates[0].get("content", {}).get("parts", []) if parts and "text" in parts[0]: content = parts[0]["text"] logger.info(f"Gemini REST call succeeded in {duration:.2f}s") return content except Exception as e: logger.error(f"Gemini REST call failed: {e}") raise ``` ```python def _get_gemini_config() -> Dict[str, str]: """Read Gemini API configuration from environment variables.""" import os base_url = os.getenv( "GEMINI_API_URL", "http://47.77.199.56/api/v1beta" ).rstrip("/") model = os.getenv("GEMINI_MODEL_NAME", "gemini-3-flash-preview") return { "api_url": f"{base_url}/models/{model}:generateContent", "api_key": os.getenv("GEMINI_API_KE ...[truncated 2190 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
index.js:97
Finding

Caller-Controlled Endpoint Receives Environment-Sourced Credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
recognize_intent.py:971
Finding

Hard-Coded Administrator Authentication Token

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
recognize_intent.py:947
Finding

Overbroad Parent-Directory Environment File Discovery

Content
View full analysis
None: """Search for and load a .env file from the current 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 found; using system environment") except ImportError: print("[warning] python-dotenv is not installed") ``` ### Technical Analysis The standalone execution path searches up to eight ancestor directories for `.env`, `.env.dev`, or `.env.local`. This can cross the Skill's directory boundary and load an unrelated parent project's environment file. Although `override=False` prevents replacement of variables already present in the process, it does not prevent previously unset secrets from being imported. The loaded values can configure Gemini, embedding, Milvus, and MySQL clients. Consequently, unrelated credentials may be used or transmitted during the Skill run. The declared functionality requires Skill-specific service configuration, not unrestricted discovery of configuration files belonging to ancestor directories. ### Attack Path 1. The Skill is installed or copied beneath a directory tree containing another application's `.env`, `.env.dev`, or `.env.local`. 2. No closer environment file is available in the Skill directory. 3. Standalone execution invokes `_load_dotenv()`. 4. The function ...[truncated 1022 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
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (24)

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

There is a significant description-behavior mismatch: a skill presented as intent parsing also appears to call external APIs, query Milvus and MySQL, participate in workflow file I/O, and influence downstream SQL generation. This is dangerous because users and orchestrators may grant trust based on the benign description while the implementation performs broader, more sensitive operations that can expose data or alter execution flow.

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 · SKILL.md (reported line 27)May include surrounding context.

md
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

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

python
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

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

python
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

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

python
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

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

python
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

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

python
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

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

python
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

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

python
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The code explicitly loads secrets from a local .env file, which is credential access behavior. In context, this is more concerning because the skill's stated purpose is intent recognition, yet it acquires API credentials and forwards them into another execution context, creating opportunities for accidental disclosure via subprocess behavior, crashes, or future code changes.

Content

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

js
const path = require('path');
const fs = require('fs');

// 加载 skills/.env
(function loadDotEnv() {
  const envFile = path.join(__dirname, '..', '.env');
  if (!fs.existsSync(envFile)) return;

Credential Access

High
Category
Privilege Escalation
Confidence
94% confidence
Finding

Reading ../.env with fs.readFileSync and populating process.env grants the skill access to locally stored secrets. Even if intended for configuration, this is sensitive capability beyond narrow NLP parsing and increases risk of credential leakage or misuse if dependent code is compromised or overly verbose in error handling.

Content

Scanner excerpt · index.js (reported line 27)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*$/);

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 · recognize_intent.py (reported line 954)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 · recognize_intent.py (reported line 954)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)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill advertises a narrow intent-recognition purpose but declares no explicit tool or permission scope while documenting capabilities that rely on environment secrets, local file writes, and network/database access. This increases the attack surface and makes it easier for the skill to overreach or be chained into unintended data access without clear operator consent.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The natural-language description and role text specify the skill entirely in Chinese and frame its behavior around Chinese-language query understanding, but do not state that this is optional, user-selected, or limited to a justified region-specific deployment. This can violate language/locale policy because it implicitly enforces a specific language without opt-in.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
76% confidence
Finding

The stated purpose is to classify intent and extract semantic fields from text. While using another language runtime can be an implementation choice, this file directly launches a system Python process via child_process.spawn, which is a broader execution capability than the manifest suggests and is not documented in the skill description.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill reads a local .env file and imports secrets into process.env, then later uses those values to supply gemini_api_url, gemini_api_key, and gemini_token to the Python subprocess. That expands the skill from simple intent parsing into secret-consuming behavior, increasing the blast radius if the downstream Python code, logs, or errors mishandle those credentials.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Multiple prompts and rules require Chinese-specific processing, such as replacing Chinese values, detecting Chinese text, and returning Chinese-formatted outputs, but the file does not present this as an explicit user opt-in or justified regional constraint. This can violate language/locale policy because the skill effectively forces a specific language behavior regardless of user preference.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill sends the full prompt, which includes user questions, over HTTP via httpx to a configured Gemini API endpoint and authenticates with API key and token headers. While there is internal logging of success/failure, there is no user-facing disclosure, confirmation, or comment warning that user input is transmitted to an external LLM service.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill goes beyond intent recognition by enriching outputs with logic_dsl, table_name, and SQL-oriented candidates via semantic search. This expands the attack surface from classification into query-construction primitives, so prompt-influenced or poisoned semantic entries could steer downstream SQL generation in ways not expected from an intent-only component.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The prompt claims the L1 extractor must not emit database fields or SQL content, but the implementation later augments concepts with logic_dsl and table_name and packages them as SQL candidates. That contradiction creates a misleading safety boundary: operators may assume the stage is non-SQL-bearing while it actually injects database-relevant logic into later pipeline steps.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The standalone runner contains a QA shortcut that trusts rewrite_output.json and forwards matched_sql directly when is_qa_matched is set, bypassing the skill's stated intent-recognition path. In a multi-step pipeline, any upstream compromise or tampered workflow file can cause arbitrary SQL to be propagated under the guise of a safe shortcut, weakening trust boundaries.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The file’s user-facing documentation is written entirely in Chinese, and runtime error strings also use Chinese phrases. This can violate a language/locale policy when the skill does not offer any user choice or explicitly document a justified locale restriction.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The main entrypoint reads prior workflow JSON and writes a new intent_output.json containing the user's query and extracted metadata. Although this behavior is functional, the file contains no user-facing warning or descriptive comment near the operation that user query data will be persisted in shared workflow files.

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:108

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

Critical
Code
suspicious.env_credential_access
Location
recognize_intent.py:151

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
index.js:98