Case Study: Isolate User Content using Different Domains
Pushkar Jaltare
Security Architect at Fastly | Ex- AWS Security | Ex Pentesting Lead
Disclaimer:
This post doesn’t represent opinions of my past or current employers. Additionally, this is my opinion and does not represent any corporation in any way.
Background
I always found it interesting that many companies like Google, Github, GitBook utilize a completely different domain name for serving user content than the main Web application. This blog post attempts to analyze the design of hosting user content on a separate domain and in the process apply the Isolation design principle to complex Web apps.
Sharing a domain between main application and hosted user content opens up the application to many security issues. Accidental disclosure of cookies between user hosted content and main application, could lead to account takeover issues. Security issue such as Cross-site scripting(XSS) becomes more dangerous as user hosted content could access cookies for main site.
Github user content domain separation
Lets analyze a bug bounty report from 2013 related to Cookie Tossing in Github. Then we will analyze the design changes made by Github to avoid the whole class of similar issues. I will copy the relevant sections from 2 blog posts here but it is recommended that you read the actual blog posts as well.
Before the domain isolation, Github pages containing HTML and JavaScript were served from userhandle.github.com. As we will see hosting user provided JavaScript under main Web application domain is a pretty bad idea.
As we can read from the GitHub blog post, GitHub Pages and the main GitHub application used to share the same domain github.com. When a user logged into the GitHub web application, a session cookie would be created server side and sent to the web browsers. The domain attribute of this cookie would be set to github.com. As this cookie is correctly scoped (with path attribute), marked as HTTPOnly (should not be accessible in JavaScript), the cookie won’t be accessible to a subdomain (userhandle.github.com). However, a malicious user doesn’t need to leak or steal the cookies. Instead the malicious user can just use JavaScript API to set a new cookie through GitHub pages as they share the same domain. I will copy the relevant section from GitHub blog below.
The cookie set by malicious user in the subdomain (userdomain.github.com), will also be sent to any requests made to the main domain (github.com) as the malicious user will not add any attributes to the cookie such as domain or path. Depending on the Web server, the server might accept the cookie set by malicious user instead of the cookie set by itself i.e the GitHub server. This behaviour could lead to security issues such as account takeover of another user account.
Github used couple of different short term mitigations for fixing this security issue. However, as GitHub described in their blog, mitigating all the different attack vectors across different Web browser turned out to be pretty challenging. In secure system design, we want to design a system in such a way that whole class of security issues becomes impossible. And as we can see, GitHub decided to use full domain isolation between GitHub domain and user content domain.
Modern Content Isolation
Google recently published a really good article on hosting user data in modern Web applications. The article discusses using sandbox domain to isolate user content from the main Web application domain. In addition to using sandbox domains, the article goes further and recommends few additional security controls on top of sandbox domains. I am going to copy the related section from Google blog here for clarity.
As we can see, Google uses a sandbox domain to isolate user hosted content from Google hosted content. However, just using a sandbox domain is not enough, as the same sandboxed domain will be used to host the contents of all the customers. As we will utilize the same subdomain between customers, we need to additional layer of security control of Public Suffix List (PSL). As we can read from Google post, adding examplesusercontent.com in PSL will ensure that user1.exampleusercontent.com and user2.exampleusercontent.com are different origins and completely isolated from each other.
领英推荐
The shim file mentioned in the Google blog post provides the HTML and CSS required for styling and basic navigation of the site. The user content is then fetched from an iFrame with sandboxing enabled. Iframe sandboxing allows Google to tighten the restriction on the framed content. Google can instruct the browser to load a specific frame's content in a low-privilege environment, allowing only the subset of capabilities necessary to do whatever work needs doing. Communication between parent window and iFrame can be achieved through PostMessage interface. We can perform input validation and checks on source and origin to avoid security issues related to communication between parent window and framed content.
Recap
So to recap, we have our main Web application at example.com . We will create a new sandboxed domain to host user content at exampleusercontent.com This new sandboxed domain ensures that any security issues (XSS or related to Cookies ) originating from user content doesn’t affect our main Web application domain. Additionally, this separation ensure that any user content with scam or spam doesn’t create any reputational risks for our main domain.
Further, we will utilize PSL to ensure that user1.exampleusercontent.com and user2.exampleusercontent.com are completely isolated from each other. With PSL enabled, both these domains will be treated as cross-origin and there shouldn’t be any sharing of cookies between them reducing the attack surface. In other words, malicious user 1 can do limited damage to legitimate user 2 - both of whom have data “hosted” on exampleusercontent.com.
Lastly, user content will be rendered inside a sandboxed iFrame to ensure that user content can’t interfere with the webpage where user content is hosted. Depending on the use case and security needs, we can add the correct attributes to sandboxed iFrame.
With this security architecture in place, we can ensure that untrusted user content can be shared in a secure manner.
Recommended Reading