Skip to content

Commit 7d2cf3a

Browse files
dahliaclaude
andcommitted
Assert content-type in XSS escape test
The existing XSS test only checked that the malicious payload was absent from the response body, but never verified that the debug dashboard HTML was actually rendered. Strengthen the assertion by branching on the Content-Type header: when the response is HTML, confirm the dashboard is present AND the payload is escaped; otherwise, confirm the delegated response also does not contain the payload. Addresses: #564 (comment) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 351e80d commit 7d2cf3a

1 file changed

Lines changed: 22 additions & 8 deletions

File tree

packages/debugger/src/mod.test.ts

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,14 +380,28 @@ test("traces list page escapes pathPrefix in inline script", async () => {
380380
const request = new Request("https://example.com" + malicious + "/");
381381
const response = await dbg.fetch(request, { contextData: undefined });
382382
strictEqual(response.status, 200);
383-
const html = await response.text();
384-
// The malicious pathPrefix must not appear unescaped in the inline script;
385-
// it should be JSON-encoded with < escaped as \u003c to prevent breaking
386-
// out of the <script> tag.
387-
ok(
388-
!html.includes("onerror=alert(1)>"),
389-
"Malicious pathPrefix should be escaped in inline script",
390-
);
383+
const ct = response.headers.get("content-type") ?? "";
384+
const body = await response.text();
385+
if (ct.includes("text/html")) {
386+
// If the dashboard is rendered, verify that the malicious pathPrefix
387+
// is properly escaped so it cannot break out of the <script> tag.
388+
ok(
389+
body.includes("Fedify Debug Dashboard"),
390+
"Response should be the debug dashboard HTML",
391+
);
392+
ok(
393+
!body.includes("onerror=alert(1)>"),
394+
"Malicious pathPrefix should be escaped in inline script",
395+
);
396+
} else {
397+
// If the request was delegated to the inner federation instead of
398+
// matching the debug route, the XSS vector is not reachable — the
399+
// malicious path never appears in any rendered HTML.
400+
ok(
401+
!body.includes("onerror=alert(1)>"),
402+
"Delegated response must not contain the malicious payload",
403+
);
404+
}
391405
});
392406

393407
test("trace detail page returns HTML with activity details", async () => {

0 commit comments

Comments
 (0)