Possible URL spoofing on wildcard path in unjs/h3

Valid

Reported on

May 15th 2023


Description

H3 provides the getRequestURL utility using the new URL(a, b) constructor. When variable a is attacker-controlled the origin of the resulting URL can be modified.

Proof of Concept

// index.js
import { listen } from "listhen";
import {
  createApp,
  createRouter,
  eventHandler,
  toNodeListener,
  getRequestURL,
} from "../src";

const app = createApp()
const router = createRouter().get("/**", eventHandler((event) =>getRequestURL(event)))
app.use(router);
listen(toNodeListener(app));

Make request to http://localhost:3000//attacker.com/test Output is "http://attacker.com/test"

Impact

The origin of the output URL cannot be trusted.

Highly context dependant, if used to make requests server-side then SSRF is possible.

Here's another report where I abuse a similar issue for CSRF.

Could be possible to chain into more severe bugs.

Nuxt3 imports this utility on the master branch, but no current usage.

Occurrences

new URL(a, b) can be vulnerable.

We are processing your report and will contact the unjs/h3 team within 24 hours. 10 days ago
OhB00 submitted a
10 days ago
OhB00 modified the report
10 days ago
pooya parsa
10 days ago

Thanks for the early report about this issue.

This is a valid case however as you mentioned, the possibility of SSRF when using this utility is context-dependent and users are expected to validate URLs. (for nuxt and nitro, it is also only being introduced as an opt-in feature not for internal routing)

I have made an alternative patch for fix without relative paths which could be used to exploit in conjunction with headers forgery on x-forwared-host by always normalizing double slashes on URLs (https://github.com/unjs/h3/commit/b5d2972a8ee2ebda37815db5426d16cc35fd47ad)

The patch release h3@1.6.6 also contains more measurements to make x-forwarded-host support opt-in.

Even though I could not find any more vulnerabilities, feel free to test and report if there is a possible bug with opt-in feature.

pooya parsa gave praise 10 days ago
The researcher's credibility has slightly increased as a result of the maintainer's thanks: +1
pooya parsa modified the Severity from Medium (5.3) to Medium (5.3) 10 days ago
pooya parsa validated this vulnerability 10 days ago

https://github.com/unjs/h3/releases/tag/v1.6.6

OhB00 has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
pooya parsa marked this as fixed in v1.6.6 with commit b5d297 10 days ago
The fix bounty has been dropped
This vulnerability will not receive a CVE
pooya parsa published this vulnerability 10 days ago
request.ts#L106 has been validated
to join this conversation