Back to skill

Security audit

patent-transaction

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its patent-marketplace purpose, but it automatically installs an unpinned spreadsheet package at runtime and handles API tokens in a less safe way.

Review before installing in a shared or sensitive environment. The skill will send patent marketplace queries to trade.9235.net using TRADE_API_TOKEN and can write exported transaction data under trade-exports. Install openpyxl through a controlled, pinned dependency process instead of allowing runtime pip installation, prefer header-based token authentication, and avoid opening exported spreadsheets from untrusted marketplace data without formula-injection protections.

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

T08 · Insecure Dependencies

Error
Location
export_deps.py:19
Finding

Unpinned Dependency Is Downloaded and Installed at Runtime

Content
View full analysis
bool: if package in _INSTALL_ATTEMPTED: return False _INSTALL_ATTEMPTED.add(package) commands: list[list[str]] = [] uv = shutil.which("uv") if uv: commands.append([uv, "pip", "install", package, "-q"]) commands.append([sys.executable, "-m", "pip", "install", package, "-q"]) for cmd in commands: try: proc = subprocess.run( cmd, timeout=180, capture_output=True, text=True, ) if proc.returncode == 0: importlib.invalidate_caches() return True except (OSError, subprocess.TimeoutExpired): continue return False def ensure_openpyxl() -> Tuple[bool, str | None]: try: import openpyxl # noqa: F401 return True, None except ImportError: if _try_install("openpyxl"): try: import openpyxl # noqa: F401 return True, None except ImportError: pass ``` ### Technical Analysis When `openpyxl` is unavailable, the skill automatically invokes `uv pip install openpyxl` or `python -m pip install openpyxl`. The package has no pinned version, integrity hash, trusted-index restriction, or prior administrative approval. Although the package name is hardcoded and therefore is not directly vulnerable to shell injection, installation still downloads executable Python package content from the package index configured in the runtime environment. Package installation and subsequent import may execute package-controlled setup, build, or import-time code with the privileges of the skill process. This creates a supply-chain execution path whose ...[truncated 1283 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
excel_export.py:38
Finding

Spreadsheet Formula Injection Through API-Controlled Export Data

Content
View full analysis
str: if text is None: return "" s = str(text) s = re.sub(r"", "", s, flags=re.IGNORECASE) s = re.sub(r"<[^>]+>", "", s) return s.replace("\n", " ").strip() def build_csv_bytes( headers: Sequence[str], rows: Sequence[Sequence[Any]] ) -> bytes: buf = io.StringIO() writer = csv.writer(buf) writer.writerow(list(headers)) for row in rows: writer.writerow( [strip_markup(c) if isinstance(c, str) else c for c in row] ) return buf.getvalue().encode("utf-8-sig") def build_xlsx_bytes( headers: Sequence[str], rows: Sequence[Sequence[Any]], sheet_name: str = "数据" ) -> bytes: deps = _load_deps() ok, err = deps.ensure_openpyxl() if not ok: raise deps.ExportNotAvailable(err or "openpyxl unavailable") from openpyxl import Workbook from openpyxl.utils import get_column_letter wb = Workbook() ws = wb.active ws.title = sheet_name[:31] or "Data" ws.append(list(headers)) for row in rows: ws.append([strip_markup(c) if isinstance(c, str) else c for c in row]) ``` Relevant API-originated fields are assembled into export rows in `trade_api.py:293-309` and `trade_api.py:338-353`, including patent titles, applicants, buyers, and sellers. ### Technical Analysis `strip_markup()` removes HTML tags and newline characters, but it does not neutralize spreadsheet control prefixes such as `=`, `+`, `-`, or `@`. API-originated string values are subsequently written directly into CSV and XLSX cells. Spreadsheet software may interpret such values as formulas rather than literal text. For XLSX output, strings beginning with `=` may be represented by `openpyxl` as formula cells. CSV consumers may similarly interpret dangerous prefixes whe ...[truncated 1607 chars]
Remediation
View remediation
Any: if not isinstance(value, str): return value value = strip_markup(value) if value.lstrip().startswith(("=", "+", "-", "@")): return "'" + value return value ``` 2. Apply the protection consistently to CSV headers, CSV cells, XLSX headers, and XLSX cells. 3. For XLSX files, explicitly force untrusted cells to a string data type rather than relying solely on inferred typing. 4. Consider neutralizing leading tab, carriage-return, and other characters that can hide a dangerous formula prefix. 5. Add regression tests for values beginning with `=`, `+`, `-`, `@`, tabs, and leading whitespace. 6. Treat all remote API fields as untrusted even if the marketplace currently performs its own validation. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
trade_api.py:133
Finding

API Credential Is Transmitted in the URL Query String

