Skip to content

fix(http): reject percent-encoded backslashes in serveDir() paths - #7321

Merged
bartlomieju merged 3 commits into
mainfrom
fix-file-server-backslash
Sep 17, 2026
Merged

bartlomieju merged 3 commits into
mainfrom
fix-file-server-backslash

Conversation

@bartlomieju

@bartlomieju bartlomieju commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

serveDir() validates request paths using POSIX semantics (posixNormalize and
a /-based dotfile check), but resolves them with the platform-aware join().
A percent-encoded backslash (%5C) survives URL parsing, is reintroduced by
decodeURIComponent(), and passes the POSIX-based checks as an ordinary
character — yet on Windows join() treats it as a path separator. As a result,
paths like /%5C.dotfile or /sub%5C..%5C..%5Cfile could resolve to dotfiles or
to files outside fsRoot on Windows.

Since the URL parser maps raw backslashes to forward slashes, a backslash can
only reach this code via percent-encoding and has no legitimate meaning in a
served path, so such requests are now rejected with 404 before any filesystem
access. As defense in depth, the final resolved path is also verified to stay
within fsRoot.

This also adds an unstable dotfiles option to serveDir(), mirroring the
serve-static-style API: "ignore" (the default) responds with 404, "deny"
responds with 403, and "allow" serves dotfiles and shows them in directory
listings. It takes precedence over the existing showDotfiles boolean, whose
behavior is unchanged.

@github-actions github-actions Bot added the http label Sep 16, 2026
@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.47619% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.03%. Comparing base (ad7c87b) to head (bbf1309).
⚠️ Report is 34 commits behind head on main.

Files with missing lines Patch % Lines
http/file_server.ts 90.47% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7321      +/-   ##
==========================================
+ Coverage   95.00%   95.03%   +0.02%     
==========================================
  Files         617      617              
  Lines       51674    51654      -20     
  Branches     9326     9365      +39     
==========================================
- Hits        49093    49089       -4     
+ Misses       2038     2022      -16     
  Partials      543      543              

☔ View full report in Codecov by Harness.
📢 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.

Bun 1.4.2 crashes when constructing a node:worker_threads Worker
(TypeError: undefined is not an object (evaluating 'this._events')),
which fails this test on every PR.
@github-actions github-actions Bot added the path label Sep 16, 2026
@bartlomieju
bartlomieju merged commit 491f4c0 into main Sep 17, 2026
17 checks passed
@bartlomieju
bartlomieju deleted the fix-file-server-backslash branch September 17, 2026 09:32
@cymian

cymian commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

@bartlomieju Thank you for your work on this! I just created #7325 to address an issue with double-separators in the containment check.

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.

2 participants