Skip to content

Commit c510070

Browse files
authored
fix(security): userinfo bypass vulnerability in HttpUriPlugin allowedUris
1 parent 4b0501c commit c510070

5 files changed

Lines changed: 46 additions & 3 deletions

File tree

.changeset/green-turtles-change.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"webpack": patch
3+
---
4+
5+
Fixed a user information bypass vulnerability in the HttpUriPlugin plugin.

lib/schemes/HttpUriPlugin.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -953,12 +953,28 @@ class HttpUriPlugin {
953953
* @returns {boolean} true when allowed, otherwise false
954954
*/
955955
const isAllowed = (uri) => {
956+
let parsedUri;
957+
try {
958+
// Parse the URI to prevent userinfo bypass attacks
959+
// (e.g., http://allowed@malicious/path where @malicious is the actual host)
960+
parsedUri = new URL(uri);
961+
} catch (_err) {
962+
return false;
963+
}
956964
for (const allowed of allowedUris) {
957965
if (typeof allowed === "string") {
958-
if (uri.startsWith(allowed)) return true;
966+
let parsedAllowed;
967+
try {
968+
parsedAllowed = new URL(allowed);
969+
} catch (_err) {
970+
continue;
971+
}
972+
if (parsedUri.href.startsWith(parsedAllowed.href)) {
973+
return true;
974+
}
959975
} else if (typeof allowed === "function") {
960-
if (allowed(uri)) return true;
961-
} else if (allowed.test(uri)) {
976+
if (allowed(parsedUri.href)) return true;
977+
} else if (allowed.test(parsedUri.href)) {
962978
return true;
963979
}
964980
}

test/configCases/asset-modules/http-url/errors.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,8 @@ module.exports = [
1616
],
1717
[
1818
/http:\/\/localhost:9990\/redirect has an outdated lockfile entry, but lockfile is frozen/
19+
],
20+
[
21+
/Module not found: Error: http:\/\/localhost:9990@127\.0\.0\.1:9100\/secret\.js doesn't match the allowedUris policy/
1922
]
2023
];
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
"use strict";
2+
3+
it("should reject URLs with userinfo that bypass allowedUris", () => {
4+
expect(() => require("http://localhost:9990@127.0.0.1:9100/secret.js")).toThrow();
5+
});
6+

test/configCases/asset-modules/http-url/webpack.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,18 @@ module.exports = [
102102
frozen: true
103103
})
104104
]
105+
},
106+
{
107+
name: "security-userinfo-bypass",
108+
...base,
109+
entry: "./index.security.js",
110+
plugins: [
111+
serverPlugin,
112+
new HttpUriPlugin({
113+
allowedUris,
114+
upgrade: false,
115+
frozen: false
116+
})
117+
]
105118
}
106119
];

0 commit comments

Comments
 (0)