Commit 1aa77e66 by CaIon

fix(ui): enforce HTTPS for backend-provided image URLs and improve URL validation

parent 06f9dec9
...@@ -27,26 +27,24 @@ import { PAYMENT_TYPES, PAYMENT_ICON_COLORS } from '../constants' ...@@ -27,26 +27,24 @@ import { PAYMENT_TYPES, PAYMENT_ICON_COLORS } from '../constants'
// UI Helper Functions // UI Helper Functions
// ============================================================================ // ============================================================================
const HAS_LOCATION =
typeof globalThis !== 'undefined' && 'location' in globalThis
/** /**
* Resolves a backend-provided image URL to http(s) only. Rejects javascript:, * Resolves a backend-provided image URL to https only. Rejects http:,
* data:, blob:, file:, and URLs with userinfo, which are unsafe in <img src/>. * data:, blob:, file:, relative paths, and URLs with userinfo, which are unsafe
* or ambiguous in <img src/>.
*/ */
function normalizeHttpIconUrl(raw: string | undefined | null): string | null { function normalizeHttpIconUrl(raw: string | undefined | null): string | null {
if (!raw) return null if (!raw) return null
const s = raw.trim() const s = raw.trim()
if (!s) return null if (!s) return null
if (!/^https:\/\//i.test(s)) return null
let url: URL let url: URL
try { try {
url = HAS_LOCATION url = new URL(s)
? new URL(s, (globalThis as { location: Location }).location.href)
: new URL(s)
} catch { } catch {
return null return null
} }
if (url.protocol !== 'http:' && url.protocol !== 'https:') { if (url.protocol !== 'https:') {
return null return null
} }
if (url.username || url.password) { if (url.username || url.password) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment