Back to skill

Security audit

data-analysis-operation

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent spreadsheet analysis tool, but it needs review because some scripts silently install unpinned Python packages and generated spreadsheets can preserve formula-like input as active content.

Install only if you are comfortable with a local data tool that reads selected spreadsheets and writes derived reports or cleaned copies. Preinstall dependencies in a controlled environment before use, avoid running the helper scripts where pip can modify a sensitive Python installation, and treat generated Excel/CSV files from untrusted datasets as potentially active spreadsheet content.

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

T08 · Insecure Dependencies

Warning
Location
scripts/analyze_data.py:28
Finding

Unpinned Runtime Dependency Installation in Data Analyzer

Content
View full analysis

Vulnerability Details

File Location: scripts/analyze_data.py:28-47
Vulnerability Type: Unpinned runtime package installation
Risk Level: Medium

Vulnerable Code

python
try:
    import pandas as pd
    import numpy as np
    from openpyxl import Workbook
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
    from openpyxl.chart import BarChart, PieChart, Reference
    from openpyxl.utils import get_column_letter
except ImportError:
    print("Required packages not found. Installing dependencies...")
    import subprocess
    subprocess.check_call([sys.executable, "-m", "pip", "install", "pandas", "openpyxl", "numpy", "-q"])
    import pandas as pd
    import numpy as np
    from openpyxl import Workbook
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
    from openpyxl.chart import BarChart, PieChart, Reference
    from openpyxl.utils import get_column_letter

Technical Analysis

If any dependency import fails, the script automatically invokes pip and installs pandas, openpyxl, and numpy. No versions or package hashes are pinned, and the configured package index is trusted implicitly.

This creates a supply-chain execution path because package installation and subsequent imports can execute package-controlled code. The installed versions may change over time, and the result depends on environment-level pip configuration such as index URLs, extra indexes, proxies, and trusted hosts. An ImportError caused by a partially broken installation may also unexpectedly trigger modification of the Python environment.

Attack Path

  1. One of the required packages is absent or raises ImportError.
  2. The script enters the exception handler.
  3. The script invokes the environment's configured pip client without version or hash verification.
  4. An attacker-controlled package index, compromised package release, dependenc ...[truncated 776 chars]
Remediation
View remediation

Remediation Suggestions

  1. Remove automatic dependency installation from application runtime.
  2. If imports fail, terminate with a clear message directing the operator to an explicit setup procedure.
  3. Declare dependencies in a lock file or requirements file with exact versions.
  4. Require cryptographic hashes during installation, such as through pip install --require-hashes.
  5. Install dependencies in an isolated virtual environment during deployment rather than while processing user data.
  6. Restrict approved package indexes and avoid untrusted --extra-index-url configurations.
  7. Run dependency vulnerability and provenance checks in CI before release.

T08 · Insecure Dependencies

Warning
Location
scripts/compare_columns.py:32
Finding

Unpinned Runtime Dependency Installation in Column Comparator

Content
View full analysis

Vulnerability Details

File Location: scripts/compare_columns.py:32-46
Vulnerability Type: Unpinned runtime package installation
Risk Level: Medium

Vulnerable Code

python
try:
    import pandas as pd
    from openpyxl import Workbook
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
except ImportError:
    print("Required packages not found. Installing pandas and openpyxl...")
    import subprocess
    subprocess.check_call([sys.executable, "-m", "pip", "install", "pandas", "openpyxl", "-q"])
    import pandas as pd
    from openpyxl import Workbook
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side

Technical Analysis

The comparator automatically downloads and installs unpinned packages whenever its initial imports fail. Package names are resolved through the current pip configuration without version constraints or hash validation.

Package installation is a code-execution boundary: installation hooks and subsequently imported package modules execute with the permissions of the Python process. The use of argument-list subprocess invocation prevents shell injection, but it does not address dependency confusion, a compromised index, a compromised upstream release, or mutable dependency resolution.

Attack Path

  1. The runtime lacks pandas or openpyxl, or an import fails.
  2. The exception handler executes python -m pip install.
  3. Pip resolves packages using the environment's configured indexes.
  4. A malicious or compromised package artifact is selected because versions and hashes are unrestricted.
  5. Package-controlled code executes during installation or the imports immediately following installation.

Impact Assessment

An attacker controlling the resolved package can execute arbitrary code with the invoking user's privileges. This can expose input datasets, local files, environment variables, tokens, and writa ...[truncated 210 chars]

