I'm looking to develop a website to host HTML5 games on. Since these games have the chance to include malicious javascript, I'd like to know how to setup a secure environment for hosting them.
It seems like embedding the game with an iframe is the answer, but I'm relatively new to website development, so some questions:
is there a simple way to host the games securely on the same domain, or...
does the game have to be hosted on a different domain, then embedded within an iframe, so that it can't interact with the parent document?
if the game is executed while hosted on another domain, can it interact with that host domain in any malicious way?
Cross-site scripting and over-scoping of cookies will be a great concern here. Utilising the browsers' Same Origin Policies will be a valuable methodology in your defence of this. ref1 ref2
Ensure your sites are served from a different domain to the contributors apps. (e.g. coolgames.com vs mycoolgames.com) - This will segregate the origin-scope of your code from theirs.
Ensure that each different contributor has their apps/games served from a unique subdomain (e.g. bob.mycoolgames.com, dave.mycoolgames.com) - This will help to segregate the origin of the different developers. Each will need to be careful to never scope cookies to .mycoolgames.com or they will overexpose themselves.
You may also wish to further protect your own app by utilising the new Content Security Policy support in modern browsers. This will additionally help to mitigate against clickjacking attacks.
Regarding iframes:
Can you explain why you think you need to use an iframe at all? What's wrong with good old fashioned links?
If the graphic design dictates that an iframe must be used, you can easily have all the embedded games iframed into a dynamic page at www.mycoolgames.com, where you will not keep any sensitive systems, data or code - keep all user authentication systems, CMS systems and data only on the applications at *.coolgames.com
First - this is a great question! I was asking myself the same question when design a hosted iframe-based solution.
Second - after a short search I've came across iframe sandbox attribute
TLDR - it enables developers to declare which security options will be applied to the iframe, letting the browser define a tailored-made restrictive scope
So.. I found a great article that gives a real world sample of this feature usage + some clear explanations (read more about this topic here). In short:
<iframe sandbox="security options goes here" src="your hosted page"></iframe>
The security options are:
allow-forms allows form submission.
allow-popups allows popups
(window.open(), showModalDialog(), target=”_blank”, etc.).
allow-pointer-lock allows (surprise!) pointer lock.
allow-same-origin
allows the document to maintain its origin; pages loaded from
https://example.com/ will retain access to that origin’s data.
allow-scripts allows JavaScript execution, and also allows features to
trigger automatically (as they’d be trivial to implement via
JavaScript).
allow-top-navigation allows the document to break out of
the frame by navigating the top-level window.
For instance:
<iframe sandbox="allow-scripts allow-popups" src="https://mywebsite.com/hosted_page"></iframe>
It is also worth mentioning that this security feature is highly supported (can I use for the rescue)
Happy reading / coding... may the security force be with you :)
Related
I'm trying to display an image on a third party website that uses csp policy of "img-src" to disallow every image.
i tried using "background-image" css on an img tag and even on a div tag but no luck.
is this possible at all? or should i ask the site owner to loss the restriction?
Generally, no, it is not possible to bypass a site owner's CSP. The whole point of enforcing a CSP on a website is so that the site owner can block outside interference for website's security.
Doing a quick search for "bypassing a csp" returned some results, but these samples are typically in very specific scenarios. So technically, yes, it can be possible to bypass a CSP through penetration testing and limited situations, but I wouldn't rely on these because they may be fixed in the future, and your workaround based on the vulnerability may be closed.
Your best bet is to contact the site owner and ask that they whitelist your site in their img-src directive so that it will show up correctly.
I am looking for an approach to allow only whitelisted scripts to run within a sandboxed iframe. I was thinking of an iframe-sandbox directive that allows only whitelisted scripts to run within an iframe. The analogy is the script-src directive in the Content Security Policy.
The problem:
<iframe sandbox="allow-same-origin allow-scripts" src="https://app.thirdparty.com" width="100%" height="800" frameBorder="0"></iframe>
The app in the iframe provides valuable functionality for my website. However, it pulls in external resources that I would like to control (i.e., block), e.g., AnalyticsJavaScript.com and TrackingPixel.com. I would like to allow scripts from app.thirdparty.com but block AnalyticsJavaScript.com and TrackingPixel.com.
Any help appreciated.
The answer to this is unfortunately complicated. With the advent of iframe sandboxing the question seems simple enough, but the spec that you're looking for is very much a work in progress. Thus, if you want decent browser support, the issue devolves into how to modify an iframe's content, which usually involves some sort of proxy.
Content Security Policy
The spec you really need is the CSP. At its simplest, you would allow specific scripts with the iframe atribute csp="...".
<iframe ...
src=""
csp="script-src https://app.thirdparty.com/"
...></iframe>
Any scripts from domains not specified (i.e. tracking scripts as in the question) would not be allowed in the response. Note that limiting scripts to those from a specified source does rely on cooperation with the third party app's server. If the server does not inform the user agent that it will adhere to the CSP restrictions then the response will be blocked.
The CSP is still a working draft and may change in the future. As stated in the comments, Chrome 61 and Opera 48 have implemented the CSP spec, but at this stage there is no sign from Firefox, Edge or Safari that they will also implement it. Unless you can guarantee that your users will only be using a browser that supports the spec, the tracking scripts will still be present for a very large percentage of users.
The remaining suggestions all involve modifying the iframe's content to remove the offending scripts.
Reverse proxy
Creating a reverse proxy to block a couple of tracking scripts in an iframe is probably equivalent to using a nuclear warhead to light a camp fire as far as overkill goes. But, if you are able to configure your server to this extent, it is the most reliable and seamless method for iframe content injection/modification/blocking that I've found.
The Wikipedia page states:
A reverse proxy is a type of proxy server that retrieves resources on behalf of a client from one or more servers. These resources are then returned to the client, appearing as if they originated from the proxy server itself.
Because the reverse proxy is an intermediary between the third party app and your site, it can transparently modify the responses to remove the undesired scripts. I'll use Apache in this example, but your implementation really depends on what server you're already using.
You need a subdomain for the proxy that points to your server IP, e.g. proxywebapp.yourdomain.com. On your server you would then create a virtual host in httpd.conf that uses the Apache mod_proxy module. Within your virtual host configuration you would then substitute the script calls to AnalyticsJavaScript.com and TrackingPixel.com with blanks. If the third party app must use HTTPS then reverse proxying gets trickier as you need an SSL virtual host and a SSL certificate for the proxy's FQDN.
<VirtualHost *:*>
ServerName proxywebapp.yourdomain.com
ProxyPreserveHost On
ProxyPass "/" "http://app.thirdparty.com/"
ProxyPassReverse "/" "http://app.thirdparty.com"
# in case any URLs have the original domain hard coded
Substitute "s|app.thirdparty.com/|proxywebapp.yourdomain.com/|i"
# replace the undesired scripts with blanks
Substitute "s|AnalyticsJavaScript/| /|i"
Substitute "s|TrackingPixel/| /|i"
</VirtualHost>
Your iframe would then point to proxywebapp.yourdomain.com.
<iframe ... src="proxywebapp.yourdomain.com" ...></iframe>
Again: total overkill but should work transparently.
Proxy scripts
A third option to consider is implementing a proxy script on your server between the iframe and third party app. You would add functionality into the proxy script that searches for and removes the undesired scripts before they reach the iframe. Additionally the proxy means the iframe's content will validate the same-origin policy, thus you could instead remove the undesired content with JavaScript in the frontend, although this may not guarantee that the scripts won't run before they are removed. There are many proxy scripts available online for all manner of backends (PHP, Node.js etc. ad nauseum). You would likely install the script and add it as the iframe's src, something like <iframe ... src="proxy.php?https://app.thirdparty.com/" ...>.
Unless properly configured for all cases, the proxy may not correctly transfer data between the third party app and its parent server. Testing will be required.
Writing your own server side proxy to remove a couple of scripts from an iframe is probably a bit excessive.
If you can't access the backend, it is possible to scrape the web app's content using JavaScript and a CORS or JSONP web app, and modify it to remove the scripts. Essentially making your own proxy in JavaScript. Such web apps (Any Origin, All Origins, etc) allow you to bypass cross-domain policy restrictions, but because they are third party you can no longer assume any of the web app's data is private. The issue with correctly communicating any data transfer between the app and its parent server will still be present.
Summary
A widely supported pure frontend solution is not feasible at the moment. But there are many ways to skin a cat and perhaps even more ways to modify an iframe's content, regardless of cross-domain restrictions.
Content Security Policy does look promising and is exactly what you're asking for, but currently its lack of widespread support means it can only be used in very niche situations. A reverse proxy that modifies content may take a lot of configuring and in this situation is like driving a full size semi-trailer over a Hot Wheels track, but will likely operate seamlessly. Content modification from a forward proxy is somewhat simpler to implement, but may break communications with the third party app's parent server.
You can't do this the way you want (for now). As mentioned in comments CSP:EE is a thing yet to come.
However you can try proxying the request and removing the unnecessary scripts from the body on the server side or on the client side, e.g.:
1) Get the needed page via XMLHTTPRequest
2) Remove unwanted
3) Inject into iframe on the page
"Workability" of this method depends purely on external app functionality. I.e. it will not work if the aforementioned app needs registration/authorisation of the end user to work, however this can still be suitable for some simple cases.
P.S.: you can implement a workaround to make such thing work via browser extension, however I'm sure this is not what you want.
I am creating a website which allows users to make their website alive for a certain amount of time. It works like this:
user uploads a .zip file containing javascript/html/css/image.
filtering the files using whitelist to remove unallowed extensions>
a new subdomain will be made with a random name containing the unzipped files.
and the user now can view his design.
so what security issues may result due uploading javascript/html/css files?
All of the files are potential security hole. JavaScript, HTML and CSS files could be dangerous because all of them may have JavaScript code in them. By allowing people to upload files that contain JavaScript code you're letting them upload code that will be executed by visitors' browsers.
On modern browsers, embedding JavaScript code in CSS files isn't a real problem. But if you expect to support older browsers, such as IE6 or 7, then the CSS files are a potential security hole as well.
A common technique used by attackers is Cross-site scripting, or XSS. Basically, attackers inject JavaScript code on a website, by using a form or some low-security API that allows visitors to send information to the website. That JavaScript code may then be executed by all other users, and could steal sensitive information. Here's some more information on it: https://en.wikipedia.org/wiki/Cross-site_scripting
Now, because all websites reside in different subdomains, they actually have different origins, and thus the browser will prevent one website's JavaScript from fiddling with another website's cookies. This is called the Same origin policy, and its described in more detail here: https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy
Do bear in mind that one of these malicious JavaScript files could change its origin by running the following code:
document.domain = "yourdomain.com";
And that could be a potential threat.
Also, the Same origin policy has different behaviour on some browsers, such as Internet Explorer. It's ideal that you read the documentation on it for the most common web browsers.
I have a web application that users HTML 5 History (pushState, etc). I would like this application to be loadable in a cross-domain iframe (kinda like the FB or Twitter iframes). A snipper of HTML (with the requisite iframe tags) could be inserted into any page, and this page would contain an iframed version of my app. For example, if my web application is located at app.mywebapp.com, aRandomWebsite.com might have the following HTML structure
<html>
<head>
</head>
<body>
<iframe src="https://app.mywebapp.com/"></iframe>
</body>
</html>
I know that in the past, cross-domain iframes were not entirely insulated from one another, and could mess with certain variables on eachother, like window.location. My question is, if I execute the following code inside my iframed application, will the parent frame (which could be very hostile), be able to take a peek at it?
window.history({}, '', 'aSecureRoute/thisIdIsVerySensitive');
This should be safe as cross domain DOM access is protected by the Same Origin Policy.
That said, there could possibly be quirks that makes it possible for www.evil.com to grab or test URLs in future versions of a popular browsers - it all depends on what vulnerabilities are discovered in future. As you cannot account for future browser bugs, I would recommend proceeding on the basis that this access should be protected. If any vulnerabilities are discovered you can direct your users to use a different browser until their current one is fixed.
Remember though that URLs should not be considered secure as they can be stored in the browser cache or history (or bookmarked), and also be logged by proxies (if not protected by HTTPS) or stored in server logs.
You should protect your secure URLs with something else too (e.g. a secure session cookie), so if the evil site grabs it it cannot then use it in future without the cookie.
Ive been asked to tackle a challenge where if we have JS delivered into an non-Friendly (aka Cross Domain) IFRAME (3rd party code being written to page), and from inside that IFRAME determine the x&y offset of the iframe into which the code is delivered. Due to cross site scripting limitations historically this has been deemed a non-starter, but we now have a need to have this ability. Anyone aware of any techniques that could get me started ?
I would start by ditching the iframe, honestly. Cross-site scripting is one thing, but what you may be looking for is a web scraper.
http://en.wikipedia.org/wiki/Web_scraping
Although I'm wondering if your intentions are benevolent if you're grabbing content from another site...