MCPcopy
hub / github.com/jgraph/drawio-desktop / assertWritablePath

Function assertWritablePath

src/main/electron.js:2940–3014  ·  view source on GitHub ↗
(p)

Source from the content-addressed store, hash-verified

2938// (defeating symlink traversal) and accepts only paths in blessedPaths or
2939// their draft/backup siblings.
2940async function assertWritablePath(p)
2941{
2942 if (typeof p !== 'string' || !p || p.includes('\0'))
2943 {
2944 throw new Error('path not authorised');
2945 }
2946
2947 const resolved = path.resolve(p);
2948 let realpath;
2949
2950 try
2951 {
2952 realpath = await fsProm.realpath(resolved);
2953 }
2954 catch (e)
2955 {
2956 // File doesn't exist yet (e.g. Save As to a new file). Canonicalise
2957 // the parent directory so symlinks in the directory chain are still
2958 // resolved.
2959 try
2960 {
2961 const parentReal = await fsProm.realpath(path.dirname(resolved));
2962 realpath = path.join(parentReal, path.basename(resolved));
2963 }
2964 catch (e2)
2965 {
2966 // Neither the file nor its parent could be realpath-canonicalised.
2967 // This happens on filesystems whose driver doesn't support the
2968 // underlying call (e.g. WinFSP "local" / Cryptomator, some FUSE
2969 // mounts), not just on missing paths. realpath is a defence-in-depth
2970 // measure against symlink traversal; when it's simply unavailable we
2971 // must not deny an otherwise-blessed write, so fall back to the
2972 // lexically-resolved path. blessedPaths is still consulted below, so
2973 // only paths the user authorised through trusted UI are accepted.
2974 realpath = resolved;
2975 }
2976 }
2977
2978 if (realpath.startsWith(appBaseDir))
2979 {
2980 throw new Error('path not authorised');
2981 }
2982
2983 // Block writes anywhere inside userData (settings store, plugins, Local
2984 // Storage). installPlugin has its own write-into-userData flow and is
2985 // out of scope here; it does not go through assertWritablePath.
2986 let userDataDir;
2987
2988 try
2989 {
2990 userDataDir = path.resolve(app.getPath('userData'));
2991 }
2992 catch (e)
2993 {
2994 userDataDir = null;
2995 }
2996
2997 if (userDataDir && (realpath === userDataDir ||

Callers 4

saveDraftFunction · 0.85
saveFileFunction · 0.85
writeFileFunction · 0.85
deleteFileFunction · 0.85

Calls 1

isDraftOrBkpOfBlessedFunction · 0.85

Tested by

no test coverage detected