Skip to content

MLE-30257 Replace encodeURI With encodeURIComponent#1094

Open
jonmille wants to merge 5 commits into
developfrom
MLE-30257
Open

MLE-30257 Replace encodeURI With encodeURIComponent#1094
jonmille wants to merge 5 commits into
developfrom
MLE-30257

Conversation

@jonmille

@jonmille jonmille commented Jul 7, 2026

Copy link
Copy Markdown

Fix CWE-22/CWE-20: Replace encodeURI with per-segment encodeURIComponent in extlibs.js

Jira: MLE-30257
Severity: Medium | CVSS: 3.5 Low | CWE: CWE-22, CWE-20

Problem

All four path-handling methods in extlibs.js (read, write, remove, list) called encodeURI() on the constructed URL path before sending the request. encodeURI() intentionally leaves /, ?, #, and other reserved characters unencoded, creating two vulnerabilities:

  • Path traversal (CWE-22): A caller-supplied path like ../../../v1/databases passed through unchanged, producing /v1/ext/../../../v1/databases. HTTP clients that normalize the path resolve this to /v1/databases — an unintended MarkLogic REST endpoint.
  • Query injection (CWE-20): A path containing ? could inject arbitrary query parameters into the request.

Solution

Added a private encodeExtPath(rawPath, trailingSlash) helper that:

  1. Strips accepted input-form prefixes (/v1/ext/, /ext/, or bare /) while requiring a leading /, preserving backward compatibility for existing call sites.
  2. Splits the remaining path on / and rejects any . or .. segment with a synchronous Error.
  3. Encodes each segment individually with encodeURIComponent().
  4. Reassembles under the fixed /v1/ext/ base.

All four methods now delegate to this helper. The write() method is additionally refactored to encode the path first, then assemble the ?perm:role=capability query string separately (role names and capability values are also now encoded with encodeURIComponent()).

A pre-existing bug in list() is also corrected as a side effect: the /ext/-prefixed branch was omitting the /v1 prefix from the request path.

Changes

File Change
extlibs.js Added encodeExtPath helper; updated read(), write(), remove(), list()
extlibs.js Added 7 security-focused tests in a new 'when handling path encoding security' block

Tests

All 16 pre-existing extlibs tests continue to pass. New tests added:

  • read('../../../v1/databases') throws with message matching /relative path components/
  • write('../../../v1/databases', ...) throws (positional-args form)
  • write({ path: '../../../v1/databases', ... }) throws (object-params form)
  • remove('../../secret') throws
  • list('../../admin') throws
  • read('my lib/module.xqy') sends a percent-encoded URL the server accepts
  • All three input forms (bare, /path, /ext/path) complete without a client-side URL construction error
23 passing

Testing instructions

# Requires a running MarkLogic instance with the test app deployed
npx mocha test-basic/extlibs.js --timeout 10000

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR hardens extension library URL path handling to mitigate CWE-22 (path traversal) and CWE-20 (query injection) by switching from encodeURI() on whole paths to per-segment encodeURIComponent() with explicit validation.

Changes:

  • Added encodeExtPath(rawPath, trailingSlash) to canonicalize and encode extension library paths while rejecting . / .. segments.
  • Updated read(), write(), remove(), and list() to use the helper; write() now builds and encodes the permissions query string separately.
  • Added security-focused tests covering traversal rejection, space encoding, and accepted input forms.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
lib/extlibs.js Introduces encodeExtPath and routes all extlib operations through it; refactors write() to build query string safely.
test-basic/extlibs.js Adds new tests for traversal blocking and encoding/canonicalization behavior.

Comment thread lib/extlibs.js
Comment thread lib/extlibs.js
Comment thread test-basic/extlibs.js Outdated
jonmille and others added 3 commits July 7, 2026 14:50
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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