fix(builder): sanitize HtmlBlock/Countdown/Gallery JS contexts
Entity-escaping alone doesn't protect JS-string or raw-HTML sinks:
- HtmlBlock.toHtml exported props.code raw; now runs it through the
same purifyHtml (DOMPurify) config already used for the live editor
preview, so <script>/on*= payloads can't survive export either.
- Countdown.toHtml interpolated targetDate directly into
`new Date("${targetDate}")` inside an inline <script> -- a value
like `2026-01-01");alert(1)//` broke out of the string literal. Now
validated against a strict date/datetime shape and JSON.stringify'd
before embedding, falling back to `new Date()` for anything invalid.
- Gallery.toHtml's lightbox used
`onclick="${id}_open('${esc(img.src)}')"`, which a single quote in
img.src could break out of. Replaced with a `data-lb-src` attribute
per thumbnail and one delegated click listener on the grid
(`e.target.closest('[data-lb-src]')`) instead of a per-item inline
handler string.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -284,6 +284,14 @@ Countdown.craft = {
|
||||
// Generate a unique ID for this countdown instance
|
||||
const uid = 'cd_' + Math.random().toString(36).slice(2, 8);
|
||||
|
||||
// Only accept a strict date/datetime shape before it's embedded in the
|
||||
// inline <script>; anything else falls back to "now" instead of letting
|
||||
// arbitrary text (e.g. `");alert(1)//`) break out of the new Date(...) call.
|
||||
const VALID_DATE_RE = /^\d{4}-\d{2}-\d{2}([T ][0-9:.\-+Z]*)?$/;
|
||||
const dateExpr = typeof targetDate === 'string' && VALID_DATE_RE.test(targetDate)
|
||||
? `new Date(${JSON.stringify(targetDate)})`
|
||||
: 'new Date()';
|
||||
|
||||
return {
|
||||
html: `<section${idAttr}${sectionStyle ? ` style="${sectionStyle}"` : ''}>
|
||||
${headingHtml}
|
||||
@@ -295,7 +303,7 @@ Countdown.craft = {
|
||||
</div>
|
||||
<script>
|
||||
(function(){
|
||||
var target = new Date("${targetDate}").getTime();
|
||||
var target = ${dateExpr}.getTime();
|
||||
function pad(n){ return String(n).padStart(2,'0'); }
|
||||
function update(){
|
||||
var diff = target - Date.now();
|
||||
|
||||
Reference in New Issue
Block a user