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<![CDATA[ ## Vulnerability Details **File Location**: `recognize_intent.py:130-165`, `recognize_intent.py:966-984` **Vulnerability Type**: Sensitive information transmitted over an insecure network channel **Risk Level**: Critical ### Complete Code Snippet ```python def _call_gemini_rest_sync( prompt: str, api_url: str, api_key: str, token: str, timeout: float = 120.0, ) -> 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
<![CDATA[ ## Remediation Suggestions 1. Remove the default bare-IP endpoint and require an explicitly configured service URL. 2. Require HTTPS and reject all plaintext HTTP endpoints. 3. Allowlist approved service origins, including an exact scheme, hostname, and port. 4. Reject IP-literal destinations unless they are explicitly approved for a controlled deployment. 5. Block loopback, private, link-local, and cloud metadata address ranges after DNS resolution. 6. Disable or strictly validate redirects so credentials cannot be redirected to another origin. 7. Retain normal TLS certificate and hostname verification. 8. Minimize prompt contents and exclude business metadata that is not required for the current model operation. 9. Document what data is transmitted, its destination, and the applicable retention policy. 10. Rotate credentials that may already have been exposed through plaintext transport. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
index.js:97
Finding
Caller-Controlled Endpoint Receives Environment-Sourced Credentials<![CDATA[ ## Vulnerability Details **File Location**: `index.js:97-108`, `recognize_intent.py:130-151` **Vulnerability Type**: Arbitrary network destination with credential forwarding **Risk Level**: High ### Complete Code Snippet ```javascript async function run({ input }) { const payload = JSON.stringify({ query: input.query || input.rewritten_query || '', memory_id: input.memory_id || '', indicators: input.indicators || [], metric_configs: input.metric_configs || [], gemini_api_url: input.gemini_api_url || process.env.GEMINI_API_URL || '', gemini_api_key: input.gemini_api_key || process.env.GEMINI_API_KEY || '', gemini_token: input.gemini_token || process.env.GEMINI_TOKEN || '', llm_timeout: input.llm_timeout || 120, }); return execPython(PYTHON_RUNNER, payload, __dirname); } ``` ```python 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"}}, } with httpx.Client(timeout=timeout) as client: resp = client.post(api_url, json=payload, headers=headers) ``` ### Technical Analysis The JavaScript wrapper independently selects each configuration value. A caller can provide `input.gemini_api_url` while omitting `gemini_api_key` and `gemini_token`. In that case, the caller-selected URL is combined with credentials taken from the process environment. The Python implementation then sends those credentials directly to the supplied URL. No destination allowlist, origin binding, IP-range restriction, or scheme validation is shown. This creates a credential-exfiltration primitive and an SSRF-like capability. The Skill legitimately requires outbound access to an LLM service, but allowing an untrusted invocation to redirect environment cr ...[truncated 1614 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Do not accept `gemini_api_url`, API keys, or tokens from ordinary Skill input. 2. Keep the endpoint under trusted server-side configuration. 3. Bind each credential to one exact approved origin; never combine a caller-selected URL with an environment credential. 4. If custom providers are required, require the caller to provide both the endpoint and a separate credential, and do not fall back to environment secrets. 5. Enforce an HTTPS origin allowlist. 6. Resolve and validate destination addresses before connecting, blocking loopback, private, link-local, multicast, and metadata ranges. 7. Revalidate the destination after redirects and DNS resolution; preferably disable redirects. 8. Use a restricted outbound proxy or network policy to limit the process to approved services. 9. Add tests confirming that an unapproved URL cannot receive environment-derived credentials. 10. Rotate any environment credentials that may have been exposed through untrusted invocations. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
recognize_intent.py:971
Finding
Hard-Coded Administrator Authentication Token<![CDATA[ ## Vulnerability Details **File Location**: `recognize_intent.py:971-983` **Vulnerability Type**: Embedded reusable secret in distributed source code **Risk Level**: High ### Complete Code Snippet ```python _default_token = ( "BI-eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJ1c2VySWRcIjpcImFkbWluXCIsXCJ1c2VyTG9na" "W5OYW1lXCI6bnVsbCxcInBob25lXCI6bnVsbCxcInN0YXR1c1wiOm51bGwsXCJpc1N5c3RlbVVzZX" "JcIjpudWxsLFwidmFsaWRUaW1lXCI6bnVsbCxcInRlbmFudElkXCI6bnVsbCxcImVuYWJsZWRcIjp" "0cnVlLFwiY3JlZGVudGlhbHNOb25FeHBpcmVkXCI6dHJ1ZSxcImFjY291bnROb25Mb2NrZWRcIjp0" "cnVlLFwiYWNjb3VudE5vbkV4cGlyZWRcIjp0cnVlLFwidXNlcm5hbWVcIjpcImFkbWluXCIsXCJhd" "XRob3JpdGllc1wiOm51bGx9IiwibmJmIjoxNzA4MTM5OTE5LCJpYXQiOjE3MDgxMzk5MTksImV4cC" "I6MTcxMDczMTkxOX0.taP4LXkfO570-eFawyzYlC4RhK9oLJ-YL9r2VfIj8pY" ) return { "api_url": f"{base_url}/models/{model}:generateContent", "api_key": os.getenv("GEMINI_API_KEY", ""), "token": os.getenv("GEMINI_TOKEN", _default_token), } ``` ### Technical Analysis A bearer-style token is embedded directly in the source and is used automatically whenever `GEMINI_TOKEN` is absent. The decoded-looking claims visible in the token include an `admin` username, although the audit cannot independently establish whether the token remains valid or exactly which server permissions it grants. Secrets included in source code are exposed to anyone who can download the Skill, inspect source archives, access source-control history, or read build artifacts. Automatic fallback also makes deployments silently rely on the shared credential rather than failing securely when configuration is missing. ### Attack Path 1. An attacker obtains the publicly or internally distributed Skill source. 2. The attacker copies the hard-coded token from `recognize_intent.py`. 3. The attacker identifies the associated API from the default configuration or deployment documentation. 4. If the token is still accepted, the attacker submits it in the `token` req ...[truncated 756 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Revoke and rotate the embedded token immediately. 2. Remove the token from the current source and all accessible source-control history. 3. Require credentials to be supplied through an approved secret manager or protected environment configuration. 4. Fail closed when required credentials are missing; do not use a shared fallback secret. 5. Issue short-lived, narrowly scoped service credentials rather than administrator credentials. 6. Bind credentials to the required API audience and approved deployment identity. 7. Add automated secret scanning to source-control and release pipelines. 8. Review service access logs for use of the exposed token and investigate unexpected requests. 9. Prevent tokens from appearing in logs, exceptions, generated reports, or client-visible error messages. ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
recognize_intent.py:947
Finding
Overbroad Parent-Directory Environment File Discovery<![CDATA[ ## Vulnerability Details **File Location**: `recognize_intent.py:947-963` **Vulnerability Type**: Cross-project secret loading beyond the Skill directory **Risk Level**: Medium ### Complete Code Snippet ```python def _load_dotenv() -> 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
<![CDATA[ ## Remediation Suggestions 1. Load configuration only from one explicit, Skill-scoped path. 2. Do not recursively search ancestor directories. 3. Prefer a path supplied by trusted deployment configuration rather than automatic discovery. 4. Verify the configuration file's owner and permissions before loading it. 5. Reject symbolic links or resolve and validate the final path against the approved Skill configuration directory. 6. Use a secret manager for API and database credentials instead of general-purpose `.env` discovery. 7. Define an allowlist of environment variable names the Skill is permitted to import. 8. Fail with a clear configuration error when the approved configuration file is absent. 9. Add tests ensuring parent-project environment files are never loaded. ]]>
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.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
## 注入服务(通过 `.env` 配置)

| 服务类 | 作用 | .env 关键配置 |
|--------|------|---------------|
| `_RealIndicatorSearcher` | 指标别名向量搜索(Milvus `indicator_alias`) | `MILVUS_*`, `EMBEDDING_*`, `INDICATOR_ALIAS_COLLECTION_NAME` |
| `_RealMetricConfigLoader` | 指标维度配置(MySQL `indicator_metric`) | `INTENT_MYSQL_*` 或 `MYSQL_*` |
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
const path = require('path');
const fs = require('fs');

// 加载 skills/.env
(function loadDotEnv() {
  const envFile = path.join(__dirname, '..', '.env');
  if (!fs.existsSync(envFile)) return;
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.

Credential Access

High
Category
Privilege Escalation
Content
// 加载 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*$/);
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.

Credential Access

High
Category
Privilege Escalation
Content
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)
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Credential Access

High
Category
Privilege Escalation
Content
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)
Confidence
60% confidence
Finding
Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Lp3

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.

Natural-Language Policy Violations

Medium
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.

Context-Inappropriate Capability

Medium
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.

Context-Inappropriate Capability

Medium
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.

Natural-Language Policy Violations

Medium
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.

Missing User Warnings

Medium
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.

Context-Inappropriate Capability

Medium
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.

Intent-Code Divergence

Medium
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.

Description-Behavior Mismatch

Medium
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.

Natural-Language Policy Violations

Low
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.

Missing User Warnings

Low
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.

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