Back to skill

Security audit

投标报价对比分析驾驶舱

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it can generate and publish sensitive bid dashboards with a real script-injection weakness and insufficient confidentiality gating.

Install only if you are comfortable reviewing generated HTML before sharing. Treat supplier names, prices, evaluator scores, and award recommendations as confidential; default to local/internal distribution, sanitize or reject untrusted quotation text, and do not publish public links unless the data owner explicitly approves external hosting.

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

T09 · Insecure Skill Coding Practices

Error
Location
bid-quote-cockpit/scripts/build_dashboard.py:1380
Finding

Stored JavaScript Injection Through Unsafe JSON Embedding in Generated Dashboards

Content
View full analysis

Vulnerability Details

File Location: bid-quote-cockpit/scripts/build_dashboard.py, lines 1380–1392
Vulnerability Type: Stored script injection in generated HTML
Risk Level: High

Vulnerable Code

python
data_js = "var DATA=" + json.dumps(
    {k: model[k] for k in ("meta", "cats", "vendors", "stats", "catMeans",
                           "hist", "charts", "staticCharts", "detailCharts",
                           "modules")}, ensure_ascii=False) + ";"

html = (
    "<!DOCTYPE html><html lang='zh-CN'><head><meta charset='utf-8'>"
    "<meta name='viewport' content='width=device-width,initial-scale=1'>"
    "<title>%s</title><style>%s</style>%s</head><body>%s"
    "<script>%s</script><script>%s</script><script>%s</script>%s"
    "</body></html>"
    % (esc(model["meta"]["project"]), CSS, panel_css, body, echarts, data_js, JS,
       panel_dom + panel_js)
)

Technical Analysis

The generator serializes the complete dashboard model using json.dumps() and inserts the resulting text directly into an executable HTML <script> element:

html
<script>var DATA=...;</script>

JSON string escaping does not protect the surrounding HTML parser context. In particular, Python's json.dumps() preserves a literal </script> sequence inside string values. HTML parsers terminate a script element when they encounter that sequence, even when it appears inside what JavaScript would otherwise treat as a quoted string.

The embedded model contains text originating from config.json, quotes.json, and optional history data. The audited model construction preserves fields such as supplier names, item descriptions, notes, source names, category labels, project metadata, and other quote content. Supplier quotation material can therefore cross from externally supplied business data into an executable browser context.

For example, a text field containing the following value would break out of the generated data script:

html
</script><script
...[truncated 2304 chars]
Remediation
View remediation

Remediation Suggestions

  1. Apply script-context-safe JSON serialization. At minimum, neutralize characters that can affect HTML parsing after serialization:
python
def json_for_script(value):
    return (
        json.dumps(value, ensure_ascii=False)
        .replace("&", "\\u0026")
        .replace("<", "\\u003c")
        .replace(">", "\\u003e")
        .replace("\u2028", "\\u2028")
        .replace("\u2029", "\\u2029")
    )

data_js = "var DATA=" + json_for_script(model_subset) + ";"

Escaping < prevents any input from producing a literal </script> sequence.

  1. Prefer a non-executable JSON container. Store serialized data in an element such as:
html
<script id="dashboard-data" type="application/json">...</script>

Then load it using:

javascript
const DATA = JSON.parse(document.getElementById("dashboard-data").textContent);

The serialized content must still neutralize literal < characters because the HTML parser recognizes script end tags regardless of the script type.

  1. Keep HTML and JavaScript escaping separate. Continue using HTML escaping for visible DOM content, but introduce a dedicated serializer for values embedded into JavaScript or JSON script blocks.

  2. Add regression tests for every externally sourced text field. Tests should generate and open dashboards containing values such as:

text
</script><script>window.__INJECTION_TEST__=true</script>

The resulting HTML must contain no literal attacker-provided </script> sequence inside the data block, and window.__INJECTION_TEST__ must remain undefined after browser rendering.

  1. Add a restrictive Content Security Policy as defense in depth. Remove inline scripts where practical and use script hashes or nonces. Restrict connect-src to required destinations so that an injection flaw cannot freely exfiltrate dashboard data. CSP is supplementary and must not replace correct serialization.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (43)

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向投标报价业务的看板生成/发布能力,核心应涉及报价汇总、横向对比、异常核查、评分定标、HTML 看板渲染与固化展示。实际代码并未处理任何投标、报价、评分、历史数据或看板业务内容,也没有生成分析结果页面;它只对一个已经存在的 HTML 看板做前端布局质量检查。虽然这可能是看板交付流程中的辅助工具,但就该代码块本身而言,其主要目的与声明的主要功能明显不同,属于未声明的独立能力,因此应判定为描述与行为不匹配。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
96% confidence
Finding

