What is a good replacement for 'styled-components' in React application to produce secure web app? - styled-components

I came to a project that uses styled-components in the frontend written in React.
It seems the decision to use it was quite unfortunate as this component ignores security aspects and generates inlined styles.
Currently, in order to have the app running, there must be weakened security by specifying style-src 'unsafe-inline' in Content Security Policy, which is not acceptable in enterprise applications (at least in our corporate).
It seems there is no workaround with this library except using nonce when server side rendering but we have currently static web and would prefer not to add SSR so this does not seem to be the right direction for us.
There is quite lot of code and rewriting the app completely would require weeks maybe even a few month.
Any experience with gradual moving away from styled-components? Is there some less painful way to get the security back?

Inline styles could be of 3 kinds:
<style>...</style> blocks, they can be allowed with 'hash-value'.
style attribute in tags like <tag style='color:green; padding:0;'>, there is no way to allow them other than 'unsafe-inline' token.
Javascript calls of HTMLElement.setAttribute('style'). There is a workaround by substitutes the system HTMLElement.setAttribute(style) with HTMLElement.style.property = val.

Related

SameSite Flag against CSRF

I was wondering if the SameSite flag on the session cookie was enough of a protection against CSRF attacks.
I see CSRF token solution everywhere, but I am not sure about the need to use a CSRF token if the cookie used for authentication is already protected by the SameSite flag (in Strict mode).
On top of that, if I understood it well, tho cookie would still be sent along with subdomain URLs like api.myapp.com which would be perfect for my needs.
This is somewhat opinionated, or at least depends on your target audience and risk appetite.
SameSite=strict is supported in almost all fairly recent browsers as seen here, but note the exception of IE11. Not many people use IE11 anymore, but for them it will not be good enough. Only you can answer whether that's good enough for your usecase, as of writing this, a significant amount of users would not be protected.
Also the general consensus seems to be that SameSite should only be used as defense in depth (eg. here or here in a similar question), but most of the concern is around Lax, and less about Strict. However, Strict is very user-unfriendly, in a real-world application you probably can't really use Strict, because that's very bad UX.
The usual arguments are around browser support (as above), GET requests changing state (only relevant to Lax), and some special cases still revolving around GET changing state.
So my take currently is that the reason SameSite=Strict is not good enough in general is the lack of full browser support (IE11), and a strong point against it is bad user experience. I can imagine circumstances where it is good enough. SameSite=Lax I think is only a defense in depth measure, because of the issues above, which probably don't affect your application now, but might in the future, and nobody will remember to think about SameSite settings.
Excellent answer from Gabor which explains the problem well. There is a way to solve this though, if you set up your code like an SPA, to work like this:
Requests for web content (such as navigation) do not require a cookie
The SameSite=strict cookie is only used in Ajax requests to get data
HOW IT WORKS
If your web app runs at https://mywebapp.com
Then issue the secure cookie as the result of calling an API at https://api.mywebapp.com
The cookie has a domain of .mywebapp.com and is SameSite + Cross Origin
OAUTH
For an OAuth back end for front end solution you would do this:
Host the API at https://api.mywebapp.com
When the web app receives an OAuth response, it sends the Authorization Code to the API
The API processes it, then issues a strongly encrypted cookie containing tokens

Implementing CSP into ASP web app

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

CSRF protection in browser extensions

I need to implement CSRF protection for my site. So I started implementing this for all forms from my site, but I have problems with implementation of it in browsers extensions (Chrome, Safari, Firefox). I have no ideas how to do this for posts from my extensions(forms and ajax posts). Had anyone implemented this ever?
Well, here are some things that I saw people actually use - in my function as addons.mozilla.org (code) reviewer:
Design a proper API. There are tons of resources on SO and the web, e.g. detailing how to properly build e.g. Restful APIs and secure them against CSRF. The thing to keep in mind is that extension APIs in contrast to regular web pages provide XHR that either doesn't care same-origin or let you define a set of locations the extension is allowed to access. Hence extension-specific APIs not need to implement CORS, which shrinks the attack surface on such APIs quite a bit. Of course, it would be better to go the extra-mile and ensure your API is secure even with CORS.
Designing a full web API can take quite a lot of time. I saw people build a very minimal one: The API consists of a single method to get the CSRF token to be used with the regular not-very-APIy existing forms.
If you cannot implement a proper API, because e.g. it's not your site/code or you simply lack the time, resources and/or skills to learn about and then design and implement an API, there is still another way: Just web-scrape the site (XHR + regex usually) and get the CSRF token that way. Again, extensions do not have to abide same-origin, so web-scraping is always a possibility, while web sites cannot do the same thing unless allowed by CORS.
Almost forgot: Some extensions are nothing more than a button that will open a regular webpage on the server - not necessarily in a regular tab, but often in some kind of panel as provided by the extension API you're dealing with.

Cakephp Security

I am new to Security of Web apps. I am developing an application in Cakephp and one of my friends told me about the Cross-site request forgery (CSRF) and cross-site scripting (XSS) attacks etc. not sure how many more are there.
I need some help in understanding how to make Cakephp defend my web app against these. we are low budget and we cant hire a security consulant as of now. We are still developing the app and plan to release in by the end of the month. so wanna take care of the initial stuff that can help me stand un hacked ;)
There is not (and cannot be) one tool you can deploy and then never have to think about security again. Deploying ‘anti-XSS’ hacks like CakePHP's Sanitize::clean will get in users' way by blocking valid input, whilst still not necessarily making the app secure. Input filtering hacks are at best an obfuscation measure, not a fix for security holes.
To have a secure web application, you must write a secure web application, from the ground up. That means, primarily, attention to detail when you are putting strings from one context into another. In particular:
any time you write a string to HTML text content or attribute value, HTML-escape it (htmlspecialchars()) to avoid HTML-injection leading to XSS. This isn't just a matter of user input that might contain attacks, it's the correct way to put plain text into HTML.
Where you are using HTML helper methods, they should take care of HTML-escaping of those elements by default (unless you turn off escape); it is very unfortunate that the CakePHP tutorial includes the bad practice of echoing unescaped strings into HTML for text outside of HTML helpers.
any time you create SQL queries with string values, SQL-escape it (with an appropriate function for your database such as mysql_real_escape_string).
If you are using CakePHP's ORM and not writing your own SQL you don't have to worry about this.
avoid using user input (eg file upload names) to name files on the filesystem (generate clean unique IDs instead) or as any part of a system() command.
include the Security component to add a form submission token scheme that will prevent XSRF on forms generated by CakePHP.
Cake can be secured relatively easy (compared to self written php scripts):
http://www.dereuromark.de/2010/10/05/cakephp-security/

Safe implementation of script tag hack to do XSS?

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.

Resources