Skip to content

fix: prevent path traversal in view lookup#7217

Closed
kuishou68 wants to merge 1 commit intoexpressjs:masterfrom
kuishou68:fix/path-traversal-view-lookup
Closed

fix: prevent path traversal in view lookup#7217
kuishou68 wants to merge 1 commit intoexpressjs:masterfrom
kuishou68:fix/path-traversal-view-lookup

Conversation

@kuishou68
Copy link
Copy Markdown

Summary

Fix a path traversal vulnerability in View.prototype.lookup where a relative view name containing ../ sequences could resolve to files outside the configured views root directories.

Problem

app.set('views', '/safe/views');
app.render('../../../etc/passwd', callback);
// Previously could read files outside /safe/views

Fix

Added a containment check after path resolution: if the resolved path does not start with the root directory prefix, the lookup is skipped for that root. Absolute paths are intentionally excluded from the check to preserve existing Express behavior (app.render('/absolute/path') is supported).

// security: ensure resolved path stays within root directory
var resolvedRoot = resolve(root);
if (!isAbsolute(name) && loc !== resolvedRoot && !loc.startsWith(resolvedRoot + sep)) {
  debug('path traversal attempt detected: "%s" resolved outside root "%s"', name, root);
  continue;
}

Testing

All existing tests pass (npm test). The fix preserves:

  • Normal relative view lookup
  • Multiple views roots (array)
  • Absolute path rendering (app.render('/abs/path'))
  • View engine extension resolution

Adds a containment check so relative view names cannot escape the
configured views root via '../' traversal. Absolute paths are
intentionally excluded from the check to preserve existing Express
behavior (app.render('/abs/path') is a documented feature).
@krzysdz
Copy link
Copy Markdown
Contributor

krzysdz commented May 5, 2026

Duplicate of #7142

Duplicate of #7216

@krzysdz krzysdz closed this May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants