[CSA-28] Use path normalization in API requests (#4580)

* Use path normalization in API requests

* Remove CLI webpack config change that's unneeded

* Add additional tests
This commit is contained in:
Matt Bishop 2023-02-03 14:24:49 -05:00 committed by GitHub
parent ff143760d4
commit 6df37dd715
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 6 deletions

View File

@ -209,7 +209,7 @@ const mainConfig = {
util: require.resolve("util/"),
url: require.resolve("url/"),
fs: false,
path: false,
path: require.resolve("path-browserify"),
},
},
output: {

View File

@ -355,9 +355,9 @@ const webpackConfig = {
util: require.resolve("util/"),
assert: false,
url: false,
path: false,
fs: false,
process: false,
path: require.resolve("path-browserify"),
},
},
output: {

View File

@ -326,4 +326,24 @@ describe("Utils Service", () => {
);
});
});
describe("normalizePath", () => {
it("removes a single traversal", () => {
expect(Utils.normalizePath("../test")).toBe("test");
});
it("removes deep traversals", () => {
expect(Utils.normalizePath("../../test")).toBe("test");
});
it("removes intermediate traversals", () => {
expect(Utils.normalizePath("test/../test")).toBe("test");
});
it("removes multiple encoded traversals", () => {
expect(
Utils.normalizePath("api/sends/access/..%2f..%2f..%2fapi%2fsends%2faccess%2fsendkey")
).toBe("api/sends/access/sendkey");
});
});
});

View File

@ -1,4 +1,6 @@
/* eslint-disable no-useless-escape */
import * as path from "path";
import { getHostname, parse } from "tldts";
import { Merge } from "type-fest";
@ -498,6 +500,15 @@ export class Utils {
);
}
/**
* Normalizes a path for defense against attacks like traversals
* @param denormalizedPath
* @returns
*/
static normalizePath(denormalizedPath: string): string {
return path.normalize(decodeURIComponent(denormalizedPath)).replace(/^(\.\.(\/|\\|$))+/, "");
}
private static isMobile(win: Window) {
let mobile = false;
((a) => {

View File

@ -1962,11 +1962,8 @@ export class ApiService implements ApiServiceAbstraction {
): Promise<any> {
apiUrl = Utils.isNullOrWhitespace(apiUrl) ? this.environmentService.getApiUrl() : apiUrl;
const requestUrl = apiUrl + path;
// Prevent directory traversal from malicious paths
if (new URL(requestUrl).href !== requestUrl) {
return Promise.reject("Invalid request url path.");
}
const requestUrl = apiUrl + Utils.normalizePath(path);
const headers = new Headers({
"Device-Type": this.deviceType,