feat: implement critical security fixes for SQL injection and authentication vulnerabilities
Test Gitea Actions / test (push) Successful in 20s
continuous-integration/drone/push Build is passing

Security Enhancements:
- Fix SQL injection vulnerabilities by replacing whereRaw queries with parameterized queries
- Add LIKE pattern escaping to prevent SQL injection in search functionality
- Implement account lockout protection (5 failed attempts = 30 min lockout)
- Add comprehensive login attempt tracking and audit trail
- Enhance JWT tokens with issuer validation, IP tracking, and password change detection
- Add logout endpoint and session management
- Prevent user enumeration with generic error messages

Database Changes:
- Add login_attempts table for authentication tracking
- Add security columns to admin_users (password_changed_at, last_login_ip, two_factor_enabled)

New Security Features:
- Brute force protection with configurable lockout duration
- Automatic cleanup of old login attempts
- Enhanced authentication middleware with stricter validation
- Monitoring scripts for security health checks

All fixes are backward compatible and production-ready with rollback plans included.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-07-13 00:40:05 +02:00
parent 0d33f21ee6
commit e35ac6a41c
36 changed files with 4152 additions and 20 deletions
+5 -3
View File
@@ -8,6 +8,7 @@ const crypto = require('crypto');
const fs = require('fs').promises;
const path = require('path');
const { archiveEvent } = require('../services/archiveService');
const { escapeLikePattern } = require('../utils/sqlSecurity');
const { formatDate } = require('../utils/dateFormatter');
// Create new event
@@ -152,10 +153,11 @@ router.get('/', adminAuth, async (req, res) => {
// Apply search filter
if (search) {
const escapedSearch = escapeLikePattern(search);
query = query.where((builder) => {
builder.where('event_name', 'like', `%${search}%`)
.orWhere('admin_email', 'like', `%${search}%`)
.orWhere('slug', 'like', `%${search}%`);
builder.where('event_name', 'like', `%${escapedSearch}%`)
.orWhere('admin_email', 'like', `%${escapedSearch}%`)
.orWhere('slug', 'like', `%${escapedSearch}%`);
});
}