Skip to content

bug: prevent pi-web malformed path from returning 500#83

Open
ALX99 wants to merge 2 commits into
masterfrom
bug/pi-web-malformed-url-400
Open

bug: prevent pi-web malformed path from returning 500#83
ALX99 wants to merge 2 commits into
masterfrom
bug/pi-web-malformed-url-400

Conversation

@ALX99

@ALX99 ALX99 commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Bug

pi-web decodes the request pathname with decodeURIComponent(url.pathname) before the static-file 4xx handling. A malformed percent-encoded path such as /%E0%A4%A throws URIError, escapes handleHttp(), and is converted by the top-level HTTP wrapper into a 500 response.

Severity and impact

This is a reliability/correctness bug in the local web server. A malformed client URL is a bad request, not an internal server failure. The impact is limited because pi-web binds only to loopback, but browser extensions, stale tabs, scripts, or local probes can trigger noisy false 500s and make logs/debugging misleading.

Evidence

Relevant code:

  • pi-web/src/server.ts: handleHttp() constructs new URL(...), then calls decodeURIComponent(url.pathname) before path normalization and before returning normal 403/404 responses.
  • Prior behavior: decodeURIComponent("/%E0%A4%A") throws URIError: URI malformed; the createServer() wrapper catches it and returns Internal error: URI malformed with status 500.
  • Regression coverage added in pi-web/tests/server.test.ts: startServer: returns 400 for malformed percent-encoded paths sends GET /%E0%A4%A and asserts status 400/body Bad Request.

This is a real defect rather than a hypothetical edge case because malformed percent escapes are accepted at the HTTP request line level, decodeURIComponent deterministically throws for them, and the server currently maps that client input error to an internal-error response.

Reproduce

Setup:

cd pi-web
npm install

Triggering request:

npm test -- tests/server.test.ts

Minimal manual reproduction before the fix:

  1. Start a pi-web server.
  2. Request GET /%E0%A4%A.

Actual result before the fix:

  • HTTP 500
  • Body includes Internal error: URI malformed

Expected result:

  • HTTP 400
  • Body: Bad Request

Root cause

Malformed request path decoding was treated the same as unexpected server failures. decodeURIComponent() can throw URIError for invalid percent-encoded UTF-8 sequences, but handleHttp() did not catch that expected client-input error locally.

Fix

Wrap only the pathname decode in a try/catch. If the failure is a URIError, return HTTP 400 Bad Request; otherwise rethrow so genuinely unexpected failures still surface through the existing 500 path.

Validation

Commands run:

  • Not run locally in this automation environment; repository contents were inspected and changed through the GitHub connector.

Regression test added:

  • pi-web/tests/server.test.tsstartServer: returns 400 for malformed percent-encoded paths

Scope

Only malformed static URL path decoding is changed. No WebSocket behavior, static path traversal checks, MIME handling, CLI parsing, session/runtime behavior, or unrelated routing semantics were changed.

@ALX99 ALX99 force-pushed the master branch 3 times, most recently from 5cf571d to dd748db Compare July 10, 2026 12:22
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.

1 participant