From 90497440bf52235712bedf6b5759846714274ce9 Mon Sep 17 00:00:00 2001 From: khangnghiem <56039341+khangnghiem@users.noreply.github.com> Date: Fri, 26 Jun 2026 19:48:15 +0000 Subject: [PATCH] Fix attribute-based XSS by escaping single quotes in custom HTML escaper Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> --- .jules/sentinel.md | 5 +++++ site/layers.js | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.jules/sentinel.md b/.jules/sentinel.md index 5e0d967e..af8c0fc8 100644 --- a/.jules/sentinel.md +++ b/.jules/sentinel.md @@ -14,3 +14,8 @@ **Vulnerability:** Several `escapeHtml` implementations used DOM manipulation (`document.createElement('div').innerHTML`) or incomplete string replacement, failing to escape single and double quotes. **Learning:** Incomplete escaping allows XSS payloads to break out of HTML attributes (e.g., ``). **Prevention:** Always use `String(text)` cast combined with a comprehensive replace chain for `&`, `<`, `>`, `"`, and `'` (e.g., `'`) in custom string escaping functions. + +## 2025-06-26 - [Title] Fix attribute-based XSS by strictly escaping single quotes in custom HTML escape functions +**Vulnerability:** Custom HTML escaping functions across the codebase (`escHtml` in `site/layers.js` and others) failed to cast input strings correctly and missed escaping single quotes (`'`). This left attributes vulnerable to XSS attacks (e.g. `data-node-id` getting a payload that breaks out using single quotes). +**Learning:** Even simple string replacement functions designed for HTML escaping need to explicitly handle single quotes and securely cast inputs, as relying on missing character replacements creates XSS vectors within HTML attributes. +**Prevention:** Always use `String(text)` in escape functions before replacing characters. Ensure that both double (`"`) and single quotes (`'`) are escaped; specifically, use `'` for single quotes to ensure maximum browser compatibility. diff --git a/site/layers.js b/site/layers.js index ce74c59f..559a3cab 100644 --- a/site/layers.js +++ b/site/layers.js @@ -10,7 +10,7 @@ export function initLayersPanel(api) { path: '〜', text: 'T', style: '◆', edge: '⟶', note: '◇', spec: '◇' }; - function escHtml(s) { return s.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } + function escHtml(s) { return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"').replace(/'/g,'''); } /** Parse FD source into a hierarchical layer tree. */ function parseLayerTree(source) {