Skip to content

fix: prevent path traversal in config file handlers#1388

Draft
ankita10119 wants to merge 9 commits into
masterfrom
DXCDT-1616
Draft

fix: prevent path traversal in config file handlers#1388
ankita10119 wants to merge 9 commits into
masterfrom
DXCDT-1616

Conversation

@ankita10119
Copy link
Copy Markdown
Contributor

🔧 Changes

Fixes a path traversal vulnerability in config file handlers where user-supplied file paths in configuration (e.g. code, customScripts) could reference files outside the config directory using sequences like ../../.

Changes:

  • DirectoryContext.loadFile: Resolves the final path and validates it stays within the config root before loading. Removes the previous fallback that silently tried the raw path if the relative path didn't exist, that fallback was the entry point for traversal
  • yaml/index.ts: Same boundary check applied to the YAML context's loadFile, throwing an explicit error if the resolved path escapes the config directory
  • databases.ts: Added config root boundary check for customScripts file paths defined in database.json
  • actions.ts / actionModules.ts: Removed the fs.existsSync branch that allowed absolute or root-relative paths to bypass the relative-path resolution, paths are now always resolved relative to the handler folder

📚 References

🔬 Testing

  • Updated existing action tests to use relative paths (./actions/code.js) instead of absolute paths, reflecting the new enforcement that file references must stay within the config directory
  • Updated YAML pages test to use relative page.html instead of an absolute path, and fixed file write ordering to match the new resolution logic
  • Path traversal attempts (e.g. ../../etc/passwd as a script path) will now throw an explicit error rather than silently loading the file

📝 Checklist

  • All new/changed/fixed functionality is covered by tests (or N/A)
  • I have added documentation for all new/changed functionality (or N/A)

@ankita10119 ankita10119 requested a review from a team as a code owner May 15, 2026 07:07
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 15, 2026

Codecov Report

❌ Patch coverage is 90.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.89%. Comparing base (0326e38) to head (4f8a467).

Files with missing lines Patch % Lines
src/context/directory/handlers/databases.ts 66.66% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1388      +/-   ##
==========================================
+ Coverage   79.86%   79.89%   +0.02%     
==========================================
  Files         153      153              
  Lines        7064     7067       +3     
  Branches     1550     1550              
==========================================
+ Hits         5642     5646       +4     
  Misses        781      781              
+ Partials      641      640       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ankita10119 ankita10119 requested a review from kushalshit27 May 18, 2026 05:43
Copy link
Copy Markdown
Contributor

@kushalshit27 kushalshit27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a breaking change — absolute and CWD-relative paths are no longer accepted

The removed fallbacks (toLoad = f in YAML context, fs.existsSync(unixPath) branch in actions) were also the mechanism that allowed users to specify absolute paths or paths relative to the working directory. Users with existing configs like this will now get a hard error:

YAML — was valid before, now throws

  pages:                                                                                                                           
    - name: login                                                                                                                  
      html: "/home/ci/scripts/login.html"      

action.json — was valid before, now throws

  { "code": "./local/scripts/action.js" } 

@ankita10119
Copy link
Copy Markdown
Contributor Author

This could be a breaking change — absolute and CWD-relative paths are no longer accepted

The removed fallbacks (toLoad = f in YAML context, fs.existsSync(unixPath) branch in actions) were also the mechanism that allowed users to specify absolute paths or paths relative to the working directory. Users with existing configs like this will now get a hard error:

YAML — was valid before, now throws

  pages:                                                                                                                           
    - name: login                                                                                                                  
      html: "/home/ci/scripts/login.html"      

action.json — was valid before, now throws

  { "code": "./local/scripts/action.js" } 

You are right @kushalshit27
The removed fallbacks were indeed the mechanism for absolute and CWD relative paths, so this is a breaking change for users relying on those patterns. Since the goal here is a security fix, keeping support for absolute paths would conflict with the boundary enforcement

Updated the error messages to guide users toward config-relative paths instead of surfacing a "path traversal" warning, which could be confusing for legitimate use cases. Will add a CHANGELOG entry to call this out explicitly.

@ankita10119 ankita10119 requested a review from kushalshit27 May 19, 2026 11:11
@kushalshit27
Copy link
Copy Markdown
Contributor

kushalshit27 commented May 20, 2026

@ankita10119 ,
Is it possible to make it backwards-compatible while fixing the issue for exports?

'/** @type {PostLoginAction} */ module.exports = async (event, context) => { console.log(@@replace@@); return {}; };',
'action-one.json': `{
"name": "action-one",
"code": "./local/testData/directory/test1/actions/code.js",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 set Unit test should be add:

  • old path
  • new path

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed and updated

@ankita10119
Copy link
Copy Markdown
Contributor Author

@ankita10119 , Is it possible to make it backwards-compatible while fixing the issue for exports?

I understand the concern @kushalshit27

But making this backwards-compatible would conflict with actually fixing the security issue. Any approach that still falls through to the raw path (absolute or CWD-relative) for unrecognized references would allow a config file to reference files like /etc/passwd or ../../secrets/.env, which would then be read and uploaded to Auth0.

The realistic attack vector is a CI pipeline pulling config from a compromised source where a malicious path silently exfiltrates sensitive files into Auth0. The hard error is necessary to close that

I've added explicit test coverage for both the rejection case (path outside config root) and the happy path (relative path within config dir), and will document this as a breaking change in the CHANGELOG.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants