|
| 1 | +# Gearbox Security Review Report |
| 2 | + |
| 3 | +**Date:** 2026-02-01 |
| 4 | +**Scope:** Full codebase (`gearbox/` and `gearbox-agent/`) |
| 5 | +**Method:** Static analysis against AI Code Security Anti-Patterns (breadth version) |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +## Executive Summary |
| 10 | + |
| 11 | +The Gearbox codebase demonstrates **strong security practices** across both the dashboard and agent applications. No critical production vulnerabilities were found. The codebase uses proper parameterized queries, cryptographically secure random generation, bcrypt password hashing, and comprehensive authentication middleware. A small number of medium and low severity issues were identified, primarily around XSS in JavaScript client-side code and a SQL injection edge case in the backup function. |
| 12 | + |
| 13 | +**Overall Security Posture: STRONG** |
| 14 | + |
| 15 | +--- |
| 16 | + |
| 17 | +## Findings Summary |
| 18 | + |
| 19 | +| # | Finding | Severity | CWE | Location | |
| 20 | +|---|---------|----------|-----|----------| |
| 21 | +| 1 | Unescaped user data in innerHTML (traffic filter label) | High | CWE-79 | `static/js/traffic/traffic-visualization.js:417,451` | |
| 22 | +| 2 | Backend data rendered without escaping (backup restore) | High | CWE-79 | `static/js/haproxy_config/editor.js:1400-1410` | |
| 23 | +| 3 | SQL injection in VACUUM INTO (backup path) | Medium | CWE-89 | `gearbox/internal/framework/database/backup.go:38` | |
| 24 | +| 4 | No rate limiting on dashboard login endpoint | Medium | CWE-307 | `gearbox/cmd/server/main.go` (login routes) | |
| 25 | +| 5 | TLS verification can be disabled via env var | Medium | CWE-295 | `gearbox/internal/framework/agent/client.go:70-78` | |
| 26 | +| 6 | Cookie Secure flag not set by default | Low | CWE-614 | `gearbox/internal/framework/auth/auth.go:46` | |
| 27 | +| 7 | CSP allows 'unsafe-inline' for scripts/styles | Low | CWE-79 | `gearbox/internal/framework/middleware/security_headers.go:60-76` | |
| 28 | +| 8 | Swagger docs publicly accessible on agent | Low | CWE-200 | `gearbox-agent/internal/api/server.go:83-85` | |
| 29 | +| 9 | Temp file created without explicit permissions | Low | CWE-377 | `gearbox-agent/internal/plugins/security/plugin.go:869` | |
| 30 | +| 10 | Error messages may expose internal details | Low | CWE-209 | Multiple locations | |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## Detailed Findings |
| 35 | + |
| 36 | +### 1. HIGH - XSS: Unescaped Filter Label in Traffic Visualization |
| 37 | + |
| 38 | +**CWE-79 (Cross-Site Scripting)** |
| 39 | + |
| 40 | +**File:** `gearbox/static/js/traffic/traffic-visualization.js` |
| 41 | +**Lines:** 417, 451 |
| 42 | + |
| 43 | +**Description:** The `activeFilter.label` value is interpolated directly into an innerHTML assignment without escaping. If the label contains user-controlled data (IP addresses, backend names), it could execute arbitrary JavaScript. |
| 44 | + |
| 45 | +**Vulnerable code pattern:** |
| 46 | + |
| 47 | +```javascript |
| 48 | +tbody.innerHTML = `<tr><td>No traffic matching filter: ${activeFilter?.label || ''}</td></tr>`; |
| 49 | +``` |
| 50 | +
|
| 51 | +**Recommendation:** Use `escapeHtml()` (already defined elsewhere in the codebase) before interpolation: |
| 52 | +
|
| 53 | +```javascript |
| 54 | +tbody.innerHTML = `<tr><td>No traffic matching filter: ${escapeHtml(activeFilter?.label || '')}</td></tr>`; |
| 55 | +``` |
| 56 | +
|
| 57 | +--- |
| 58 | +
|
| 59 | +### 2. HIGH - XSS: Backend Data in Backup Restore UI |
| 60 | +
|
| 61 | +**CWE-79 (Cross-Site Scripting)** |
| 62 | +
|
| 63 | +**File:** `gearbox/static/js/haproxy_config/editor.js` |
| 64 | +**Lines:** 1400-1410 |
| 65 | +
|
| 66 | +**Description:** Backend API response data (`b.reason`, `b.id`) is rendered via innerHTML without escaping. If the database contains malicious data, it could execute scripts. The `b.id` is also used in an inline `onclick` handler, which is vulnerable to attribute escape attacks. |
| 67 | +
|
| 68 | +**Recommendation:** Escape all dynamic values with `escapeHtml()` and use event listeners instead of inline onclick handlers. |
| 69 | +
|
| 70 | +--- |
| 71 | +
|
| 72 | +### 3. MEDIUM - SQL Injection in Database Backup |
| 73 | +
|
| 74 | +**CWE-89 (SQL Injection)** |
| 75 | +
|
| 76 | +**File:** `gearbox/internal/framework/database/backup.go` |
| 77 | +**Line:** 38 |
| 78 | +
|
| 79 | +**Description:** The backup path is constructed and interpolated directly into a SQL statement via `fmt.Sprintf`: |
| 80 | +
|
| 81 | +```go |
| 82 | +_, err := d.db.Exec(fmt.Sprintf("VACUUM INTO '%s'", backupPath)) |
| 83 | +``` |
| 84 | +
|
| 85 | +SQLite's `VACUUM INTO` does not support parameterized queries, but the backup path should be validated to contain only safe filesystem characters before use. |
| 86 | +
|
| 87 | +**Recommendation:** Add explicit path validation (alphanumeric, slashes, hyphens, underscores, dots only) before constructing the query. Reject any path containing single quotes. |
| 88 | +
|
| 89 | +--- |
| 90 | +
|
| 91 | +### 4. MEDIUM - No Rate Limiting on Dashboard Login |
| 92 | +
|
| 93 | +**CWE-307 (Improper Restriction of Excessive Authentication Attempts)** |
| 94 | +
|
| 95 | +**Description:** The dashboard login endpoint has account lockout (5 failed attempts, 15-minute lockout) but no per-IP rate limiting. Distributed brute force attacks across multiple accounts could bypass the per-account lockout. |
| 96 | +
|
| 97 | +**Current mitigation:** Account lockout after 5 failures. |
| 98 | +
|
| 99 | +**Recommendation:** Add per-IP rate limiting to the login endpoint, similar to the token bucket algorithm already implemented in the agent (`gearbox-agent/internal/framework/middleware/ratelimit.go`). |
| 100 | +
|
| 101 | +--- |
| 102 | +
|
| 103 | +### 5. MEDIUM - TLS Verification Bypass via Environment Variable |
| 104 | +
|
| 105 | +**CWE-295 (Improper Certificate Validation)** |
| 106 | +
|
| 107 | +**File:** `gearbox/internal/framework/agent/client.go` |
| 108 | +**Lines:** 70-78 |
| 109 | +
|
| 110 | +**Description:** Setting `GEARBOX_INSECURE_TLS=true` disables TLS certificate verification. While this is intentional for development, it could be exploited if an attacker gains control of environment variables. |
| 111 | +
|
| 112 | +**Current mitigation:** Warning logged when enabled; `#nosec G402` annotation present. |
| 113 | +
|
| 114 | +**Recommendation:** Document the security implications clearly and consider restricting this to explicitly non-production environments. |
| 115 | +
|
| 116 | +--- |
| 117 | +
|
| 118 | +### 6. LOW - Cookie Secure Flag Default |
| 119 | +
|
| 120 | +**CWE-614 (Sensitive Cookie in HTTPS Session Without 'Secure' Attribute)** |
| 121 | +
|
| 122 | +**File:** `gearbox/internal/framework/auth/auth.go` |
| 123 | +**Line:** 46 |
| 124 | +
|
| 125 | +**Description:** The `Secure` cookie flag defaults to `false` and is only enabled when TLS is configured. If the application is deployed behind a TLS-terminating proxy without being configured for TLS, session cookies could be sent over HTTP. |
| 126 | +
|
| 127 | +**Current mitigation:** Warning logged when running without TLS. |
| 128 | +
|
| 129 | +--- |
| 130 | +
|
| 131 | +### 7. LOW - CSP Allows unsafe-inline |
| 132 | +
|
| 133 | +**CWE-79 (Cross-Site Scripting)** |
| 134 | +
|
| 135 | +**File:** `gearbox/internal/framework/middleware/security_headers.go` |
| 136 | +**Lines:** 60-76 |
| 137 | +
|
| 138 | +**Description:** The Content-Security-Policy allows `'unsafe-inline'` for both scripts and styles, which reduces XSS protection. This is documented as necessary for Tailwind CSS and inline event handlers. |
| 139 | +
|
| 140 | +**Recommendation:** Long-term, consider migrating to CSP nonces or hashes for inline scripts. |
| 141 | +
|
| 142 | +--- |
| 143 | +
|
| 144 | +### 8-10. LOW - Minor Issues |
| 145 | +
|
| 146 | +- **Swagger docs public** on the agent could aid reconnaissance (`gearbox-agent/internal/api/server.go:83-85`) |
| 147 | +- **Temp file permissions** not explicitly set in security plugin (`gearbox-agent/internal/plugins/security/plugin.go:869`) |
| 148 | +- **Error messages** in some handlers use `%v` formatting which could expose internal paths |
| 149 | +
|
| 150 | +--- |
| 151 | +
|
| 152 | +## Security Strengths |
| 153 | +
|
| 154 | +The codebase demonstrates many excellent security practices: |
| 155 | +
|
| 156 | +| Category | Implementation | Rating | |
| 157 | +|----------|---------------|--------| |
| 158 | +| **Secrets Management** | No hardcoded production secrets; env vars required; auto-generation with crypto/rand | Excellent | |
| 159 | +| **Password Security** | bcrypt cost 12; entropy validation (50+ bits); common password blacklist | Excellent | |
| 160 | +| **Session Management** | 128-bit crypto/rand tokens; server-side validation; DB-backed; proper cookie flags | Excellent | |
| 161 | +| **CSRF Protection** | 256-bit tokens; validated on all state-changing requests | Excellent | |
| 162 | +| **SQL Injection** | Parameterized queries throughout; whitelist validation for dynamic columns | Excellent | |
| 163 | +| **Command Injection** | exec.Command with separate args (no shell); input validation on IPs, packages, branches | Strong | |
| 164 | +| **Cryptography** | crypto/rand everywhere; TLS 1.2+ enforced; AES-256-GCM for API key encryption | Excellent | |
| 165 | +| **Authentication** | Bearer token with constant-time comparison; WebSocket token auth (60s TTL); passkey support | Excellent | |
| 166 | +| **Rate Limiting** | Token bucket algorithm on agent (50 req/s, burst 100); per-IP tracking | Strong | |
| 167 | +| **Input Validation** | SQL injection detection; email RFC 5322 validation; branch name whitelist regex | Strong | |
| 168 | +| **Security Headers** | CSP, X-Frame-Options DENY, X-Content-Type-Options, HSTS, Referrer-Policy | Strong | |
| 169 | +| **WebSocket Security** | Origin validation; short-lived single-use tokens; configurable allowed origins | Excellent | |
| 170 | +| **Audit Logging** | Login/logout/password changes logged with IP and user-agent | Strong | |
| 171 | +| **Config Redaction** | Automatic redaction of passwords, tokens, and secrets in HAProxy configs | Excellent | |
| 172 | +| **File Permissions** | API key files stored with 0600; proper backup directory validation | Strong | |
| 173 | +
|
| 174 | +--- |
| 175 | +
|
| 176 | +## Recommendations by Priority |
| 177 | +
|
| 178 | +### Immediate |
| 179 | +
|
| 180 | +1. Escape `activeFilter.label` in `traffic-visualization.js` (lines 417, 451) |
| 181 | +2. Escape backup data in `haproxy_config/editor.js` (lines 1400-1410) |
| 182 | +
|
| 183 | +### High Priority |
| 184 | +
|
| 185 | +3. Add per-IP rate limiting to dashboard login endpoint |
| 186 | +4. Add path validation before `VACUUM INTO` in `backup.go` |
| 187 | +
|
| 188 | +### Medium Priority |
| 189 | +
|
| 190 | +5. Add input validation for log source fields (Unit, FilePath, Priority) in `streamer.go` |
| 191 | +6. Add domain name validation before certbot/acme.sh commands in `collector.go` |
| 192 | +7. Consider DOMPurify for complex HTML rendering in JavaScript |
| 193 | +
|
| 194 | +### Low Priority |
| 195 | +
|
| 196 | +8. Document `GEARBOX_INSECURE_TLS` security implications |
| 197 | +9. Protect Swagger docs in production agent deployments |
| 198 | +10. Set explicit permissions (0600) on temp files |
| 199 | +11. Review error messages for information disclosure |
| 200 | +12. Long-term: migrate from CSP `unsafe-inline` to nonces |
| 201 | +
|
| 202 | +--- |
| 203 | +
|
| 204 | +## Domains Reviewed |
| 205 | +
|
| 206 | +| Security Domain | Issues Found | Notes | |
| 207 | +|-----------------|-------------|-------| |
| 208 | +| 1. Secrets and Credentials | 0 | No hardcoded secrets; proper encryption at rest | |
| 209 | +| 2. Injection (SQL/Cmd/LDAP) | 1 Medium | VACUUM INTO path; command execution is safe | |
| 210 | +| 3. Cross-Site Scripting | 2 High, 1 Low | innerHTML without escaping in 2 JS files | |
| 211 | +| 4. Authentication and Sessions | 1 Medium, 1 Low | Missing login rate limiting; cookie Secure flag | |
| 212 | +| 5. Cryptographic Failures | 1 Medium | TLS skip verify option (documented/intentional) | |
| 213 | +| 6. Input Validation | 0 | Comprehensive validation framework | |
| 214 | +| 7. Configuration and Deployment | 1 Low, 1 Low | Swagger exposure; error message detail | |
| 215 | +| 8. Dependency and Supply Chain | Not Scanned | Recommend separate `go mod audit` | |
| 216 | +| 9. API Security | 0 | Proper auth middleware on all protected routes | |
| 217 | +| 10. File Handling | 1 Low | Temp file permissions | |
0 commit comments