Back to skill

Security audit

MeterSphere

Security checks for vulnerabilities and agentic risk

Overview

This MeterSphere skill has a legitimate disclosed purpose, but it needs Review because several write and credential-handling paths are too unsafe for automatic trust.

Install only if you can tightly control the skill directory and .env file, use HTTPS-only trusted MeterSphere URLs, use least-privilege and separate read/write API keys, set the default template/version/project IDs explicitly, avoid METERSPHERE_HEADERS_JSON unless necessary, do not pass untrusted OpenAPI URLs, and avoid sharing verification output that may contain credential prefixes.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ms.sh:8
Finding

Arbitrary Command Execution Through Executable .env Loading

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/verify_installation.py:42
Finding

MeterSphere Credential Material Disclosed in Verification Output

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/ms.py:167
Finding

Authenticated MeterSphere Traffic Can Be Sent Over Plain HTTP

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ms_generate.py:16
Finding

Unrestricted OpenAPI URL Retrieval Enables Internal-Network Access

Content
View full analysis
str: p = Path(path) if p.exists(): return p.read_text(encoding='utf-8') if path.startswith('http://') or path.startswith('https://'): with urllib.request.urlopen(path, timeout=30) as r: return r.read().decode('utf-8', errors='replace') raise FileNotFoundError(path) ``` ### Technical Analysis The OpenAPI importer permits retrieval from any HTTP or HTTPS URL. It does not: - Restrict destination hosts. - Reject loopback, link-local, private, or reserved IP addresses. - Revalidate destinations after DNS resolution. - Validate redirect targets. - Require HTTPS. - Enforce an expected content type. - Limit the response body size before reading it into memory. In an Agent workflow, untrusted instructions or documents may influence the OpenAPI source passed to this function. The process can consequently be induced to connect to services reachable from the Agent's network but not directly reachable by the attacker. This creates server-side request forgery-like behavior in the local Agent context. The unrestricted `read()` also creates a memory-exhaustion opportunity. ### Attack Path 1. An attacker supplies or embeds an OpenAPI source URL in task content. 2. The Agent invokes `ms api import-generate` or `ms api import-create` with that URL. 3. `load_text()` sends a request to the attacker-selected destination. 4. The destination may be a loopback service, private-network host, cloud metadata endpoint, or a public URL that redirects to one. 5. Retrieved content is parsed and may be printed in generated output or incorporated into data subsequently uploaded to MeterSphere. 6. Alternatively, a very large response consumes excessive memory and disrupts the Agent process. ### Imp ...[truncated 498 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/ms_batch.py:143
Finding

Hardcoded Tenant-Specific IDs Can Misroute Created Test Assets

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
Findings (84)

Tainted flow: 'req' from os.environ.get (line 172, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The script sends authenticated outbound requests to a fully environment-controlled BASE_URL, attaching accessKey and a derived signature header. In an agent/skill context, this can exfiltrate credentials or sensitive payloads to an attacker-controlled endpoint if the environment is poisoned or the skill is repointed unexpectedly.

Content

Scanner excerpt · scripts/ms.py (reported line 174)May include surrounding context.

python
data = None if body is None else json.dumps(body, ensure_ascii=False).encode('utf-8')
    req = request.Request(url, data=data, headers=make_headers(), method=method.upper())
    try:
        with request.urlopen(req) as resp:
            charset = resp.headers.get_content_charset() or 'utf-8'
            print(resp.read().decode(charset, errors='replace'))
    except error.HTTPError as e:

Tainted flow: 'req' from os.environ.get (line 122, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The script sends authenticated requests to a fully environment-controlled BASE_URL, including accessKey and derived signature headers. If an attacker can influence environment variables or execution context, they can redirect credentials and sensitive payload data to an arbitrary host, turning the tool into an exfiltration proxy.

Content

Scanner excerpt · scripts/ms_batch.py (reported line 41)May include surrounding context.

python
def request_json(method, path, body=None):
    data = None if body is None else json.dumps(body, ensure_ascii=False).encode('utf-8')
    req = urllib.request.Request(BASE_URL + path, data=data, headers=headers(), method=method)
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.loads(r.read().decode('utf-8', errors='replace'))

def request_multipart(method, path, fields=None, files=None):

Tainted flow: 'req' from os.environ.get (line 122, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The multipart helper likewise transmits signed credentials and uploaded content to an environment-controlled destination. In a skill context that processes test assets and potentially internal API definitions, this can leak sensitive organizational data if configuration is tampered with.

Content

Scanner excerpt · scripts/ms_batch.py (reported line 123)May include surrounding context.

python
req_headers['Content-Length'] = str(len(body))
    
    req = urllib.request.Request(BASE_URL + path, data=body, headers=req_headers, method=method)
    with urllib.request.urlopen(req, timeout=60) as r:
        return json.loads(r.read().decode('utf-8', errors='replace'))

Tainted flow: 'req' from os.environ.get (line 65, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

The destination BASE_URL is taken from environment/.env and used directly for authenticated outbound requests, causing the script to send accessKey and signature headers plus case-related data to whatever host is configured. In an agent-skill context, that makes exfiltration easier if the skill directory or environment is tampered with, especially because there is no allowlist, scheme enforcement, or user confirmation.

Content

Scanner excerpt · scripts/ms_case_report.py (reported line 60)May include surrounding context.

python
headers=headers(),
        method='POST',
    )
    with request.urlopen(req, timeout=60) as resp:
        return json.loads(resp.read().decode('utf-8', errors='replace'))

Tainted flow: 'req' from os.environ.get (line 65, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

This GET path has the same issue as the POST helper: the code trusts an environment-controlled BASE_URL and performs authenticated network access without constraining the remote endpoint. In a skill ecosystem, untrusted or modified configuration can redirect requests and leak credentials or sensitive case metadata to an attacker-controlled server.

Content

Scanner excerpt · scripts/ms_case_report.py (reported line 66)May include surrounding context.

python
def get_json(path: str):
    req = request.Request(BASE_URL + path, headers=headers(), method='GET')
    with request.urlopen(req, timeout=60) as resp:
        return json.loads(resp.read().decode('utf-8', errors='replace'))

Tainted flow: 'req' from os.environ.get (line 65, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/ms_review_summary.py (reported line 60)May include surrounding context.

python
headers=headers(),
        method='POST',
    )
    with request.urlopen(req, timeout=60) as resp:
        return json.loads(resp.read().decode('utf-8', errors='replace'))

Tainted flow: 'req' from os.environ.get (line 65, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/ms_review_summary.py (reported line 66)May include surrounding context.

python
headers=headers(),
        method='POST',
    )
    with request.urlopen(req, timeout=60) as resp:
        return json.loads(resp.read().decode('utf-8', errors='replace'))

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

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

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

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

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

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

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

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

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

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

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

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

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

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

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 26)May include surrounding context.

md
- [ ] 记录每个密钥的权限范围和有效期
- [ ] 在生产环境中使用前,在测试环境中验证权限

### 3. 检查和控制 .env 文件
**警告**: 脚本会从技能目录加载 .env 文件
**验证**:
- [ ] 确保 .env 文件仅包含预期的环境变量

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

The declared purpose focuses on MeterSphere test-asset management, but the skill also performs installation verification, reads local configuration files, checks file permissions, probes network connectivity, and scans for hardcoded IDs. This mismatch is security-relevant because operators may grant trust based on the high-level description without realizing the skill inspects local files and performs broader environment/network validation actions.

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

python
SCRIPT_DIR = Path(__file__).resolve().parent
SKILL_DIR = SCRIPT_DIR.parent
ENV_FILE = SKILL_DIR / '.env'
if ENV_FILE.exists():
    load_dotenv(ENV_FILE)

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

python
SCRIPT_DIR = Path(__file__).resolve().parent
SKILL_DIR = SCRIPT_DIR.parent
ENV_FILE = SKILL_DIR / '.env'
if ENV_FILE.exists():
    load_dotenv(ENV_FILE)

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/ms.sh (reported line 6)May include surrounding context.

sh
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
ENV_FILE="${SKILL_DIR}/.env"

if [[ -f "$ENV_FILE" ]]; then
  set -a

Description-Behavior Mismatch

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

When required IDs are absent, the script silently substitutes hardcoded project-specific templateId and versionId values, which can cause test assets to be created in the wrong project or tenant context. In a test-management integration, that can corrupt another project's data, leak organizational information across boundaries, or trigger unauthorized changes with valid credentials.

Content

No source excerpt is available for this finding.

Credential Access

High
Category
Privilege Escalation
Confidence
83% confidence
Finding

The code is explicitly designed to read secrets from a local .env file in the skill directory, which is a credential-handling weakness because secrets may be stored in plaintext near code and become accessible to other local processes, backups, or accidental commits. In a reusable agent skill, this pattern broadens exposure of MeterSphere credentials beyond a dedicated secret-management boundary.

Content

Scanner excerpt · scripts/ms_case_report.py (reported line 13)May include surrounding context.

python
SCRIPT_DIR = Path(__file__).resolve().parent
SKILL_DIR = SCRIPT_DIR.parent
ENV_FILE = SKILL_DIR / '.env'

if ENV_FILE.exists():
    for line in ENV_FILE.read_text(encoding='utf-8').splitlines():

Credential Access

High
Category
Privilege Escalation
Confidence
85% confidence
Finding

The script automatically reads credentials from a repository-adjacent .env file, which encourages plaintext secret storage near code and increases the chance of accidental disclosure through source control, backups, or permissive filesystem access. In an agent skill context, this is more dangerous because skills are often shared, packaged, or inspected by automation, widening the exposure path for API secrets.

Content

Scanner excerpt · scripts/ms_review_summary.py (reported line 13)May include surrounding context.

python
SCRIPT_DIR = Path(__file__).resolve().parent
SKILL_DIR = SCRIPT_DIR.parent
ENV_FILE = SKILL_DIR / '.env'

if ENV_FILE.exists():
    for line in ENV_FILE.read_text(encoding='utf-8').splitlines():

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · INSTALLATION_CHECKLIST.md (reported line 27)May include surrounding context.

md
- [ ] 确保 .env 文件仅包含预期的环境变量
- [ ] 检查 .env 文件中没有额外的敏感信息
- [ ] 使用 `.env.example` 作为模板创建安全的 .env 文件
- [ ] 设置适当的文件权限 (chmod 600 .env)

### 4. 警惕 HEADERS_JSON
**风险**: METERSPHERE_HEADERS_JSON 可以注入任意 HTTP 头

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 312)May include surrounding context.

md
- [ ] 确保 .env 文件仅包含预期的环境变量
- [ ] 检查 .env 文件中没有额外的敏感信息
- [ ] 使用 `.env.example` 作为模板创建安全的 .env 文件
- [ ] 设置适当的文件权限 (chmod 600 .env)

### 4. 警惕 HEADERS_JSON
**风险**: METERSPHERE_HEADERS_JSON 可以注入任意 HTTP 头

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The entire skill documentation is written in Chinese, including headings, instructions, warnings, and troubleshooting, with no indication that the skill is region-specific or that users may choose another language. Under the policy rule for language/locale, this is a natural-language constraint imposed without user opt-in or justification.

Content

No source excerpt is available for this finding.