fix(security): isActive defense-in-depth, MIME magic bytes upload, tenantId=origins OAuth
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 54s

This commit is contained in:
2026-03-15 17:34:19 +01:00
parent ef4c23d6a2
commit 379a9a115b
3 changed files with 30 additions and 1 deletions

View File

@@ -64,6 +64,11 @@ export const requireAuth = async (
return;
}
if (!data.data.user.isActive) {
res.status(401).json({ success: false, error: "ACCOUNT_DISABLED", message: "Account is disabled" });
return;
}
(req as AuthenticatedRequest).user = data.data.user;
next();
} catch (err) {

View File

@@ -1,6 +1,23 @@
import { Router, Request, Response } from "express";
import path from "path";
import fs from "fs";
/**
* Vérifie les magic bytes d'un fichier vidéo déjà écrit sur disque.
* MP4 : bytes 4-7 = 'ftyp' (0x66 0x74 0x79 0x70)
* WebM : bytes 0-3 = 0x1A 0x45 0xDF 0xA3
*/
const isValidVideoMagicBytes = (filePath: string): boolean => {
const fd = fs.openSync(filePath, "r");
const buf = Buffer.alloc(12);
fs.readSync(fd, buf, 0, 12, 0);
fs.closeSync(fd);
const isWebM = buf[0] === 0x1a && buf[1] === 0x45 && buf[2] === 0xdf && buf[3] === 0xa3;
const isMP4 = buf[4] === 0x66 && buf[5] === 0x74 && buf[6] === 0x79 && buf[7] === 0x70;
return isMP4 || isWebM;
};
import multer, { FileFilterCallback } from "multer";
import { AppDataSource } from "../config/data-source";
import { Video } from "../entities/Video";
@@ -71,6 +88,13 @@ router.post(
res.status(400).json({ success: false, error: "NO_FILE" });
return;
}
if (!isValidVideoMagicBytes(req.file.path)) {
fs.unlinkSync(req.file.path);
res.status(415).json({ success: false, error: "INVALID_FILE_CONTENT", message: "File content does not match a valid video format" });
return;
}
res.status(201).json({
success: true,
data: { storageKey: req.file.filename, storageType: "local" },

View File

@@ -27,7 +27,7 @@ export default function LoginPage() {
function handleOAuth(providerId: string) {
if (oauthLoading) return;
setOauthLoading(providerId);
window.location.href = `${base}/api/v1/oauth/${providerId}?redirectUrl=${redirectUrl}`;
window.location.href = `${base}/api/v1/oauth/${providerId}?redirectUrl=${redirectUrl}&tenantId=origins`;
}
async function handleSubmit(e: React.FormEvent) {