diff --git a/src/components/admin/media-grid.tsx b/src/components/admin/media-grid.tsx index 39b6b16e..a80b4bb1 100644 --- a/src/components/admin/media-grid.tsx +++ b/src/components/admin/media-grid.tsx @@ -6,9 +6,10 @@ import { uploadMedia } from "@/actions/admin-media"; type MediaFile = { name: string; url: string }; function validImageUrl(url: string): string { - // Only allow relative URLs (starting with /) to prevent XSS via absolute URLs. - if (url.startsWith("/")) return url; - return ""; + if (!url.startsWith("/")) return ""; + if (/[<>"']/.test(url)) return ""; + if (/(data|javascript|vbscript|file):/i.test(url)) return ""; + return url; } export function AdminMediaGrid() { diff --git a/src/components/admin/media-picker.tsx b/src/components/admin/media-picker.tsx index e1d99930..af649c2c 100644 --- a/src/components/admin/media-picker.tsx +++ b/src/components/admin/media-picker.tsx @@ -6,9 +6,10 @@ import { uploadMediaAndReturn } from "@/actions/admin-media"; type MediaFile = { name: string; url: string }; function validImageUrl(url: string): string { - // Only allow relative URLs (starting with /) to prevent XSS via absolute URLs. - if (url.startsWith("/")) return url; - return ""; + if (!url.startsWith("/")) return ""; + if (/[<>"']/.test(url)) return ""; + if (/(data|javascript|vbscript|file):/i.test(url)) return ""; + return url; } export function MediaPicker({ diff --git a/src/lib/auth/laravel-encrypter.ts b/src/lib/auth/laravel-encrypter.ts index 92561930..3bfcfeba 100644 --- a/src/lib/auth/laravel-encrypter.ts +++ b/src/lib/auth/laravel-encrypter.ts @@ -30,6 +30,7 @@ export class LaravelEncrypter { encrypt(value: string, serialize = true): string { const iv = randomBytes(16); const data = serialize ? phpSerializeString(value) : value; + // snyk:ignore:javascript/CipherWithNoIntegrity // AES-256-CBC is required for Laravel compatibility. Integrity is provided // by the HMAC-SHA256 MAC (verified by decrypt before any output is returned), // not by the cipher mode itself. Switching to GCM would break existing @@ -55,6 +56,7 @@ export class LaravelEncrypter { throw new Error("The MAC is invalid."); } const iv = Buffer.from(json.iv, "base64"); + // snyk:ignore:javascript/CipherWithNoIntegrity // AES-256-CBC required for Laravel compatibility; MAC already verified // above so padding-oracle / tampering is not a risk. const decipher = createDecipheriv("aes-256-cbc", this.key, iv);