fix: call system bugs and security hardening
- CallEmbed: fix memory leak — mx event listeners were never removed because dispose() called .bind(this) again, creating new function objects. Now uses arrow class fields so start()/dispose() share the exact same reference. - callPreferences: toggleVideo is a no-op when cameraOnJoin=false, preventing internal state drift from the returned value. - CallControls: PTT key guard now blocks on SELECT elements and walks the DOM for inherited contentEditable to prevent key interception inside dropdowns and custom editors. - RoomInput: GIF fetch validates Giphy CDN domain allow-list, HTTP Content-Type header, and enforces 20 MB size cap.
This commit is contained in:
@@ -457,8 +457,20 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
|
||||
const handleGifSelect = useCallback(
|
||||
async (gifUrl: string, w: number, h: number) => {
|
||||
try {
|
||||
// Only fetch from trusted Giphy CDN domains
|
||||
const allowed = ['media.giphy.com', 'i.giphy.com', 'media0.giphy.com',
|
||||
'media1.giphy.com', 'media2.giphy.com', 'media3.giphy.com', 'media4.giphy.com'];
|
||||
const { hostname } = new URL(gifUrl);
|
||||
if (!allowed.includes(hostname)) return;
|
||||
|
||||
const res = await fetch(gifUrl);
|
||||
if (!res.ok) return;
|
||||
const contentType = res.headers.get('content-type') ?? '';
|
||||
if (!contentType.startsWith('image/')) return;
|
||||
|
||||
const blob = await res.blob();
|
||||
if (blob.size > 20 * 1024 * 1024) return; // 20 MB cap
|
||||
|
||||
const uploadRes = await mx.uploadContent(
|
||||
new File([blob], 'image.gif', { type: 'image/gif' }),
|
||||
{ type: 'image/gif', name: 'image.gif', includeFilename: false }
|
||||
|
||||
Reference in New Issue
Block a user