Skip to main content
gitGost enforces multiple layers of security controls to prevent abuse, protect the service, and maintain GitHub’s trust. This page documents all rate limits, size restrictions, and validation checks.

Per-IP Rate Limiting

5 PRs per IP per hour—the primary abuse prevention mechanism.

Implementation

From handlers.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)
Cannot be bypassed by:
  • VPN/Tor rotation during the 1-hour window (IP still tracked)
  • Multiple git remotes (same IP)
  • Different repositories (per-IP, not per-repo)
Can be bypassed by:
  • 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

From router.go:49:
Enforced via middleware before push processing:
Pushes larger than 100 MB are rejected with HTTP 413 (Request Entity Too Large).

Upload Pack Limit: 50 MB

For fetch/pull operations (less critical, but still limited):

Why Size Limits?

gitGost processes git packs in-memory during anonymization. Large pushes could exhaust server memory.
Prevents attackers from DoS-ing the service with huge binary uploads.
GitHub has its own size limits. gitGost aligns with practical GitHub constraints.
100 MB is sufficient for:
  • Large feature branches
  • Multiple commits
  • Reasonable binary assets
Not sufficient for:
  • Video files, large datasets (use Git LFS)
  • Entire repository history dumps

User Experience

When size limit is exceeded:
Git shows:

Repository Name Validation

Validation Rules

From router.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

From router.go:14-19:
Applied to:
  • POST /admin/panic
  • POST /admin/rollback

Rollback Endpoint: 5 Requests/Minute

Additional limit specific to rollback:
This prevents accidental mass-closure of legitimate PRs.

Global Burst Detection

Automatic botnet detection across all IPs.

How It Works

From handlers.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

Per-IP rate limiting alone is insufficient against distributed botnets.
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
Global burst detection catches this:
  • 400 pushes in 60s ≫ 20 threshold → Alert
  • 100 distinct IPs ≫ 10 threshold → Alert
  • Admin activates panic mode, rollback closes all 400 PRs

Panic Mode

Emergency service suspension when under attack.

Activation

From handlers.go:789-815:

Effect

When panic mode is active:
Users see:

Action Tokens (Security)

Single-use, time-limited tokens prevent password exposure in ntfy notifications.
From handlers.go:616-641:
This prevents:
  • 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

From handlers.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:
After 2 hours, PRs are no longer eligible for rollback (assumed legitimate if not flagged quickly).

Security Headers & Proxy Protection

Trusted Proxies: Disabled

From router.go:134:
Critical for privacy: gitGost does NOT trust X-Forwarded-For or similar headers.
This prevents:
  • Attackers from spoofing source IPs via proxy headers
  • Bypassing rate limits by injecting fake IPs
  • Correlation attacks via header injection
Trade-off: If gitGost runs behind a reverse proxy, c.ClientIP() returns the proxy’s IP, not the end user’s. This is acceptable because:
  1. Rate limiting still works (limits per-proxy-IP)
  2. Real user IP is never logged anyway (privacy by design)

Anonymous Authentication

Git operations require no authentication:
This ensures:
  • 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)

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