diff --git a/app/protocol_filter.ts b/app/protocol_filter.ts index ec9ad3c9b..f17c84290 100644 --- a/app/protocol_filter.ts +++ b/app/protocol_filter.ts @@ -9,6 +9,15 @@ import type { import { isAbsolute, normalize } from 'path'; import { existsSync, realpathSync } from 'fs'; +import { + getAvatarsPath, + getBadgesPath, + getDraftPath, + getPath, + getStickersPath, + getTempPath, + getUpdateCachePath, +} from '../ts/util/attachments'; type CallbackType = (response: string | ProtocolResponse) => void; @@ -51,6 +60,17 @@ function _createFileHandler({ installPath: string; isWindows: boolean; }) { + const allowedRoots = [ + userDataPath, + installPath, + getAvatarsPath(userDataPath), + getBadgesPath(userDataPath), + getDraftPath(userDataPath), + getPath(userDataPath), + getStickersPath(userDataPath), + getTempPath(userDataPath), + getUpdateCachePath(userDataPath), + ]; return (request: ProtocolRequest, callback: CallbackType): void => { let targetPath; @@ -95,24 +115,17 @@ function _createFileHandler({ return; } - if ( - !properCasing.startsWith( - isWindows ? userDataPath.toLowerCase() : userDataPath - ) && - !properCasing.startsWith( - isWindows ? installPath.toLowerCase() : installPath - ) - ) { - console.log( - `Warning: denying request to path '${realPath}' (userDataPath: '${userDataPath}', installPath: '${installPath}')` - ); - callback({ error: -10 }); - return; + for (const root of allowedRoots) { + if (properCasing.startsWith(isWindows ? root.toLowerCase() : root)) { + callback({ path: realPath }); + return; + } } - callback({ - path: realPath, - }); + console.log( + `Warning: denying request to path '${realPath}' (allowedRoots: '${allowedRoots}')` + ); + callback({ error: -10 }); }; } diff --git a/ts/util/attachments.ts b/ts/util/attachments.ts index 9e3e1fd1f..293bff482 100644 --- a/ts/util/attachments.ts +++ b/ts/util/attachments.ts @@ -21,7 +21,13 @@ const createPathGetter = if (!isString(userDataPath)) { throw new TypeError("'userDataPath' must be a string"); } - return join(userDataPath, subpath); + + const maybeSymlink = join(userDataPath, subpath); + if (fse.pathExistsSync(maybeSymlink)) { + return fse.realpathSync(maybeSymlink); + } + + return maybeSymlink; }; export const getAvatarsPath = createPathGetter(AVATAR_PATH);