Remediation
View remediation

Remediation Suggestions

Remove the runtime pip invocation and make dependency installation an explicit deployment step. Pin exact dependency versions and hashes, use a dedicated virtual environment, configure an approved package repository, and fail safely when imports are unavailable. Dependency artifacts should be scanned and verified in CI before the Skill is distributed.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/analyze_data.py:468
Finding

Spreadsheet Formula Injection in Generated Analysis Reports

Content
View full analysis

Vulnerability Details

File Location: scripts/analyze_data.py:468-479
Vulnerability Type: Spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

python
for col in cat_cols:
    top_vals = all_results[col].get("top_values", [])
    if top_vals:
        ws_top = wb.create_sheet(title=f"Top-{col[:26]}")
        write_header(ws_top, 1, 1, "Value", header_fill_orange)
        write_header(ws_top, 1, 2, "Count", header_fill_orange)
        write_header(ws_top, 1, 3, "Percentage", header_fill_orange)
        total = sum(v["count"] for v in top_vals)
        for i, item in enumerate(top_vals, 2):
            write_cell(ws_top, i, 1, str(item["value"]))
            write_cell(ws_top, i, 2, item["count"], is_number=True)
            pct = f"{item['count'] / all_results[col]['count'] * 100:.1f}%" if all_results[col]['count'] > 0 else "0%"
            write_cell(ws_top, i, 3, pct)

The helper used above assigns the value directly:

python
def write_cell(ws, row, col, value, is_number=False):
    cell = ws.cell(row=row, column=col, value=value)
    cell.alignment = num_alignment if is_number else cell_alignment
    cell.border = thin_border

Technical Analysis

Categorical values originate in the analyzed input file and are written directly into XLSX cells. No neutralization is applied to text beginning with spreadsheet formula indicators such as =, +, -, or @.

In particular, openpyxl can store a string beginning with = as a formula. Consequently, an attacker who controls a source data value can cause the generated workbook to contain an active formula rather than inert text.

Attack Path

  1. An attacker places a formula-like value in a categorical input column, for example =HYPERLINK("https://attacker.example","Open").
  2. The victim runs analyze_data.py against the crafted CSV or Excel file.
  3. The value appears among the categorical top val ...[truncated 886 chars]
Remediation
View remediation

Remediation Suggestions

  1. Create a centralized spreadsheet-text sanitizer and apply it to every source-derived string.
  2. Neutralize values whose first meaningful character is =, +, -, or @, including values preceded by whitespace, tabs, carriage returns, or other control characters.
  3. Prefix unsafe values with an apostrophe or explicitly force openpyxl cells to use the string data type.
  4. Keep numeric values numeric only after strict type validation.
  5. Add regression tests using formula payloads in categorical values, column names, summaries, and source-file metadata.
  6. Document that generated reports must treat source data as untrusted.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/compare_columns.py:207
Finding

Spreadsheet Formula Injection in Column Comparison Workbooks

Content
View full analysis

Vulnerability Details

File Location: scripts/compare_columns.py:207-246
Vulnerability Type: Spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

python
# Sheet 2: Only in Column A
if mode in ("full", "diff", "unique_a"):
    ws_a = wb.create_sheet(title=f"Only in {col_a_name[:28]}")
    style_header(ws_a, 1, 1, header_fill_a, f"Only in '{col_a_name}'")
    style_header(ws_a, 1, 2, header_fill_a, "Row Numbers (in original)")
    for i, val in enumerate(only_in_a, 2):
        # Find row numbers where this value appears
        rows = series_a[series_a == val].index.tolist()
        rows_str = ", ".join(str(r + 2) for r in rows[:10])
        if len(rows) > 10:
            rows_str += f" ... (+{len(rows)-10} more)"
        style_cell(ws_a, i, 1, val)
        style_cell(ws_a, i, 2, rows_str)

# Sheet 3: Only in Column B
if mode in ("full", "diff", "unique_b"):
    ws_b = wb.create_sheet(title=f"Only in {col_b_name[:28]}")
    style_header(ws_b, 1, 1, header_fill_b, f"Only in '{col_b_name}'")
    style_header(ws_b, 1, 2, header_fill_b, "Row Numbers (in original)")
    for i, val in enumerate(only_in_b, 2):
        rows = series_b[series_b == val].index.tolist()
        rows_str = ", ".join(str(r + 2) for r in rows[:10])
        if len(rows) > 10:
            rows_str += f" ... (+{len(rows)-10} more)"
        style_cell(ws_b, i, 1, val)
        style_cell(ws_b, i, 2, rows_str)

