Skip to content

What a session can retrieve

Documents refer to other documents by URL. Following a reference retrieves whatever that URL identifies. That’s fine when you control the documents. When you don’t, a document could refer to http://169.254.169.254/ or file:///etc/passwd. Following that reference would make your app retrieve it. That’s why a session retrieves nothing unless the allowRetrieval config allows it.

allowRetrieval is a list of URLs. A URL that ends with / allows everything under that URL. Any other URL allows only that exact URL. An origin such as https://example.com allows everything on it with or without the / because it’s the URL of the origin’s root, https://example.com/. An empty list allows nothing. In Node.js, a relative URL is relative to the working directory. In a browser, it’s relative to the page. A worker has no page, so use absolute URLs there.

The default is ["./"], which allows the files in the working directory in Node.js and what’s in the page’s directory in a browser. Your own list replaces the default, so include "./" if you still want to allow local files. This list allows local files and one API:

TypeScript
const h = new Hyperjump({
allowRetrieval: ["./", "https://api.example.com/"]
});

Retrieving a URL the list doesn’t allow throws a RetrievalError. Its cause is an HttpError for a 403, the way a server refuses a request, and the url of the error’s response is the URL that the session refused. The HttpError message says how to allow that URL:

Output
403 Forbidden -- Retrieving 'https://example.com/other' isn't allowed. Use the 'allowRetrieval' config to allow it.

When a session’s own list refused the URL, the message says to use the session’s allowRetrieval option instead because that list replaces the config’s.

Different parts of an app don’t always trust the same things, so a session can have its own list. The session’s list replaces the config’s list instead of adding to it. That means a session can allow less than its Hyperjump does:

TypeScript
const session = h.session({ allowRetrieval: ["./documents/"] });

Checking a URL before the session retrieves it isn’t enough on its own because there are other ways to end up somewhere you didn’t allow. allowRetrieval covers these too:

  • Symlinks. In Node.js, the session compares file: URLs by their real paths so a symlink in an allowed directory can’t lead outside it.
  • Redirects. In Node.js, the session checks where a redirect leads before it follows the redirect. A server can’t make the session send a request to a URL you didn’t allow. In a browser, fetch follows redirects itself and sends the request before the session can check it. The session then checks the URL that the response came from and doesn’t use a response from a URL you didn’t allow.
  • The cache. The check happens before the URL scheme plugins run so a cached response can’t get around the check.

The check applies to every URL scheme, including the ones you add. A plugin can redirect to another URL the way a urn: plugin redirects a Uniform Resource Name (URN) to the URL it maps to. The list has to allow both the URN and the URL. For more information, see URL schemes.