auth0-deploy-cli 8.39.0 → 9.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [9.0.0-beta.1] - 2026-07-02
11
+
12
+ ### Security
13
+
14
+ - Prevent path traversal attacks in config file handlers for directory and YAML contexts. [#1418]
15
+
10
16
  ## [8.39.0] - 2026-06-30
11
17
 
12
18
  ### Added
@@ -1854,7 +1860,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1854
1860
  [#1409]: https://github.com/auth0/auth0-deploy-cli/issues/1409
1855
1861
  [#1411]: https://github.com/auth0/auth0-deploy-cli/issues/1411
1856
1862
  [#1412]: https://github.com/auth0/auth0-deploy-cli/issues/1412
1857
- [Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v8.39.0...HEAD
1863
+ [#1418]: https://github.com/auth0/auth0-deploy-cli/issues/1418
1864
+ [Unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v9.0.0-beta.1...HEAD
1865
+ [9.0.0-beta.1]: https://github.com/auth0/auth0-deploy-cli/compare/v8.39.0...v9.0.0-beta.1
1858
1866
  [8.39.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.38.0...v8.39.0
1859
1867
  [8.38.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.37.0...v8.38.0
1860
1868
  [8.37.0]: https://github.com/auth0/auth0-deploy-cli/compare/v8.36.0...v8.37.0
@@ -25,15 +25,7 @@ function parse(context) {
25
25
  // The `module.code` can be a file path. It needs to be loaded.
26
26
  // It can be a relative path, so we need to handle both cases.
27
27
  const unixPath = module.code.replace(/[\\/]+/g, '/').replace(/^([a-zA-Z]+:|\.\/)/, '');
28
- if (fs_extra_1.default.existsSync(unixPath)) {
29
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
30
- `Please update your configuration to use paths relative to the config directory. ` +
31
- `Current absolute path used: ["${module.code}"]`);
32
- module.code = context.loadFile(unixPath, moduleFolder);
33
- }
34
- else {
35
- module.code = context.loadFile(path_1.default.join(context.filePath, module.code), moduleFolder);
36
- }
28
+ module.code = context.loadFile(unixPath, moduleFolder);
37
29
  }
38
30
  return module;
39
31
  });
@@ -26,17 +26,7 @@ function parse(context) {
26
26
  if (action.code) {
27
27
  // Convert `action.code` path to Unix-style path by replacing backslashes and multiple slashes with a single forward slash, and remove leading drive letters or './'.
28
28
  const unixPath = action.code.replace(/[\\/]+/g, '/').replace(/^([a-zA-Z]+:|\.\/)/, '');
29
- if (fs_extra_1.default.existsSync(unixPath)) {
30
- // If the Unix-style path exists, load the file from that path
31
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
32
- `Please update your configuration to use paths relative to the config directory. ` +
33
- `Current absolute path used: ["${action.code}"]`);
34
- action.code = context.loadFile(unixPath, actionFolder);
35
- }
36
- else {
37
- // Otherwise, load the file from the context's file path
38
- action.code = context.loadFile(path_1.default.join(context.filePath, action.code), actionFolder);
39
- }
29
+ action.code = context.loadFile(unixPath, actionFolder);
40
30
  }
41
31
  return action;
42
32
  });
@@ -43,9 +43,7 @@ function getDatabase(folder, configRoot, mappingOpts) {
43
43
  const resolvedBase = path_1.default.resolve(configRoot);
44
44
  const toLoad = path_1.default.resolve(folder, script);
45
45
  if (!toLoad.startsWith(resolvedBase + path_1.default.sep)) {
46
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
47
- `Please update your configuration to use paths relative to the config directory. ` +
48
- `Current absolute path used: ["${script}"]`);
46
+ throw new Error(`File reference "${script}" in database custom script "${name}" must be relative to the config directory. Absolute paths and paths outside the config root are not supported.`);
49
47
  }
50
48
  database.options.customScripts[name] = (0, tools_1.loadFileAndReplaceKeywords)(toLoad, mappingOpts);
51
49
  }
@@ -68,14 +68,12 @@ class DirectoryContext {
68
68
  };
69
69
  }
70
70
  loadFile(f, folder) {
71
- const basePath = path.join(this.filePath, folder);
72
- let toLoad = path.join(basePath, f);
73
- if (!(0, utils_1.isFile)(toLoad)) {
74
- // try load not relative to yaml file
75
- toLoad = f;
76
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
77
- `Please update your configuration to use paths relative to the config directory. ` +
78
- `Current absolute path used: ["${f}"]`);
71
+ const resolvedBase = path.resolve(this.filePath);
72
+ const inSubfolder = path.resolve(this.filePath, folder, f);
73
+ const inRoot = path.resolve(this.filePath, f);
74
+ const toLoad = (0, utils_1.isFile)(inSubfolder) ? inSubfolder : inRoot;
75
+ if (!toLoad.startsWith(resolvedBase + path.sep)) {
76
+ throw new Error(`File reference "${f}" must be relative to the config directory. Absolute paths and paths outside the config root are not supported.`);
79
77
  }
80
78
  return (0, tools_1.loadFileAndReplaceKeywords)(toLoad, {
81
79
  mappings: this.mappings,
@@ -43,15 +43,12 @@ class YAMLContext {
43
43
  })();
44
44
  }
45
45
  loadFile(f) {
46
- let toLoad = path_1.default.join(this.basePath, f);
47
- if (!(0, utils_1.isFile)(toLoad)) {
48
- // try load not relative to yaml file
49
- toLoad = f;
50
- logger_1.default.warn(`Support for absolute paths and paths outside the config root will be deprecated in a future version to improve the security of the tool. ` +
51
- `Please update your configuration to use paths relative to the config directory. ` +
52
- `Current absolute path used: ["${f}"]`);
46
+ const resolvedBase = path_1.default.resolve(this.basePath);
47
+ const toLoad = path_1.default.resolve(this.basePath, f);
48
+ if (!toLoad.startsWith(resolvedBase + path_1.default.sep)) {
49
+ throw new Error(`File reference "${f}" must be relative to the config directory. Absolute paths and paths outside the config root are not supported.`);
53
50
  }
54
- return (0, tools_1.loadFileAndReplaceKeywords)(path_1.default.resolve(toLoad), {
51
+ return (0, tools_1.loadFileAndReplaceKeywords)(toLoad, {
55
52
  mappings: this.mappings,
56
53
  disableKeywordReplacement: this.disableKeywordReplacement,
57
54
  });
@@ -11,6 +11,10 @@ const promise_pool_executor_1 = require("promise-pool-executor");
11
11
  const client_1 = __importDefault(require("./client"));
12
12
  const schema_1 = __importDefault(require("./schema"));
13
13
  const handlers_1 = __importDefault(require("./handlers"));
14
+ // Cache the compiled AJV validator to avoid recompiling the schema on every validate() call.
15
+ // Schema compilation is expensive (~5s) due to the complexity of the combined resource schema.
16
+ const ajv = new ajv_1.default({ useDefaults: true, nullable: true });
17
+ const validateSchema = ajv.compile(schema_1.default);
14
18
  const calculateDryRunChanges_1 = require("../calculateDryRunChanges");
15
19
  const utils_1 = require("../../utils");
16
20
  const utils_2 = require("../utils");
@@ -105,13 +109,12 @@ class Auth0 {
105
109
  }
106
110
  }
107
111
  async validate() {
108
- const ajv = new ajv_1.default({ useDefaults: true, nullable: true });
109
112
  const nonNullAssets = Object.keys(this.assets)
110
113
  .filter((k) => this.assets[k] != null)
111
114
  .reduce((a, k) => ({ ...a, [k]: this.assets[k] }), {});
112
- const valid = ajv.validate(schema_1.default, nonNullAssets);
115
+ const valid = validateSchema(nonNullAssets);
113
116
  if (!valid) {
114
- throw new Error(`Schema validation failed loading ${JSON.stringify(ajv.errors, null, 4)}`);
117
+ throw new Error(`Schema validation failed loading ${JSON.stringify(validateSchema.errors, null, 4)}`);
115
118
  }
116
119
  await this.runStage('validate');
117
120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auth0-deploy-cli",
3
- "version": "8.39.0",
3
+ "version": "9.0.0-beta.1",
4
4
  "description": "A command line tool for deploying updates to your Auth0 tenant",
5
5
  "main": "lib/index.js",
6
6
  "bin": {