Skip to main content

Module url

Module url 

Source
Expand description

The one kind of URL Shell::open_url hands to the system: an absolute http or https URL, checked before any backend sees it.

§Decision: a type, not a string the backends each check

What a platform does with a string it is told to “open” is far wider than “show a web page”. ShellExecuteW with the open verb runs an executable (C:\x.exe), opens any file with its associated program (\\server\share\ payload.lnk), and starts any registered protocol handler (ms-msdt:, search-ms:, file:), each of which has been a remote-code-execution path in its own right. xdg-open and NSWorkspace openURL are as broad. A game that passes on a link it was sent — a server’s news feed, a mod’s homepage, a chat message — must never reach any of that, so the check cannot be left to each backend to remember. WebUrl is the only thing open_url takes, and WebUrl::parse is the only way to make one, so a string that fails the check never reaches a system call on any platform.

§What is accepted

RFC 3986’s URI with the scheme http or https (in any case, as section 3.1 says schemes are) and an authority: //, a host, and an optional port. Stricter than the grammar in four ways, each on the side of refusing:

  • Only the characters RFC 3986 lets a URI contain (section 2): the unreserved set, the delimiters, and % followed by two hex digits. Everything else must arrive percent-encoded, which turns away whitespace at either end or inside, NUL and every other control character, the " that would end a quoted argument on the browser’s command line, the \ that Windows reads as a separator, and non-ASCII text.
  • No user information. https://bank.example@evil.example names the host after the @, which is how a link is made to read as one site and go to another; a game has no use for a password in a URL either.
  • [ and ] only around an IPv6 address literal in the host, as section 3.2.2 says, and no IPvFuture literal.
  • A port is one to five digits, at most 65535, where the grammar allows any run of digits or none.

The string is kept exactly as given: nothing is decoded, normalised or lower-cased, so what the browser opens is what the caller passed.

Structs§

WebUrl
An absolute http or https URL, the only kind Shell::open_url opens.

Enums§

WebUrlError
Why a string is not a WebUrl.