# Rate Limiting Audit - 20251123-124317 == Rate Limiter Implementation == /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:24:// Rate limiting configuration /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:26: rateLimitWindow = 1 * time.Minute /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:32:// Input validation limits for forum content /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:41:type rateLimiter struct { /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:51:var writeLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:52:var readLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:54:func (rl *rateLimiter) checkRateLimit(key string, maxRequests int, window time.Duration) bool { /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:199: // Configure connection pool limits /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:500: limitStr := r.URL.Query().Get("limit") /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:503: limit := 20 /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:505: if l, err := strconv.Atoi(limitStr); err == nil && l > 0 && l <= 100 { /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:506: limit = l /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:541: args = append(args, limit, offset) /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1246: // Wrap all routes with rate limiting and body size limit /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1247: rateLimitedHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1248: // Limit request body size to prevent DoS /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1256: if readLimiter.checkRateLimit(clientIP, maxReadRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1257: log.Printf("SECURITY: Read rate limit exceeded for IP %s on %s", clientIP, r.URL.Path) /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1262: if writeLimiter.checkRateLimit(clientIP, maxWriteRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1263: log.Printf("SECURITY: Write rate limit exceeded for IP %s on %s", clientIP, r.URL.Path) /home/administrator/projects/coppertone.tech/backend/functions/forum-service/main.go:1274: Handler: rateLimitedHandler, /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:27:// Request size limit /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:56: TaxRate float64 `json:"taxRate"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:146: DailyLimit *float64 `json:"dailyLimit"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:147: MonthlyLimit *float64 `json:"monthlyLimit"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:168: ExchangeRate float64 `json:"exchangeRate"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:255: ExchangeRate *float64 `json:"exchangeRate,omitempty"` // For crypto /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:461: // Limit request body size to prevent DoS /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1587: // Determine payment method and get exchange rate /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1590: var exchangeRate float64 /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1620: // Get exchange rate (use cached price or fetch from API) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1622: exchangeRate = *token.PriceUSD /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1624: // Fallback: use stored exchange rate /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1626: SELECT rate FROM exchange_rates /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1629: `, token.TokenSymbol).Scan(&exchangeRate) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1631: http.Error(w, "Exchange rate not available for this token", http.StatusServiceUnavailable) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1650: // Get exchange rate for native currency /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1652: SELECT rate FROM exchange_rates /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1655: `, network.NativeCurrency).Scan(&exchangeRate) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1657: // Use fallback rates for common currencies /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1660: exchangeRate = 3000 // Fallback /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1662: exchangeRate = 50000 // Fallback /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1664: exchangeRate = 1 // Fallback /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1666: http.Error(w, "Exchange rate not available", http.StatusServiceUnavailable) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1669: log.Printf("Warning: Using fallback exchange rate for %s", network.NativeCurrency) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1678: amountCrypto = big.NewFloat(amountUSD / exchangeRate) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1699: amount_crypto, amount_usd_at_time, exchange_rate, /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1703: amountCryptoStr, amountUSD, exchangeRate, network.MinConfirmations) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:1728: ExchangeRate: exchangeRate, /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2156: pw.is_active, pw.is_primary, pw.requires_approval_above, pw.daily_limit, /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2157: pw.monthly_limit, pw.created_at, pw.updated_at, pn.network_code /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2177: &wn.IsActive, &wn.IsPrimary, &wn.RequiresApprovalAbove, &wn.DailyLimit, /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2178: &wn.MonthlyLimit, &wn.CreatedAt, &wn.UpdatedAt, &wn.NetworkCode) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2198: DailyLimit *float64 `json:"dailyLimit"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2199: MonthlyLimit *float64 `json:"monthlyLimit"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2231: requires_approval_above, daily_limit, monthly_limit) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2235: req.RequiresApprovalAbove, req.DailyLimit, req.MonthlyLimit).Scan(&walletID) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2283: DailyLimit *float64 `json:"dailyLimit"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2284: MonthlyLimit *float64 `json:"monthlyLimit"` /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2334: if updates.DailyLimit != nil { /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2335: setClauses = append(setClauses, fmt.Sprintf("daily_limit = $%d", argIndex)) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2336: args = append(args, *updates.DailyLimit) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2339: if updates.MonthlyLimit != nil { /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2340: setClauses = append(setClauses, fmt.Sprintf("monthly_limit = $%d", argIndex)) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2341: args = append(args, *updates.MonthlyLimit) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2700: // Get exchange rate /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2701: var exchangeRate float64 = 1.0 /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2706: exchangeRate = priceUSD.Float64 /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2709: // Get native currency rate /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2713: SELECT rate FROM exchange_rates /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2716: `, nativeCurrency).Scan(&exchangeRate) /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2719: amountCrypto := req.Amount / exchangeRate /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2724: resp.ExchangeRate = &exchangeRate /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2823:// generatePaymentReference generates a unique payment reference. /home/administrator/projects/coppertone.tech/backend/functions/payment-service/main.go:2824:func generatePaymentReference() string { /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:24:// Rate limiting configuration /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:26: rateLimitWindow = 1 * time.Minute /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:32:type rateLimiter struct { /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:42:var writeLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:43:var readLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:45:func (rl *rateLimiter) checkRateLimit(key string, maxRequests int, window time.Duration) bool { /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:280: // Configure connection pool limits /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:302: // Limit request body size to prevent DoS /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:307: // Rate limiting /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:310: if readLimiter.checkRateLimit(clientIP, maxReadRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:311: log.Printf("SECURITY: Read rate limit exceeded for IP %s on %s", clientIP, r.URL.Path) /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:316: if writeLimiter.checkRateLimit(clientIP, maxWriteRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/work-management-service/main.go:317: log.Printf("SECURITY: Write rate limit exceeded for IP %s on %s", clientIP, r.URL.Path) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:19:// TestRateLimiter tests the rate limiting functionality /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:20:func TestRateLimiter(t *testing.T) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:21: rl := &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:23: // Test that first request is not rate limited /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:24: if rl.checkRateLimit("test-ip", 5, time.Minute) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:25: t.Error("First request should not be rate limited") /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:28: // Fill up the limit /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:30: rl.checkRateLimit("test-ip", 5, time.Minute) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:33: // 6th request should be rate limited /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:34: if !rl.checkRateLimit("test-ip", 5, time.Minute) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:35: t.Error("6th request should be rate limited") /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:38: // Different IP should not be rate limited /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:39: if rl.checkRateLimit("other-ip", 5, time.Minute) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:40: t.Error("Different IP should not be rate limited") /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:44:func TestRateLimiterClearAttempts(t *testing.T) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:45: rl := &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:49: rl.checkRateLimit("test-ip", 5, time.Minute) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:55: // Should not be rate limited after clearing /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:56: if rl.checkRateLimit("test-ip", 5, time.Minute) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:57: t.Error("Should not be rate limited after clearing attempts") /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:391:func TestGenerateJWT(t *testing.T) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:401: token, err := generateJWT(user, roles) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:29:// Rate limiting configuration /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:31: rateLimitWindow = 15 * time.Minute // Window for counting attempts /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:45:// rateLimiter tracks login attempts per IP/email /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:46:type rateLimiter struct { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:58:var loginLimiter = &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:59:var registerLimiter = &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:61:// checkRateLimit returns true if the request should be blocked /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:62:func (rl *rateLimiter) checkRateLimit(key string, maxAttempts int, window time.Duration) bool { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:106:func (rl *rateLimiter) recordFailedAttempt(key string) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:119: if now.Sub(info.firstTry) > rateLimitWindow { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:134:func (rl *rateLimiter) clearAttempts(key string) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:169: maxEmailLength = 254 // RFC 5321 limit /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:171: maxPasswordLength = 72 // bcrypt limit /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:380: Handler: limitBodySize(corsMiddleware(http.DefaultServeMux)), /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:492: // Configure connection pool limits /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:510:// limitBodySize middleware limits the request body size to prevent DoS attacks /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:511:func limitBodySize(next http.Handler) http.Handler { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:570: // Rate limit registrations by IP /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:572: if registerLimiter.checkRateLimit(clientIP, maxRegisterPerHour, time.Hour) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:573: log.Printf("SECURITY: Registration rate limit exceeded for IP %s", clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:632: passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:700: // Rate limit registrations by IP /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:702: if registerLimiter.checkRateLimit(clientIP, maxRegisterPerHour, time.Hour) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:703: log.Printf("SECURITY: Blockchain registration rate limit exceeded for IP %s", clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:833: // Rate limit by IP and email combination /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:834: rateLimitKey := clientIP + ":" + strings.ToLower(req.Email) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:835: if loginLimiter.checkRateLimit(rateLimitKey, maxLoginAttempts, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:836: log.Printf("SECURITY: Rate limit exceeded for %s", rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:851: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:862: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:868: // Clear rate limit on successful login /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:869: loginLimiter.clearAttempts(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:872: // Generate token pair (access + refresh) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:873: tokenResponse, err := generateTokenPair(userID, clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:876: http.Error(w, "Failed to generate tokens", http.StatusInternalServerError) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:898: // Rate limit by IP and address combination /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:899: rateLimitKey := clientIP + ":" + strings.ToLower(req.Address) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:900: if loginLimiter.checkRateLimit(rateLimitKey, maxLoginAttempts, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:901: log.Printf("SECURITY: Rate limit exceeded for blockchain login %s", rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:908: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:923: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:932: // Clear rate limit on successful login /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:933: loginLimiter.clearAttempts(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:936: // Generate token pair (access + refresh) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:937: tokenResponse, err := generateTokenPair(userID, clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:940: http.Error(w, "Failed to generate tokens", http.StatusInternalServerError) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:983: // Generate new token pair /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:984: tokenResponse, err := generateTokenPair(userID, clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1101: passwordHash, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1433:// generateAccessToken creates a short-lived JWT access token /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1434:func generateAccessToken(userID int) (string, error) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1470:// generateRefreshToken creates a secure random refresh token and stores it in the database /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1471:func generateRefreshToken(userID int, clientIP string) (string, error) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1472: // Generate cryptographically secure random token /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1475: return "", fmt.Errorf("failed to generate random token: %w", err) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1480: tokenHash, err := bcrypt.GenerateFromPassword([]byte(token), bcrypt.DefaultCost) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1559:// generateCSRFToken creates a cryptographically secure CSRF token /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1560:func generateCSRFToken() (string, error) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1563: return "", fmt.Errorf("failed to generate CSRF token: %w", err) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1571: tokenHash, err := bcrypt.GenerateFromPassword([]byte(csrfToken), bcrypt.DefaultCost) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1642:// generateTokenPair creates access, refresh, and CSRF tokens /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1643:func generateTokenPair(userID int, clientIP string) (*AuthTokenResponse, error) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1644: accessToken, err := generateAccessToken(userID) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1646: return nil, fmt.Errorf("failed to generate access token: %w", err) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1649: refreshToken, err := generateRefreshToken(userID, clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1651: return nil, fmt.Errorf("failed to generate refresh token: %w", err) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1654: // Generate CSRF token /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1655: csrfToken, err := generateCSRFToken() /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1657: return nil, fmt.Errorf("failed to generate CSRF token: %w", err) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1676:func generateToken(userID int) (string, error) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1677: return generateAccessToken(userID) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1738:func generateJWT(user User, roles []string) (string, error) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:1753: hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) /home/administrator/projects/coppertone.tech/backend/functions/ipfs-service/main.go:97: // Generate a new identity for this node /home/administrator/projects/coppertone.tech/backend/functions/ipfs-service/main.go:98: priv, _, err := crypto.GenerateKeyPairWithReader(crypto.Ed25519, -1, rand.Reader) /home/administrator/projects/coppertone.tech/backend/functions/ipfs-service/main.go:100: return fmt.Errorf("failed to generate key pair: %w", err) /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:23:// Rate limiting configuration /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:25: rateLimitWindow = 1 * time.Minute /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:31:// Input validation limits /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:43:// rateLimiter tracks requests per IP /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:44:type rateLimiter struct { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:54:var writeLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:55:var readLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:57:func (rl *rateLimiter) checkRateLimit(key string, maxRequests int, window time.Duration) bool { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:113: BlogTypeUser = "USER" // Community blogs (user authored, separate section) /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:222: // Configure connection pool limits /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:291: // Migrate old published boolean to new status /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:334:// rateLimitMiddleware applies rate limiting based on request method /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:335:func rateLimitMiddleware(next http.HandlerFunc) http.HandlerFunc { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:339: // Apply different limits for read vs write operations /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:341: if readLimiter.checkRateLimit(clientIP, maxReadRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:342: log.Printf("SECURITY: Read rate limit exceeded for IP %s", clientIP) /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:347: if writeLimiter.checkRateLimit(clientIP, maxWriteRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:348: log.Printf("SECURITY: Write rate limit exceeded for IP %s", clientIP) /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:657: // Admin panel only shows SITE blogs - user community blogs have separate endpoints /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1140:// These endpoints are completely separate from SITE blogs (admin/staff content) /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1829: // ============ COMMUNITY BLOG ROUTES (Separate from Site Blogs) ============ /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1953: // Wrap all routes with rate limiting and body size limit /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1954: rateLimitedHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1955: // Limit request body size to prevent DoS /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1962: // Apply different limits for read vs write operations /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1964: if readLimiter.checkRateLimit(clientIP, maxReadRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1965: log.Printf("SECURITY: Read rate limit exceeded for IP %s on %s", clientIP, r.URL.Path) /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1970: if writeLimiter.checkRateLimit(clientIP, maxWriteRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1971: log.Printf("SECURITY: Write rate limit exceeded for IP %s on %s", clientIP, r.URL.Path) /home/administrator/projects/coppertone.tech/backend/functions/blog-service/main.go:1982: Handler: rateLimitedHandler, /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:23:// Rate limiting configuration /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:25: rateLimitWindow = 1 * time.Minute /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:31:type rateLimiter struct { /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:41:var submitLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:42:var readLimiter = &rateLimiter{requests: make(map[string]*requestInfo)} /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:44:func (rl *rateLimiter) checkRateLimit(key string, maxRequests int, window time.Duration) bool { /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:134: mux.HandleFunc("/submit", corsMiddleware(rateLimitSubmit(submitHandler))) /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:141: // Wrap with rate limiting and body size limit for all requests /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:142: rateLimitedMux := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:143: // Limit request body size to prevent DoS /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:150: // Read requests (GET) have higher limits /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:152: if readLimiter.checkRateLimit(clientIP, maxReadRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:153: log.Printf("SECURITY: Read rate limit exceeded for IP %s on %s", clientIP, r.URL.Path) /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:164: Handler: rateLimitedMux, /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:199:// rateLimitSubmit applies strict rate limiting for contact form submissions /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:200:func rateLimitSubmit(next http.HandlerFunc) http.HandlerFunc { /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:204: if submitLimiter.checkRateLimit(clientIP, maxSubmitRequests, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:205: log.Printf("SECURITY: Contact form rate limit exceeded for IP %s", clientIP) /home/administrator/projects/coppertone.tech/backend/functions/contact-service/main.go:248: // Configure connection pool limits == Login Attempt Limiting == /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:21: rl := &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:44:func TestRateLimiterClearAttempts(t *testing.T) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:45: rl := &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:47: // Add some attempts /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:52: // Clear attempts /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:53: rl.clearAttempts("test-ip") /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main_test.go:57: t.Error("Should not be rate limited after clearing attempts") /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:31: rateLimitWindow = 15 * time.Minute // Window for counting attempts /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:32: maxLoginAttempts = 5 // Max failed login attempts per window /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:34: lockoutDuration = 30 * time.Minute // How long to lock out after max attempts /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:45:// rateLimiter tracks login attempts per IP/email /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:48: attempts map[string]*attemptInfo /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:51:type attemptInfo struct { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:58:var loginLimiter = &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:59:var registerLimiter = &rateLimiter{attempts: make(map[string]*attemptInfo)} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:62:func (rl *rateLimiter) checkRateLimit(key string, maxAttempts int, window time.Duration) bool { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:67: info, exists := rl.attempts[key] /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:70: rl.attempts[key] = &attemptInfo{count: 1, firstTry: now} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:96: if info.count > maxAttempts { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:105:// recordFailedAttempt records a failed attempt (for login failures) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:106:func (rl *rateLimiter) recordFailedAttempt(key string) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:111: info, exists := rl.attempts[key] /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:114: rl.attempts[key] = &attemptInfo{count: 1, firstTry: now} /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:126: if info.count >= maxLoginAttempts { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:129: log.Printf("SECURITY: IP/email %s locked out after %d failed attempts", key, info.count) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:133:// clearAttempts clears attempts for a key (called on successful login) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:134:func (rl *rateLimiter) clearAttempts(key string) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:137: delete(rl.attempts, key) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:574: http.Error(w, "Too many registration attempts. Please try again later.", http.StatusTooManyRequests) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:704: http.Error(w, "Too many registration attempts. Please try again later.", http.StatusTooManyRequests) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:835: if loginLimiter.checkRateLimit(rateLimitKey, maxLoginAttempts, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:837: http.Error(w, "Too many login attempts. Please try again later.", http.StatusTooManyRequests) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:851: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:852: log.Printf("SECURITY: Failed login attempt for email %s from IP %s (user not found)", req.Email, clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:862: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:863: log.Printf("SECURITY: Failed login attempt for email %s from IP %s (wrong password)", req.Email, clientIP) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:869: loginLimiter.clearAttempts(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:900: if loginLimiter.checkRateLimit(rateLimitKey, maxLoginAttempts, rateLimitWindow) { /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:902: http.Error(w, "Too many login attempts. Please try again later.", http.StatusTooManyRequests) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:908: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:923: loginLimiter.recordFailedAttempt(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:933: loginLimiter.clearAttempts(rateLimitKey) /home/administrator/projects/coppertone.tech/backend/functions/auth-service/main.go:973: log.Printf("SECURITY: Invalid refresh token attempt from IP %s: %v", clientIP, err)