Unified security documentation: OWASP compliance, implementation review, and vulnerability history.
| Standard | Status | Notes |
|---|---|---|
| OWASP Top 10 2025 | ✅ 10/10 | All categories addressed |
| OWASP API Security Top 10 | ✅ 10/10 | Including DoS prevention |
| OWASP GenAI Top 10 | ✅ 10/10 | No new AI attack surface |
- RBAC: Testing Objective and Testing Method require Assessor role.
- Enforcement: Frontend disables fields; backend validates with
authenticate,authorize,requireRole. - Auth: Session-based + Bearer token; role checked on every request.
- HTTPS in production; secure cookies:
httpOnly,sameSite: 'strict',securein production. - No sensitive data in cookies; session timeout configured.
- EC2 (production): Sensitive platform settings (SMTP, AI tokens, SSO client secrets) use
OSCAL_SECRETS_MODE=aws-smand a single AWS Secrets Manager JSON bundle;config.jsonholds{ "_sm": "OSCAL/..." }pointers only. Saves fail if SM is unavailable (no plaintext fallback). Startup auto-migrates any plaintext to SM. Seebackend/utils/secretsManager.jsandbackend/utils/configSecretMigration.js. - Local / Docker / offline: Secrets are stored as
{ "_cfgenc": "v1$..." }envelopes inconfig.jsonusing PBKDF2-SHA256 + AES-256-GCM (backend/utils/configFieldCrypto.js). SetOSCAL_CONFIG_FIELD_SECRETorSESSION_SECRET. Docker entrypoint generates and persists keys under/data/.field-secretand/data/.session-secret. Pass vault is not required. - Optional operator tooling: Legacy pass bundle sync scripts (
push-pass-to-secrets-manager.sh, etc.) remain for migrating secrets to SM; setOSCAL_PASS_DISABLED=1in Docker (default in compose). - Never commit plaintext secrets; use
config.json.examplepointers or_cfgencplaceholders only.
- Current storage format: New and rotated passwords are stored as PBKDF2-SHA256 with random salt and 100,000 iterations (
pbkdf2$sha256$...prefix). Implementation:backend/auth/userManager.js(hashPassword/verifyPassword). - Legacy format: Older rows may still hold a single-round SHA-256 hex of the password (64 hex characters, no
pbkdf2$prefix). Verifying those rows requires the same digest algorithm until each user successfully signs in once with the correct password. - Automatic upgrade: On successful password authentication, if the stored value is legacy format,
migratePasswordToPBKDF2rewrites the stored hash to PBKDF2. No user action beyond normal login. - Removal gate: When no users remain on legacy format in all environments you operate (see Platform Admin GET
/api/users/legacy-password-hash-stats), the legacy verification branch inverifyPasswordmay be deleted; until then, removing it would lock out any account still on legacy hashes. - Static analysis (CodeQL
js/insufficient-password-hash): Tools flag anycreateHash('sha256')used with password material. Here that call exists only for backward-compatible verification of already stored legacy digests, not for new storage. Governance: document this transitional behavior; use GitHub “won’t fix” / dismissal with the same narrative if the alert persists until the legacy branch is removed after migration completes.
- Sanitization: User input sanitized for OSCAL; no raw user input in queries or commands.
- No SQL: Data in JSON files and client storage; no command execution with user input.
- Output encoding for context (HTML, OSCAL).
- Secure defaults; optional fields; separation of SAR vs SSP.
- No stack traces to users; generic error messages in production.
- Security logging: Auth success/failure, access denied, validation failures.
- Structured logs with OpenTelemetry-style attributes; no secrets in logs.
- Error handling: Specific exceptions; generic user-facing messages.
- Request limits: Export payloads use configurable caps (default 10,000 controls, 512KB metadata); set
OSCAL_EXPORT_MAX_CONTROLSandOSCAL_EXPORT_MAX_METADATA_BYTESfor large catalogs. Same checks apply to CCM/Excel/PDF and async job routes. - Rate limiting: 100 requests per 15 minutes per IP.
- Timeout: 240-second server timeout.
- Token-based CSRF for state-changing browser requests.
- API endpoints use Bearer token (CSRF not applicable); architecture documented for scanner suppression.
- Issue: fast-xml-parser DoS (CVE-2026-25128); transitive via
@aws-sdk/xml-builder. - Scope: AWS Bedrock integration only (optional).
- Fix:
fast-xml-parser5.2.5 → 5.3.4;@aws-sdk/xml-builderupdated.npm audit: 0 vulnerabilities. - Action: If using AWS Bedrock, run integration tests after upgrade.
- Issue: CSRF middleware caused 403 on many API endpoints.
- Fix: API routes under
/api/exempted; Bearer token used for API (CSRF not applicable). State-changing browser flows still use CSRF tokens.
- OWASP Top 10 2025
- OWASP API Security Top 10
- OWASP GenAI Top 10
- AI integration – architecture and security
Version: 1.7.23 · Last updated: June 2026