Content
View full analysis
Dict[str, Any]: if params is None: params = {} if self._skill_mode and self.token: params["t"] = self.token params["v"] = 1 url = f"{self.base_url}/{endpoint.lstrip('/')}" try: resp = requests.get(url, params=params, timeout=30) if resp.status_code != 200: return { "success": False, "errorCode": resp.status_code, "message": resp.text[:200], } raw = resp.json() if not isinstance(raw, dict): return {"success": False, "errorCode": 203, "message": "Invalid response format"} return self._normalize_response(raw) except requests.exceptions.Timeout: return {"success": False, "errorCode": 408, "message": "Request timed out"} except requests.exceptions.ConnectionError: return {"success": False, "errorCode": 503, "message": "Connection failed"} except Exception as e: return {"success": False, "errorCode": 500, "message": str(e)} ``` ### Technical Analysis Passing `params` to `requests.get()` serializes the API token as `?t=` in the complete request URL. TLS protects the URL while it is in transit between correctly authenticated endpoints, but it does not prevent the URL from being recorded at either endpoint or by authorized infrastructure. Complete URLs are commonly retained by reverse proxies, API gateways, web-server access logs, application-performance monitoring systems, debugging tools, and tracing platforms. Query parameters may also appear in exception diagnostics. These systems frequently have broader readership and longer retention than dedicated secret s ...[truncated 1239 chars]
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (17)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares network, shell, environment variable, and file-write capabilities but does not constrain them with an explicit tool scope such as permissions or allowed-tools. In a skill that sends authenticated requests and exports Excel files, this ambiguity increases the chance of unintended command execution, overbroad file writes, or data exfiltration beyond what users would reasonably expect.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill describes authenticated trade queries and Excel export to an external service but does not clearly disclose that user-supplied search terms, transaction-related data, and tokens may be transmitted off-platform. In a due-diligence and marketplace context, those queries may reveal confidential commercial interest, making the lack of disclosure and consent materially risky.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The trigger phrases are broad and overlap with ordinary patent-related conversation, which can cause the skill to activate unexpectedly during unrelated discussions. Because the skill can use credentials, call an external API, and export files, accidental activation may leak user queries or initiate external actions without sufficiently clear user intent.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Modifying the execution environment at runtime by installing packages is a broader and riskier behavior than simple data export. This can undermine reproducibility, violate least-privilege expectations, and permit unreviewed third-party code to be fetched and installed during ordinary skill execution.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The skill performs runtime package installation via subprocess, which introduces network-dependent code acquisition and execution in the host environment. Even if intended to improve export functionality, this expands capability beyond normal patent marketplace operations and can expose users to supply-chain risk, unexpected system changes, and policy bypass in restricted environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

Automatic package installation launches subprocesses and may perform network-backed system changes without explicit user consent or warning. In agent or hosted environments, this can surprise operators, breach platform policy, or install code from external repositories in contexts where outbound network or package changes are not expected.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · export_deps.py (reported line 32)May include surrounding context.

python
for cmd in commands:
        try:
            proc = subprocess.run(
                cmd,
                timeout=180,
                capture_output=True,

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

Multiple user-facing strings, including the module docstring, CLI description, help text, errors, and secret-configuration hint, are presented exclusively in Chinese. That creates a language policy concern because the skill does not offer any language choice or indicate that Chinese is an optional or region-specific mode.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The client appends the API token as the t query parameter on GET requests in skill mode. Tokens in URLs are commonly exposed via logs, browser/history equivalents, reverse proxies, monitoring systems, and referrer propagation, so this weakens credential confidentiality even if HTTPS is used.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The markdown explicitly advertises export and export_orders commands that generate Excel output, which implies file creation on the user's system. The README provides usage and configuration details but does not include any user-facing warning about file output location, overwriting behavior, or handling of exported transaction data.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file contains only Chinese-language instructions and labels, with no indication that users may choose another language or that the language restriction is required by context. Under the stated policy, forcing a specific language without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This Python file contains natural-language strings presented to users only in Chinese, starting with the module description. The policy requires avoiding forced language or locale choices unless the skill offers opt-in or clearly documents a justified regional scope, which is not present in this file.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The returned status message shown after export fallback is written only in Chinese, which can impose a language choice on users. There is no indication in this file that the user can choose a language or that the Chinese-only behavior is intentionally constrained to a documented locale-specific use case.

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 documentation string is written only in Chinese, which imposes a specific language on users and maintainers without any opt-in or explanation that the skill is intended for a Chinese-only audience. The policy allows locale constraints when they are justified or optional, but neither is present here.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

This code instantiates and uses a TradeAPI that depends on the secret TRADE_API_TOKEN, but the only disclosure appears reactively in the ValueError handler after execution fails. For a code file, access to credentials should have some visible user disclosure such as a comment, docstring, or user-facing message explaining that the skill relies on configured secrets and external API access.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The top-level natural-language documentation is exclusively in Chinese and does not provide any language choice or indicate that the skill is intentionally limited to a Chinese-speaking or region-specific audience. Under the language/locale policy, forcing a single language without opt-in can be a policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

The export path calls xl.export_table(...) to create outbound assets under trade-exports, which is a file-write operation. While the returned message confirms export after the fact, there is no prior warning, confirmation, or inline disclosure in this file that invoking export operations will write potentially sensitive transaction data to local files.

Content

No source excerpt is available for this finding.

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
excel_export.py:33

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
main.py:28

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
trade_api.py:33