From 5773aef863041a719ef9a6a2b068f2daeed21d2c Mon Sep 17 00:00:00 2001 From: gitmotion <43588713+gitmotion@users.noreply.github.com> Date: Fri, 20 Jun 2025 14:17:17 -0700 Subject: [PATCH] Remove hsts from helmet and apply new pin status check limits --- src/app.js | 6 +++++- src/middleware/rateLimiter.js | 21 ++++++++++++++++++++- src/middleware/security.js | 11 +++++++---- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/app.js b/src/app.js index b1379fb..689b912 100644 --- a/src/app.js +++ b/src/app.js @@ -17,7 +17,7 @@ const logger = require('./utils/logger'); const { ensureDirectoryExists } = require('./utils/fileUtils'); const { getHelmetConfig, requirePin } = require('./middleware/security'); const { safeCompare } = require('./utils/security'); -const { initUploadLimiter, pinVerifyLimiter, downloadLimiter } = require('./middleware/rateLimiter'); +const { initUploadLimiter, pinVerifyLimiter, pinStatusLimiter, downloadLimiter } = require('./middleware/rateLimiter'); const { injectDemoBanner, demoMiddleware } = require('./utils/demoMode'); const { originValidationMiddleware, getCorsOptions } = require('./middleware/cors'); @@ -41,6 +41,7 @@ app.use((req, res, next) => { const publicPaths = [ '/login', '/login.html', + '/api/auth/logout', '/api/auth/verify-pin', '/api/auth/pin-required', '/api/auth/pin-length', @@ -71,6 +72,9 @@ const fileRoutes = require('./routes/files'); const authRoutes = require('./routes/auth'); // Use routes with appropriate middleware +// Apply strict rate limiting to PIN verification, but more permissive to status checks +app.use('/api/auth/pin-required', pinStatusLimiter); +app.use('/api/auth/logout', pinStatusLimiter); app.use('/api/auth', pinVerifyLimiter, authRoutes); app.use('/api/upload', requirePin(config.pin), initUploadLimiter, uploadRouter); app.use('/api/files', requirePin(config.pin), downloadLimiter, fileRoutes); diff --git a/src/middleware/rateLimiter.js b/src/middleware/rateLimiter.js index 6ba6046..9491262 100644 --- a/src/middleware/rateLimiter.js +++ b/src/middleware/rateLimiter.js @@ -48,7 +48,7 @@ const chunkUploadLimiter = createLimiter({ /** * Rate limiter for PIN verification attempts - * Prevents brute force attacks + * Prevents brute force attacks on actual PIN verification */ const pinVerifyLimiter = createLimiter({ windowMs: 15 * 60 * 1000, // 15 minutes @@ -57,6 +57,24 @@ const pinVerifyLimiter = createLimiter({ error: 'Too many PIN verification attempts. Please try again later.' }, standardHeaders: true, + legacyHeaders: false, + // Apply strict rate limiting only to PIN verification, not PIN status checks + skip: (req) => { + return req.path === '/pin-required'; // Skip rate limiting for PIN requirement checks + } +}); + +/** + * Rate limiter for PIN status checks + * More permissive for checking if PIN is required + */ +const pinStatusLimiter = createLimiter({ + windowMs: 60 * 1000, // 1 minute window + max: 30, // 30 requests per minute + message: { + error: 'Too many requests. Please wait before trying again.' + }, + standardHeaders: true, legacyHeaders: false }); @@ -78,5 +96,6 @@ module.exports = { initUploadLimiter, chunkUploadLimiter, pinVerifyLimiter, + pinStatusLimiter, downloadLimiter }; \ No newline at end of file diff --git a/src/middleware/security.js b/src/middleware/security.js index cc101cf..74b384b 100644 --- a/src/middleware/security.js +++ b/src/middleware/security.js @@ -48,16 +48,19 @@ const BASE_URL = process.env.BASE_URL || `http://localhost:${PORT}`; // } function getHelmetConfig() { + // const isSecure = BASE_URL.startsWith('https://'); + return { noSniff: true, // Prevent MIME type sniffing frameguard: { action: 'deny' }, // Prevent clickjacking - hsts: { maxAge: 31536000, includeSubDomains: true }, // Enforce HTTPS for one year - crossOriginEmbedderPolicy: true, - crossOriginOpenerPolicy: { policy: 'same-origin-allow-popups' }, - crossOriginResourcePolicy: { policy: 'same-origin' }, + crossOriginEmbedderPolicy: false, // Disable for local network access + crossOriginOpenerPolicy: false, // Disable to prevent warnings on HTTP + crossOriginResourcePolicy: { policy: 'cross-origin' }, // Allow cross-origin for local network referrerPolicy: { policy: 'no-referrer-when-downgrade' }, // Set referrer policy ieNoOpen: true, // Prevent IE from executing downloads + // hsts: isSecure ? { maxAge: 31536000, includeSubDomains: true } : false, // Only enforce HTTPS if using HTTPS // Disabled Helmet middlewares: + hsts: false, contentSecurityPolicy: false, // Disable CSP for now dnsPrefetchControl: true, // Disable DNS prefetching permittedCrossDomainPolicies: false,