Back to skill

Security audit

jf-smart-store-inspection

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly does what it claims, but it handles sensitive store patrol data and can generate HTML reports that render API-returned content unsafely.

Install only if you trust the JF account context and operators who will run these commands. Treat delete/start/stop actions as live business operations, keep JF_ENDPOINT set to the official API host, and avoid opening or sharing generated reports from untrusted patrol data until the HTML escaping and URL validation issue is fixed.

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

Warning
Location
assets/patrol_report_template.html:232
Finding

Stored HTML and JavaScript Injection in Generated Patrol Reports

Content
View full analysis

Vulnerability Details

File Location: assets/patrol_report_template.html:232-304
Related Data Flow: scripts/smart_store_inspection.py:768-769, 833-844
Vulnerability Type: Stored HTML injection / DOM-based cross-site scripting
Risk Level: Medium

Vulnerable Code

The report generator retrieves records from the remote API and embeds the resulting data in an executable HTML report:

python
# scripts/smart_store_inspection.py:768-769
print(f"[info] Fetching AI patrol records ({args.begin} ~ {args.end}) ...")
records = _fetch_records(body)
python
# scripts/smart_store_inspection.py:833-844
with open(template_path, "r", encoding="utf-8") as f:
    html = f.read()

payload = json.dumps(report, ensure_ascii=False).replace("</", "<\\/")
marker = "window.__REPORT__ = null;"
if marker not in html:
    print("[error] Template is missing the data marker.", file=sys.stderr)
    sys.exit(1)
html = html.replace(marker, f"window.__REPORT__ = {payload};")

with open(args.output, "w", encoding="utf-8") as f:
    f.write(html)

The report template subsequently interpolates API-returned values into HTML markup:

javascript
// assets/patrol_report_template.html:232-236
function tableize(el, cols, rows) {
  if (!rows.length) { el.innerHTML = '<div class="empty">(无数据)</div>'; return; }
  const head = cols.map(c => `<th>${c.label}</th>`).join('');
  const body = rows.map(r => '<tr>' + cols.map(c => `<td>${r[c.key] != null ? r[c.key] : '-'}</td>`).join('') + '</tr>').join('');
  el.innerHTML = `<div class="table-wrap"><table class="detail"><thead><tr>${head}</tr></thead><tbody>${body}</tbody></table></div>`;
}
javascript
// assets/patrol_report_template.html:252-263
(R.records||[]).forEach(r => {
  const tr = document.createElement('tr');
  const pic = r.cloudPictureUrl
    ? `<a href="${r.cloudPictureUrl}" target="_blank" style="color:var(--primary);">查看</a>`
    : '<span style="color:#9ca3af;">无</span>';
  const detail = r.detailDat
...[truncated 3640 chars]
Remediation
View remediation

Remediation Suggestions

  1. Replace dynamic innerHTML construction with DOM APIs:

    • Create elements using document.createElement.
    • Insert remote text using textContent.
    • Set validated attributes using setAttribute or corresponding DOM properties.
  2. Validate cloudPictureUrl before use:

    • Parse it with new URL(...).
    • Permit only expected https: URLs.
    • Optionally restrict hosts to the expected image service.
    • Reject active or unexpected schemes such as javascript:, data:, and file:.
  3. Apply context-aware escaping if HTML-string generation cannot be removed:

    • Escape &, <, >, ", and ' for text and attribute contexts.
    • Do not rely on the Python </ replacement, because it only protects the initial script embedding.
  4. Add a restrictive Content Security Policy to generated reports, for example by disallowing inline script and limiting image and connection destinations. Move the template’s inline JavaScript to a separately generated resource or use a nonce/hash if a self-contained report is required.

  5. Add regression tests containing malicious values in every API-derived field, including:

    • HTML elements with event handlers.
    • Quotes that escape attributes.
    • Closing tags.
    • javascript: and data: URLs.
    • SVG-based payloads.
  6. Treat every API response field as untrusted even if the backend normally validates it, because device metadata, integrations, or compromised upstream records may introduce attacker-controlled content.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • 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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (43)

Tainted flow: 'url' from os.getenv (line 154, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
92% confidence
Finding

The destination host is derived from the JF_ENDPOINT environment variable and then used to construct authenticated HTTPS requests. If an attacker or misconfigured runtime can control that environment variable, the script will send signed requests and operational data to an arbitrary external host, enabling SSRF-like exfiltration of API metadata and misuse of credentials/signatures.

Content

Scanner excerpt · scripts/smart_store_inspection.py (reported line 134)May include surrounding context.

python
for attempt in range(retries + 1):
        try:
            resp = requests.post(url, json=body, headers=headers, timeout=30)
            result = resp.json()
        except requests.RequestException as exc:
            if attempt < retries:

Tainted flow: 'url' from os.getenv (line 154, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Confidence
92% confidence
Finding

This GET helper uses the same environment-controlled base URL for outbound authenticated requests. In this skill, the requests include API authentication headers, so endpoint manipulation could redirect sensitive operational traffic to an attacker-controlled server or unintended internal service.

Content

Scanner excerpt · scripts/smart_store_inspection.py (reported line 159)May include surrounding context.

python
for attempt in range(retries + 1):
        try:
            resp = requests.get(url, headers=headers, timeout=30)
            result = resp.json()
        except requests.RequestException as exc:
            if attempt < retries:

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

声明描述的是一个面向智慧巡店和AI巡检运营的业务技能,重点在巡店业务流程和巡检配置/报告能力。而代码片段仅是底层认证辅助组件:生成时间戳和请求签名,用于调用杰峰 OpenAPI。虽然这类加密工具可能是相关系统的配套支撑模块,但就该代码片段本身而言,其实际行为与声明的主要用途存在明显偏离,且缺少描述中几乎全部核心业务能力。因此应判定为描述与代码行为不匹配。

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/smart_store_inspection.py --session ./session init

Static analysis

Detected: suspicious.env_credential_access

Python code POSTs credential environment variables to an environment-controlled URL.

Critical
Code
suspicious.env_credential_access
Location
scripts/smart_store_inspection.py:134