| Version | Supported |
|---|---|
| 1.x | ✅ |
| < 1.0 | ❌ |
Please do not report security vulnerabilities through public GitHub issues.
If you discover a security vulnerability in Fortify, please report it by emailing:
Please include the following information in your report:
- Type of vulnerability (e.g., rate limit bypass, DoS, injection)
- Full path to the source file(s) related to the vulnerability
- Step-by-step instructions to reproduce the issue
- Proof-of-concept or exploit code (if possible)
- Impact assessment of the vulnerability
You should receive an initial response within 48 hours acknowledging receipt. We will work with you to understand and validate the issue, and aim to release a fix within 90 days depending on severity.
Fortify implements several security measures to protect against common attack vectors:
- IPv6 Zone Identifier Stripping: Prevents bypass by varying zone identifiers (e.g.,
fe80::1%eth0vsfe80::1%eth1) - Unicode Normalization (NFC): Prevents bypass using Unicode equivalent strings
- Key Sanitization: Validates and sanitizes all rate limiting keys
- Log Injection Protection: Control characters are sanitized from log output
- HTTP Header Validation: Header names validated per RFC 7230 at construction time
- Key Length Limits: Prevents memory exhaustion from long keys (
DefaultMaxKeyLength: 256) - Maximum Key Count: Limits total buckets in memory store (
DefaultMaxKeys: 100,000) - Token Limits:
MaxTokensPerRequestprevents integer overflow attacks - Rate/Burst Caps: Configuration values capped to prevent overflow
- Thread-Safe Operations: All public methods are safe for concurrent use
- Atomic Operations: Uses
sync.Map,atomic.Int64, and per-key mutexes - Race Detector: All tests pass with Go's race detector enabled
// Fail-closed (default, recommended for security-critical applications)
limiter := ratelimit.New(ratelimit.Config{
Rate: 100,
Burst: 200,
FailOpen: false, // Deny requests on storage errors
})
// Fail-open (for high-availability scenarios)
limiter := ratelimit.New(ratelimit.Config{
Rate: 100,
Burst: 200,
FailOpen: true, // Allow requests on storage errors
})The Reset() method clears all rate limiting state. Applications MUST implement authorization checks before calling Reset():
// WRONG: Exposed without authorization
http.HandleFunc("/admin/reset", func(w http.ResponseWriter, r *http.Request) {
limiter.Reset(r.Context()) // SECURITY RISK: No authorization!
})
// CORRECT: With proper authorization
http.HandleFunc("/admin/reset", func(w http.ResponseWriter, r *http.Request) {
if !isAdmin(r) {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
limiter.Reset(r.Context())
})The token bucket algorithm relies on system time. System clock adjustments (NTP, manual changes) may affect rate limiting accuracy:
- Forward jump: May allow temporary rate limit bypass
- Backward jump: May temporarily block legitimate requests
Mitigation: The implementation caps elapsed time to prevent extreme effects from clock skew.
The in-memory store is suitable for single-instance deployments. For distributed systems:
- Implement a custom
Storeusing Redis, DynamoDB, or similar - Consider fail-open behavior for store availability issues
- Monitor key count to prevent exhaustion attacks
- HIGH: IPv6 zone identifier bypass in
KeyFromIP- attackers could bypass rate limits by varying IPv6 zone identifiers - MEDIUM: Unicode normalization missing in
SanitizeKey- equivalent Unicode strings could bypass rate limits - MEDIUM: UTF-8 truncation issue - byte-based truncation could split multi-byte characters
- LOW: Log injection via control characters in keys
- Updated
go-redisto v9.7.3 to address CVE-2025-29923 (Redis backend module)
The codebase has been reviewed for:
- OWASP Top 10 vulnerabilities
- CWE Top 25 issues
- Go-specific security patterns
- Concurrency safety (race detector)
See SECURITY_AUDIT_REPORT.md for the latest audit report.
We believe in responsible disclosure and will:
- Acknowledge receipt of vulnerability reports within 48 hours
- Provide regular updates on remediation progress
- Credit reporters in release notes (unless anonymity is requested)
- Not pursue legal action against good-faith security researchers
Thank you for helping keep Fortify secure!