EDIT: created a solid specification issue here: Security considerations for serving html files · Issue #514 · solid/specification · GitHub
TL;DR
I think it’s a security issue that pods serve html files, as the web treats html files from the same origin with the same security permissions. Solid pods breaks the base assumption of web security that files from the same origin are equally trustworthy. Thus I’d like to discuss if this should be disallowed, either in the spec or just removed from the implementations.
Introduction
Currently pods serve html files when visiting them in the browser. For instance, going to pod.example.org/public/file.html will render the html file in the browser. My question is, is this secure? And if yes, under what conditions?
I didn’t think it completely through, but my gut feeling is that it is not secure, always leaving a security issue, especially if html files there use sensitive data.
Main security issue
The main problem is, that the web often assumes applications on the same origin to share a security context. There is a limit how applications can interact with applications on different origins, but if the application is on the same origin it is much easier with less security boundaries. (See eg Same-origin policy - Web security | MDN)
This does not map to Solid pods. Here, we can give one app access to /foo
and another app access to /bar
which share an origin, but can be trusted on different levels. For instance it could be /drawing
and /banking
, where we likely want the drawing app not to interfere with the banking application.
Examples
- LocalStorage: this is a storage that is shared within the same origin. The drawing app would be able to access stored data from the banking app.
- Cookies: By default cookies use
SameSite: Lax
which means they are not send cross-origin, but are sent on the same origin. Requests from the drawing app would include cookies from the banking app. A real case is this issue where the Drawing would be able to use themashlibNSS session cookies. - Iframes: Given an app
/banking/index.html
, a malicious drawing app/drawing/evil.html
can include the banking app as an iframe and access the contents of it. A real case is this issue where Mashlib accidentically gives html files it displays access to its window (EDIT: apparently mashlib manually fetches the html file, so it’s not a real case of this. But the idea is the same). - Url history: the url is modifiable as long as the origin stays the same. Thus the app
/drawing/index.html
could usewindow.history.pushState('page2', 'Title', '/banking/index.html');
to trick the user into believing they are looking at the banking app.
In addition to these app-app issues, serving html files can also cause issues when only one evil application is present:
- Service Workers: a service worker can act as a proxy within it’s scope. The scope is everything within the same folder or subfolders (
/foo/serviceWorker.js
can intercept requests to/foo/**/*
). It requires substantial prerequisites, but when an attacker is able to install a service worker, they have limited control over all nested resources in the folder, regardless of their access control.
I’m pretty sure there are other cases, where it could be troublesome that apps of different trust-level are hosted on the same origin.
My current conclusion
Given these issues, I don’t think it is safe for pods to serve html files such that they are rendered by the user. For service workers, you could disable them with a CSP header (worker-src). For the other issues, I think it would require apps not to use any sensitive information. My guess is also, that there are more issues I didn’t think of yet, as Solid breaks a base assumption that web security relies upon, so maybe even the case where no sensitive information is handled causes security issues.
So I would consider to not serve html files, or to disable Javascript (and maybe more?) via the Content Security Policy header. With this the above issues should be migitated, but one can still use minimal html websites.