test(security): cover privileged API proxy boundary

This commit is contained in:
Shadowbroker
2026-08-17 01:11:15 -06:00
parent 21df433103
commit 054528edab
@@ -5,7 +5,7 @@
* 1. Document CSP remains hydration-safe for the Next.js runtime
* 2. CSP is deterministic across repeated requests
* 3. next.config.ts no longer owns a static CSP header
* 4. Proxy does not break API/static routes (matcher exclusion)
* 4. Proxy screens API routes before handlers while static assets stay excluded
* 5. Google Fonts domains are preserved in CSP
* 6. Production CSP preserves required directives
*/
@@ -117,12 +117,30 @@ describe('next.config.ts CSP removal', () => {
});
// ---------------------------------------------------------------------------
// 4. Proxy does not break API/static routes
// 4. Proxy screens APIs while keeping document/static behavior intact
// ---------------------------------------------------------------------------
describe('proxy matcher exclusions', () => {
it('excludes /api paths', () => {
expect(matcherExcludes('/api/mesh/events')).toBe(true);
describe('proxy matcher and privileged API boundary', () => {
it('includes /api paths so the request-boundary security guard runs', () => {
expect(matcherExcludes('/api/mesh/events')).toBe(false);
});
it('non-sensitive API requests pass through without document CSP', () => {
expect(getCsp('/api/mesh/events')).toBe('');
});
it('rejects hostile cross-origin privileged API requests before route handling', () => {
const req = new NextRequest('http://localhost/api/settings/tor/reset-identity', {
method: 'POST',
headers: {
host: 'localhost',
origin: 'https://evil.example',
'sec-fetch-site': 'cross-site',
},
});
const response = proxy(req);
expect(response.status).toBe(403);
expect(response.headers.get('Content-Security-Policy')).toBeNull();
});
it('excludes /_next/static paths', () => {