该代码与声明的“投标报价对比分析驾驶舱”主功能明显不符。脚本没有处理供应商报价数据、没有计算总价排名/单方造价/异常报价/评分定标,也没有构建或发布业务看板。它的核心行为是对已有 HTML 页面做渲染级文本导出与断言,用于交付前检查页面文案和数值是否正确。这更像一个辅助测试/验收工具,而不是用户描述的驾驶舱本体。虽然它可能属于看板项目的配套质检脚本,但就该代码块本身而言,声明未准确代表其实际行为。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about a business-facing bid comparison cockpit that outputs an interactive HTML dashboard with procurement analysis features. The supplied code does something entirely different: it is a developer utility/lint script for validating generated HTML/JS against accidental references to Python constant names. It reads local files, parses constants and script blocks, strips comments, checks for identifier leaks, prints diagnostics, and returns an exit code. There is no implementation of dashboard generation, quote analysis, scoring logic, HTML publication, or end-user cockpit functionality. This is a clear primary-purpose mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

声明描述的是一个业务分析与展示类技能,核心用途应是根据供应商报价数据生成并发布交互式投标报价对比看板。实际代码却是 verify_dashboard.js,一个辅助性的技术校验脚本:它接收现成的 HTML 文件路径,抽取其中脚本块,在沙箱中执行并校验图表配置、DOM 引用、空容器以及 undefined/NaN 泄漏,最后决定是否允许交付。虽然它与“看板交付”场景相关,但它并未实现声明中的主要业务功能,也未处理投标报价分析内容本身。因此这不是单纯的实现细节差异,而是主要目的与能力明显不一致。

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is for a domain-specific tender/bid analysis cockpit with concrete analytical outputs and optional modules. The actual code chunk is instead a massive encoded/minified implementation of low-level chart/rendering functionality: shapes, paths, text styling, gradients, animation, hit-testing, and related utilities. That kind of code could be a dependency used by a dashboard, but on its own it does not implement the declared application behavior. There is no visible logic for ingesting supplier quotations, comparing multiple bid rounds, calculating rankings/unit costs, validating anomalies, producing evaluator scoring conclusions, freezing scores into HTML bytes, or publishing a generated page. Therefore the supplied code does not accurately represent the declared skill purpose and is materially mismatched.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description is for a procurement/bid comparison skill with specific analytical outputs and publication behavior. However, the actual code chunk is a generic, minified visualization/charting engine payload rather than application logic for bid comparison. It contains broad chart library functionality: locale strings, toolbox labels, dataset/source handling, series/component models, rendering tasks, themes, symbols, tooltips, visual mappings, and scheduling. Those are supporting visualization capabilities, but the code provided does not demonstrate the declared primary purpose or the specific business behaviors claimed. Because the visible code is materially different in purpose and lacks the domain-specific workflow and output-generation behavior described, this is a description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description promises a domain-specific procurement/bid-analysis dashboard generator with concrete analytical outputs and publishing behavior. The actual code chunk, despite being labeled as a Python file, is a base64/minified blob whose decoded visible structure is clearly JavaScript visualization engine code: rendering paths, fills/strokes, canvas/SVG operations, chart model/view lifecycle, axes/scales, geometry handling, events, and data visualization internals. That may be a supporting dependency for dashboards, but by itself it does not implement the declared business function. There is no evidence in the supplied chunk of reading supplier quotes, computing total-price rankings, comparing bill-of-quantities sections, validating anomalies, fixing judge scores into output HTML, or publishing a self-contained HTML page. Therefore the supplied code does not accurately represent the declared purpose and is materially mismatched.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The declared description is for a domain-specific procurement/bidding analysis tool that should ingest supplier quotations, compare totals and line items, compute unit costs, perform anomaly and consistency checks, optionally embed judge scoring, and output a self-contained HTML dashboard. The provided code does not show such domain logic. Instead, it is dominated by minified rendering-engine functionality: axis coordinate transforms, tick generation, label placement, SVG/canvas rendering, path builders, animation CSS generation, line/bar series drawing, clipping, gradients, and layout internals. While such code could be a dependency used by a dashboard, this chunk by itself does not implement the declared product behavior and therefore does not accurately represent the described skill. There is no visible evidence of quotation parsing, bid comparison, scoring/finalization logic, HTML dashboard assembly, or cloud publishing behavior.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a domain-specific bidding quotation comparison cockpit that should contain logic for comparing supplier quotes, computing rankings and unit costs, validating anomalies and cross-checks, rendering optional historical/evaluator sections, and producing a self-contained read-only HTML deliverable. The provided code chunk instead looks like bundled/minified general-purpose charting library source. It defines rendering/layout behavior for multiple chart types, coordinate systems, axes, grids, radar, pie, scatter, geo/map support, SVG and GeoJSON parsing, and interaction controls. Those are generic visualization primitives, not the claimed business application. While such a library could be a supporting dependency of the cockpit, the supplied code chunk itself does not implement the declared purpose and exhibits major unrelated capabilities, so the description does not accurately represent what this code chunk actually does.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a domain-specific tender/bid quotation comparison dashboard generator with procurement-oriented analytics and optional fixed judge scoring embedded into output HTML. The actual code chunk instead contains what looks like encoded/minified frontend charting engine internals: coordinate systems for geo views, tree/treemap/graph series models and views, rendering paths, layout algorithms, roam/zoom actions, symbol/edge handling, and visual mapping. There is no visible implementation of bid comparison, supplier quote parsing, ranking, anomaly detection, reconciliation checks, scoring workflows, HTML report generation, publication, or immutable embedded evaluation data. This is a material purpose mismatch rather than a supporting implementation detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a domain-specific procurement/bidding analysis tool with concrete outputs and optional fixed judge-score embedding into a read-only HTML dashboard. The actual code chunk does not show any bid, supplier, pricing, scoring, report-generation, HTML assembly, or publication logic. Instead, it consists of heavily minified JavaScript-like rendering code embedded in a Python file, implementing generic chart/graphics features across many chart types. That is a materially different primary purpose. Even if such charting code could be a dependency of the intended tool, the supplied chunk itself does not substantiate the declared business functionality and instead exposes broad unrelated visualization capabilities. Therefore this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description promises a domain-specific procurement analysis tool that compares vendor bids, computes rankings and checks, and outputs a publishable self-contained HTML cockpit. The provided code instead is an opaque encoded/minified chunk whose decoded structure clearly corresponds to generic charting/rendering engine code: functions and types for pictorialBar, themeRiver, sunburst, custom series, animations, labels, clipping, coordinate systems, and axis pointers. These are low-level visualization capabilities, not the business logic described. While a bid cockpit might legitimately depend on a charting library, this code chunk by itself does not implement the declared purpose and is materially different in primary behavior. Therefore the description does not accurately represent what this supplied code chunk actually does.

