Back to skill

Security audit

Llm Usage Aggregator

Security checks for vulnerabilities and agentic risk

Overview

This is a local LLM usage report generator, but its generated Excel files may contain sensitive user identifiers and should be handled carefully.

Install only if you are comfortable processing LLM usage logs locally and storing the resulting workbook. Treat input logs and outputs as sensitive because raw user identifiers can appear in the report. Avoid using untrusted CSV/XLS files, or sanitize values beginning with =, +, -, or @ before opening or sharing the generated Excel workbook.

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
scripts/aggregate_llm_usage.py:441
Finding

Spreadsheet Formula Injection in Generated Excel Reports

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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 (10)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

The code substantially matches the declared purpose: it aggregates LLM usage data, distinguishes internal/external users, summarizes by provider/model/user, calculates costs from pricing_config.json, and exports Excel output. However, there is a notable description/behavior mismatch in the report structure: the description says it outputs a 'multi-sheet Excel report' for the aggregations, which implies separate sheets per dimension, while the code creates one summary sheet ('汇总报表') containing four sections and only one additional sheet for pricing details. Also, the code supports Excel input as well as CSV, which is an undeclared extra capability, though relatively minor. Primary purpose remains aligned, so this is a limited but real mismatch.

Content

No source excerpt is available for this finding.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · scripts/aggregate_llm_usage.py (reported line 128)May include surrounding context.

python
detail['unit_price_completion'] = completion_price
        prompt_cost = prompt / 1_000_000 * prompt_price
        completion_cost = completion / 1_000_000 * completion_price
        return prompt_cost + completion_cost, detail

    # 图片类型:按张计价,单价 × generated_image_count
    if detail['model_type'] == '图片':

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
78% confidence
Finding

The primary description is written entirely in Chinese and presents the skill behavior and usage in that language without indicating that users may choose another language or that the locale restriction is intentional for a region-specific tool. Under the language/locale policy, forcing a specific language without opt-in can be a natural-language policy violation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill processes direct identifiers such as email and phone and produces user-level summaries, but provides no privacy notice, minimization guidance, masking behavior, or retention boundaries. This can lead to unnecessary exposure of personal data in generated reports, especially if outputs are shared broadly or stored insecurely.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The script constructs a combined user identifier from email, phone, or user_id and then exports it into both summary and detail Excel sheets. This can disclose personally identifiable information to anyone with access to the generated workbook, especially since the tool aggregates operational logs and makes broad per-user reporting easy to share or redistribute.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

This JSON file includes user-facing natural-language values such as the note field and model_type in Chinese (for example, "维护价" and "文本"). Because the file does not document that it is region-specific or provide any language/locale opt-in, it appears to enforce a specific language in a general configuration artifact.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

Later entries continue the same pattern of Chinese-only descriptive text in note/model_type fields, indicating the locale restriction is systemic rather than isolated. Under the policy, fixed language/locale content should either be optional for users or clearly justified as region-specific.

Content

No source excerpt is available for this finding.

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/aggregate_llm_usage.py (reported line 360)May include surrounding context.

python
for row_idx, row_data in enumerate(grouped.itertuples(), header_row + 1):
            ws.cell(row=row_idx, column=1, value=row_data[1]).border = thin_border
            for col_idx, field in enumerate(agg_fields, 2):
                cell = ws.cell(row=row_idx, column=col_idx, value=getattr(row_data, field))
                cell.border = thin_border
            cost_val = getattr(row_data, cost_field)
            cell = ws.cell(row=row_idx, column=cost_col_idx, value=round(cost_val, 4))

Dynamic attribute access via getattr()

Low
Category
Dangerous Code Execution
Confidence
50% confidence
Finding

Dynamic getattr() with a non-literal attribute name can access arbitrary object attributes, potentially bypassing access controls.

Content

Scanner excerpt · scripts/aggregate_llm_usage.py (reported line 362)May include surrounding context.

python
for col_idx, field in enumerate(agg_fields, 2):
                cell = ws.cell(row=row_idx, column=col_idx, value=getattr(row_data, field))
                cell.border = thin_border
            cost_val = getattr(row_data, cost_field)
            cell = ws.cell(row=row_idx, column=cost_col_idx, value=round(cost_val, 4))
            cell.number_format = '#,##0.0000'
            cell.border = thin_border

Static analysis

No suspicious patterns detected.