diff --git a/packages/server/src/routes/users.ts b/packages/server/src/routes/users.ts index 535c4f54..1ce73adf 100644 --- a/packages/server/src/routes/users.ts +++ b/packages/server/src/routes/users.ts @@ -10,12 +10,14 @@ import { deleteUploadFile } from '../utils/fileCleanup.js'; import { tombstoneUser } from '../utils/userDeletion.js'; import { generateSnowflake } from '../utils/snowflake.js'; -/** Validates that a URL is a safe asset URL (relative upload path or http/https) */ +/** Validates that a URL is a safe asset URL (relative upload path, bare filename, or http/https) */ function isValidAssetUrl(url: string | null | undefined): boolean { if (!url || url.trim().length === 0) return true; // empty/null = clearing const trimmed = url.trim(); if (trimmed.startsWith('/api/uploads/')) return true; if (trimmed.startsWith('https://') || trimmed.startsWith('http://')) return true; + // Accept bare filenames (the existing convention) — no slashes, no traversal + if (!trimmed.includes('/') && !trimmed.includes('\\') && !trimmed.includes('..')) return true; return false; } diff --git a/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx b/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx index cde850c0..57bbe70d 100644 --- a/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx +++ b/packages/web/src/components/modals/settingsPanels/AccountPanel.tsx @@ -214,8 +214,8 @@ export function AccountPanel() { setPasswordSuccess(''); setPasswordResults(null); - if (newPassword.length < 6) { - setPasswordError('New password must be at least 6 characters'); + if (newPassword.length < 8) { + setPasswordError('New password must be at least 8 characters'); return; } if (newPassword !== confirmNewPassword) {