Back to skill

Security audit

OvitalMap Parcel CSV

Security checks for vulnerabilities and agentic risk

Overview

This parcel CSV skill matches its stated workflow, but it needs review because untrusted text can be persisted into CSV archives in a form spreadsheet apps may treat as formulas.

Install only if you are comfortable with it creating and updating local CSV exports and archives. Set OVITALMAP_WORKSPACE to a dedicated folder, review coordinates and parcel codes before approving writes, and avoid opening generated archive CSVs in spreadsheet software when provider names or notes came from untrusted sources unless those fields have been sanitized.

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/archive_manager.py:50
Finding

Persistent CSV Formula Injection Through Untrusted Archive Fields

Content
View full analysis
120 or any(char in code for char in "/\\\r\n,"): raise ValueError("Invalid parcel_code") provider = str(row.get("provider_name") or "").strip() if not provider: raise ValueError(f"{code}: provider_name is required") vertices = parse_boundary_coords(str(row.get("boundary_coords") or "")) errors = validate_coordinates(vertices, require_polygon=True) if errors: raise ValueError(f"{code}: {'; '.join(errors)}") validated = {header: row.get(header, "") for header in COUNTRY_HEADERS} validated.update( { "parcel_code": code, "provider_name": provider, "boundary_coords": build_boundary_string(vertices), } ) return validated ``` The resulting fields are passed to the generic CSV writer without spreadsheet-formula neutralization: ```python def write_csv(filepath, headers, rows): path = Path(filepath) path.parent.mkdir(parents=True, exist_ok=True) with path.open("w", encoding="utf-8", newline="") as handle: writer = csv.writer(handle) writer.writerow(headers) for row in rows: writer.writerow([row.get(header, "") for header in headers]) ``` ### Technical Analysis The archive validation checks that `provider_name` is non-empty but does not reject or neutralize spreadsheet formula prefixes. Other archive fields copied through the `validated` dictionary, particularly `provider_notes`, receive no formula-specific validation either. Python's `csv.writer` correctly quotes values for CSV syntax, but quoting does not prevent spreadsheet applications from interpreting cell c ...[truncated 2540 chars]
Remediation
View remediation
=HYPERLINK(...) =HYPERLINK(...) ``` 7. Verify the resulting files in all spreadsheet applications supported by the project, because formula interpretation and single-quote handling can vary between products. ]]>
Vulnerability Patterns
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (17)

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

The code chunk is narrowly a coordinate conversion utility. Its primary function is converting structured decimal, DMS, or UTM coordinate pairs into WGS84 lon/lat and returning them as JSON after validation. The declared description, however, presents a broader parcel-boundary processing workflow involving CSV export for OvitalMap, stable parcel code assignment, archive maintenance/deduplication, text or image ingestion, and archive re-exports. Those major capabilities are absent from the code shown. While the coordinate-conversion portion partially aligns with the description, the actual code does not implement the declared primary parcel/archive management behavior, so this is a clear mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding

The declared description presents a full parcel-processing and export workflow, but the supplied code chunk implements only a narrow coordinate normalization/validation utility. Its primary behavior is reading JSON vertices, normalizing them, warning on likely lat/lon swaps, validating coordinate ranges, and emitting JSON. It explicitly leaves country selection unresolved (pending_confirmation) and does not perform the main promised functions such as CSV export, archive management, parcel code generation, or multi-format/image ingestion. This is a material description-behavior mismatch, not just an incomplete supporting detail.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
89% confidence
Finding

The code’s core purpose partially matches the description in that it builds OvitalMap-compatible CSV exports for parcel boundaries/vertices and performs some validation and duplicate-vertex cleanup. However, several prominent declared capabilities are not represented in this code chunk: stable parcel code assignment, maintenance of deduplicated archives, and support for text/image coordinate ingestion or multiple raw coordinate formats. The actual code is narrower: it exports already-structured parcel data to per-parcel CSV files under a country directory. Because the description claims broader end-to-end archive and code-management behavior than the supplied code actually implements, this is a material description/behavior mismatch.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description is about geospatial parcel processing and archive management. The code chunk does something entirely different: it performs conservative string normalization and exact matching of provider names, then emits a JSON result. There is no functionality related to parcel boundaries, coordinates, CSV export, images, archive handling, or parcel code generation. This is a clear material mismatch in primary purpose and capabilities.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared description presents a full geospatial parcel-processing skill. In contrast, this code chunk is a response protocol utility: it formats workflow guidance based on an already-produced result object. While the messages reference parcel workflows, duplicates, code confirmation, and export instructions, the code does not implement those capabilities. Its primary purpose is orchestration/output formatting for an agent pipeline, which is materially different from the declared end-user functionality. Therefore this is a clear description-behavior mismatch.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
85% confidence
Finding

The skill declares access to environment-controlled workspace paths and instructs use of scripts that read and write files, but it does not define any explicit tool scope or permission boundaries. In an agent setting, this can enable broader-than-expected filesystem access, especially because the workspace defaults to the current working directory when the environment variable is unset.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This markdown file contains natural-language requirements that force Chinese column names and labels such as 文件夹, 名称, and Chinese Comment content. Under the policy rule, a skill should not impose a specific language or locale unless the user can opt in or the region-specific requirement is explicitly justified.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The correct_coordinates flow performs a backup and then overwrites archive records in both country and master archives, which is a safety-critical file modification. While there is an internal backup and a replace_existing guard elsewhere, this file does not present any confirmation prompt, user-facing log/print, or explanatory warning comment/docstring for this destructive update path.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill manifest says it can maintain deduplicated country archives as part of parcel conversion workflows, and this file is specifically named country_locator, implying country identification. However, the implementation never performs any country lookup and hard-codes country_code/country_name to None with method set to pending_confirmation, so the actual behavior is limited to validation and coordinate-order correction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file hard-codes Chinese column headers and later also constructs Chinese comment labels, which imposes a specific language output regardless of user preference or locale. The policy allows locale constraints only when justified or user-selectable, and neither is present in this code.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The instructions specify OvitalMap import labels using Chinese terms (轨迹, 标签) as normative guidance. This is a natural-language locale constraint presented without any user opt-in or alternative language handling, which can violate language/locale policy expectations.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The file instructs users to choose OvitalMap options labeled with specific Chinese terms (轨迹 and 标签) and does not offer a language choice or note that these labels depend on locale. This can violate language/locale policy by assuming a fixed interface language for all users.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

append_parcels persists new rows into both country and master archives via STORE.commit, which is a file write affecting user data. The function has a brief docstring about conflict behavior, but it does not warn that it modifies persistent archives or provide any user-facing notice in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

update_cadastre modifies both country and master archive rows and commits the changes to storage. Although replacement of an existing value requires confirmation via the replace_existing flag, there is no visible warning, log, or explanatory documentation here that the function writes persistent archive data.

Content

No source excerpt is available for this finding.

Intent-Code Divergence

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The docstring actively narrows the function's behavior to validation-only, which contradicts the intent conveyed by the function name locate_country and the result structure containing country fields. This is more than incomplete documentation because it describes a non-locating behavior for a function explicitly presented as a country locator.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

The returned instructions embed Chinese labels "轨迹" and "标签" directly in user-facing strings. This imposes a specific language/locale in the output without any visible user opt-in or alternative language handling, which matches the language/locale policy concern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The append_csv and write_csv helpers create directories and write or append to files, which are safety-relevant file modification operations. In this file there is no confirmation prompt, logging/print statement, or inline warning comment/docstring disclosing that behavior to the user.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.