fix(security): Phase 1 P0 hardening from cross-project audit
Close open uploads, image-proxy SSRF, fail-open AI quotas in production, auth gaps on app routes, and MCP tenant isolation issues. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -32,7 +32,7 @@ import { randomBytes } from 'crypto';
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import { registerTools } from './tools.js';
|
||||
import { validateApiKey, resolveUser } from './auth.js';
|
||||
import { validateApiKey } from './auth.js';
|
||||
import { requestContext } from './request-context.js';
|
||||
import config, { validateConfig, printConfig } from './config.js';
|
||||
import {
|
||||
@@ -278,21 +278,25 @@ if (config.enableMetrics) {
|
||||
app.use(
|
||||
withErrorHandling(async (req, res, next) => {
|
||||
if (!config.requireAuth) {
|
||||
req.userSession = { id: 'dev-user', name: 'Development User', isAuth: false };
|
||||
req.userSession = {
|
||||
id: 'dev-user',
|
||||
name: 'Development User',
|
||||
isAuth: false,
|
||||
userId: config.userId || null,
|
||||
};
|
||||
recordAuth(true, 'dev-mode');
|
||||
return next();
|
||||
}
|
||||
|
||||
const apiKey = req.headers['x-api-key'];
|
||||
const headerUserId = req.headers['x-user-id'];
|
||||
|
||||
if (!apiKey && !headerUserId) {
|
||||
if (!apiKey) {
|
||||
recordAuth(false, 'missing-credentials');
|
||||
return res
|
||||
.status(401)
|
||||
.json(
|
||||
mcpError(McpErrors.AUTH_FAILED.code, {
|
||||
detail: 'Provide x-api-key or x-user-id header',
|
||||
detail: 'Provide x-api-key header',
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -328,24 +332,6 @@ app.use(
|
||||
return res.status(401).json(mcpError(McpErrors.AUTH_FAILED.code, { detail: 'Invalid API key' }));
|
||||
}
|
||||
|
||||
if (headerUserId) {
|
||||
const user = await resolveUser(prisma, headerUserId);
|
||||
if (!user) {
|
||||
recordAuth(false, 'user-not-found');
|
||||
return res.status(401).json(mcpError(McpErrors.AUTH_FAILED.code, { detail: 'User not found' }));
|
||||
}
|
||||
req.userSession = getOrCreateSession(`user:${user.id}`, {
|
||||
name: user.name,
|
||||
userId: user.id,
|
||||
userName: user.name,
|
||||
userEmail: user.email,
|
||||
userRole: user.role,
|
||||
authMethod: 'user-id',
|
||||
});
|
||||
recordAuth(true, 'user-id');
|
||||
return next();
|
||||
}
|
||||
|
||||
recordAuth(false, 'auth-failed');
|
||||
return res.status(401).json(mcpError(McpErrors.AUTH_FAILED.code, { detail: 'Authentication failed' }));
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user