Content

No source excerpt is available for this finding.

YARA rule 'privilege_escalation_tools': Privilege escalation tools and techniques [hacktools]

High
Category
YARA Match
Confidence
75% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · install_bid_quote_cockpit.py (reported line 2276)May include surrounding context.

python
9nLHFjKGQsMikpLnJl
cGxhY2UoL3tzfS9nLGQrIiIpLnJlcGxhY2UoL3tTU1N9L2cscWMoZiwzKSkucmVwbGFjZSgve1N9L2csZisiIil9ZnVuY3Rpb24gUWModCxlKXt2
YXIgbj11byh0KSxpPW5bbnAoZSldKCkrMSxyPW5baXAoZSldKCksbz1uW3JwKGUpXSgpLGE9bltvcChlKV0oKSxzPW5bYXAoZSldKCksbD0wPT09
bltzcChlKV0oKSx1PWwmJjA9PT1zLGg9dSYmMD09PWEsYz1oJiYwPT09byxwPWMmJjE9PT1yO3JldHVybiBwJiYxPT09aT8ieWVhciI6cD8ibW9u
dGgiOmM/ImRheSI6aD8iaG91ciI6dT8ibWludXRlIjpsPyJzZWNvbmQiOiJtaWxsaXNlY29uZCJ9ZnVuY3Rpb24gdHAodCxlLG4pe3ZhciBpPWoo
dCk/dW8odCk6dDtzd2l0Y2goZT1lfHxRYyh0LG4pKXtjYXNlInllYXIiOnJldHVybiBpW2VwKG4pXSgpO2Nhc2UiaGFsZi15ZWFyIjpyZXR1cm4g
aVtucChuKV0oKT49Nj8xOjA7Y2FzZSJxdWFydGVyIjpyZXR1cm4gTWF0aC5mbG9vcigoaVtucChuKV0oKSsxKS80KTtjYXNlIm1vbnRoIjpyZXR1
cm4gaVtucChuKV0oKTtjYXNlImRheSI6cmV0dXJuIGlbaXAobildKCk7Y2FzZSJoYWxmLWRheSI6cmV0dXJuIGlbcnAobildKCkvMjQ7Y2FzZSJo
b3VyIjpyZXR1cm4gaVtycChuKV0oKTtjYXNlIm1pbnV0ZSI6cmV0dXJuIGlbb3AobildKCk7Y2FzZSJzZWNvbmQiOnJldHVybiBpW2FwKG4pXSgp
O2Nhc2UibWlsbGlzZWNvbmQiOnJldHVybiBpW3NwKG4pXSgpfX1mdW5jdGlvbiBlcCh0KXtyZXR1c

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown file uses only Chinese for installation, operation, and safety instructions, and does not provide an opt-in language choice or explain that the skill is intentionally limited to a Chinese-speaking or region-specific audience. Under the policy rule, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill explicitly instructs users to run local Python, Node, and Chrome-based scripts, but it does not declare any tool restrictions or allowed-tools/permissions scope. In an agent environment, that mismatch can cause the skill to be executed with broader file, shell, and environment access than users expect, increasing the risk of unintended file reads/writes or command execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill encourages publishing generated dashboards to cloud pages or public links and states that evaluator scores may be permanently baked into the HTML. Without a prominent warning about sensitive commercial quotations, scoring results, and embedded evaluation data becoming publicly accessible, users may unintentionally disclose confidential procurement information.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill repeatedly encourages publishing generated bid-analysis dashboards to cloud pages or public links, but it does not prominently require a confidentiality review, data minimization, or explicit user confirmation before uploading potentially sensitive commercial bid data. In procurement contexts, quote amounts, vendor identities, scoring, and award recommendations are often confidential, so publishing them via public hosting can cause unauthorized disclosure and commercial harm.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill’s descriptive and instructional content is entirely in Chinese, and there is no statement offering language or locale choice to the user. Under the policy, forcing a specific language without opt-in is a natural-language policy violation unless the constraint is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

