Description
SecureFS (lib/run/secure-fs.js) is meant to restrict all file access performed on behalf of a collection run to --working-dir, with an additional --no-insecure-file-read flag to disallow escaping it entirely. It does this by overriding specific fs methods to route through resolvePath/resolvePathSync, which reject any resolved path outside the working directory:
https://github.com/postmanlabs/newman/blob/develop/lib/run/secure-fs.js#L143-L185
Only stat and createReadStream are overridden this way. Every other method — including readFile — is copied straight from the real fs module with no path check:
// Attach all functions in fs to postman-fs
Object.getOwnPropertyNames(fs).map((prop) => {
if (prop === DEPRECATED_SYNC_WRITE_STREAM || prop === EXPERIMENTAL_PROMISE || typeof fs[prop] !== FUNCTION) {
return;
}
SecureFS.prototype[prop] = fs[prop]; // <-- readFile ends up as raw fs.readFile
});
readFile is exactly the method postman-runtime calls in practice — for both client certificate files and CA certs:
https://github.com/postmanlabs/postman-runtime/blob/develop/lib/runner/request-helpers-presend.js#L443
https://github.com/postmanlabs/postman-runtime/blob/develop/lib/requester/requester-pool.js#L49
Both call fileResolver.readFile(path, callback) directly — never stat or createReadStream. So the one file-reading path that's actually exercised at runtime is completely unsandboxed, regardless of --working-dir or --no-insecure-file-read.
Impact
A collection (or environment/CLI options) that supplies an absolute certificate path — e.g. via sslClientCert/sslClientKey/sslClientCertList, or a collection-scripted variable feeding one of those — can read arbitrary files on the filesystem the newman process can access, even when the operator has explicitly locked the run down with --working-dir <dir> --no-insecure-file-read. This defeats the entire purpose of that flag combination for any newman invocation that runs an untrusted/third-party collection (e.g. in CI).
Repro
const SecureFS = require('./lib/run/secure-fs');
const fs = new SecureFS('/tmp/some-safe-working-dir', /* insecureFileRead */ false);
fs.resolvePath('/etc/passwd', (err) => {
console.log(err.message); // PPERM: insecure file access outside working directory (correctly blocked)
});
fs.readFile('/etc/passwd', (err, data) => {
console.log(err); // null
console.log(data.length); // file contents read straight off disk, sandbox bypassed entirely
});
Fix
Override readFile the same way stat already is, routing through resolvePath:
SecureFS.prototype.readFile = function (path, options, callback) {
if (!callback && typeof options === 'function') {
callback = options;
options = undefined;
}
this.resolvePath(path, (err, resolvedPath) => {
if (err) {
return callback(err);
}
return this._fs.readFile(resolvedPath, options, callback);
});
};
PR with fix + regression tests (which fail against current develop and pass with the fix): #3370
Note: I'm aware SECURITY.md asks that vulnerabilities be reported privately to security@postman.com — filing here instead since the fix is attached and the affected surface (explicit certificate paths, not arbitrary collection-supplied file paths) is narrower than a full unauthenticated RCE-style bug. Happy to follow up privately if preferred.
Description
SecureFS(lib/run/secure-fs.js) is meant to restrict all file access performed on behalf of a collection run to--working-dir, with an additional--no-insecure-file-readflag to disallow escaping it entirely. It does this by overriding specificfsmethods to route throughresolvePath/resolvePathSync, which reject any resolved path outside the working directory:https://github.com/postmanlabs/newman/blob/develop/lib/run/secure-fs.js#L143-L185
Only
statandcreateReadStreamare overridden this way. Every other method — includingreadFile— is copied straight from the realfsmodule with no path check:readFileis exactly the methodpostman-runtimecalls in practice — for both client certificate files and CA certs:https://github.com/postmanlabs/postman-runtime/blob/develop/lib/runner/request-helpers-presend.js#L443
https://github.com/postmanlabs/postman-runtime/blob/develop/lib/requester/requester-pool.js#L49
Both call
fileResolver.readFile(path, callback)directly — neverstatorcreateReadStream. So the one file-reading path that's actually exercised at runtime is completely unsandboxed, regardless of--working-diror--no-insecure-file-read.Impact
A collection (or environment/CLI options) that supplies an absolute certificate path — e.g. via
sslClientCert/sslClientKey/sslClientCertList, or a collection-scripted variable feeding one of those — can read arbitrary files on the filesystem the newman process can access, even when the operator has explicitly locked the run down with--working-dir <dir> --no-insecure-file-read. This defeats the entire purpose of that flag combination for any newman invocation that runs an untrusted/third-party collection (e.g. in CI).Repro
Fix
Override
readFilethe same waystatalready is, routing throughresolvePath:PR with fix + regression tests (which fail against current
developand pass with the fix): #3370Note: I'm aware
SECURITY.mdasks that vulnerabilities be reported privately to security@postman.com — filing here instead since the fix is attached and the affected surface (explicit certificate paths, not arbitrary collection-supplied file paths) is narrower than a full unauthenticated RCE-style bug. Happy to follow up privately if preferred.