Back to skill

Security audit

百炼智能 · 招投标全能助手

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent procurement assistant, but it needs Review because it preserves login-bypass links in shareable reports and handles local credentials and device identifiers with incomplete safeguards.

Install only if you are comfortable with the provider API receiving your procurement queries and, for zero-config setup, a MAC-derived device hash after consent. Avoid sharing generated reports containing sk or auto-login sid links outside trusted recipients, and prefer supplying your own API key through a secure environment variable rather than relying on plaintext local credential storage.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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 (4)

T01 · Skill Instruction Hijacking

Warning
Location
SKILL.md:168
Finding
Mandatory Promotional Content and Vendor-Link Injection into Agent Outputs<![CDATA[ ## Vulnerability Details **File Location**: `SKILL.md:168-182`; `references/company-intel/report-template.md:193`; `references/opportunity-radar/report-template.md:80`; `scripts/bid-decision/render_report.py:198-284`; `scripts/company-intel/render_report.py:453-479`; `scripts/opportunity-radar/render_report.py:215-305` **Vulnerability Type**: Output manipulation through Skill instructions **Risk Level**: Medium ### Vulnerable Code and Instructions The main Skill instructions require fixed introductory content and an additional recommendation after every answer: ```markdown ## Installation-success self-introduction (fixed output; every item is required) After every answer, provide exactly one most relevant next-step recommendation. Select it according to what the user just did. ``` Report templates similarly require persistent monitoring promotions: ```markdown - Monitoring hook (fixed output) → Ask whether the user wants to turn the company investigation into a scheduled competitor-dynamics weekly report. ``` ```markdown - Subscription guidance (fixed output) → Ask whether the user wants to turn the scan conditions into a daily automated opportunity report. ``` The renderers also inject fixed branding and vendor calls to action independently of the report data. For example, the company-intelligence renderer contains the following fixed footer: ```python parts.append( '<div class="footer">' f'<div class="cta">📡 想持续盯这家公司的中标动态和新增客户?可把本次背调固化成「竞对动态周报」定时跑增量 · ' f'更深度的多公司在线对比分析,可登录知了标讯主站查看 · 企业完整档案与更多商机详情,见 ' f'<a href="https://agent.zhiliaobiaoxun.com" target="_blank">知了商机大师</a>' f' · 本报告由 <a href="https://ai.zhiliaobiaoxun.com" target="_blank">知了标讯 AI 开放平台</a> 企业情报 Skill 生成</div>' ) ``` ### Technical Analysis These instructions alter the Agent's response behavior beyond the minimum functionality required to search procurement records, assess bids, or render reports. They require promotional recommendations and vendor link ...[truncated 1686 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove requirements that promotional material be emitted after every answer. 2. Replace “fixed output” rules with optional recommendations that are shown only when directly relevant and requested. 3. Make report branding and calls to action configurable, with an option to generate a neutral report. 4. Clearly label any vendor recommendation as promotional content. 5. Do not automatically recommend scheduled monitoring unless the user explicitly asks for recurring execution. 6. Separate analytical findings from commercial links in both Agent responses and generated reports. 7. Add tests verifying that ordinary search and analysis requests can complete without promotional output. ]]>

T09 · Insecure Skill Coding Practices

Error
Location
scripts/bid-decision/render_report.py:59
Finding
HTML Attribute Injection and Unsafe URL-Scheme Handling in Report Renderers<![CDATA[ ## Vulnerability Details **File Location**: `scripts/bid-decision/render_report.py:59,138-139,204`; `scripts/company-intel/render_report.py:86,168-169,203,301,394,411`; `scripts/opportunity-radar/render_report.py:57,143-144` **Vulnerability Type**: Stored HTML injection and unsafe link generation **Risk Level**: High ### Vulnerable Code All three renderers define escaping through `xml.sax.saxutils.escape`: ```python from xml.sax.saxutils import escape as _esc def esc(s) -> str: return _esc(str(s if s is not None else "")) ``` They then place escaped, attacker-influenced values inside double-quoted HTML attributes: ```python def _link(text, url): return f'<a href="{esc(url)}" target="_blank">{esc(text)}</a>' if url else esc(text) ``` The bid-decision renderer also directly constructs a link from report input: ```python bid_link = f'<div class="meta"><a style="color:#d8f3ec" href="{esc(d["bid_url"])}" target="_blank">查看公告原文 ↗</a></div>' if d.get("bid_url") else "" ``` Equivalent vulnerable patterns occur in the company-intelligence renderer: ```python src_html = ( f'<span class="src">来源:<a href="{esc(src)}" target="_blank">{esc(src)}</a></span>' if src else "" ) ``` ```python inner += ( f'<div class="member-note">公司完整档案(业务词云/联系人/合作图谱免登录直达):' f'<a href="{esc(prof["url"])}" target="_blank">{esc(prof["url"])}</a></div>' ) ``` ### Technical Analysis `xml.sax.saxutils.escape()` escapes `&`, `<`, and `>` by default, but it does not escape quotation marks unless an explicit entity mapping is provided. It is therefore insufficient for values inserted into quoted HTML attributes. For example, an input URL shaped like the following can terminate the `href` attribute and introduce an event handler: ```text https://example.invalid/" onclick="alert(document.domain) ``` The generated markup would contain a new `onclick` attribute. The renderers also perform no URL parsing or scheme allowlisting. A value such as the following ca ...[truncated 2014 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use context-appropriate HTML attribute escaping: ```python from html import escape def esc_text(value) -> str: return escape(str(value if value is not None else ""), quote=False) def esc_attr(value) -> str: return escape(str(value if value is not None else ""), quote=True) ``` 2. Validate every URL with `urllib.parse.urlsplit()` and allow only explicitly supported schemes: ```python from urllib.parse import urlsplit def safe_url(value) -> str: value = str(value or "").strip() parsed = urlsplit(value) if parsed.scheme.lower() not in {"https", "http"}: return "" if not parsed.netloc: return "" return esc_attr(value) ``` 3. Reject control characters, protocol-relative URLs, malformed hostnames, and active schemes including `javascript:`, `data:`, `file:`, and `vbscript:`. 4. Add `rel="noopener noreferrer"` to every link that uses `target="_blank"`. 5. Prefer a proper HTML templating engine with automatic context-aware escaping. 6. Add a restrictive Content Security Policy. Where inline script is required, use a nonce rather than allowing unrestricted inline execution. 7. Add regression tests for quote injection, event-handler injection, mixed-case schemes, whitespace-obfuscated schemes, and encoded `javascript:` URLs. 8. Apply the correction consistently to all three renderers and every direct `href` construction. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
references/auto-register.md:175
Finding
Plaintext API Key Persistence Without Required Owner-Only File Permissions<![CDATA[ ## Vulnerability Details **File Location**: `references/auto-register.md:175-188` **Vulnerability Type**: Insecure local credential storage **Risk Level**: Medium ### Vulnerable Instructions The automatic registration workflow persists a bearer API key in a plaintext JSON file: ```json { "api_key": "zlbx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "source": "auto", "registered_at": "2026-05-10T10:30:00Z" } ``` The accompanying file-handling requirements are limited to directory creation and configuration merging: ```markdown - If the directory does not exist, first create `~/.zlbx`. - If the file already exists, merge rather than overwrite it. - The `source: "auto"` field must be written. ``` No owner-only permissions are required for either the directory or the credential file. ### Technical Analysis The API key is a bearer credential: possession is sufficient to authenticate API requests. Persisting it in plaintext can be acceptable for a command-line application only when access controls are explicitly enforced. The workflow relies on the process's current umask and pre-existing directory permissions. On systems with permissive defaults, shared home directories, unusual container mounts, backup synchronization, or pre-created configuration paths, the file may be readable by unintended local principals. The instructions also do not require atomic creation, symlink checks, or protection against replacing `~/.zlbx/config.json` with a link to another path. Consequently, an implementation that follows only the documented requirements may expose the key or write it through an attacker-controlled filesystem object. ### Attack Path 1. Automatic registration returns a valid API key. 2. The Agent creates `~/.zlbx` and writes `config.json` using default permissions. 3. A permissive umask, insecure pre-existing directory, shared mount, or malicious symbolic link leaves the credential accessible outside the intended user account. 4. Another local proces ...[truncated 631 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create the configuration directory with owner-only permissions: ```python config_dir.mkdir(mode=0o700, parents=True, exist_ok=True) os.chmod(config_dir, 0o700) ``` 2. Create the credential file with mode `0600`, independent of the current umask. 3. Write the file atomically using a temporary file in the same protected directory, call `fsync()`, set permissions, and then use `os.replace()`. 4. Refuse to follow symbolic links and verify that the target is a regular file owned by the current user. 5. Prefer an operating-system credential store such as Keychain, Credential Manager, or Secret Service. 6. Never include the API key in console output, exception messages, telemetry, generated reports, or shell command history. 7. Document key rotation and revocation procedures. 8. Validate and repair unsafe permissions when reading an existing configuration file. ]]>

other

Note
Location
references/auto-register.md:40
Finding
Stable Hardware-Derived Device Fingerprint Sent to an External Registration Service<![CDATA[ ## Vulnerability Details **File Location**: `references/auto-register.md:40-119` **Vulnerability Type**: Device fingerprint collection and external transmission **Risk Level**: Low ### Relevant Instructions The workflow reads and hashes a physical network interface's MAC address. On Linux, it uses: ```bash iface=$(ls /sys/class/net | grep -vE '^(lo|docker|veth|br-|tun|tap)' | sort | head -n1) cat "/sys/class/net/$iface/address" 2>/dev/null \ | tr -d ':-' | tr 'A-Z' 'a-z' \ | sha256sum | awk '{print $1}' ``` On macOS, it uses: ```bash ifconfig | awk '/ether/{print $2; exit}' \ | tr -d ':' | tr 'A-Z' 'a-z' \ | shasum -a 256 | awk '{print $1}' ``` The resulting value is sent with platform and architecture data: ```json { "device_features": { "hostname": "", "platform": "darwin", "arch": "arm64", "username": "", "home_path": "", "mac_hash": "abc123..." }, "agent_kind": "claude-code", "agent_version": "...", "skill_version": "flagship-1.0.1", "ch": "s142" } ``` The destination is: ```text POST https://ai.zhiliaobiaoxun.com/web-api/internal/auto-register ``` ### Technical Analysis A SHA-256 hash of a normalized MAC address remains a stable device identifier. Hashing protects the original MAC address from immediate plaintext disclosure, but it does not make the result anonymous. The identifier can still support durable correlation of registrations from the same physical interface. The workflow requires user consent before collection and provides an API-key-based opt-out, which materially reduces the risk. Nevertheless, collection of a hardware-derived identifier is not necessary to perform tender analysis itself. It serves the provider's trial-abuse prevention and account-registration requirements rather than the Skill's core analytical functions. The documentation characterizes the collected values as having no identity significance. That description understates the correlation properties of a stable M ...[truncated 1346 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace the MAC-derived identifier with a randomly generated installation identifier stored locally. 2. If abuse prevention requires server involvement, use a revocable, scoped token rather than a permanent hardware-derived value. 3. Clearly describe the value as a stable device identifier rather than claiming it has no identity significance. 4. State the retention period, access policy, deletion process, and whether the identifier is used for any purpose beyond trial deduplication. 5. Provide separate consent for hardware fingerprinting rather than combining it with general account creation. 6. Allow registration without hardware fingerprinting, potentially with a lower trial limit or an alternative verification mechanism. 7. Salt or key any unavoidable identifier derivation on the server, with rotation and purpose separation. 8. Ensure that a failed collection does not produce a shared constant identifier that can incorrectly associate unrelated devices. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (13)

Lp3

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding
The skill explicitly instructs the agent to read and write local files, including `~/.zlbx/config.json`, while declaring no corresponding permissions. This creates a capability/permission mismatch that can lead to unauthorized local secret access or persistence of credentials outside the user's expected consent boundary.

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The skill includes an auto-registration flow that collects device-derived identifiers (OS, CPU architecture, MAC-hash) and creates platform accounts, which is outside the stated bidding-analysis purpose and introduces privacy-sensitive behavior. Even though the document describes minimization and consent, this still expands the skill from analysis into account provisioning and device fingerprinting, creating unnecessary data collection and external account linkage risk.

Description-Behavior Mismatch

High
Confidence
98% confidence
Finding
The document states that user consent must be obtained before any collection or registration, but the pseudocode later performs feature collection and registration automatically when no API key is present. This mismatch is dangerous because implementers may follow the code path instead of the prose, causing silent collection and external transmission of device fingerprint data without user approval.

Intent-Code Divergence

High
Confidence
98% confidence
Finding
The file expressly forbids collecting data before consent, yet the provided pseudocode omits that check and calls collect_device_features() directly in the auto-registration branch. Because this is a privacy-affecting contradiction in implementation guidance, it can lead to non-consensual fingerprint collection and transmission, especially in agent environments where users may not realize setup actions are occurring.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The template explicitly requires user-facing links to preserve raw `sk`免登录 parameters and to output them back to the user. If `sk` is a bearer-style access token or user-scoped bypass parameter, exposing it enables link sharing, replay, and unintended access to enterprise data outside the immediate conversation. In this skill context, that is more dangerous because the skill routinely handles company intelligence and account-scoped data, so tokenized links may grant broader access than the user intended to disclose.

Context-Inappropriate Capability

Medium
Confidence
86% confidence
Finding
The template instructs the agent to serialize report data to a temporary file and run a local Python script to generate HTML. That expands the skill from pure text generation into filesystem write and code-execution behavior, increasing the attack surface for path manipulation, unsafe data handling, and unintended local side effects. In a report-template file, this capability is not strictly necessary to fulfill the core enterprise-intel analysis task.

Context-Inappropriate Capability

Medium
Confidence
89% confidence
Finding
The template goes beyond formatting guidance and instructs the agent to create a temporary JSON file and execute a local Python script. That introduces local code-execution and filesystem-write behavior based on report content, which expands the skill’s authority and can become dangerous if untrusted data is passed into the script path, output path, or rendered HTML without strict validation.

Context-Inappropriate Capability

Medium
Confidence
88% confidence
Finding
The skill documents an API that returns company project contact information, including phone numbers and named contacts tied to bidding activity. Even though free accounts receive masked numbers, the interface still enables targeted harvesting of business contact data and the description explicitly supports access to full numbers for paid users, which expands the skill from analysis into direct personal/business contact exposure.

Description-Behavior Mismatch

Medium
Confidence
94% confidence
Finding
The documentation instructs the skill to automatically register an account and persist a newly issued API key into a local file under ~/.zlbx/config.json. That exceeds a read/query-only account scope and introduces unauthorized state-changing behavior plus local credential storage, which can surprise users and widen the blast radius if the host or profile directory is later compromised.

Context-Inappropriate Capability

High
Confidence
98% confidence
Finding
The skill directs collection of device fingerprinting attributes (platform, architecture, and MAC-derived hash) to perform auto-registration. This is unnecessary for a tender search assistant's core function and creates privacy risk, persistent device correlation, and possible tracking across sessions or accounts, especially because failure is silently tolerated and collection is normalized as part of onboarding.

Ssd 3

Medium
Confidence
96% confidence
Finding
The template explicitly instructs the agent to expose and preserve the full `url` including the `sk` parameter in user-facing output and generated HTML. If `sk` is an authentication or signed-access token, disclosing it to users, chat logs, exports, or downstream recipients can bypass normal login controls and enable unauthorized reuse of access to linked records. In this skill context, the risk is amplified because the links are intentionally propagated into reports designed for sharing.

Ssd 3

High
Confidence
99% confidence
Finding
Preserving and displaying raw login-bypass `sk` parameters is a direct sensitive-data disclosure issue. Such parameters commonly act as bearer secrets embedded in URLs; once shown in chat, Markdown, JSON, HTML, logs, or shared files, they can be copied by unintended recipients and used to access gated company pages or deeper platform content. The surrounding instructions to keep `sk` '原样' and include it in multiple output formats materially increase leakage channels.

External Transmission

Medium
Category
Data Exfiltration
Content
> ### ⚠️ 请求体必须用 JSON 序列化函数生成,不要手拼字符串
>
> 用 `json.dumps(payload)` / `requests.post(url, json=payload)` / `JSON.stringify(payload)`,
> 或 `curl -d @file`;**不要用字符串拼接,也不要用 Python 的 `str(dict)`**
> (后者产出单引号,服务端会报 `Expecting property name enclosed in double quotes`)。
>
Confidence
87% confidence
Finding
This section instructs the agent to send collected device features to an external service via JSON POST. In context, the danger is not the use of JSON serialization itself, but that the skill is designed to exfiltrate device-derived data to a remote endpoint as part of automatic account creation, which increases privacy and tracking risk beyond the core skill purpose.

Static analysis

No suspicious patterns detected.