T09 · Insecure Skill Coding Practices
- Location
scripts/openlayers_scaffold.py:134- Finding
Stored JavaScript Injection Through Embedded GeoJSON Content
- Content
View full analysis
` element. JSON serialization makes the data valid JavaScript syntax but does not make it safe for embedding in an HTML script element. In particular, `json.dumps` does not escape the HTML parser-sensitive sequence ``. A malicious GeoJSON property can therefore terminate the existing script element and introduce a new attacker-controlled script element. For example, a property containing the following value would survive JSON serialization: ```json { "type": "Feature", "properties": { "name": "" }, "geometry": { "type": "Point", "coordinates": [0, 0] } } ``` The browser's HTML parser recognizes the closing `` sequence regardless of whether it appears inside what JavaScript treats as a string literal. Consequently, the injected script executes when the generated HTML page is opened. ### Attack Path 1. An attacker creates or modifies a GeoJSON file containing a property value with a `` breakout payload. 2. The victim obtains the file and invokes the documented scaffold command: ```bash python3 scripts/openlayers_scaffold.py geojson \ --out ./openlayers-geojson.html \ --geojson ./untrusted.geojson ` ...[truncated 1217 chars]- Remediation
View remediation
{escaped_geojson_payload} ``` Before embedding the serialized JSON, escape characters that can affect HTML parsing. At minimum, replace `<` with its JSON Unicode escape: ```python geojson_payload = json.dumps( geojson_obj, ensure_ascii=True, indent=2, ).replace("<", "\\u003c") ``` For defense in depth, also escape `>`, `&`, U+2028, and U+2029 where applicable. Alternatively, load the GeoJSON as a separate resource rather than embedding it in the generated page. Add regression tests that generate a page from GeoJSON properties containing: ```text ``` The test should verify that the generated HTML contains no literal `` sequence originating from the GeoJSON payload and that no injected element is created when the page is parsed. ]]>
