Back to skill

Security audit

Mapbox Data Visualization Patterns

Security checks for vulnerabilities and agentic risk

Overview

This documentation-only skill is mostly coherent, but several copyable examples use unsafe map popup HTML patterns that could expose users' apps to browser-side injection.

Review this skill before installing if you may copy its popup examples. Replace Popup#setHTML patterns that include dataset values with DOM construction, textContent, setDOMContent, or a vetted sanitizer, and pin any npm package versions you adopt.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (4)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:76
Finding

DOM XSS Through Unsanitized Choropleth Feature Properties

Content
View full analysis
{ if (e.features.length > 0) { map.getCanvas().style.cursor = 'pointer'; const feature = e.features[0]; popup .setLngLat(e.lngLat) .setHTML( `

${feature.properties.name}

Population: ${feature.properties.population.toLocaleString()}

` ) .addTo(map); } }); ``` ### Technical Analysis The example inserts GeoJSON feature properties into an HTML template and passes the result to `mapboxgl.Popup#setHTML()`. The `name` property is not encoded, sanitized, or constrained before the browser parses it as markup. GeoJSON can originate from remote services or user-controlled datasets. If an attacker can influence `feature.properties.name`, they can supply HTML containing executable event handlers or other active content. For example, a malicious name containing an image element with an `onerror` handler would be interpreted as HTML when the popup is displayed. ### Attack Path 1. An attacker gains control over, contributes to, or compromises the GeoJSON source used by the map. 2. The attacker places an HTML payload in the `name` property of a state feature. 3. The application loads the malicious feature. 4. A user moves the pointer over the affected feature. 5. The event handler interpolates the property into a string and calls `setHTML()`. 6. The browser parses the attacker-controlled markup in the application's origin and may execute its script-capable content. ### Impact Assessment Successful exploitation permits arbitrary client-side script execution in the security context of an application implementing th ...[truncated 340 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/circles-lines.md:43
Finding

DOM XSS Through Unsanitized Earthquake Popup Properties

Content
View full analysis
{ const props = e.features[0].properties; new mapboxgl.Popup() .setLngLat(e.features[0].geometry.coordinates) .setHTML( `

Magnitude ${props.mag}

Depth: ${props.depth} km

Time: ${new Date(props.time).toLocaleString()}

` ) .addTo(map); }); ``` ### Technical Analysis The `mag` and `depth` properties are interpolated directly into markup passed to `setHTML()`. The documentation does not validate that these properties are finite numbers or encode them for an HTML context. Although earthquake magnitude and depth are normally numeric, GeoJSON property types are not enforced by this code. A compromised or attacker-controlled data source can supply strings containing active HTML. Clicking the corresponding feature causes the application to parse those values as markup. ### Attack Path 1. The attacker controls or modifies an earthquake feature in the GeoJSON source. 2. The attacker substitutes an HTML payload for `mag` or `depth`. 3. A victim's browser loads and renders the feature. 4. The victim clicks the affected map point. 5. The click handler interpolates the malicious value into the popup HTML. 6. The browser parses the payload in the application's origin, potentially executing attacker-controlled script. ### Impact Assessment Exploitation can provide arbitrary JavaScript execution with the victim application's browser privileges. This may allow DOM manipulation, theft of accessible session or application data, authenticated same-origin requests, phishing overlays, and capture of information entered by the victim. Server-level or operating-system privileges are not directly obtained. ]]>
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
references/legends-use-cases.md:62
Finding

DOM XSS in Interactive Data Inspector

Content
View full analysis
{ const feature = e.features[0]; const properties = feature.properties; // Build properties table const propsTable = Object.entries(properties) .map(([key, value]) => `${key}:${value}`) .join(''); new mapboxgl.Popup() .setLngLat(e.lngLat) .setHTML( `

Feature Details

${propsTable}
` ) .addTo(map); }); ``` ### Technical Analysis This generic inspector enumerates every feature property and inserts both property names and values directly into an HTML table. Neither side is encoded or sanitized before the resulting string is passed to `setHTML()`. The generic nature of the inspector increases exposure because any property in an imported dataset becomes an HTML injection source. An attacker only needs control of a property key or value; no particular data schema is required. ### Attack Path 1. An attacker creates or modifies a feature containing malicious HTML in a property name or value. 2. The application imports the dataset and renders the feature. 3. A victim clicks the feature. 4. `Object.entries()` includes the malicious key or value in `propsTable`. 5. The completed table is passed to `setHTML()`. 6. The browser parses the injected markup and may execute script-capable content under the application's origin. ### Impact Assessment The vulnerability can lead to arbitrary browser-side code execution in the hosting application's origin. An attacker may access non-HttpOnly tokens or other client-side data, perform authenticated requests, alter map co ...[truncated 173 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
references/legends-use-cases.md:91
Finding

Unpinned Third-Party npm Dependency Installation Guidance

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (9)

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · AGENTS.md (reported line 72)May include surrounding context.

Color Scale Types:

javascript
// Linear (continuous)
['interpolate', ['linear'], ['get', 'value'], 0, '#fff', 100, '#000']

Hidden Instructions

High
Category
Prompt Injection
Confidence
70% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · AGENTS.md (reported line 519)May include surrounding context.

Color Scale Types:

javascript
// Linear (continuous)
['interpolate', ['linear'], ['get', 'value'], 0, '#fff', 100, '#000']

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/animation.md (reported line 87)May include surrounding context.

md
// Poll for updates every 5 seconds
  setInterval(async () => {
    const response = await fetch('https://api.example.com/live-data');
    const data = await response.json();

    // Update source

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The popup example builds HTML with unescaped feature property keys and values and passes it to setHTML(), so any untrusted GeoJSON or vector-tile attribute containing HTML or script-like payloads can be rendered in the page context. In a mapping application, data properties are often externally sourced or user-controlled, which makes this a practical client-side injection/XSS risk rather than a purely theoretical issue.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The example encourages rendering arbitrary feature properties as raw HTML without any warning that map data may be untrusted. Even if no exploit is immediately present in the snippet itself, this pattern normalizes unsafe handling of dataset content and increases the chance that downstream users will expose popups to attacker-controlled values.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
81% confidence
Finding

This markdown file includes a real-time update example that fetches data from an API endpoint on an interval, which is a network operation covered by the missing-warning rule for markdown files. The surrounding documentation presents the pattern as a generic recipe but does not warn that it will repeatedly contact a remote service and may transmit usage context or consume network resources.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The manifest describes patterns for visualizing data on maps, focusing on layer types, styling, animation, and performance. The 'Real-Time Data Updates' section includes concrete HTTP polling and WebSocket connectivity examples, which introduce external data acquisition behavior rather than just visualization patterns.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
74% confidence
Finding

Polling a remote API with fetch and opening a WebSocket connection are capabilities beyond purely demonstrating map rendering and animation techniques. While related to real-time visualization, the manifest does not explicitly state that the skill covers remote data access or live-stream integration.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This markdown file includes example code that polls an HTTPS endpoint and opens a WebSocket connection to remote services, which are network operations covered by the missing-warning rule for markdown files. The surrounding documentation presents these as patterns but does not mention privacy, external connectivity, or data-sharing implications.

Content

No source excerpt is available for this finding.