@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
104 lines • 4.85 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import path from 'node:path';
import fs from 'node:fs';
import { SoloError } from '../../core/errors/solo-error.js';
export class PathEx {
/**
* This method requires that the path to a directory or file is real and exists.
*
* This method is not safe. Use this instead of path.join(...) directly when you cannot confine a user to a base
* directory. It is best to avoid using user input directly for constructing paths. If you must use user input, it is
* recommended to use `PathEx.safeJoinWithBaseDirConfinement(...)` to join paths.
*
* For more information see: https://owasp.org/www-community/attacks/Path_Traversal
* @param paths - The paths to join
*/
static joinWithRealPath(...paths) {
// nosemgrep
return fs.realpathSync(path.join(...paths));
}
/**
* Securely joins paths while preventing path traversal attacks. Requires that the base directory is real and exists.
* This method requires that the path to a directory or file is real and exists.
*
* @param baseDirectory - The base directory to enforce
* @param paths - The paths to join
* @throws Error if the resolved path is outside the base directory.
* @returns The safely joined path.
*/
static safeJoinWithBaseDirConfinement(baseDirectory, ...paths) {
// nosemgrep: javascript_pathtraversal_rule-non-literal-fs-filename
const resolvedBase = fs.realpathSync(baseDirectory); // Ensure baseDirectory is absolute
// nosemgrep
const resolvedPath = fs.realpathSync(path.resolve(resolvedBase, ...paths)); // Resolve the user path
if (!resolvedPath.startsWith(resolvedBase + path.sep)) {
throw new SoloError(`Path traversal detected: ${resolvedPath} is outside ${resolvedBase}`);
}
return resolvedPath;
}
/**
* This method requires that the path to a directory or file is real and exists.
*
* This method is not safe unless a literal is used as the parameter.
*/
static realPathSync(path) {
// nosemgrep: javascript_pathtraversal_rule-non-literal-fs-filename
return fs.realpathSync(path);
}
/**
* Joins the given paths. This is a wrapper around path.join. It is recommended to only use this when you are dealing
* with part of a path that is not a complete path reference on its own.
*
* This method is not safe unless literals are used as parameters. Use this instead of path.join(...) directly when
* you cannot confine a user to a base directory. It is best to avoid using user input directly for constructing paths.
* If you must use user input, it is recommended to use `PathEx.safeJoinWithBaseDirConfinement(...)` to join paths.
*
* For more information see: https://owasp.org/www-community/attacks/Path_Traversal
* @param paths
*/
static join(...paths) {
// nosemgrep: path-join-resolve-traversal
return path.normalize(path.join(...paths));
}
/**
* Resolves the given paths to an absolute path. This is a wrapper around path.resolve. It is recommended to only use this when you are dealing
* with part of a path that is not a complete path reference on its own.
*
* This method is not safe unless literals are used as parameters. Use this instead of path.resolve(...) directly when you cannot confine a user to a base
* directory.
*
* For more information see: https://owasp.org/www-community/attacks/Path_Traversal
* @param paths
*/
static resolve(...paths) {
// nosemgrep: path-join-resolve-traversal
return path.resolve(...paths);
}
/**
* Solve the relative path from {from} to {to} based on the current working directory. This is a wrapper around path.relative. It is recommended to only use this when you are dealing with part of a path that is not a complete path reference on its own.
*
* This method is not safe unless literals are used as parameters. Use this instead of path.relative(...) directly when you cannot confine a user to a base
* directory.
*
* For more information see: https://owasp.org/www-community/attacks/Path_Traversal
* @param from
* @param to
* @returns The relative path from `from` to `to`.
*/
static relative(from, to) {
return path.relative(from, to);
}
/**
* Return the last portion of a path. This is a wrapper around path.basename.
*/
static basename(pathValue, suffix) {
return path.basename(pathValue, suffix);
}
/**
* Platform-specific path delimiter for PATH-like environment variables.
*/
static get delimiter() {
return path.delimiter;
}
}
//# sourceMappingURL=path-ex.js.map