mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-20 09:09:35 +02:00
fix(html-view): answer the rendered page's CORS preflight
A sandboxed page is opaque-origin, so a fetch() of its own data file with a non-safelisted header preflights with `Origin: null`. The auth hook refused the OPTIONS (the html-view exemption admitted GET and HEAD only) and, without a password, the security-headers hook answered a bare 204 with no Access-Control-Allow-Origin, so the fetch failed either way. The exemption now admits OPTIONS for a live capability, and registerSecurityHeaders answers it itself with Allow-Origin `*`, Allow-Methods `GET, HEAD` and Allow-Headers `*` (no credentials are involved). An unknown or revoked capability still gets the 401, and writes on the capability path are still refused. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
4544379b3b
commit
06f1e5ddc8
3 files changed
+34
-3
No files matched your search
@@ -336,6 +336,25 @@ describe('the html-view exemption', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("answers the page's CORS preflight, read-only, and nothing else", async () => {
|
||||
const preflight = (url: string) =>
|
||||
app.inject({
|
||||
method: 'OPTIONS',
|
||||
url,
|
||||
headers: { origin: 'null', 'access-control-request-method': 'GET', 'access-control-request-headers': 'x-req' },
|
||||
});
|
||||
const res = await preflight(`/html-view/${htmlCapability}/data.json`);
|
||||
expect(res.statusCode).toBe(204);
|
||||
expect(res.headers['access-control-allow-origin']).toBe('*');
|
||||
expect(res.headers['access-control-allow-methods']).toBe('GET, HEAD');
|
||||
expect(res.headers['access-control-allow-headers']).toBe('*');
|
||||
expect(res.headers['access-control-allow-credentials']).toBeUndefined();
|
||||
// An unknown or revoked capability is not a preflight anyone answers.
|
||||
expect((await preflight('/html-view/AAAAAAAAAAAAAAAAAAAAAAAA/data.json')).statusCode).toBe(401);
|
||||
htmlViewCapabilities.revokeOwner(undefined);
|
||||
expect((await preflight(`/html-view/${htmlCapability}/data.json`)).statusCode).toBe(401);
|
||||
});
|
||||
|
||||
it('never exempts a write on the capability path', async () => {
|
||||
for (const method of ['POST', 'PUT'] as const) {
|
||||
const res = await app.inject({ method, url: `/html-view/${htmlCapability}/index.html`, payload: {} });
|
||||
|
||||
Reference in new issue
Block a user