We're trying to implement CSP into one of our sites and although we understand how to allow or not allow scripts, we're still confused on the nonce/sha* part. We have outside scripts such as bootstrap and jquery that come with the integrity="sha*" and that inline scripts or styles should be avoided. Everything inline should be refactored into an external file.
The question we have is, do we create a sha* key/nonce-* for every js or css file in our site (not external) or just putting 'self' after script-src/style-src in the Content-Security-Policy is sufficient?
Thanks for any help on this.
You don’t need nonces for linked JavaScript files; they authorize inline Script tags. The “self” (or URL) authorize the linked files. The cleanup you have to do is get rid of “onclick” attributes in the HTML. The SHA hashes are there to verify the integrity of the linked files.
So:
Clean up inline “onclick” (and similar), and “style” attributes.
Use nonces for inline script (and style) tags.
Use SHA hashes for linked scripts from outside sources
Related
Can anyone know how to remove unsafe inline and unsafe eval from content security policy using nonce,
anyone have any resource how to implement nonce as i am unable to implement it properly i think i am getting errors in node.js application.
I have tried the helmet, meta tags, set Headers nothing worked.
You can't remove 'unsafe-eval' with nonces, you'll need to rewrite or replace the code.
Nonces are hard. You will need to insert the nonce in the CSP and in code dynamically. It also needs to change with every pageload to be secure. Frameworks don't always permit this. Also remember that inline event handlers aren't nonceable and need to be rewritten. I would suggest to try to rewrite all static script and style into separate files and then see if you still need nonces for the rest or if you can handle it in other ways.
https://github.com/wyday/mod_cspnonce is an apache module that can be used to implement nonce in place of unsafe-inline.
We are working on a new feature within Node JS application, where the user can upload any document (pdf, excel, img, etc) and we'll process it in order to show it to other users. Process- I mean to get it's text, generate thumbnail, count pages and more.
While doing it we have a very important point to think of - how can we make sure that no attackers are using this feature to atack our site or even our users?
While the XSS is very poplar point- I'm sure there are other vulnerabilities we should prevent.
I'm sure this subject is a main point of any site/tool that manipulates UGC,
but I was not able to find any standards/cheat-sheats/even a bullets list that describes the process of protect my site while manipulating UGC.
Any reference, link, knowledge share or even an example of another dev language will be appreciate!
Web security has a big scope but you're right, XSS is the most popular but it has a few types:
Reflected XSS - where the malicious script comes from the current HTTP request.
Stored XSS - where the malicious script comes from the website's database.
DOM-based XSS - where the vulnerability exists in client-side code rather than server-side code
In my opinion, the third one (Dom-based) is the most actual for your app because people can upload some script that will be located in the IMG SRC and when the user loads this image - the malicious script could steal sensitive data such as Cookies/auth tokens, etc.
The most popular protection, in this case, is just to sanitize the special symbols during the "handling process". Sanitize is when you replace the HTML symbols into HTML entities such as: < to < etc.
You can manually create some Regexp to do it but I'd rather suggest using something like that: dompurify it has many useful features such as:
Supports HTML, MathML, and SVG
Supports the usual tag/attribute whitelisting/blacklisting and URL regex whitelisting
Has special options to sanitize further for certain common types of HTML template metacharacters
and many others
About Web Security whitelists and other possible vulnerabilities.
Please, check these ones, I think they might be useful for you
Web Security OWASP cheatsheet - This resource contains a very detailed list with all possible web security rules with examples and solutions
OWASP XSS Filter cheatsheet - The document especially for XSS as the most common one
An automated scanning tool is flagging the fact that our Javascript bundle is not being returned with a Content-Security-Policy header even though the document itself has the header.
My understanding is that the Content-Security-Policy header controls the loading of resources within a document. Does it provide any benefit when added to the resources themselves?
The short answer is generally no.
The long answer is you need to set your content-types properly. There is a scenario if you don't set correctly content-type it lead issues unless js files are not static, rendered in the background. If an attacker could find the manipulate first bytes of dynamic JS files, they could run those file context as an HTML. So if you don't use dynamic JS files or those files don't allow to manipulate first bytes. You don't need to set CSP policies.
I host a website that allows users to download a file that is stored on a content distribution network (CDN). The link to the file on the CDN from my site is something like <a href=https://cdndomain.com/path/to/file>. I’d like to have a way for my users to ensure that file has not been manipulated by the CDN.
Of course, I can publish a hash of the file on my site (which of course is secured by SSL/TLS). Then, after the user downloads the file, they can take a hash of the file and verify that it matches the hash published on my site. This is not uncommon. But, many of my users are not savvy enough to understand this process. And, even for those that are, this process is somewhat cumbersome. I’m looking for a more automated/convenient way to ensure that file has not been manipulated.
I know that Content Security Policy (CSP) and Subresource Integrity (SRI) are now supported by Chrome, Firefox, and Safari. Using CSP/SRI, sites can ensure that .js files, .css files, etc., hosted elsewhere and referenced by <script> or <link> tags have not been manipulated, by including hashes of the target files in the <script> or <link> tags using the integrity attribute, e.g.:
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
or
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
This is very convenient, because the browser checks that the hash of the target file matches the hash specified in the integrity attribute ‘behind the scenes’, without any user intervention. After downloading the file from the CDN, the browser takes a hash of the file and checks that this hash matches the hash provided in the integrity attribute of the <script> or <link> tag. If the hashes does not match, the browser warns the user and does not execute the script or apply the css stylesheet.
I’m looking for something similar for a resource referenced in an <a> tag – whereby I can specify a hash of the target resource in the <a> tag, and the browser would perform a similar check after downloading the resource from the CDN, but before making it available to the user, and warn the user if the hashes do not match. But according to the MDN docs referenced above, CSP and SRI only apply to <script> tags and <link> tags, not to <a> tags.
Does anyone know of a solution?
Neither SRI nor CSP is really made for that; the item isn't actually being loaded on the page so neither of them will actually fire not that there's a way to specify requirements on an <a> tag anyway.
It's not quite the security vector either of these are made for either; these are meant to stop malicious code from being run in the browser. Once you've downloaded a file you're pretty much on your own unless it triggers the built-in Chrome "suspicious download" warning.
I would say your options are:
A) Provide a page where the user can upload the file to generate said hash for them and, while you're under the hood, might as well actually match it and generate a message that says "this matches the hash of X file!"
B) Ditch the CDN. They are by definition a Man In The Middle, so to fully trust TLS you'd need to deliver the file directly to the user or at least have full control of the CDN.
Which you pick depends on a combination of how much effort you want to put and how practical it is to ditch your CDN. Obviously A) lets you keep your CDN but is far more programming, B) is basically free of programming but could be extremely easy or completely impossible logistically.
Take a look at this script https://github.com/ShopupStore/IntegrityChecker , Even though it is for image, you will get the Idea for implementing it for tag. This script uses sha256 polyfill for the purpose, The final markup may look like this
<a data-href="https://cdn.example.com/1.jpg" data-hash="496aa8990b87f584dffc43e5953d38abcbc30a2edab131fd304fec43d6d9b289" data-fallback="https://example.com/1.jpg" class="link">
Like a lot of developers, I want to make JavaScript served up by Server "A" talk to a web service on Server "B" but am stymied by the current incarnation of same origin policy. The most secure means of overcoming this (that I can find) is a server script that sits on Server "A" and acts as a proxy between it and "B". But if I want to deploy this JavaScript in a variety of customer environments (RoR, PHP, Python, .NET, etc. etc.) and can't write proxy scripts for all of them, what do I do?
Use JSONP, some people say. Well, Doug Crockford pointed out on his website and in interviews that the script tag hack (used by JSONP) is an unsafe way to get around the same origin policy. There's no way for the script being served by "A" to verify that "B" is who they say they are and that the data it returns isn't malicious or will capture sensitive user data on that page (e.g. credit card numbers) and transmit it to dastardly people. That seems like a reasonable concern, but what if I just use the script tag hack by itself and communicate strictly in JSON? Is that safe? If not, why not? Would it be any more safe with HTTPS? Example scenarios would be appreciated.
Addendum: Support for IE6 is required. Third-party browser extensions are not an option. Let's stick with addressing the merits and risks of the script tag hack, please.
Currently browser venders are split on how cross domain javascript should work. A secure and easy to use optoin is Flash's Crossdomain.xml file. Most languages have a Cross Domain Proxies written for them, and they are open source.
A more nefarious solution would be to use xss how the Sammy Worm used to spread. XSS can be used to "read" a remote domain using xmlhttprequest. XSS isn't required if the other domains have added a <script src="https://YOUR_DOMAIN"></script>. A script tag like this allows you to evaluate your own JavaScript in the context of another domain, which is identical to XSS.
It is also important to note that even with the restrictions on the same origin policy you can get the browser to transmit requests to any domain, you just can't read the response. This is the basis of CSRF. You could write invisible image tags to the page dynamically to get the browser to fire off an unlimited number of GET requests. This use of image tags is how an attacker obtains documnet.cookie using XSS on another domain. CSRF POST exploits work by building a form and then calling .submit() on the form object.
To understand the Same Orgin Policy, CSRF and XSS better you must read the Google Browser Security Handbook.
Take a look at easyXDM, it's a clean javascript library that allows you to communicate across the domain boundary without any server side interaction. It even supports RPC out of the box.
It supports all 'modern' browser, as well as IE6 with transit times < 15ms.
A common usecase is to use it to expose an ajax endpoint, allowing you to do cross-domain ajax with little effort (check out the small sample on the front page).
What if I just use the script tag hack by itself and communicate strictly in JSON? Is that safe? If not, why not?
Lets say you have two servers - frontend.com and backend.com. frontend.com includes a <script> tag like this - <script src="http://backend.com/code.js"></script>.
when the browser evaluates code.js is considered a part of frontend.com and NOT a part of backend.com. So, if code.js contained XHR code to communicate with backend.com, it would fail.
Would it be any more safe with HTTPS? Example scenarios would be appreciated.
If you just converted your <script src="https://backend.com/code.js> to https, it would NOT be any secure. If the rest of your page is http, then an attacker could easily man-in-the-middle the page and change that https to http - or worse, include his own javascript file.
If you convert the entire page and all its components to https, it would be more secure. But if you are paranoid enough to do that, you should also be paranoid NOT to depend on an external server for you data. If an attacker compromises backend.com, he has effectively got enough leverage on frontend.com, frontend2.com and all of your websites.
In short, https is helpful, but it won't help you one bit if your backend server gets compromised.
So, what are my options?
Add a proxy server on each of your client applications. You don't need to write any code, your webserver can automatically do that for you. If you are using Apache, look up mod_rewrite
If your users are using the latest browsers, you could consider using Cross Origin Resource Sharing.
As The Rook pointed out, you could also use Flash + Crossdomain. Or you could use Silverlight and its equivalent of Crossdomain. Both technologies allow you to communicate with javascript - so you just need to write a utility function and then normal js code would work. I believe YUI already provides a flash wrapper for this - check YUI3 IO
What do you recommend?
My recommendation is to create a proxy server, and use https throughout your website.
Apologies to all who attempted to answer my question. It proceeded under a false assumption about how the script tag hack works. The assumption was that one could simply append a script tag to the DOM and that the contents of that appended script tag would not be restricted by the same origin policy.
If I'd bothered to test my assumption before posting the question, I would've known that it's the source attribute of the appended tag that's unrestricted. JSONP takes this a step further by establishing a protocol that wraps traditional JSON web service responses in a callback function.
Regardless of how the script tag hack is used, however, there is no way to screen the response for malicious code since browsers execute whatever JavaScript is returned. And neither IE, Firefox nor Webkit browsers check SSL certificates in this scenario. Doug Crockford is, so far as I can tell, correct. There is no safe way to do cross domain scripting as of JavaScript 1.8.5.