Back to skill

Security audit

HCP data process assist

Security checks for vulnerabilities and agentic risk

Overview

This is a local HCP Excel extraction skill with no hidden network or persistence, but malicious input values could become active formulas in generated spreadsheets.

Use this skill only with trusted HCP exports unless the script is patched to escape formula-leading spreadsheet text before writing XLSX files. Be aware that passing a directory batch-processes supported Excel files in that directory, and use --overwrite carefully because it replaces existing generated output files.

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/extract_hcp.py:82
Finding

Spreadsheet Formula Injection Through Untrusted Export Values

Content
View full analysis

Vulnerability Details

File Location: scripts/extract_hcp.py:43-65, 82-92, 189-204
Vulnerability Type: Spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

python
def parse_tsv_scalar(value: str) -> object:
    text = value.strip()
    if not text:
        return None
    if text.upper() == "TRUE":
        return True
    if text.upper() == "FALSE":
        return False
    if re.fullmatch(r"[+-]?[0-9]+", text):
        if len(text.lstrip("+-")) > 1 and text.lstrip("+-").startswith("0"):
            return text
        try:
            return int(text)
        except ValueError:
            return text
    if re.fullmatch(r"[+-]?(?:[0-9]*\.[0-9]+|[0-9]+\.[0-9]*)(?:[Ee][+-]?[0-9]+)?", text):
        try:
            return float(text)
        except ValueError:
            return text
    return text
python
if suffix == ".xls":
    with path.open("r", encoding="utf-16") as handle:
        reader = csv.reader(handle, delimiter="\t")
        rows = [[parse_tsv_scalar(cell) for cell in row] for row in reader]

    wb = Workbook()
    ws = wb.active
    ws.title = safe_sheet_title(path.stem)
    for row_index, row in enumerate(rows, start=1):
        for col_index, value in enumerate(row, start=1):
            ws.cell(row=row_index, column=col_index, value=value)
python
ws.cell(row=row, column=start_col, value=group.title)
...
ws.cell(row=row, column=start_col, value=sample_value)
ws.cell(row=row, column=start_col + 1, value=mean_value)
ws.cell(row=row, column=start_col + 2, value=cv_value)

Technical Analysis

The script accepts data from an untrusted UTF-16, tab-delimited .xls export and writes parsed strings directly into a newly generated XLSX workbook. parse_tsv_scalar() performs type conversion but does not neutralize strings beginning with a spreadsheet formula marker, particularly =.

OpenPyXL tre ...[truncated 2162 chars]

Remediation
View remediation

Remediation Suggestions

Introduce a centralized safe-cell conversion function and apply it to every untrusted textual value written to a workbook, including raw imported cells, group titles, headers, sample names, means, and CV values.

Recommended controls:

  1. Treat formula-leading input as literal text. At minimum, neutralize strings whose first non-whitespace character is =.
  2. For defense in depth and interoperability with other spreadsheet writers, consider handling +, -, and @ when they are not valid values expected by the relevant field.
  3. Explicitly set untrusted textual cells to the text data type rather than relying solely on visual formatting.
  4. Preserve legitimate numeric and Boolean values while sanitizing only string values.
  5. Add regression tests using malicious sample names, group titles, and headers.
  6. Document that input workbooks and text exports are untrusted data.

Example hardening approach:

python
def safe_excel_value(value: object) -> object:
    if not isinstance(value, str):
        return value

    stripped = value.lstrip()
    if stripped.startswith("="):
        return "'" + value
    return value

Apply the function at all workbook write boundaries:

python
cell = ws.cell(
    row=row_index,
    column=col_index,
    value=safe_excel_value(value),
)

If preserving the exact displayed value without a visible apostrophe is required, explicitly write the value as a text cell and verify the resulting XLSX cell type in automated tests. Sanitization must occur before every assignment of attacker-controlled text, not only in the summary sheet.

Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (2)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill instructs users to run a local script that reads user-supplied files, but the manifest does not declare any tool scope or permissions to constrain that file access. Even though the documented behavior appears limited to processing HCP Excel exports, undeclared file-read capability weakens least-privilege guarantees and can enable broader-than-expected access if the skill is integrated into an agent runtime with filesystem tools.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The manifest description is written only in Chinese, which can impose a language constraint on users without offering an opt-in or alternative locale. The policy specifically calls for flagging language or locale restrictions when they are not optional or justified.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.