Skip to content

Commit 7d4b793

Browse files
committed
chore(security): P3 batch — placeholder email + swagger gate
Two of the eight P3 audit findings warrant a focused fix; the others are informational / future-proofing / feature-requests and stay in the findings doc as backlog. ### P3-1 — SECURITY.md placeholder contact email SECURITY.md instructed reporters to email security@example.com "(replace with actual email)" — a TODO that never got replaced. Two call sites (line 25 and line 213) just stripped both. GitHub Security Advisories is the recommended path anyway: report stays private to the maintainer until a fix is ready to ship, doesn't require running a security inbox, and integrates with CVE numbering when needed. ### P3-2 — Swagger UI gate `/swagger` and `/swagger/*` were registered unconditionally with no auth. In production, this lets any unauthenticated caller enumerate every endpoint + JSON schema of the agent — a fingerprinting aid for attackers, and the kind of detail that pairs with CVE search to find known-vulnerable builds. In development the UI is genuinely useful for debugging the API contract. Gate behind a new opt-in: GEARBOX_AGENT_SWAGGER_ENABLED=true. Default is off (production-safe). When enabled, the startup log emits a WARN making the operator aware the UI is reachable. config.SwaggerEnabled wires through ServerConfig.SwaggerEnabled to the NewServer route registration. Existing prod deployments inherit the default (off) without action. P3-1 and P3-2 from the 2026-05 security audit.
1 parent c174f39 commit 7d4b793

4 files changed

Lines changed: 41 additions & 16 deletions

File tree

SECURITY.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ Please do not report security vulnerabilities through public GitHub issues, disc
1919

2020
### 2. Report Privately
2121

22-
Please report security vulnerabilities via one of these methods:
23-
24-
- **GitHub Security Advisories** (Preferred): Use the "Security" tab and click "Report a vulnerability"
25-
- **Email**: Send details to security@example.com (replace with actual email)
22+
Please report security vulnerabilities via GitHub Security Advisories: use the
23+
"Security" tab and click "Report a vulnerability". This keeps the report
24+
private to the maintainer until a fix is ready to ship.
2625

2726
### 3. Include the Following Information
2827

@@ -208,10 +207,12 @@ Subscribe to the repository to receive notifications of security updates.
208207

209208
## Contact
210209

211-
For security-related questions or concerns, please contact:
210+
For security-related questions or concerns, please use GitHub Security
211+
Advisories on this repository — click the "Security" tab, then "Report a
212+
vulnerability". Reports stay private to the maintainer until a fix lands.
212213

213-
- **Security Team**: security@example.com (replace with actual email)
214-
- **GitHub Security**: Use the "Security" tab to report vulnerabilities
214+
For non-vulnerability security questions (e.g. deployment hardening
215+
guidance), open a regular GitHub Discussion or issue.
215216

216217
## License
217218

gearbox-agent/cmd/gearbox-agent/main.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,12 +312,13 @@ func main() {
312312

313313
// Create and start API server
314314
serverCfg := api.ServerConfig{
315-
ListenAddr: cfg.ListenAddr,
316-
APIKey: apiKey,
317-
CertFile: tlsCfg.CertPath,
318-
KeyFile: tlsCfg.KeyPath,
319-
Version: Version,
320-
Logger: logger,
315+
ListenAddr: cfg.ListenAddr,
316+
APIKey: apiKey,
317+
CertFile: tlsCfg.CertPath,
318+
KeyFile: tlsCfg.KeyPath,
319+
Version: Version,
320+
Logger: logger,
321+
SwaggerEnabled: cfg.SwaggerEnabled, // P3-2: off by default; opt in via GEARBOX_AGENT_SWAGGER_ENABLED=true
321322
}
322323
// Only set MetadataProvider if sync service is configured
323324
// (Go interfaces holding nil pointers are not themselves nil)

gearbox-agent/internal/api/server.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ type ServerConfig struct {
4545
WebhookURL string
4646
SyncTrigger SyncTrigger
4747

48+
// SwaggerEnabled controls whether the Swagger UI / OpenAPI spec are
49+
// served at /swagger and /swagger/*. Useful in development; in
50+
// production it lets unauthenticated callers enumerate the agent's
51+
// endpoints + schemas. Default false (off in production). See
52+
// 2026-05 security audit P3-2.
53+
SwaggerEnabled bool
54+
4855
// WebSocket settings (optional)
4956
EventBus *events.Bus
5057

@@ -85,9 +92,16 @@ func NewServer(cfg ServerConfig) *Server {
8592
// Health endpoint (no auth required, no rate limit)
8693
r.Get("/health", handlers.Health)
8794

88-
// Swagger UI (no auth required)
89-
r.Get("/swagger", httpSwagger.Handler(httpSwagger.URL("/swagger/doc.json")))
90-
r.Get("/swagger/*", httpSwagger.Handler(httpSwagger.URL("/swagger/doc.json")))
95+
// Swagger UI (no auth required) — only served when explicitly enabled.
96+
// In production, leaving this on lets unauthenticated callers enumerate
97+
// every endpoint + schema, which is a fingerprinting aid for attackers
98+
// (2026-05 security audit P3-2). Set SWAGGER_ENABLED=true at deploy
99+
// time when debugging an API contract; default off.
100+
if cfg.SwaggerEnabled {
101+
r.Get("/swagger", httpSwagger.Handler(httpSwagger.URL("/swagger/doc.json")))
102+
r.Get("/swagger/*", httpSwagger.Handler(httpSwagger.URL("/swagger/doc.json")))
103+
cfg.Logger.Warn("Swagger UI enabled at /swagger; unauth-readable. Disable for production deploys.")
104+
}
91105

92106
// Webhook endpoint (uses GitHub signature verification, not API key)
93107
var webhookHandler *WebhookHandler

gearbox-agent/internal/framework/config/config.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ type Config struct {
6060

6161
// Certificate renewal detection
6262
CertbotTimer string // Custom certbot timer name (default: auto-detect)
63+
64+
// SwaggerEnabled, when true, serves the Swagger UI + OpenAPI spec at
65+
// /swagger and /swagger/*. Off by default to avoid exposing the agent's
66+
// endpoint + schema list to unauthenticated callers in production. See
67+
// 2026-05 security audit P3-2.
68+
SwaggerEnabled bool
6369
}
6470

6571
// DefaultConfig returns the default configuration.
@@ -152,6 +158,9 @@ func Load() (*Config, error) {
152158
// Certificate renewal detection (optional override)
153159
cfg.CertbotTimer = os.Getenv("HAPROXY_CERTBOT_TIMER")
154160

161+
// Swagger UI off by default; opt in for dev / API debugging.
162+
cfg.SwaggerEnabled = os.Getenv("GEARBOX_AGENT_SWAGGER_ENABLED") == "true"
163+
155164
return cfg, nil
156165
}
157166

0 commit comments

Comments
 (0)