Skip to content

Commit

Permalink
create path validation for file paths
Browse files Browse the repository at this point in the history
  • Loading branch information
youngbryanyu committed Jan 18, 2024
1 parent d608e67 commit 5811062
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## 1.1.0 - 1/17/24
Create input validation check for paths, where the input must not be outside the root dir of the project.

## 1.0.8 - 1/17/24
Fix package.json

Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "simple-app-config",
"version": "1.0.8",
"version": "1.1.0",
"description": "A simple configuration manager for different environments",
"license": "MIT",
"repository": {
Expand Down Expand Up @@ -54,6 +54,7 @@
],
"author": "Young Yu",
"dependencies": {
"app-root-path": "^3.1.0",
"dotenv": "^16.3.1"
},
"devDependencies": {
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions src/simple-app-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { UnsupportedTypeError } from './errors/unsupportedTypeError';
import { UndefinedConfigValueError } from './errors/undefinedConfigValueError';
import EnvParser from './utils/envParser';
import StringUtil from './utils/stringUtil';
import appRootPath from 'app-root-path';

/**
* Customization options when running {@link Config.configure}
Expand Down Expand Up @@ -342,14 +343,32 @@ export class Config {

/**
* Checks if a .env file is valid. A .env file is valid if all the below are true:
* - It is a safe path, meaning its prefix is the root of the project
* - It exists
* @param path The path of the .env file to check.
* @returns A boolean indicating whether the .env file is valid.
*/
private static isValidEnvFile(path: string): boolean {
/* Return false if path is safe */
if (!Config.isSafePath(path)) {
return false;
}

/* Return whether the path exists */
return fs.existsSync(path);
}

/**
* Returns whether the path is safe. A path is safe if:
* - Its prefix begins with the absolute path to the root of the project
* @param path
*/
private static isSafePath(filePath: string): boolean {
const root = appRootPath.path;
const resolvedPath = path.resolve(filePath);
return resolvedPath.startsWith(root);
}

/**
* Resets and values set previously by dotenv to undefined from the previous call of dotenv.config
* @param Path to the .env file.
Expand Down Expand Up @@ -418,13 +437,19 @@ export class Config {

/**
* Checks if a config file is valid. A config file is valid if all the below are true:
* - It is a safe path, meaning its prefix is the root of the project
* - It exists
* - It isn't a directory
* - It matches a valid file extension
* @param filePath The path of the config file to check.
* @returns A boolean indicating whether the config file is valid.
*/
private static isValidConfigFile(filePath: string): boolean {
/* Check if path is safe */
if (!Config.isSafePath(filePath)) {
return false;
}

/* Return false if the path doesn't exist */
if (!fs.existsSync(filePath)) {
return false;
Expand Down
23 changes: 23 additions & 0 deletions tests/simple-app-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,29 @@ describe('simple-app-config Tests', () => {
expect(numberVal).toBe(3);
});

/* Test unsafe .env path */
it('should not load the .env file if the path is unsafe', () => {
/* Set up */
process.env[EnvArgs.ConfigPath] = `${__dirname}/config/default.json`;
process.env[EnvArgs.EnvPath] = `../../../..`;
Config.configure({ force: true });

/* Compare against expected */
const env = Config.get('ENV');
expect(env).toBe('default');
});

/* Test unsafe config path */
it('should not load the .env file if the path is unsafe', () => {
/* Set up */
process.env[EnvArgs.ConfigPath] = `../../../..`;
process.env[EnvArgs.EnvPath] = `${__dirname}/config/.env.testing`;
Config.configure({ force: true });

/* Compare against expected */
expect(Config.get('ENV')).toBe('default');
});

/* Test configuring twice without forcing */
it('should do nothing if configure is called a second time.', () => {
/* Set up spies */
Expand Down

0 comments on commit 5811062

Please sign in to comment.