Harden backend against critical and high security vulnerabilities
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m51s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m51s
- Fix WebSocket CheckOrigin to use proper url.Parse instead of string stripping - Add admin auth checks to Users/User GraphQL queries - Remove GraphQL GET transport to prevent CSRF via cross-site links - Add application-level IP-based login rate limiting (5 attempts/min) - Add path traversal bounds check on radio file upload - Require DEV_MODE for GraphQL introspection and playground - Move notes backend endpoint behind admin middleware - Add dedicated Nginx rate limit zone for GraphQL (10r/s) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
45
backend/services/ratelimit.go
Normal file
45
backend/services/ratelimit.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RateLimiter struct {
|
||||
mu sync.Mutex
|
||||
attempts map[string][]time.Time
|
||||
max int
|
||||
window time.Duration
|
||||
}
|
||||
|
||||
func NewRateLimiter(max int, window time.Duration) *RateLimiter {
|
||||
return &RateLimiter{
|
||||
attempts: make(map[string][]time.Time),
|
||||
max: max,
|
||||
window: window,
|
||||
}
|
||||
}
|
||||
|
||||
func (rl *RateLimiter) Allow(key string) bool {
|
||||
rl.mu.Lock()
|
||||
defer rl.mu.Unlock()
|
||||
|
||||
now := time.Now()
|
||||
cutoff := now.Add(-rl.window)
|
||||
|
||||
// Remove expired entries
|
||||
valid := rl.attempts[key][:0]
|
||||
for _, t := range rl.attempts[key] {
|
||||
if t.After(cutoff) {
|
||||
valid = append(valid, t)
|
||||
}
|
||||
}
|
||||
|
||||
if len(valid) >= rl.max {
|
||||
rl.attempts[key] = valid
|
||||
return false
|
||||
}
|
||||
|
||||
rl.attempts[key] = append(valid, now)
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user