fix(security): implement file upload security enhancements
Test Gitea Actions / test (push) Successful in 16s
continuous-integration/drone/push Build is passing

- Add path traversal protection with secureStatic middleware
- Implement proper MIME type validation for all file uploads
- Add content-based file validation (magic numbers)
- Create comprehensive fileSecurityUtils for secure file operations
- Update adminPhotos.js with enhanced validation
- Update adminSettings.js for secure logo/favicon uploads
- Addresses file upload vulnerabilities from security scan

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
This commit is contained in:
2025-07-13 19:30:17 +02:00
co-authored by Claude
parent 051e21cbaf
commit 66841e8af7
5 changed files with 319 additions and 16 deletions
+15 -6
View File
@@ -56,18 +56,18 @@ const storage = multer.diskStorage({
}
});
const { validateFileType } = require('../utils/fileSecurityUtils');
const upload = multer({
storage: storage,
limits: {
fileSize: 50 * 1024 * 1024, // 50MB limit
},
fileFilter: (req, file, cb) => {
// Accept images only
const allowedTypes = /jpeg|jpg|png|webp/;
const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = allowedTypes.test(file.mimetype);
// Accept images only with proper validation
const allowedMimeTypes = ['image/jpeg', 'image/png', 'image/webp'];
if (mimetype && extname) {
if (validateFileType(file.originalname, file.mimetype, allowedMimeTypes)) {
return cb(null, true);
} else {
cb(new Error('Only JPEG, PNG and WebP images are allowed'));
@@ -75,6 +75,15 @@ const upload = multer({
}
});
const { createFileUploadValidator } = require('../utils/fileSecurityUtils');
// Create content validator middleware
const validateUploadContent = createFileUploadValidator({
allowedTypes: ['image/jpeg', 'image/png', 'image/webp'],
maxFileSize: 50 * 1024 * 1024,
validateContent: true
});
// Upload photos for an event
router.post('/:eventId/upload', adminAuth, (req, res, next) => {
upload.array('photos', 20)(req, res, (err) => {
@@ -90,7 +99,7 @@ router.post('/:eventId/upload', adminAuth, (req, res, next) => {
}
next();
});
}, async (req, res) => {
}, validateUploadContent, async (req, res) => {
try {
const { eventId } = req.params;
const { category_id } = req.body;