Skip to content

Security hardening: findings from peon-app audit (2026-07-26) #17

Description

@hironate

Summary

Static security review of peon-app (control plane). Not a live pentest.

Result: 0 Critical · 3 High · 8 Medium · 5 Low · 2 Info

No confirmed Critical unauthenticated remote RCE. Strongest gaps: auth rate limiting, notification SSRF, and service delete without container teardown.

High (do first)

[ ] H-01 — No rate limiting on login / signup / OTP / forgot-password

  • Where: src/app/api/auth/login, signup, resend-otp, forgot-password
  • Risk: Password brute-force, 6-digit OTP spray, email flood
  • Fix: IP + account rate limits; CAPTCHA after N failures; alert on bursts

[ ] H-02 — Notification webhook SSRF

  • Where: src/services/internal/notifications/notifications.ts (postJson)
  • Risk: Workspace admin can point Discord/Slack/WEBHOOK URLs at internal/metadata hosts
  • Fix: HTTPS-only; block private/link-local/metadata IPs; reject unsafe redirects

[ ] H-03 — Service delete does not stop/remove host containers

Medium

  • M-01 Git-over-SSH StrictHostKeyChecking=nodeploy/engine.ts (pin known_hosts / prefer GitHub App HTTPS)
  • M-02 Host-key TOFU + fail-open on unparseable pin — lib/ssh/host-key.ts
  • M-03 Generic deploy webhooks = URL token only — add HMAC + rate limit
  • M-04 No CSP / HSTS / frame security headers — next.config.ts
  • M-05 ENCRYPTION_KEY SHA-256 fallback accepts weak secrets — require 32-byte base64
  • M-06 DB dump/restore inlines unquoted passwords — lib/docker/databases.ts
  • M-07 API tokens have no scopes (full role via MCP) — add read/deploy/admin scopes
  • M-08 Terminal ticket in WebSocket query string — prefer header / first-message auth

Low / Info

  • L-01 bcrypt cost 10; no password max length
  • L-02 7-day sessions without idle timeout
  • L-03 resend-otp without pending-signup guard
  • L-04 Admin paths gated by owner email vs isInstanceAdmin mismatch in proxy.ts
  • L-05 Keep Dependabot / CI dependency audit required
  • I-01 Document PaaS trust model (admin Dockerfile/terminal = host control)
  • I-02 Public DB port footgun — warn / auto-close on stop/delete

Already in good shape (no action)

  • Project/workspace RBAC on service APIs
  • AES-256-GCM secrets at rest
  • Revocable sessions (sid + AuthSession)
  • OTP hashed + attempt caps
  • Git sync shell quoting + safe ref names
  • GitHub/GitLab/Stripe signature verification
  • SSH hostVerifier Peon→VPS (fix: verify SSH host keys with trust-on-first-use and optional pinning #15)
  • Terminal re-checks membership on connect
  • Chat mutating tools require approval
  • Agent push bearer + timingSafeEqual

Suggested 30-day order

  1. H-01, L-03 — auth rate limits
  2. H-02 — SSRF guards
  3. H-03 — delete teardown (beyond warn: stop service before delete — containers keep running #16 warning)
  4. M-01, M-04, M-05 — git host keys, headers, encryption key
  5. M-03, M-06, M-07 — webhooks, DB shell, token scopes
  6. M-08, L-02, L-05 — terminal ticket, idle timeout, CI audit

Limitations

Static review only. No production exploit attempts. Infra / AWS IAM / host OS outside this repo.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions