fix(security): pre-launch security hardening audit & remediation (#320)

- Webhook HMAC: capture raw request bytes via express.json verify callback
  instead of re-serializing with JSON.stringify
- AES-256-GCM: use NIST-recommended 12-byte IV (backward compatible with
  existing 16-byte IVs)
- Node proxy tokens: add 1-year default expiry (previously no expiry)
- Host console env filtering: pattern-based approach blocking SECRET,
  PASSWORD, TOKEN, KEY, CREDENTIAL keywords (previously only 4 explicit keys)
- CORS: deny cross-origin requests when FRONTEND_URL is unset in production
  (previously fell back to allowing all origins)
This commit is contained in:
Anso
2026-04-01 20:50:43 -04:00
committed by GitHub
parent e1a6db1044
commit 2d6b4c233d
7 changed files with 36 additions and 20 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ import path from 'path';
const ALGORITHM = 'aes-256-gcm';
const KEY_LENGTH = 32; // 256 bits
const IV_LENGTH = 16;
const IV_LENGTH = 12; // NIST SP 800-38D recommended length for GCM
const ENCRYPTED_PREFIX = 'enc:';
export class CryptoService {
+7 -2
View File
@@ -18,9 +18,14 @@ export class HostTerminalService {
// Strip sensitive backend secrets from the PTY environment so they are not
// visible to the console user via `env` / `printenv`.
const SENSITIVE_KEYS = ['JWT_SECRET', 'AUTH_PASSWORD', 'AUTH_PASSWORD_HASH', 'DATABASE_URL'];
// Pattern-based filtering: block any env var containing sensitive keywords.
// Explicit fallback set catches vars that don't match patterns (e.g. DATABASE_URL).
const SENSITIVE_PATTERNS = /SECRET|PASSWORD|TOKEN|KEY|CREDENTIAL/i;
const SENSITIVE_KEYS = new Set(['DATABASE_URL']);
const safeEnv = Object.fromEntries(
Object.entries(process.env as Record<string, string>).filter(([k]) => !SENSITIVE_KEYS.includes(k))
Object.entries(process.env as Record<string, string>).filter(
([k]) => !SENSITIVE_PATTERNS.test(k) && !SENSITIVE_KEYS.has(k)
)
);
const ptyProcess = pty.spawn(shell, [], {