Back to skill

Security audit

Dvp Composer

Security checks for vulnerabilities and agentic risk

Overview

This DVP drafting skill is mostly purpose-aligned, but it should be reviewed because it can overwrite project files and generate Excel workbooks from untrusted text without neutralizing formulas.

Install only if you are comfortable with the skill creating and overwriting files inside dvp_workspace. Keep backups of existing DVP work, use trusted study materials/templates, and inspect generated XLSX files for unexpected formulas or links before distributing them to sponsors, CRO teams, or sites.

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/generate_xlsx.py:69
Finding

Excel Formula Injection Through Untrusted Workbook Cell Values

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_xlsx.py, lines 69-74, 115-118, 140-143, 154-158, and 182-184
Vulnerability Type: Spreadsheet formula injection
Risk Level: Medium

Vulnerable Code

Check-list values are written directly to workbook cells:

python
for col, value in enumerate(values, 1):
    cell = ws.cell(row=row_idx, column=col, value=value)
    _apply_cell(cell, row_fill)
    if col == 9 and value in SEVERITY_FILLS:
        cell.fill = SEVERITY_FILLS[value]
        if value == "Critical":
            cell.font = Font(bold=True, color="FFFFFF")

Summary values are also written without sanitization:

python
for idx, (label, value) in enumerate(sections, 1):
    if label:
        ws.cell(row=idx, column=1, value=label).font = Font(bold=True, size=11)
    ws.cell(row=idx, column=2, value=value).alignment = Alignment(wrap_text=True)

Revision-history values are handled in the same manner:

python
for row_idx, rev in enumerate(revisions, 2):
    for col, key in enumerate(["version", "date", "author", "description", "reviewer", "status"], 1):
        cell = ws.cell(row=row_idx, column=col, value=rev.get(key, ""))
        _apply_cell(cell)

External-reconciliation values are written directly:

python
for row_idx, item in enumerate(items, 2):
    for col, key in enumerate(
        ["recon_id", "data_source", "provider", "key_fields",
         "method", "frequency", "discrepancy_handling", "responsible_party", "notes"], 1
    ):
        _apply_cell(ws.cell(row=row_idx, column=col, value=item.get(key, "")))

Template mode contains an additional direct-write sink:

python
for row_idx, check in enumerate(input_data.get("checks", []), 2):
    for col_idx, field_name in header_to_field.items():
        check_sheet.cell(row=row_idx, column=col_idx + 1, value=check.get(field_name, ""))

Technical Analysis

The ...[truncated 3297 chars]

Remediation
View remediation

Remediation Suggestions

Introduce one centralized conversion function and apply it to every value derived from JSON or user-provided content before assigning it to a workbook cell:

python
FORMULA_PREFIXES = ("=", "+", "-", "@")

def safe_excel_text(value):
    if not isinstance(value, str):
        return value

    # Account for control characters that spreadsheet applications may
    # ignore before recognizing a formula.
    normalized = value.lstrip("\t\r\n")
    if normalized.startswith(FORMULA_PREFIXES):
        return "'" + value
    return value

Replace every untrusted cell assignment with the sanitized value:

python
cell = ws.cell(
    row=row_idx,
    column=col,
    value=safe_excel_text(value),
)

Apply the same protection to:

  • Check-list fields.
  • Summary values and role entries.
  • Revision-history fields.
  • External-data reconciliation fields.
  • All values written through template column mappings.

Additional hardening measures:

  1. Treat all imported DVP content as text by default; allow formulas only through an explicit, trusted allowlist.
  2. Keep pre-existing formulas in a trusted user template separate from values imported from JSON.
  3. Validate the generated workbook before distribution by loading it and rejecting unexpected cells whose data_type is f.
  4. Add automated tests for values beginning with =, +, -, @, tabs, carriage returns, and newlines.
  5. Test every affected section in both default and template generation modes.
  6. Document that generated workbooks must not contain formulas originating from study materials or other untrusted input.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • 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
Findings (11)

Self-Modification

High
Category
Rogue Agent
Confidence
85% confidence
Finding

Skill modifies its own code, configuration, or behavior at runtime. Self-modification enables an agent to escalate privileges, disable safety constraints, or install persistent backdoors.

Content

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

md
2. At each phase's [Done] step, write all deliverable files to `dvp_workspace/`
3. At the start of each phase (except Phase 1), read the previous phase's deliverable files first
4. File names are hard-coded in each phase instruction — do not rename them
5. Overwrite existing files without asking for confirmation
6. All files use Markdown format. The only exceptions are: `dvp_content.json` (JSON), `DVP_<ProtocolNumber>_v1.0.xlsx` (Excel), and any user-provided template files.

### Cross-Phase File: assumptions-and-gaps.md

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
87% confidence
Finding

The skill directs the agent to read multiple local files and phase reference documents, but it declares no explicit tool scope or allowed-tools boundary. That creates an authorization gap where file access capabilities may be broader than intended, increasing the chance of reading unrelated sensitive files if the workflow or prompt is manipulated.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

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

md
2. At each phase's [Done] step, write all deliverable files to `dvp_workspace/`
3. At the start of each phase (except Phase 1), read the previous phase's deliverable files first
4. File names are hard-coded in each phase instruction — do not rename them
5. Overwrite existing files without asking for confirmation
6. All files use Markdown format. The only exceptions are: `dvp_content.json` (JSON), `DVP_<ProtocolNumber>_v1.0.xlsx` (Excel), and any user-provided template files.

### Cross-Phase File: assumptions-and-gaps.md

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly instructs the agent to overwrite existing files in dvp_workspace without confirmation. This is dangerous because it can destroy prior work, replace user-provided artifacts such as templates or intermediate deliverables, and make prompt-triggered data loss easy to cause unintentionally.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This markdown file contains natural-language instructions that constrain query language preference to CN/EN at L040. Under the policy rule, forcing a specific language or locale without user opt-in or documented justification is a violation; nothing here explains why only these languages are allowed or offers another option beyond bilingual CN/EN.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

At L097-L102, the skill instructs the agent to ask the user to choose only among Chinese, English, or bilingual output. This is a locale policy concern because the allowed choices are hard-coded and exclude other user-preferred languages, with no documented justification that the workflow is region-specific.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The tip at L230 specifically calls out Chinese characters in query wording, implying expected use of a specific language/locale in generated content. The file does not offer the user a language choice or document a justified locale restriction, which can violate the language/locale policy.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This markdown skill instructs the agent to write output to dvp_workspace/review-report.md, which affects user files. The description and instructions do not explicitly warn the user that the skill will create or overwrite a file, so the file-modifying behavior is not clearly disclosed.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This markdown file directs the skill to write multiple files into dvp_workspace/, and later requires those files to be written before presenting the summary. While the write location is named, the description does not explicitly warn the user that the skill will create or overwrite files in the workspace as part of execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

The markdown says that if the user has a DVP Excel template, the skill should read it to inspect structure and conventions. Because this involves accessing user-provided file contents, a brief disclosure about reading the file and using its contents for formatting would improve transparency.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

The summary template at L185 uses a fixed [CN/EN] placeholder, which implies only those locales are supported. Even though this is a template detail, it codifies a language restriction without stating a project-specific reason or allowing other user-selected locales.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.