MCPcopy
hub / github.com/Doorman11991/smallcode / safeResolvePath

Function safeResolvePath

src/security/sanitize.js:125–163  ·  view source on GitHub ↗

* Resolve a user-supplied path safely against `cwd`. * Returns { ok: true, fullPath, displayPath } on success, * or { ok: false, reason } on rejection. * * Rules: * - Resolved absolute path must be inside `cwd` (unless allowOutside=true) * - Path must not match a sensitive pattern * - P

(reqPath, cwd, options = {})

Source from the content-addressed store, hash-verified

123 * - Path must not contain NUL bytes
124 */
125function safeResolvePath(reqPath, cwd, options = {}) {
126 if (typeof reqPath !== 'string' || reqPath.length === 0) {
127 return { ok: false, reason: 'path must be a non-empty string' };
128 }
129 if (reqPath.indexOf('\u0000') !== -1) {
130 return { ok: false, reason: 'path contains NUL byte' };
131 }
132 // Expand ~ for the user's home directory only when explicitly allowed
133 let candidate = reqPath;
134 if (candidate === '~' || candidate.startsWith('~/') || candidate.startsWith('~\\')) {
135 if (!options.allowHome) {
136 return { ok: false, reason: 'home-relative paths are blocked' };
137 }
138 candidate = path.join(os.homedir(), candidate.slice(2));
139 }
140 // Strip leading ./ for normalization
141 candidate = candidate.replace(/^\.[/\\]/, '');
142 const fullPath = path.resolve(cwd, candidate);
143
144 // Sensitive path check
145 for (const re of SENSITIVE_PATH_RE) {
146 if (re.test(fullPath)) {
147 return { ok: false, reason: 'path is sensitive (auth credentials)' };
148 }
149 }
150
151 // Containment check (default ON — opt out for tools that legitimately
152 // need to read outside the project, like reading user's global config)
153 if (!options.allowOutside) {
154 const normCwd = path.resolve(cwd);
155 const rel = path.relative(normCwd, fullPath);
156 if (rel.startsWith('..') || path.isAbsolute(rel)) {
157 return { ok: false, reason: 'path resolves outside project root' };
158 }
159 }
160
161 const displayPath = path.relative(cwd, fullPath) || path.basename(fullPath);
162 return { ok: true, fullPath, displayPath };
163}
164
165// ─── Shell escaping ─────────────────────────────────────────────────────────
166

Callers 5

extractImagesFunction · 0.85
resolveReferencesFunction · 0.85
_executeToolMethod · 0.85
handleMCPToolCallFunction · 0.85
executeToolFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected