feat: enforce maximum password length of 64 characters in user registration and password update
Build & Push Docker Image / build (push) Successful in 4m19s
Build & Push Docker Image / build (push) Successful in 4m19s
This commit is contained in:
+18
-7
@@ -24,6 +24,14 @@ import {
|
||||
discoverInstance,
|
||||
} from '../config/federation.js';
|
||||
|
||||
// Avatar image filenames are produced by the upload endpoint as
|
||||
// "<userId>_<timestamp>.<ext>". Reject anything that doesn't match this shape
|
||||
// so a guest can't smuggle path traversal or arbitrary URL fragments through
|
||||
// the unauthenticated guest-join endpoint.
|
||||
const SAFE_AVATAR_FILENAME_RE = /^[0-9]+_[0-9]+\.(jpg|png|gif|webp)$/;
|
||||
// Mirrors auth.js: only allow hex/hsl/named CSS colors.
|
||||
const SAFE_AVATAR_COLOR_RE = /^(?:#[0-9a-fA-F]{3,8}|hsl\(\d{1,3},\s*\d{1,3}%,\s*\d{1,3}%\)|[a-zA-Z]{1,30})$/;
|
||||
|
||||
// L6: constant-time string comparison for access/moderator codes
|
||||
function timingSafeEqual(a, b) {
|
||||
if (typeof a !== 'string' || typeof b !== 'string') return false;
|
||||
@@ -664,15 +672,18 @@ router.post('/:uid/guest-join', guestJoinLimiter, async (req, res) => {
|
||||
}
|
||||
|
||||
const baseUrl = getBaseUrl(req);
|
||||
// Validate client-supplied avatar fields before embedding them in a URL
|
||||
// that BBB will fetch — guest-join is unauthenticated.
|
||||
const safeAvatarImage = (typeof avatar_image === 'string' && SAFE_AVATAR_FILENAME_RE.test(avatar_image))
|
||||
? avatar_image : null;
|
||||
const safeAvatarColor = (typeof avatar_color === 'string' && SAFE_AVATAR_COLOR_RE.test(avatar_color))
|
||||
? avatar_color : null;
|
||||
let guestAvatarURL;
|
||||
if (avatar_image) {
|
||||
// Use avatar image of the logged-in user
|
||||
guestAvatarURL = `${baseUrl}/api/auth/avatar/${avatar_image}`;
|
||||
} else if (avatar_color) {
|
||||
// Initials with user color
|
||||
guestAvatarURL = `${baseUrl}/api/auth/avatar/initials/${encodeURIComponent(name.trim())}?color=${encodeURIComponent(avatar_color)}`;
|
||||
if (safeAvatarImage) {
|
||||
guestAvatarURL = `${baseUrl}/api/auth/avatar/${encodeURIComponent(safeAvatarImage)}`;
|
||||
} else if (safeAvatarColor) {
|
||||
guestAvatarURL = `${baseUrl}/api/auth/avatar/initials/${encodeURIComponent(name.trim())}?color=${encodeURIComponent(safeAvatarColor)}`;
|
||||
} else {
|
||||
// Default: initials without color
|
||||
guestAvatarURL = `${baseUrl}/api/auth/avatar/initials/${encodeURIComponent(name.trim())}`;
|
||||
}
|
||||
const joinUrl = await joinMeeting(room.uid, name.trim(), isModerator, guestAvatarURL);
|
||||
|
||||
Reference in New Issue
Block a user