文件标题及全文说明均以中文编写,并将关键字段说明、规则和固定文案默认设定为中文,但没有说明这是面向特定中文用户群体的区域性技能,也没有提供用户语言选择。这可能构成语言/locale 策略问题,因为技能行为默认绑定到单一语言而缺乏用户选择或明确 justification。

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The file title and the entire guidance are written in Chinese, and line L046 further instructs only that technical terms remain in English, implying the rest of the deliverable should be in Chinese. This creates a language policy constraint without any user opt-in or alternative locale guidance.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown spec appears to require Chinese as the operating language for readers and implementers, but it does not provide any opt-in, alternative language option, or justification that the skill is region-specific. Under the policy, forcing a specific language without user choice is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file title and all instructional content are written in Chinese, and the document does not indicate that language selection is optional or that the skill is region-specific. Under the stated policy, forcing a specific language or locale without user opt-in is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The script accepts an arbitrary external HTML fragment via --score-panel, extracts and <script> blocks with regex, and then embeds the remaining DOM plus the extracted scripts directly into the final output without sanitization or origin restrictions. Because the generated dashboard is intended to be published as a self-contained HTML page, this creates a script injection path that can change page behavior, exfiltrate embedded scoring data, or make the supposedly fixed read-only artifact execute attacker-controlled code in every viewer’s browser.

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 · bid-quote-cockpit/scripts/check_overflow.py (reported line 146)May include surrounding context.

python
def measure(chrome, path, width):
    url = "file:///" + os.path.abspath(path).replace("\\", "/")
    p = subprocess.run(
        [chrome, "--headless=new", "--disable-gpu", "--no-sandbox", "--hide-scrollbars",
         "--virtual-time-budget=6000", "--window-size=%d,1200" % width, "--dump-dom", url],
        capture_output=True, text=True, encoding="utf-8", errors="replace")

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 · bid-quote-cockpit/scripts/dump_rendered.py (reported line 115)May include surrounding context.

python
p_html = os.path.join(tmpdir, "probe.html")
        io.open(p_html, "w", encoding="utf-8", newline="").write(out_html)
        url = "file:///" + p_html.replace("\\", "/")
        p = subprocess.run(
            [chrome, "--headless=new", "--disable-gpu", "--no-sandbox", "--hide-scrollbars",
             "--virtual-time-budget=%d" % budget, "--window-size=%d,1200" % width,
             "--user-data-dir=" + os.path.join(tmpdir, "prof"), "--dump-dom", url],

Static analysis

Detected: suspicious.dynamic_code_execution

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
bid-quote-cockpit/assets/echarts.min.js:45