fix(ui): add validation for custom colors from localStorage

Add security validation to prevent malicious or invalid hex colors from
being applied when loaded from localStorage.

Security improvements:
- Validate custom color in ThemeSelector before setting to state
- Validate custom color in index.html before applying theme
- Prevent potential XSS vulnerabilities from malicious localStorage content

Code quality improvements:
- Add explanatory comments for HSL to RGB conversion magic numbers
- Improve code clarity with inline documentation

Addresses feedback from code review regarding input validation and
security best practices.

Signed-off-by: jom-sq <148157197+jom-sq@users.noreply.github.com>
This commit is contained in:
jom-sq
2025-11-03 11:00:30 -05:00
parent 7341f55dfc
commit c4e11a52df
2 changed files with 18 additions and 6 deletions
+8 -4
View File
@@ -25,7 +25,11 @@
// Apply custom theme colors if enabled
const customThemeEnabled = localStorage.getItem('custom_theme_enabled') === 'true';
if (customThemeEnabled) {
const customColor = localStorage.getItem('custom_theme_color') || '#32353b';
let customColor = localStorage.getItem('custom_theme_color') || '#32353b';
// Validate the color before applying it
if (!hexToRgb(customColor)) {
customColor = '#32353b';
}
applyCustomThemeColors(customColor, isDark);
}
} else {
@@ -78,9 +82,9 @@
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
if (t < 1/6) return p + (q - p) * 6 * t; // Hue in red-yellow range
if (t < 1/2) return q; // Hue in yellow-green range
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; // Hue in green-blue range
return p;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
@@ -3,7 +3,12 @@ import { Moon, Sliders, Sun, Palette, type LucideIcon } from 'lucide-react';
import { Button } from '../ui/button';
import { Switch } from '../ui/switch';
import { CustomColorPicker } from './CustomColorPicker';
import { applyCustomTheme, resetThemeColors, DEFAULT_THEME_COLOR } from '../../utils/colorUtils';
import {
applyCustomTheme,
resetThemeColors,
DEFAULT_THEME_COLOR,
isValidHexColor,
} from '../../utils/colorUtils';
import { cn } from '../../utils';
interface ThemeSelectorProps {
@@ -68,7 +73,10 @@ export function ThemeSelector({
}
if (e.key === 'custom_theme_color' && e.newValue) {
setCustomColor(e.newValue);
// Validate the color before setting it to state
if (isValidHexColor(e.newValue)) {
setCustomColor(e.newValue);
}
}
if (e.key === 'custom_theme_enabled') {