Back to skill

Security audit

LingJi运营工单分析

Security checks for vulnerabilities and agentic risk

Overview

The skill does what it claims, but its PDF report generator handles sensitive ticket data in ways that need review before use.

Install only in a dedicated, least-privileged environment and use it on authorized ticket exports. Treat generated terminal output, PDFs, and the temporary HTML file as sensitive internal data. Avoid using external messaging apps for reports unless approved, and do not run the PDF generator on workbooks from untrusted sources until workbook values are HTML-escaped and browser JavaScript/network access are constrained.

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)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/generate_pdf.py:112
Finding

Unescaped Spreadsheet Values Allow Active HTML Injection During PDF Generation

Content
View full analysis
{handler} {h_total} {completed} {pending} {very_sat} {avg_sat:.1f} {avg_time:.0f}分钟 """ type_rows = "" for t, c in df['工单类型'].value_counts().items(): type_rows += f"{t}{c}{c/total*100:.1f}%" status_rows = "" for s, c in df['工单状态'].value_counts().items(): status_rows += f"{s}{c}{c/total*100:.1f}%" sat_rows = "" for opt, cnt in df['满意度选项'].value_counts().items(): sat_rows += f"{opt}{cnt}{cnt/total*100:.1f}%" issue_rows = "" for issue, cnt in issue_counts.most_common(15): issue_rows += f"{issue}{cnt}{cnt/total*100:.1f}%" module_rows = "" for module, cnt in df['模块'].value_counts().head(10).items(): module_rows += f"{module}{cnt}{cnt/total*100:.1f}%" menu_rows = "" for menu, cnt in df['菜单'].value_counts().head(10).items(): menu_rows += f"{menu}{cnt}{cnt/total*100:.1f}%" group_rows = "" for group, cnt in df['处理工作组'].value_counts().head(10).items(): group_rows += f"{group}{cnt}{cnt/total*100:.1f}%" ``` The resulting document is subsequently loaded into a JavaScript-capable browser: ```python html_path = "/tmp/lingji_report.html" with open(html_path, "w", encoding="utf-8") as f: f.write(html_content) with sync_playwright() as p: browser = p.chromium.launch() page = browser.new_page() page.goto(f"file://{html_path}") page.pdf( path=output_path, format="A4", margin={"top": "15mm", "bottom": "15mm", "left": "15m ...[truncated 2398 chars]
Remediation
View remediation
{html_text(handler)}..." type_rows += ( f"{html_text(t)}" f"{c}{c / total * 100:.1f}%" ) ``` 2. Prefer a template engine configured with automatic escaping rather than assembling HTML through string concatenation. 3. Disable JavaScript because the report does not require it: ```python browser = p.chromium.launch() context = browser.new_context(java_script_enabled=False) page = context.new_page() ``` 4. Block network requests during rendering unless a specific resource is explicitly required: ```python page.route( "**/*", lambda route: route.continue_() if route.request.url.startswith("file://") else route.abort() ) ``` 5. Validate workbook fields against expected types and reasonable length limits before report generation. 6. Add regression tests containing HTML metacharacters and malicious markup, verifying that they appear as literal text and do not generate requests or alter report structure. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_pdf.py:380
Finding

Predictable Shared Temporary File Allows Symlink-Based File Overwrite

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:133
Finding

Installation Instructions Use Unpinned Packages and Browser Components

Content
View full analysis
Remediation
View remediation
openpyxl== playwright== ``` 2. Generate and verify cryptographic hashes for Python artifacts, for example with `pip-tools`, and install with: ```bash python -m pip install --require-hashes -r requirements.txt ``` 3. Document the trusted package index explicitly: ```bash python -m pip install \ --index-url https://pypi.org/simple \ --require-hashes \ -r requirements.txt ``` 4. Commit a lockfile or hashed requirements file to make dependency resolution reproducible. 5. Record and review the Chromium revision associated with the pinned Playwright version. Perform browser installation only from the expected Playwright distribution channel. 6. Run dependency vulnerability and provenance checks as part of release maintenance, and update pins through a controlled review process. 7. Recommend installation inside a dedicated, least-privileged virtual environment rather than a global or privileged Python environment. ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (5)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The skill is explicitly designed to analyze operational ticket exports and generate shareable reports, but it does not warn users that ticket fields may contain sensitive personal, operational, or internal business data. In this context, omission of a privacy/data-handling warning materially increases the risk of accidental over-collection, inclusion of sensitive content in outputs, and unsafe downstream sharing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The maintenance guidance explicitly suggests sending generated PDF reports through WeChat/WhatsApp, which can expose internal ticket details to external or insufficiently controlled platforms if the report contains personal, operational, or incident data. Because the skill produces polished, easily shareable reports from support-ticket exports, this recommendation increases the likelihood of inadvertent data leakage beyond approved enterprise boundaries.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The module description and downstream parsing/report generation logic are written specifically for Chinese text, including Chinese duration units and Chinese report labels. This effectively forces a specific language/locale behavior with no user opt-in or documented justification in the file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The script prints per-ticket identifiers, handler names, and timeout details for overdue tickets directly to stdout. In environments where terminal output is shared, logged, or collected by automation, this can expose operationally sensitive records and personnel information beyond the intended audience.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

This code loads an Excel file that appears to contain operational work-order data, then proceeds to print summaries and record details to stdout. While the script includes status messages, it does not disclose that sensitive fields such as handler names, ticket numbers, and ticket content may be processed and displayed, which matters for a data-analysis skill handling user or system data.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.