How To Break Content Security Policy? - javascript

Content Security Policy seems really robust, but I don't think it's perfect (and I've seen sources that refer to it as a "partial" prevention for XSS). My question is: what sorts of XSS attacks does it not prevent?

No all browsers have implemented it, so users using non-supported browsers it offers no protection.
http://caniuse.com/#search=csp
Even on supported browsers, unless the Content Security Policy is to disable all JavaScript (in-line, internal/external domain) then it still leaves areas open to where JavaScript can be run. Which means, if any malicious JavaScript can make its way into those zones, then Content Security Policy will not stop the XSS from happening.
Some examples of of where CSP will not stop XSS:
If an application is using inline (on the page) JavaScript and the CSP policy allows it. If unencoded/unvalidated/malicious values are put into the page then the browser will run the malicious JavaScript just like it will run the intented JavaScript. (Currently ASP.Net Web Form apps need JavaScript to run on the page, so any malicious input that is displayed will be executed by the browser.
If you are dynamically creating your JS files for your app and unencoded/unvalidated/malicious values are inserted into that file, that will cause a XSS vulnerability.
If you are sending pages and/or JavaScript files over http and not https an a MITM attack can modify the values over the wire.
If you are loading JavaScript files from a third party domain and their security gets compromised, malicious scripts could be sent to your app instead of the originally intended scripts (think CDNs).
These are just some of the examples I could think of off the top of my head.
Some of these concerns look like they can be mitigated through use of the CSP Level 2 directives, but there is limited support for them.
In short, CSP is a very nice layer of defense, but it should not be your only line of defense. Even though it will not cover everything and not all browsers currently supported it, it is an additional layer of security I can use to keep my application and users safe.

Related

How to Load an external web page inside my one and hide some content (avoiding cross site problems)

I need to incorporate in my web application some content from an external dynamic web page on which I have no control.
Then I need to filter some of the content of this page or to hide it for presenting only the relevant part that is interesting for my use.
I need also that the scripts on the external page are still working on the source site of the loaded content without cross-site protection.
Is all that possible? How can I do it? Any code example, please?
I suppose that this can be made with JS on client side .
I work on back side and these themes are quite extraneous to me, please don't blame me.
No, it is not possible.
Browser same-origin policy is designed to prevent malicious websites from doing evil.
Same-origin Policy restricts JavaScript network access to prevent evil.
Same-origin Policy also restricts script API Access to prevent evil.
From the Docs:
JavaScript APIs like iframe.contentWindow, window.parent, window.open, and window.opener allow documents to directly reference each other. When two documents do not have the same origin, these references provide very limited access to Window and Location objects.
To communicate between documents from different origins, use window.postMessage.
— MDN Web Security Reference - Cross-origin script API access
One can not use <iframe> elements as a way to "avoid cross site problems". The Same Origin Policy was created to protect users from evil web pages.

How to ensure that JavaScript page does not communicate

I created a small JavaScript application for which I reused some (quite large) JavaScript resources that I downloaded from the internet.
My application runs in the browser like other interactive web applications but works entirely offline.
However, I intend to enter some private information in the application which it shall visualize. Since I cannot ultimately trust the JavaScript pieces that I downloaded, I wonder if there is a JavaScript option to make sure that no data is downloaded and, in particular, uploaded to the web.
Note that I am aware that I can cutoff the local internet connection or perhaps change browser settings or use an application firewall, but this would not be a solution that suits my needs. You may assume that the isolation of a browser instance is save, that is no other, possibly malicious, web sites can access my offline JavaScript application or the user data I enter. If there is a secure way to (automatically) review the code of the downloaded resources (e.g. because communication is possible only via a few dedicated JavaScript commands that I can search for) that would be an acceptable solution too.
You should take a look at the Content Security Policy (CSP) (see here and here). This basically blocks every connection from your browser to any other hosts, unless explicitely allowed. Be aware that not all browsers support CSP, which leads to potential security problems.
Reviewing the library code might be difficult because there are many ways to mask such code pieces.
Find it yourself by watching your browser's network activity while your application is in action.
There are more than enough tools to do this. Also, if you know how to use netstat command line tool, it is readily shipped with windows.
Here is one cool chrome extension which watches the traffic of the current tab.
https://chrome.google.com/webstore/detail/http-trace/idladlllljmbcnfninpljlkaoklggknp
And, here is another extension which can modify the selected traffic.
https://chrome.google.com/webstore/detail/tamper-chrome-extension/hifhgpdkfodlpnlmlnmhchnkepplebkb?hl=en
You can set the filters and modify all requests/responses happening in your page.
If you want to write an extension to block requests yourself, check this answer out.

Can HTTP Access Control (CORS) prevent other domains from running my scripts?

I know by default the HTML page on other domains can't access my images, videos. They can only show them. But sadly, they can still run my scripts. If my script exposes some variables to the global scope, then the internal logic may be known by others.
I have a private website that others can't visit. Only I can visit it by sending a token in the Cookie to the server. If the token isn't included in the Cookie, every request will cause a 500 server error response. This is secure because everything is on HTTPS.
But unfortunately, I find this isn't very safe on my own machine, because after I visit my site and then visit a malicious site, this malicious site can use the following method to run my script:
<script src="https://my-website.com/main.js"></script>
That's because the Cookies of my website on my machine will be sent to my server as 3rd-party Cookies.
How to prevent that? Can access-control-allow-origin do so?
P.S. I don't want to disable all 3rd-party cookies in browser settings. Cookie's SameSite also doesn't make sense because only Chrome support it now.
There are a number of imaginable ways to prevent other sites from using the script element to run copies of scripts from your site in their sites, but CORS isn’t one of them.
Browsers are where the same-origin policy (SOP) is enforced and browsers are what block JavaScript running in Web apps from being able to use responses from cross-origin requests.
But browsers don’t use SOP/CORS when a Web app uses the script element to embed some JavaScript. Specifically, browsers don’t check that the script is served from the other site with an Access-Control-Allow-Origin header, which is the foundation of the whole CORS protocol.
So CORS is definitely not a solution to the problem you seem to want to solve.
But unfortunately, I find this isn't very safe on my own machine, because after I visit my site and then visit a malicious site, this malicious site can use the following method to run my script:
<script src="https://my-website.com/main.js"></script>
But if that site embeds your script in theirs that way, it runs within their origin, not yours. It runs there as a trusted script with all the same privileges of any script they’ve written themselves.
In that scenario, the other site is the one taking a security risk—because you can at any time change your https://my-website.com/main.js script to do anything you want at their site.
That is, by embedding your script that way, the other site gives your script programmatic fully-trusted access to do anything it wants at their entire origin—gifting you an XSS opportunity.

In modern browsers, is there any security limitation for JavaScript bookmarklets?

I read an article about bookmarklets which says that bookmarklets are so powerful they can be dangerous. For example, a malicious bookmarklet can collect your "cookies", "localStorage", the string in the password input box and then send it to a remote server, which is similar to "script injection".
I'm curious about that. Since this article was written in 2007 (8 years ago), is there any limitation for bookmarklets (as well as browser plugins) to improve the security in modern browsers?
Bookmarklets are scripts run by the user. Yes, they can do all of the things you mentioned (limited in the same way that any other code in the page you inject them into is limited), but only when the user triggers them. They are indeed script injection, but script injection by the person in charge of the machine. The user can do at least as much, and really quite a lot more, by opening the browser's developer's tools.
But answering the question you actually asked: No, I don't think any new restrictions have been put on bookmarklets in the last several years.
The Content Security Policy is not intended to affect bookmarklets:
Enforcing a CSP policy should not interfere with the operation of user-supplied scripts such as third-party user-agent add-ons and JavaScript bookmarklets.
but has some unintended consequences:
Bookmarklets. People love them, and CSP breaks them.
Instapaper, for instance, injects a script tag to load instapapering code from Instapaper's origin. I suspect it would end up injecting CSS as well. Though the bookmarklet itself executes as expected, it's actions on the page are subject to the page's policy, so these loads are likely blocked. That's certainly the case on mikewest.org and github.com.
CSP blocks javascript: protocol URIs which load external scripts:
Whenever the user agent would execute script contained in a javascript URI, instead the user agent must not execute the script. (The user agent should execute script contained in "bookmarklets" even when enforcing this restriction.)
Fixing that would make most of my bookmarklets work, but it won't help with bookmarklets associated with services like Pocket and SubToMe. Those bookmarklets load external scripts which will be blocked by GitHub's script-src CSP directive.
script-src can be circumvented by running bookmarklet code through developer tools or userscripts, but that's besides the point
...although you are limited in what URL you can use to inject a script into certain CSP-protected documents, you can insert ANY text DIRECTLY into the document.
A userscript which converts bookmarklets to script tags would be another workaround
References
Content Security Policy Level 2
The Resurrection of Bookmarklets
Chromium Issue 233903: CSP: Bookmarklets should bypass pages' policies
Mozilla Bug #866522- Bookmarklets affected by CSP
Webkit Bug 149000 – Some extensions triggers CSP violation reports
333318 - Remove support for BeforeLoad event - chromium - Monorail

What is the reason/background that the <script> tag is not part of the Same origin Policy

The last months I read a lot about the Same Origin Policy of browsers and Cross Domain Requests.
All the time I am wondering, for what reasons the <script> tag is not part of it?
I found the question to be asked several times, also here on stackoverflow, but all replies didn't answer why it isn't part of it.
Is this due to historical reasons or what is the background behind this idea?
I hope somebody can help me with this question.
I don't know they reasons that it was decided that foreign <script> didn't need to be blocked, but there are many benefits of that decision.
Not all scripts have to be hosted on your own site, and, as a corollary,
scripts can be hosted by content delivery networks that can deliver them faster and allow the client to use cached versions of popular scripts.
Foreign scripts allow us to have cross-domain AJAX requests via JSONP.
Also, script tags historically predate the Same Origin Policy, so it would make sense that scripts could reference files not necessarily hosted by the same site, to be consistent with how the a, img, embed, frame and other tags also did.
Certainly part of the reason is that the <script> tag is much older than the same origin policy, so preventing its use would break a lot of web pages.
I believe the other reason is that the same original policy works to prevent information from being accessed by a different origin than it was created in. The script tag doesn't permit information to be sent to its origin, or at least, no more information than any other GET request such as <style> or <img> would.
Though there are likely ways around it, script tag src parameters are generally fixed values set in your static HTML. Both historically and even now in terms of security risks, there's not much concern over cross-domain script requests in this fashion. On the other hand, there is certainly a large benefit in allowing it — CDNs for script downloads, jQuery hosted on the cloud, etc. There's also backward-compatibility to consider.
This is not quite as true for AJAX requests, where the script URL may (and often does) come from user input or other dynamic state. On average, the barrier to entry for breaking this is much lower than for breaking a script tag, where "breaking" = "causing a security breach".
Source: guessing

Categories

Resources