Skip to content

Harden toFSPath against path traversal - #229

Open
webharerob wants to merge 1 commit into
mainfrom
feature/harden-tofspath
Open

webharerob wants to merge 1 commit into
mainfrom
feature/harden-tofspath

Conversation

@webharerob

Copy link
Copy Markdown
Member

Changes

  • toFSPath now rejects . and .. path segments (eg. mod::system/../x, mod::system/./lib/, @webhare/../x), also when allowUnmatched or keepUnmatched is set
  • Add a root option to toFSPath. It takes a resource path, eg. mod::mymodule/data/. With root set, . and .. are allowed as long as the result stays inside both the root and the module/storage folder the path resolves against, so mod::modulename/../bla is still rejected. The root itself must not contain dot segments
  • With root set, the result must be inside the root even when the path has no dot segments

Testing

  • Extended testPaths in system.nodejs.test_resources: rejection of dot segments in all namespaces, dot names that aren't segments (..x, .y), resolving inside a root, escaping the root, escaping the module/storage folder, and invalid roots. The test passes locally

Deprecations and API changes

  • Breaking: toFSPath now throws for resource paths that contain . or .. segments. Callers that relied on these being resolved must pass a root or normalize the path first (resolveResource already does)
  • New: root option for toFSPath in @webhare/services

TODOs / FIXMEs

  • None

toFSPath now rejects '.' and '..' path segments by default. A new 'root'
option (a resource path) permits them as long as the resolved path stays
inside both that root and the module/storage folder it was resolved
against, so eg. mod::modulename/../bla is never accepted.
@webharerob
webharerob requested a review from a team November 12, 2026 12:34
@unilynx
unilynx requested a balanced review from Copilot November 12, 2026 12:41

Copilot AI left a comment

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.

🟡 Changes recommended

The unmatched-input fallback bypasses dot-segment and root-containment validation, allowing paths outside the configured root or traversal segments to escape rejection.

1 open issue
What changed in this PR

This PR hardens resource-to-filesystem conversion in @webhare/services by rejecting dot segments by default and introducing an explicit containment root.

Changes:

  • Reject . and .. segments in mapped resource paths unless a root is provided.
  • Add a root option intended to constrain resolved paths to both the specified root and their module/storage folder.
  • Extend path tests for traversal rejection, root containment, and invalid roots.
File Description
whtree/​modules/​webhare_testsuite/​tests/​system/​nodejs/​test_resources.ts Adds traversal and root-containment test cases.
whtree/​jssdk/​services/​src/​resources.ts Adds root options, separates base resolution, and validates path containment.

Review effort: Balanced

Comment on lines +28 to +29
if (typeof resolved !== "object" || resolved === null) //unmatched, return as-is (null or the original resource)
return resolved;

This branch has not been deployed

No deployments
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.

2 participants