Back to skill

Security audit

工业化数据处理

Security checks for vulnerabilities and agentic risk

Overview

The skill performs its stated IQC conversion and submission workflow, but it embeds reusable credentials and sends/stores tokens and business data insecurely.

Review carefully before installing. Only use this in a controlled internal environment after rotating the exposed password, replacing hardcoded credentials with managed secrets, enforcing HTTPS, confirming the destination API is intended, restricting token file permissions, and deciding how long logs and run outputs should be retained.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
scripts/jwt_token.py:32
Finding
Hardcoded Reusable API Credentials<![CDATA[ ## Vulnerability Details **File Location**: `scripts/jwt_token.py`, lines 32–36 **Vulnerability Type**: Hardcoded credentials **Risk Level**: High ### Vulnerable Code ```python API_BASE_URL = "http://192.168.60.241:1120" # Server base address LOGIN_PATH = "/api/GenUser/TokenLogin" # Login endpoint USERNAME = "kang" # Login account PASSWORD = "kang123456" # Login password LOGIN_MESSAGE = "测试,手机端e12a5481c32d23b024226d5e2d7a47aac0870cfc5252b055282b668004a0ebbd,Rule" ``` ### Technical Analysis A reusable username and password are embedded directly in the distributed source code. Any person or process with read access to the Skill package can recover these credentials without executing the Skill. The credentials are used by `fetch_token()` to authenticate to the fixed `/api/GenUser/TokenLogin` endpoint. Source-level secrets cannot be effectively restricted to authorized operators, and rotating them requires modifying and redistributing the package. The hardcoded `LOGIN_MESSAGE` also appears to contain a persistent client or device identifier. Although it is not proven to be an authentication secret, embedding it may facilitate impersonation of the expected client. ### Attack Path 1. An attacker obtains read access to the Skill package, source archive, deployment image, backup, or source repository. 2. The attacker opens `scripts/jwt_token.py` and extracts `USERNAME`, `PASSWORD`, and the client-identifying message. 3. The attacker establishes network access to `192.168.60.241:1120`, such as from the same internal network or through a compromised internal host. 4. The attacker submits the extracted values to `/api/GenUser/TokenLogin`. 5. If the credentials remain valid, the attacker receives a JWT and uses it against API operations available to that account. ### Impact Assessment Successful exploitation grants the API privileges assigned to the `kang` account. The exact server-side ...[truncated 354 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Immediately rotate the exposed password and invalidate JWTs issued from it where supported. 2. Remove usernames, passwords, and reusable client identifiers from source code and version-control history. 3. Retrieve credentials from an approved secret manager, protected OS credential store, or explicitly supplied runtime secret. 4. Use a dedicated service identity with only the permissions required to request a narrowly scoped product-submission token. 5. Prefer short-lived workload identity, mutual TLS, or another non-password machine-authentication mechanism. 6. Prevent secrets from appearing in command-line arguments, logs, exception messages, or ordinary output files. 7. Add secret scanning to source-control and release pipelines. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/jwt_token.py:116
Finding
Credentials, Bearer Tokens, and IQC Records Transmitted over Plaintext HTTP<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/jwt_token.py`, lines 32 and 116–125 - `scripts/data_submit.py`, lines 33 and 144–152 **Vulnerability Type**: Cleartext transmission of sensitive information **Risk Level**: High ### Vulnerable Code Authentication request: ```python API_BASE_URL = "http://192.168.60.241:1120" def fetch_token(timeout: float) -> str: url = f"{API_BASE_URL.rstrip('/')}{LOGIN_PATH}" payload = { "user_account": USERNAME, "user_password": PASSWORD, "message": LOGIN_MESSAGE, } headers = {"Content-Type": "application/json; charset=utf-8"} logging.info(f"请求登录接口: {url}") resp = requests.post(url, json=payload, headers=headers, timeout=timeout) ``` Authenticated data submission: ```python API_BASE_URL = "http://192.168.60.241:1120" url = f"{api_base_url.rstrip('/')}{API_SUBMIT_PATH}" headers = { "Authorization": f"Bearer {token}", "Content-Type": "application/json; charset=utf-8", } logging.info(f"发送 {len(parts)} 条记录 → {url}") try: resp = requests.post(url, json=parts, headers=headers, timeout=timeout) ``` ### Technical Analysis Both authentication and data submission use a hardcoded `http://` endpoint rather than HTTPS. Consequently, the following information is transmitted without transport encryption: - The API username and password. - The persistent client-identifying message. - The returned or subsequently used JWT bearer token. - Generated product-part and industrial IQC records. A private RFC1918 address does not provide confidentiality or server authenticity. Any attacker with network-path visibility may inspect or modify plaintext traffic. Bearer tokens are particularly sensitive because possession is normally sufficient for replay until expiration or revocation. The code also does not enforce an HTTPS-only policy because the destination is directly configured with the HTTP scheme. ### Attack Path 1. The attacker obtains a position on t ...[truncated 1105 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the HTTP endpoint with an HTTPS endpoint and reject any non-HTTPS URL at startup. 2. Use a certificate issued by a trusted internal or public certificate authority and retain normal certificate verification. 3. Do not disable TLS verification or accept arbitrary certificates. 4. Consider mutual TLS for service-to-service authentication on the internal network. 5. Use short-lived, audience-restricted, and operation-scoped bearer tokens. 6. Add server-side replay protections, token revocation, and monitoring for anomalous authentication or submission activity. 7. Rotate the exposed password and invalidate tokens after migrating to encrypted transport. 8. Where the threat model warrants it, use certificate pinning with a managed rotation process. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/jwt_token.py:160
Finding
JWT Bearer Tokens Stored in Plaintext Files Without Explicit Access Restrictions<![CDATA[ ## Vulnerability Details **File Location**: `scripts/jwt_token.py`, lines 160–188 **Vulnerability Type**: Insecure storage of authentication tokens **Risk Level**: Medium ### Vulnerable Code ```python def save_token(token: str, token_file: Path) -> None: token_file.write_text(token, encoding="utf-8") logging.info(f"Token 已写入: {token_file}") def get_daily_cache_file() -> Path: date_str = datetime.now().strftime("%Y%m%d") return TOKEN_CACHE_DIR / f"jwt_token_{date_str}.txt" def load_daily_cached_token() -> str | None: cache_file = get_daily_cache_file() if not cache_file.exists(): return None token = cache_file.read_text(encoding="utf-8").strip() if not token: return None logging.info(f"复用当天缓存 Token: {cache_file}") return token def save_daily_cache_token(token: str) -> None: cache_file = get_daily_cache_file() cache_file.write_text(token, encoding="utf-8") logging.info(f"当天缓存 Token 已更新: {cache_file}") ``` ### Technical Analysis The same bearer token is persisted in two ordinary plaintext locations: - The per-run `output/jwt_token.txt` file. - A date-based file under `token_cache`. `Path.write_text()` creates or truncates files according to the process umask and does not explicitly enforce owner-only permissions. On a shared system, permissive directory permissions or umask settings may expose the token to other local users and processes. Backups, artifact collection, or accidental packaging of run output can also retain the token. The daily cache is reused solely according to its filename and presence. The code does not inspect token expiry before reuse. In addition, the `expire_minutes` workflow parameter is accepted but ignored, so the documented 30-minute setting does not control token lifetime. ### Attack Path 1. An attacker obtains local read access to the project directory, a `run_*` directory, `token_cache`, a backup, or a collected build artifact. 2. The attacker r ...[truncated 724 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Avoid persistent token storage and retain the token only in memory for the duration of the submission workflow. 2. If persistence is operationally required, use an OS-backed credential store or an approved encrypted secret store. 3. Create token files atomically with owner-only permissions, such as mode `0600`, and ensure parent directories are not accessible to unrelated users. 4. Never include token files in output archives, backups, logs, or release packages. 5. Parse and validate expiry, issuer, audience, and intended scope before reusing a cached token. 6. Delete expired and stale cache entries automatically. 7. Make token lifetime a server-enforced policy rather than relying on the currently ignored `expire_minutes` argument. 8. Use separate least-privileged tokens for each run where practical. ]]>

T08 · Insecure Dependencies

Warning
Location
scripts/jwt_token.py:7
Finding
Unpinned Third-Party Runtime Dependencies<![CDATA[ ## Vulnerability Details **File Locations**: - `scripts/jwt_token.py`, lines 7–22 - `scripts/data_submit.py`, lines 9–26 - `scripts/preprocess_excel.py`, runtime imports of `pandas`, `openpyxl`, and `xlrd` **Vulnerability Type**: Uncontrolled dependency resolution **Risk Level**: Medium ### Vulnerable Code From `scripts/jwt_token.py`: ```python 依赖: pip install requests """ import argparse import logging import sys from datetime import datetime from logging.handlers import RotatingFileHandler from pathlib import Path try: import requests except ModuleNotFoundError as _exc: raise SystemExit("缺少依赖 requests,请先执行: pip install requests") from _exc ``` From `scripts/data_submit.py`: ```python 依赖: pip install requests """ try: import requests except ModuleNotFoundError as _exc: raise SystemExit("缺少依赖 requests,请先执行: pip install requests") from _exc ``` Additional dependencies are imported without a project lockfile: ```python import pandas as pd ``` ```python importlib.import_module("openpyxl") importlib.import_module("xlrd") ``` ### Technical Analysis The project instructs operators to install `requests` without a version constraint or integrity hash. It also depends on `pandas`, `openpyxl`, and `xlrd`, but the audited directory contains no dependency lockfile or hash-verified requirements manifest. As a result, installations may resolve to different package versions over time. A compromised package release, package-index account, repository mirror, or dependency in the transitive dependency graph could introduce code that executes during installation or import. No evidence was found that the Skill intentionally references a typosquatted package or an explicitly untrusted index. The issue is the lack of reproducible, integrity-verified dependency management rather than proof that a currently named package is malicious. ### Attack Path 1. An operator follows the embedded instruction and runs `pip install requests`, or man ...[truncated 1068 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Provide a reviewed dependency manifest covering `requests`, `pandas`, `openpyxl`, `xlrd`, and all required transitive packages. 2. Pin exact versions and use cryptographic hashes, for example through a hash-locked requirements file. 3. Generate and commit a lockfile using a controlled dependency-management process. 4. Install packages only from an approved package repository or internally mirrored index. 5. Enable automated vulnerability, license, provenance, and integrity scanning. 6. Review and test dependency updates before deployment rather than resolving mutable latest versions at runtime. 7. Build and distribute a signed, reproducible runtime artifact where practical. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (12)

Missing User Warnings

High
Confidence
99% confidence
Finding
The script sends a username and password to an HTTP endpoint at a private IP address, which provides no transport-layer confidentiality or integrity. Anyone with network visibility or man-in-the-middle capability on that network can intercept credentials and the returned JWT, then reuse them to authenticate as the user.

Missing User Warnings

High
Confidence
99% confidence
Finding
The username and password are hardcoded directly in the script, making credential exposure likely through source control, backups, logs, screenshots, and accidental sharing. Because the same credentials are then used for authentication, compromise of the codebase or artifact is equivalent to compromise of the account.

Intent-Code Divergence

Medium
Confidence
98% confidence
Finding
The workflow hardcodes a JWT secret key directly in the manifest while presenting the step as a security/authentication layer. A static embedded secret is easily disclosed through source access, logs, backups, or package distribution, allowing forged tokens and undermining the trust model of any downstream submission step.

Missing User Warnings

Medium
Confidence
87% confidence
Finding
The manifest includes a JWT generation step and a final data submission step, but the description does not warn users that authentication material is used and data may be transmitted outward. This lack of disclosure can cause users to run the skill without understanding that it may create tokens and submit processed enterprise data to another system.

Missing User Warnings

Medium
Confidence
89% confidence
Finding
The skill explicitly enables persistent logging, checkpoint saving, and output file retention but does not warn users that operational data may be written to disk. In a workflow that processes enterprise Excel/CSV/JSON data, this can expose sensitive business information through logs, saved intermediates, or retained artifacts beyond the user's expectations.

Intent-Code Divergence

Medium
Confidence
95% confidence
Finding
The docstring states that paths are determined solely by script-internal configuration, implying fixed configured locations. However, main() loads a run ID from current_run_id.txt and derives per-run INPUT_JSON_DIR_CONFIG and TOKEN_FILE_CONFIG dynamically, so the effective file paths are not solely the static configured ones described in the documentation.

External Transmission

Medium
Category
Data Exfiltration
Content
}
    logging.info(f"发送 {len(parts)} 条记录 → {url}")
    try:
        resp = requests.post(url, json=parts, headers=headers, timeout=timeout)
        resp.raise_for_status()
        result = resp.json()
        state  = result.get("httpstate")
Confidence
91% confidence
Finding
The script transmits JSON payloads and a Bearer JWT to an HTTP endpoint using cleartext transport, which exposes both sensitive business data and authentication tokens to interception or modification by anyone on the network path. In an industrial data submission context, this materially increases the risk of credential theft, replay, tampering, and unauthorized API actions.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The script writes the JWT to output/jwt_token.txt and also caches it in token_cache without any access-control checks, encryption, or permission hardening. A local user, another process, or a later workflow step with filesystem access can read and reuse the bearer token until it expires.

External Transmission

Medium
Category
Data Exfiltration
Content
headers = {"Content-Type": "application/json; charset=utf-8"}

    logging.info(f"请求登录接口: {url}")
    resp = requests.post(url, json=payload, headers=headers, timeout=timeout)

    # 先尝试解析响应体,以便在 raise_for_status 前记录服务端错误信息
    try:
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
This code file contains natural-language strings exclusively in Chinese in the module docstring, CLI description, argument help, errors, and logs. Under the policy, forcing a specific language without user opt-in is a locale/language policy violation unless the constraint is explicitly justified, which is not present here.

Natural-Language Policy Violations

Low
Confidence
79% confidence
Finding
The natural-language description and operational commentary are entirely in Chinese, with no indication that users may choose another language or that the skill is intentionally restricted to a Chinese-speaking or region-specific context. Per SQP-3, forcing a specific language without opt-in can violate language/locale policy expectations.

Natural-Language Policy Violations

Low
Confidence
95% confidence
Finding
This file includes its module docstring, CLI description, help text, and runtime messages only in Chinese. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale constraint is explicitly justified.

Static analysis

Detected: suspicious.exposed_secret_literal

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
SKILL.md:60