CVE-2025-58765
Description
wabac.js provides a full web archive replay system, or 'wayback machine', using Service Workers. A Reflected Cross-Site Scripting (XSS) vulnerability exists in the 404 error handling logic of wabac.js v2.23.10 and below. The parameter requestURL (derived from the original request target) is directly embedded into an inline <script> block without sanitization or escaping. This allows an attacker to craft a malicious URL that executes arbitrary JavaScript in the victim’s browser. The scope may be limited by CORS policies, depending on the situation in which wabac.js is used. The vulnerability is fixed in wabac.js v2.23.11.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
@webrecorder/wabacnpm | < 2.23.11 | 2.23.11 |
replaywebpagenpm | < 2.3.17 | 2.3.17 |
@webrecorder/archivewebpagenpm | < 0.15.4 | 0.15.4 |
Affected products
1- Range: 2.12.0, 2.13.15, 2.14.0, …
Patches
20c59ee0081c8deps: bump to warcio 2.4.5 (#276)
2 files changed · +6 −6
package.json+2 −2 modified@@ -1,6 +1,6 @@ { "name": "@webrecorder/wabac", - "version": "2.23.10", + "version": "2.23.11", "main": "index.js", "type": "module", "exports": { @@ -37,7 +37,7 @@ "path-parser": "^6.1.0", "process": "^0.11.10", "stream-browserify": "^3.0.0", - "warcio": "^2.4.3" + "warcio": "^2.4.5" }, "devDependencies": { "@swc-node/register": "^1.10.9",
yarn.lock+4 −4 modified@@ -3736,10 +3736,10 @@ warcio@^2.4.0: uuid-random "^1.3.2" yargs "^17.7.2" -warcio@^2.4.3: - version "2.4.3" - resolved "https://registry.yarnpkg.com/warcio/-/warcio-2.4.3.tgz#37ff95c2358d0d5ddb16e924fe200c4774b3903d" - integrity sha512-c397HNfLE7yJsyVF3XKXB+Yh3q3WKljhdYRPkKF9eyZMtB+HIxj1aBqgq0nTYz492KMKtzygBo0Gx+Gi0fJ9dg== +warcio@^2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/warcio/-/warcio-2.4.5.tgz#ba39c38e433491ab9016282813b9cf6539c3d808" + integrity sha512-b6R/aIsR4fXzrpY/Zud7LqHFi2Bt8Ov5VLOnruHQ10rk129e9d0KOCZlyRmPD6ENTcV7yze5rXvJ5WSNS8R1zw== dependencies: "@types/pako" "^1.0.7" "@types/stream-buffers" "^3.0.7"
25feb4a5af69Security: Reduce XSS attack surface for templated HTML (#275)
2 files changed · +119 −90
src/collection.ts+1 −1 modified@@ -191,7 +191,7 @@ export class Collection { if (await handleAuthNeeded(e, this.config)) { return notFound( request.request, - '<p style="margin: auto">Please wait, this page will reload after authentication...</p>', + "Please wait, this page will reload after authentication...", 401, ); }
src/notfound.ts+118 −89 modified@@ -73,58 +73,72 @@ function getHTMLNotFound( liveRedirectOnNotFound: boolean, msg?: string, ) { - return ` - <!doctype html> - <html> - <head> - <script> - window.requestURL = "${requestURL}"; - </script> - </head> - <body style="font-family: sans-serif"> - <h2>Archived Page Not Found</h2> - <p>${msg || "Sorry, this page was not found in this archive:"}</p> - <p><code id="url" style="word-break: break-all; font-size: larger"></code></p> - ${ - liveRedirectOnNotFound && request.mode === "navigate" - ? ` - <p>Redirecting to live page now... (If this URL is a file download, the download should have started).</p> - <script> - window.top.location.href = window.requestURL; - </script> - ` - : ` - ` - } - <p id="goback" style="display: none"><a href="#" onclick="window.history.back()">Go Back</a> to the previous page.</a></p> - - <p> - <a id="livelink" target="_blank" href="">Load the live page</a> in a new tab (or download the file, if this URL points to a file). - </p> - - <script> - document.querySelector("#url").innerText = window.requestURL; - document.querySelector("#livelink").href = window.requestURL; - let isTop = true; - try { - if (window.parent._WB_wombat_location) { - isTop = false; - } - } catch (e) { - - } - if (isTop) { - document.querySelector("#goback").style.display = ""; - - window.parent.postMessage({ - wb_type: "archive-not-found", - url: window.requestURL, - ts: "${requestTS}" - }, "*"); - } - </script> - </body> - </html> + return /* HTML */ ` + <!doctype html> + <html> + <head> + <script> + window.requestURL = ${JSON.stringify(requestURL)}; + </script> + </head> + <body style="font-family: sans-serif"> + <h2>Archived Page Not Found</h2> + <p id="msg"></p> + <p> + <code + id="url" + style="word-break: break-all; font-size: larger" + ></code> + </p> + ${liveRedirectOnNotFound && request.mode === "navigate" + ? /* HTML */ ` + <p> + Redirecting to live page now... (If this URL is a file download, + the download should have started). + </p> + <script> + window.top.location.href = window.requestURL; + </script> + ` + : ` + `} + <p id="goback" style="display: none"> + <a href="#" onclick="window.history.back()">Go Back</a> to the + previous page. + </p> + + <p> + <a id="livelink" target="_blank" href="">Load the live page</a> in a + new tab (or download the file, if this URL points to a file). + </p> + + <script> + document.querySelector("#url").innerText = window.requestURL; + document.querySelector("#msg").innerText = ${JSON.stringify( + msg || "Sorry, this page was not found in this archive:", + )}; + document.querySelector("#livelink").href = window.requestURL; + let isTop = true; + try { + if (window.parent._WB_wombat_location) { + isTop = false; + } + } catch (e) {} + if (isTop) { + document.querySelector("#goback").style.display = ""; + + window.parent.postMessage( + { + wb_type: "archive-not-found", + url: window.requestURL, + ts: ${JSON.stringify(requestTS)}, + }, + "*", + ); + } + </script> + </body> + </html> `; } @@ -135,8 +149,8 @@ function getScriptCSSNotFound( msg?: string, ) { return `\ -/* - ${msg ? msg : type + " Not Found"} +/* + ${msg || type + " Not Found"} URL: ${requestURL} TS: ${requestTS} */ @@ -152,40 +166,55 @@ export function getProxyNotFoundResponse(url: string, status: number) { } function getHTMLNotProxyError(requestURL: string, status: number) { - return ` - <!doctype html> - <html> - <head> - <script> - window.requestURL = "${requestURL}"; - </script> - </head> - <body style="font-family: sans-serif"> - <h2>Live page could not be loaded</h2> - <p>Sorry, this page was could not be loaded through the archiving proxy. Check the URL and try again.</p> - <p><code id="url" style="word-break: break-all; font-size: larger">Status Code: ${status}</code></p> - <p id="goback" style="display: none"><a href="#" onclick="window.history.back()">Go Back</a> to the previous page.</a></p> - - <script> - let isTop = true; - try { - if (window.parent._WB_wombat_location) { - isTop = false; - } - } catch (e) { - - } - if (isTop) { - document.querySelector("#goback").style.display = ""; - - window.parent.postMessage({ - wb_type: "live-proxy-url-error", - url: window.requestURL, - status: ${status}, - }, "*"); - } - </script> - </body> - </html> + return /* HTML */ ` + <!doctype html> + <html> + <head> + <script> + window.requestURL = ${JSON.stringify(requestURL)}; + </script> + </head> + <body style="font-family: sans-serif"> + <h2>Live page could not be loaded</h2> + <p> + Sorry, this page was could not be loaded through the archiving proxy. + Check the URL and try again. + </p> + <p> + <code + id="url" + style="word-break: break-all; font-size: larger" + ></code> + </p> + <p id="goback" style="display: none"> + <a href="#" onclick="window.history.back()">Go Back</a> to the + previous page. + </p> + + <script> + document.getElementById("url").innerText = ${JSON.stringify( + `Status Code: ${status}`, + )}; + let isTop = true; + try { + if (window.parent._WB_wombat_location) { + isTop = false; + } + } catch (e) {} + if (isTop) { + document.querySelector("#goback").style.display = ""; + + window.parent.postMessage( + { + wb_type: "live-proxy-url-error", + url: window.requestURL, + status: ${JSON.stringify(status)}, + }, + "*", + ); + } + </script> + </body> + </html> `; }
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
8- github.com/advisories/GHSA-w765-jm6w-4hhjghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-58765ghsaADVISORY
- github.com/webrecorder/archiveweb.page/pull/315ghsaWEB
- github.com/webrecorder/replayweb.page/pull/448ghsaWEB
- github.com/webrecorder/replayweb.page/releases/tag/v2.3.17ghsaWEB
- github.com/webrecorder/wabac.js/commit/25feb4a5af69a6b65694426eae67b890be438c4cnvdWEB
- github.com/webrecorder/wabac.js/releases/tag/v2.23.11nvdWEB
- github.com/webrecorder/wabac.js/security/advisories/GHSA-w765-jm6w-4hhjnvdWEB
News mentions
0No linked articles in our index yet.