# Sheet 4: Common values
if mode in ("full", "common"):
    ws_common = wb.create_sheet(title="Common Values")
    style_header(ws_common, 1, 1, header_fill_common, "Common to both columns")
    for i, val in enumerate(in_both, 2):
        style_cell(ws_common, i, 1, val)

The cell helper does not sanitize values:

python
def style_cell(ws, row, col, value):
    cell = ws.cell(row=row, column=col, value=value)
    cell.alignment = cell_alignment
    cell.border = thi
...[truncated 1377 chars]
Remediation
View remediation

Remediation Suggestions

Sanitize every source-derived value before passing it to ws.cell. Reject or escape strings beginning with spreadsheet formula characters after stripping leading control characters. Explicitly store untrusted values as literal strings, centralize this behavior in style_cell, and test all output modes with values beginning with =, +, -, and @.

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/data_analysis_operations.py:198
Finding

Spreadsheet Formula Injection Across Analysis, Comparison, and Cleaning Exports

Content
View full analysis

Vulnerability Details

File Location: scripts/data_analysis_operations.py:198-204, 319-331, 419-423
Vulnerability Type: Spreadsheet formula injection in XLSX and CSV exports
Risk Level: Medium

Vulnerable Code

Categorical values are exported to the analysis workbook:

python
cat_stats_data.append({
    '列名': col,
    '数据类型': '分类',
    '唯一值数量': unique_count,
    '最高频值': df[col].mode().iloc[0] if not df[col].mode().empty else 'N/A',
    '最高频计数': df[col].value_counts().iloc[0] if not df[col].value_counts().empty else 0
})

cat_stats_df = pd.DataFrame(cat_stats_data)
cat_stats_df.to_excel(writer, sheet_name='分类统计', index=False)

Compared values are exported without neutralization:

python
if only_in_a:
    pd.DataFrame({'仅在A列的值': only_in_a}).to_excel(writer, sheet_name='仅A列', index=False)

if only_in_b:
    pd.DataFrame({'仅在B列的值': only_in_b}).to_excel(writer, sheet_name='仅B列', index=False)

if common_values:
    pd.DataFrame({'共有的值': common_values}).to_excel(writer, sheet_name='共有值', index=False)

Cleaned source data is also written directly:

python
# 保存清洗后的数据
if file_path.lower().endswith(('.xlsx', '.xls', '.xlsm')):
    df.to_excel(output_file, index=False)
else:
    df.to_csv(output_file, index=False, encoding='utf-8')

Technical Analysis

The main CLI exports source-derived values through pandas without applying formula neutralization. This affects analysis reports, column-comparison reports, cleaned XLSX files, and cleaned CSV files.

XLSX writers may interpret formula-leading strings as spreadsheet formulas. CSV files do not encode cell types, so spreadsheet applications may interpret fields beginning with =, +, -, or @ as formulas when users open the output. Trimming string columns during cleaning does not mitigate the issue and may remove leading spaces that previously prevented immediate formula interpretation.

Attack Path

...[truncated 1128 chars]

Remediation
View remediation

Remediation Suggestions

  1. Sanitize all object and string columns before XLSX or CSV export.
  2. Detect formula indicators after removing or examining leading whitespace and control characters.
  3. For XLSX output, force untrusted text to literal string cells and escape formula-leading content.
  4. For CSV output intended for spreadsheet use, prefix unsafe fields with an apostrophe or use an explicitly documented safe encoding strategy.
  5. Preserve a distinction between sanitized display output and original data if exact-value retention is required.
  6. Apply the same sanitizer to column names, source paths, summary values, and generated metadata.
  7. Add automated tests covering analyze, compare, and clean with formula payloads in every exported field.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (25)

Tp4

High
Category
MCP Tool Poisoning
Confidence
93% confidence
Finding

