CSRF protection in browser extensions - google-chrome-extension

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.

Related

Is it insecure to include your login page in your single page application?

My understanding is that, if you include your login page in your SPA, then the user is receiving all of your code before they're even authenticated. And yet, it seems to be a very common practice. Isn't this incredibly insecure?? Why or why not?
An SPA would have all the page structures (html and javascript code for the design of pages), but obviously not data. Data would be downloaded in subsequent ajax requests, and that is the point. To download actual data, a user would have to be authenticated to the server, and all security would then be implemented server-side. An unauthorized user should not be able to access data from the server. But the idea is that how pages look is not a secret, anybody can have a look at pages of the SPA without data, and that's fine.
Well, and here comes the catch that people often overlook. Html is one thing, but there is all the javascript in an SPA that can access all the data. Basically the code of the SPA is an API documentation if you like, a list of possible queries that the backend can handle. Sure, it should all be secure server-side, but that's not always the case, people make mistakes. With such a "documentation" that an SPA is, it can be much easier for an attacker to evaluate server-side security and find authorization / access-control flaws in server-side code which may enable access to data that should not be accessible to the attacker.
So in short, having access to how pages look (without data) should be ok. However, giving away how exactly the API works can in certain scenarios help an attacker, and therefore adds some risk, which is inherent to SPAs.
It must be noted though that it should not matter. As security by obscurity should not be used (ie. it should not be a secret how things work, only things like credentials should be secrets), it should be fine to let anyone know all the javascript, or the full API documentation. However, the real world is not always so idealistic. Often attackers don't know how stuff works, and it can be of real help to be able to for example analyze an SPA, because people that write the backend code do make mistakes. In other cases the API is public and documented anyway, in which case having an SPA presents no further risk.
If you put the SPA behind authentication (only authenticated users can download the SPA code), that complicates CDN access a lot, though some content delivery networks do support some level of authentication I think.
Yet there is a real benefit of having a separate (plain old html) login page outside the SPA. If you have the login page in the SPA, you can only get an access token (session id, whatever) in javascript, which means it will be accessible to javascript, and you can only store it in localStorage, or a plain non-httpOnly cookie. This may easily result in the authentication token being stolen via cross-site scripting (XSS). A more secure option is to have a separate login page, which sets the authentication token as a httpOnly cookie, inaccessible to any javascript, and as such, safe from XSS. Note though that this brings the risk of CSRF, which you wil lhave to deal with then, as opposed to the token/session id being sent as something like a request header.
In many cases, having the login in the SPA and storing the authentication token in localStorage is acceptable, but this should be an informed decision, and you should be aware of the risk (XSS, vs CSRF in the other case).
It's clear that data loaded into an SPA must be secured behind an API through authn. But I think you can also secure layout so it is "less ok" having access to how pages look. With metamodel-driven development, you can serve layout configuration from a secured API. I am not talking about serving HTML (that's SSR), I am talking about serving JSON. That layout configuration is nothing but a JSON file on the server defining the content of your screen (fully or partially). Then your SPA code turns into a generic interpreter/render of that metamodel that parses the payload, renders components and binds data. If your API is L3, voilà, you get a fully working API-driven app.

phantomjs --web-security=no

In the documentation for phantomjs, there is an option to turn off web security and allow XHR (cross domain requests).
Does this present a security risk to a user if you are filling forms with credentials such as usernames and passwords and then downloading screenshots with casper/phantom?
Maybe.
Allowing cross domain XHR opens up a few attacks. E.g. see https://stackoverflow.com/a/7615287/841830. See also Is CORS a secure way to do cross-domain AJAX requests?
But this tends not to come up with the normal use cases for Phantom: whether you are testing your own web site, or screen-scraping, you tend to go to pre-decided URLs and links, and are not sending secret information, and are not going to be tricked by a new and suspicious link. You are unlikely to be logged into your bank, or Facebook, while testing your site or scraping google search results. (BUT, if you are scraping google pages that force you to sign into Google first, be a bit more careful - perhaps set up a dedicated gmail account just for your scraping.)
So, in summary, the attacks are a bit more obscure and unlikely, compared to a normal desktop browsing session, but they are still there, so only use --web-security=no when your script otherwise will not work.

Securing a RESTful API

For my current side project, which is a modular web management system (which could contain modules for database management, cms, project management, resource management, time tracking, etc…), I want to expose the entire system as a RESTful API as I think that will make the system as more usable. The system itself is going to be coded in ASP.MET MVC3 however if I make all the data/actions available through a RESTful API, that should make the system very easy to use with PHP, Ruby, Python, etc… (they could even make there own interface to manage certain data if they wanted).
However, the one thing that seems hard to do easily (from the user's using the RESTful API point of view) with a RESTful API is security with ajax functionality. If I wanted something that was complex to setup and use, I would just create SOAP services but the whole drive for using a RESTful API is that it is very easy. The most common way of securing a RESTful API with with a key that is associated with a user. This works fine when all the calls are done on the server side however once you start doing ajax functionality, that changes. I would want the RESTful API to be able to be called directly from javascript however anyone who are firebug would easily be able to access the key the user is using allow that person access to the system. Is there a better way the secure a RESTful API where it does not make the user of the RESTful API do complex things just to set it up?
For one thing, you can't prevent the user of your API to not expose his key.
But, if you are writing a client for your API, I would suggest using your server side to do any requests to the API, while your HTML pages provide the data from the user. If you absolutely must use Javascript to make calls to the API and you still have a server side that populates the page in question, then you can obscure the actual key via a one-way digest algorithm in a timestamp-dependant way, while generating the page, and make it that your api checks that digest in a time-dependant way too.
Also, I'd suggest that you take a look into OAuth Nonces and timestamps a bit more deeply. Twitter and other API providers obviously have this problem too, so they must be doing something with the Nonce values.
It is possible to make some signature in request from javascript. But I'm hot sure, how 'RESTfull' urls would be with this extra info. And there you have the same problem: anyone who can see your making-signature-algorithm can make his own signature, witch you server will accept as well.
SSL stands for secure socket layer. It is crucial for security in REST API design. This will secure your API and make it less vulnerable to malicious attacks.
Other security measures you should take into consideration include: making the communication between server and client private and ensuring that anyone consuming the API doesn’t get more than what they request.
SSL certificates are not hard to load to a server and are available for free mostly during the first year. They are not expensive to buy in cases where they are not available for free.
The clear difference between the URL of a REST API that runs over SSL and the one which does not is the “s” in HTTP:
https :// mysite.com/posts runs on SSL.
http :// mysite.com/posts does not run on SSL.

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.

Why is the http auth UI so poor in browsers?

Why isn't there a logout button? Why no list of "websites you're logged into"? Is it because of some issue with the HTTP specs?
Life would be much easier for web developers if they could actually rely on HTTP auth ...
As far as HTTP is concerned, it is stateless. One of the main reasons why Internet is scalable.
No technical reason. I suppose if anything, the auth UI is neglected because fewer and fewer web sites are still using HTTP Basic Authentication, trending more towards various cookie-related login schemes... precisely because the auth UI is so poor!
One could probably hack together a Firefox add-on to do it quite easily, which would be the quickest fix. (And the same goes for the other question with the poor file upload UI too.) I'd use it!
Have you entered a bug report for major browsers ? (At least, ones with bug trackers, Firefox, Chrome (Chromium) etc.
List of open HTTP Auth sessions would be useful.
Because it's not the browser that "knows" it's logged in. It's the server which authenticates the browser on every request. Every server can have different authentication mechanism - using different names and content for the authentication cookies, basic authentication, etc.

Resources