CallMeTechie
DE Login
Home Products Blog About Contact

Security

v1.x · Updated 3 weeks ago

Security Hardening v1.5.1

Comprehensive security hardening of the entire GateControl project. Based on a full security audit with 39 identified issues across 4 areas: Authentication, Input Validation, Docker/Infrastructure, and Frontend.

Overview

SeverityFoundFixedBy Design
CRITICAL66
HIGH1212
MEDIUM1111
LOW/INFO1073
Total39363

CRITICAL Fixes

  • #1 — Prototype Pollution CSRF Bypass: req.tokenAuth, req.tokenId, and req.tokenScopes are defensively reset in requireAuth().
  • #2 — Route-Auth Forward-Auth without Header: /route-auth/verify returns 401 Unauthorized when x-route-domain is missing.
  • #3 — Caddy Config Injection: Header names/values validated, rate_limit_window allowlist, sticky_cookie_name regex.
  • #4 — DNS-Check SSRF: Domain validation before DNS lookup, resolved IPs not included in response.
  • #5 — Node as Root: Intentionally kept — WireGuard CLI requires root, container isolation is the security boundary.
  • #6 — Key-File Permissions: After chown -R, secret files are reset to root:root with chmod 600.

HIGH Fixes

  • #7 — Route-Auth Lockout: Changed from IP-based to email-based (prevents IP rotation bypass).
  • #8 — OTP Range: Full range 000000–999999 with padStart.
  • #9 — OTP Resend: Requires valid pending 2FA session.
  • #10 — Route-Auth CSRF Key: Dedicated HMAC-derived key instead of shared app secret.
  • #11 — WireGuard Config Injection: DNS validated as IP list, keepalive as integer, newlines blocked.
  • #12 — Email HTML Injection: All interpolated values in email templates escaped.
  • #13 — Route Target SSRF: Private/loopback IPs blocked as direct route targets (peer-linked routes not affected).
  • #14 — Metrics Token Leak: ?token= query parameter removed, header auth only.
  • #15 — WG Key in Logs: wg-quick output filtered.
  • #16 — Trust Proxy: Restricted to loopback.
  • #17 — CSP Styles: Split into style-src-elem (nonce) and style-src-attr (inline).
  • #18 — Dashboard XSS: API integers with parseInt and textContent.

MEDIUM Fixes

  • #19 — TOTP Replay Prevention: In-memory tracking of used codes (90s expiry).
  • #20 — Session Secure Warning: Warning in production without HTTPS.
  • #21 — Rate-Limiter Bypass: Increased limit only for session auth.
  • #22 — Backup Key Validation: Regex allowlist for settings keys.
  • #23 — IP Filter Fix: req.ip instead of raw X-Forwarded-For.
  • #24 — CSS Injection: Peer group color validated against hex regex.
  • #25 — Monitoring XSS: Response time sanitized with parseInt.
  • #26 — API Key Masking: ip2location key not in DOM, shows "Key is set".
  • #27 — Health Endpoint: Details only for localhost.
  • #28 — WG Signal Handling: Guard variable prevents race condition.

LOW/INFO Fixes

#Fix
#30Rate-limit error strings i18n (EN+DE)
#31Hardcoded German strings replaced with i18n
#32Dead code removed
#33Argon2 parallelism reduced (4 → 1)
#37frame-ancestors: 'self' in CSP
#38Crypto split with length check
#39Branding fields: max 255/2000 characters

Breaking Changes

#13 — Route Targets: Private IPs Blocked

Direct entry of private or loopback IP addresses as route targets is blocked. Affected: 127.x, 10.x, 172.16-31.x, 192.168.x, 169.254.x, 0.x.

Not affected: Routes with peer linking. The WireGuard peer IP is still accepted.

Migration: Create a WireGuard peer for the target device and select the peer in the route dropdown instead of entering the IP manually.

#14 — Prometheus: Query Parameter Auth Removed

?token=gc_xxx is no longer accepted. Header auth only:

scrape_configs:
  - job_name: 'gatecontrol'
    metrics_path: '/metrics'
    authorization:
      type: 'Bearer'
      credentials: 'gc_abc123...'
    static_configs:
      - targets: ['gatecontrol.example.com:443']
    scheme: https

Alternative: credentials_file for even more security.

Other Breaking Changes

FixImpact
#7Lockout per email instead of IP
#10Route-auth CSRF tokens invalid once after update (reload the page)
#16Only loopback trusted as proxy
#26ip2location API key no longer visible in the UI
#27/health externally only returns {ok: true/false}

Cookie Settings

We use cookies to improve your experience. Essential cookies are always active.

Privacy Policy
ESC
↑↓ navigate open esc close