该代码与声明中的一部分功能一致:它确实处理 Excel/CSV 文件,并执行数据分析、质量检查、相关性分析以及生成 Excel 报告。但声明包含“列对比”“数据清洗”“操作工具集”等能力,而代码中没有看到对列间差异/匹配的专门比较功能,也没有对数据进行清洗、修复、标准化、去重后写回等操作。代码主要是读取数据并生成分析报告,属于分析/汇总工具,而不是‘全面的数据分析和操作工具集’。未发现额外的高风险越权能力;不匹配主要在于声明夸大了实际功能范围。

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 50)May include surrounding context.

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

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/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
python scripts/data_analysis_operations.py analyze <文件路径> [选项]

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill advertises shell-based script execution but does not declare any tool scope such as allowed-tools or permissions. In an agent environment, this can lead to overbroad access or implicit shell invocation without clear authorization boundaries, increasing the chance of unintended file operations or command execution.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The trigger keywords are very broad and can match ordinary user requests about data, causing the skill to activate outside its intended scope. In agent systems, overbroad activation increases the risk of unnecessary file access, unexpected shell usage, or the wrong workflow being selected for sensitive data.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill describes automatic cleaning actions such as filling missing values, deleting rows, and deduplicating data without prominently warning that user data may be altered. This is dangerous because users may invoke the skill expecting analysis only, but destructive or irreversible modifications could occur to important datasets.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

Runtime package installation is a supply-chain and execution risk because it pulls and executes external code during normal script operation. That behavior is not required for the stated purpose of analyzing Excel/CSV data and increases the attack surface in managed agent environments.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The script auto-installs packages without prior confirmation, meaning a simple attempt to analyze a file can cause silent external network access and local environment changes. In agent or enterprise contexts this can violate least privilege, break reproducibility, and expose systems to dependency confusion or malicious package updates.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
95% confidence
Finding

The script executes pip at runtime via subprocess, which gives the skill an unnecessary code execution and environment modification capability beyond simple data analysis. If triggered in a privileged or sensitive environment, it can install arbitrary package code from package indexes and change interpreter state without explicit operator approval.

Content

Scanner excerpt · scripts/analyze_data.py (reported line 39)May include surrounding context.

python
except ImportError:
    print("Required packages not found. Installing dependencies...")
    import subprocess
    subprocess.check_call([sys.executable, "-m", "pip", "install", "pandas", "openpyxl", "numpy", "-q"])
    import pandas as pd
    import numpy as np
    from openpyxl import Workbook

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

Automatically installing Python packages at runtime expands the tool's behavior beyond column comparison into software installation, which can introduce supply-chain risk and unexpected privilege or network use. In an agent skill context, this is more dangerous because users may run the skill expecting only file analysis, not environment modification and code fetched from external repositories.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The script performs package installation without meaningful prior confirmation, causing silent environment changes and possible execution of third-party package code. This is risky in automation or enterprise settings because it can violate change-control expectations, break reproducibility, and expose the host to malicious or tampered packages.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
90% confidence
Finding

The script invokes pip via subprocess at runtime when imports fail, which introduces unexpected code execution and network/package-management behavior into a local data-processing tool. Even though the command arguments are hardcoded and not shell-injected, installing packages on the fly can execute untrusted setup/build steps or pull compromised dependencies, especially in sensitive or restricted environments.

Content

Scanner excerpt · scripts/compare_columns.py (reported line 41)May include surrounding context.

python
except ImportError:
    print("Required packages not found. Installing pandas and openpyxl...")
    import subprocess
    subprocess.check_call([sys.executable, "-m", "pip", "install", "pandas", "openpyxl", "-q"])
    import pandas as pd
    from openpyxl import Workbook
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file’s natural-language description and all user-facing help/messages are written in Chinese, indicating the skill is intended to operate in a single language. There is no visible opt-in, language selection, or documentation justifying a locale-specific restriction, which can violate a language/locale policy requiring user choice.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
82% confidence
Finding

The clean_data function removes empty columns, drops duplicate rows, fills missing values, trims strings, and writes the modified dataset to a new file. Although it logs steps after execution, there is no prior warning in the function docstring or command help that the operation alters dataset contents, which is a safety-relevant disclosure for data-modifying behavior.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

Natural-language descriptions, usage guidance, and examples are all presented in Chinese, which effectively imposes a language requirement on users. The file does not offer an alternative language, an opt-in language preference, or a documented justification for being Chinese-only.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The argument help and choices claim support for 'unique_a', 'unique_b', and 'common', but the code only has special handling for mode == 'diff' and otherwise always generates the same full report. This is an intent/documentation mismatch because the user-facing CLI contract says those modes exist when the implementation does not actually honor them.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.