# AOC v1.7.12 Release Notes **Release Date:** 2026-04-27 ## Security Hardening (Penetration Test Remediation) This release addresses all findings from the internal soft penetration test of v1.7.11. ### Critical Fix: CORS Credentials Leak - **Issue:** When `AUTH_ENABLED=true` and `CORS_ORIGINS="*"`, the CORS middleware reflected any origin with `Access-Control-Allow-Credentials: true`, allowing cross-origin authenticated requests from attacker-controlled domains. - **Fix:** When auth is enabled with a wildcard origin, `allow_credentials` is now forced to `False`. CORS still works for unauthenticated requests, but bearer tokens cannot be leaked cross-origin. ### High Fix: Missing Security Headers - Added `X-Content-Type-Options: nosniff` - Added `X-Frame-Options: DENY` - Added `Referrer-Policy: strict-origin-when-cross-origin` - Added `Permissions-Policy` restricting browser features (accelerometer, camera, geolocation, gyroscope, magnetometer, microphone, payment, USB) ### Medium Fixes - **Rate limiter fail-closed:** Previously, a Redis outage silently disabled all rate limiting. The rate limiter now returns `429` when Redis is unreachable. - **OpenAPI docs exposure:** `/docs`, `/redoc`, and `/openapi.json` are disabled by default. Set `DOCS_ENABLED=true` to re-enable (intended for development only). ### Low Fixes - **Information disclosure:** `/api/config/auth` no longer leaks `tenant_id` and `client_id` when `auth_enabled=false`. - **Webhook validation token:** Added length cap (1024 chars) and ASCII-only validation before echoing `validationToken`. Response now includes `X-Content-Type-Options: nosniff`. ## Files Changed | File | Change | |------|--------| | `backend/main.py` | CORS fix, security headers middleware, conditional OpenAPI docs | | `backend/config.py` | Added `DOCS_ENABLED` setting | | `backend/rate_limiter.py` | Fail-closed on Redis errors | | `backend/routes/config.py` | Hide tenant/client IDs when auth disabled | | `backend/routes/webhooks.py` | Validate validationToken before echo | | `backend/tests/conftest.py` | Enhanced FakeRedis mock with `incr`/`expire` | | `.env.example` | Documented `DOCS_ENABLED` | | `VERSION` | Bumped to 1.7.12 | ## Test Results - **80/80 pytest tests passing** - Penetration test report: `PEN_TEST_REPORT_v1.7.11.md`