Per-IP Rate Limiting
Implementation
Fromhandlers.go:559-562:
How It Works
1
Request Arrives
gitGost extracts the client IP from the TCP connection:
2
Sliding Window Check
The system checks the last 1 hour of push attempts from this IP:
3
Limit Enforcement
If count exceeds 5, the request is rejected:
4
Admin Notification
On first excess (6th attempt), admin is notified via ntfy:
User Experience
When rate limit is exceeded, users see:Bypass Protection
In-memory storage means rate limit resets on service restart. This is intentional:
- Prevents disk I/O for every push (performance)
- Automatically resets on legitimate service updates
- Still effective against botnet attacks (which persist across restarts)
- VPN/Tor rotation during the 1-hour window (IP still tracked)
- Multiple git remotes (same IP)
- Different repositories (per-IP, not per-repo)
- Rotating IPs faster than the 1-hour window (requires botnet or many VPNs)
- Waiting 1 hour between batches of 5 PRs
Push Size Limits
Maximum Push Size: 100 MB
Fromrouter.go:49:
Upload Pack Limit: 50 MB
For fetch/pull operations (less critical, but still limited):Why Size Limits?
Memory Protection
Memory Protection
gitGost processes git packs in-memory during anonymization. Large pushes could exhaust server memory.
Abuse Prevention
Abuse Prevention
Prevents attackers from DoS-ing the service with huge binary uploads.
GitHub API Limits
GitHub API Limits
GitHub has its own size limits. gitGost aligns with practical GitHub constraints.
Reasonable for Code
Reasonable for Code
100 MB is sufficient for:
- Large feature branches
- Multiple commits
- Reasonable binary assets
- Video files, large datasets (use Git LFS)
- Entire repository history dumps
User Experience
When size limit is exceeded:Repository Name Validation
Validation Rules
Fromrouter.go:78-93:
What’s Blocked
Why Strict Validation?
Security: Prevents path traversal attacks
Stability: Avoids file system issues with special characters
Compatibility: Aligns with GitHub’s repository naming rules
Admin Endpoint Rate Limiting
Admin endpoints (panic button, rollback) have stricter limits:Panic Endpoint: 10 Requests/Minute/IP
Fromrouter.go:14-19:
POST /admin/panicPOST /admin/rollback
Rollback Endpoint: 5 Requests/Minute
Additional limit specific to rollback:Global Burst Detection
Automatic botnet detection across all IPs.
How It Works
Fromhandlers.go:566-572:
1
Every Push is Recorded Globally
Regardless of IP:
2
Sliding Window Analysis
System checks if in the last 60 seconds:
- 20+ total pushes (across all IPs), OR
- 10+ distinct IPs pushed
3
Alert Trigger
If thresholds exceeded:
4
Admin Response
Admin receives ntfy notification with action buttons:
- Activate Panic Mode (suspend all pushes)
- Close Burst PRs (rollback recent PRs)
- Deactivate Panic Mode (resume service)
Why This Matters
Example attack:- Botnet with 100 IPs
- Each IP pushes 4 PRs (under per-IP limit of 5)
- Total: 400 PRs in 60 seconds
- Per-IP limit didn’t trigger, but service is overwhelmed
- 400 pushes in 60s ≫ 20 threshold → Alert
- 100 distinct IPs ≫ 10 threshold → Alert
- Admin activates panic mode, rollback closes all 400 PRs
Panic Mode
Activation
Fromhandlers.go:789-815:
Effect
When panic mode is active:Action Tokens (Security)
Single-use, time-limited tokens prevent password exposure in ntfy notifications.
handlers.go:616-641:
- Password exposure in ntfy notification URLs
- Token reuse by third parties who intercept notifications
- Replay attacks (tokens expire in 10 minutes)
Rollback System
Close all PRs created during a burst with a single action.
How It Works
Fromhandlers.go:826-908:
1
PR Registration During Bursts
When global burst is active, all new PRs are registered:
2
Admin Triggers Rollback
Via ntfy action button or direct API call:
3
Concurrent PR Closure
Up to 5 workers close PRs in parallel:
4
Response
Admin receives summary:
TTL: 2 Hours
PRs are only tracked for rollback for 2 hours:Security Headers & Proxy Protection
Trusted Proxies: Disabled
Fromrouter.go:134:
- Attackers from spoofing source IPs via proxy headers
- Bypassing rate limits by injecting fake IPs
- Correlation attacks via header injection
c.ClientIP() returns the proxy’s IP, not the end user’s. This is acceptable because:
- Rate limiting still works (limits per-proxy-IP)
- Real user IP is never logged anyway (privacy by design)
Anonymous Authentication
Git operations require no authentication:- No user accounts or registration
- No credentials to leak
- True anonymous access
Summary Table
Monitoring & Transparency
Public Metrics
Real-time service health (memory, goroutines, uptime)
Service Status
Check if panic mode is active
Total PRs
Aggregate PR count (no personal data)
Recent Activity
Last 10 PRs (owner, repo, URL only)
Related Documentation
Threat Model
Attack vectors and mitigations
Privacy Guarantees
Data retention and logging policies
Anonymity Limits
When gitGost is NOT sufficient
Self-Hosting
Run your own instance with custom limits