mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Prevent illegal file paths from being generated
This commit is contained in:
parent
3fbdc69f3f
commit
fdee4b334f
@ -155,16 +155,31 @@ export function toCanonicalUriPath(path: string): string {
|
|||||||
encodeURIComponent(decodeURIComponent(part)));
|
encodeURIComponent(decodeURIComponent(part)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Characters not allowed in a Windows file path
|
||||||
|
const forbiddenSymbols = {
|
||||||
|
'<': '%3C',
|
||||||
|
'>': '%3E',
|
||||||
|
':': '%3A',
|
||||||
|
'"': '%22',
|
||||||
|
'|': '%7C',
|
||||||
|
'?': '%3F',
|
||||||
|
// `*` does not get converted by `encodeUriComponent`
|
||||||
|
'*': '%2A',
|
||||||
|
} as const;
|
||||||
|
const forbiddenRegex = new RegExp(`[${Object.keys(forbiddenSymbols).join('')}]`, 'ug');
|
||||||
/**
|
/**
|
||||||
* This function is used when converting a URI to a file path. Decodes all components of a URI path,
|
* This function is used when converting a URI to a file path. Decodes all components of a URI path,
|
||||||
* with the exception of encoded slash characters, as this would lead to unexpected file locations
|
* with the exception of encoded slash characters, as this would lead to unexpected file locations
|
||||||
* being targeted (resulting in erroneous behaviour of the file based backend).
|
* being targeted (resulting in erroneous behaviour of the file based backend).
|
||||||
|
* Characters that would result in an illegal file path remain percent encoded.
|
||||||
*
|
*
|
||||||
* @param path - The path to decode the URI path components of.
|
* @param path - The path to decode the URI path components of.
|
||||||
* @returns A decoded copy of the provided URI path (ignoring encoded slash characters).
|
* @returns A decoded copy of the provided URI path (ignoring encoded slash characters).
|
||||||
*/
|
*/
|
||||||
export function decodeUriPathComponents(path: string): string {
|
export function decodeUriPathComponents(path: string): string {
|
||||||
return transformPathComponents(path, decodeURIComponent);
|
return transformPathComponents(path, (part): string => decodeURIComponent(part)
|
||||||
|
// The characters replaced below result in illegal Windows file paths so need to be encoded
|
||||||
|
.replace(forbiddenRegex, (val): string => forbiddenSymbols[val as keyof typeof forbiddenSymbols]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +96,7 @@ describe('PathUtil', (): void => {
|
|||||||
|
|
||||||
describe('#toCanonicalUriPath', (): void => {
|
describe('#toCanonicalUriPath', (): void => {
|
||||||
it('encodes only the necessary parts.', (): void => {
|
it('encodes only the necessary parts.', (): void => {
|
||||||
expect(toCanonicalUriPath('/a%20path&/name')).toBe('/a%20path%26/name');
|
expect(toCanonicalUriPath('/a%20path&*/name')).toBe('/a%20path%26*/name');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('leaves the query string untouched.', (): void => {
|
it('leaves the query string untouched.', (): void => {
|
||||||
@ -138,6 +138,11 @@ describe('PathUtil', (): void => {
|
|||||||
expect(decodeUriPathComponents('/a%25252Fb')).toBe('/a%25252Fb');
|
expect(decodeUriPathComponents('/a%25252Fb')).toBe('/a%25252Fb');
|
||||||
expect(decodeUriPathComponents('/a%2525252Fb')).toBe('/a%2525252Fb');
|
expect(decodeUriPathComponents('/a%2525252Fb')).toBe('/a%2525252Fb');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('ensures illegal path characters are encoded.', async(): Promise<void> => {
|
||||||
|
expect(decodeUriPathComponents('/a<path%3F%3E/*:name?abc=def&xyz'))
|
||||||
|
.toBe('/a%3Cpath%3F%3E/%2A%3Aname?abc=def&xyz');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#encodeUriPathComponents', (): void => {
|
describe('#encodeUriPathComponents', (): void => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user