Sanitize CSS values

When generating CSS from external data (JSON, user input, theme files), validate and sanitize both CSS property names and values before injecting them into style elements to prevent style-breaking input and XSS/style injection.

copy reviewer prompt

Prompt

Reviewer Prompt

When generating CSS from external data (JSON, user input, theme files), validate and sanitize both CSS property names and values before injecting them into style elements to prevent style-breaking input and XSS/style injection.

Motivation: Building CSS via string concatenation (e.g. --term-${key}: ${value};) can allow malicious or malformed keys/values to break the stylesheet or inject content. Use browser APIs and input validation to make this safe.

How to apply:

  • Prefer CSSOM APIs instead of raw string injection: use element.style.setProperty(propertyName, value).
  • Escape property names with CSS.escape when used in a context that requires serialization.
  • Validate values with a whitelist or conservative regex: disallow characters that can break CSS such as ;, } or HTML tag delimiters, and limit length. For colors/units consider explicit parsers or allowlists (hex colors, rgb(), numbers+units).
  • If full fidelity is required, parse/serialize values using strict rules rather than passing arbitrary strings into a style element.

Example (adapted from the discussion):

// unsafe: --term-${key}: ${value}; // safer approach: function isValidKey(key) { // allow lowercase letters, numbers, and hyphens (adjust to your naming rules) return /^[a-z0-9-]+$/.test(key); }

function isValidValue(value) { if (typeof value !== ‘string’ || value.length > 200) return false; // disallow characters that can close or break CSS rules return !/[;{}<>]/.test(value); }

async function applyTheme(themeJson, styleEl) { for (const [key, value] of Object.entries(themeJson)) { if (!isValidKey(key) || !isValidValue(String(value))) continue; // reject invalid entries

// use CSS custom property API which avoids injecting raw CSS text
// ensure the property name is valid per your rules
styleEl.style.setProperty(`--term-${CSS.escape(key)}`, String(value));   } }

Notes:

  • CSS.escape is broadly available and safe for serializing identifiers; still validate keys to match your naming expectations.
  • For values that are colors or units, prefer strict parsing (e.g., validate hex, rgb(), or numeric+unit) rather than a permissive regex.
  • When creating

References: [0]

Source discussions