Back to skill

Security audit

City of Edmonton Open Data

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward City of Edmonton open-data CLI, with one CSV-export safety caveat users should understand.

Install only if you are comfortable with a Bash-invoked helper that contacts data.edmonton.ca and may cache the public dataset catalog locally. Treat CSV output as untrusted remote data; prefer JSON for analysis, or sanitize CSV files before opening them in spreadsheet applications.

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/edmonton_data.py:151
Finding
Unsafe CSV Export Permits Spreadsheet Formula Injection<![CDATA[ ## Vulnerability Details **File Location**: `scripts/edmonton_data.py:151-161` **Vulnerability Type**: Improper neutralization of CSV fields and spreadsheet formulas **Risk Level**: Medium ### Vulnerable Code ```python if options.get("csv"): # CSV output if not data: print("No data returned.") return keys = list(data[0].keys()) print(",".join(keys)) for row in data: vals = [str(row.get(k, "")).replace(",", ";") for k in keys] print(",".join(vals)) else: print(json.dumps(data, indent=2, default=str)) ``` ### Technical Analysis The CSV export constructs records by directly joining API-provided column names and values. Replacing commas with semicolons is not standards-compliant CSV encoding and does not safely handle quotation marks, carriage returns, line feeds, or other record delimiters. More importantly, fields beginning with spreadsheet formula indicators such as `=`, `+`, `-`, or `@` are emitted unchanged. If a City of Edmonton dataset contains malicious or compromised text, the resulting file can contain active spreadsheet formulas. The documented usage encourages redirecting this output to a file: ```bash python3 scripts/edmonton_data.py fetch 24uj-dj8v --limit 100 --csv > permits.csv ``` CSV quoting alone prevents structural corruption but does not prevent spreadsheet applications from interpreting a quoted cell as a formula. Formula-prefixed cells therefore require separate neutralization when the export is intended for spreadsheet use. ### Attack Path 1. An attacker places a formula-prefixed value in a source represented by an Edmonton open dataset, or dataset content is otherwise compromised. 2. A user exports that dataset using `fetch <dataset-id> --csv`. 3. The script writes the attacker-controlled value to the CSV output without formula neutralization. 4. The user opens the exported file in spreadsheet software that evaluates ...[truncated 1080 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Replace manual string joining with Python's standard `csv` module so delimiters, quotation marks, and line breaks are encoded correctly: ```python import csv def neutralize_spreadsheet_formula(value): text = str(value) if text.startswith(("=", "+", "-", "@")): return "'" + text return text writer = csv.writer(sys.stdout, lineterminator="\n") writer.writerow(neutralize_spreadsheet_formula(k) for k in keys) for row in data: writer.writerow( neutralize_spreadsheet_formula(row.get(k, "")) for k in keys ) ``` 2. Apply formula neutralization to both headers and values. Consider ignoring leading whitespace when detecting formulas because some spreadsheet applications may interpret whitespace-prefixed formulas. 3. If preserving exact source values is required, provide two explicit modes: - A standards-compliant raw CSV mode that preserves values and warns that the output is unsafe to open in spreadsheet software. - A spreadsheet-safe mode that neutralizes formula prefixes. 4. Add automated tests covering: - Commas and semicolons. - Double quotation marks. - CR and LF characters. - Formula prefixes `=`, `+`, `-`, and `@`. - Empty and non-string values. - Formula prefixes preceded by whitespace, tabs, or control characters. 5. Document the trust boundary: dataset content is remote input even when it originates from a government open-data portal. ]]>
Vulnerability Patterns
  • 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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.