Browser Binding CSRF Defense and Authentication



Browser Binding CSRF Defense and AuthenticationFlorian Müller, 2011-06-09This document describes a possible solution for the CSRF problem that we discover with the Bowser Binding. In order to understand this issue, please refer to the SC discussions. This idea needs verification. Parts of it have been implemented but there is no complete end-to-end test, yet.Tokens and HashingThe basic problem is that the browser doesn’t know which application or script the user has authorized to talk to a CMIS repository. We have to prevent a malicious script from taking over a legitimate, open session. Basic authentication and cookies set by the CMIS repository are not an option because the browser would send them with all requests from all applications/scripts.Since CMIS repositories may contain sensible data, we have to protect both, GET and POST requests.Adding a token that is only shared by the application and the repository can protect POST requests. A GET URL has to be signed. Signing requires a session and a secret token.The problem boils down to how tokens are exchanged in secure manner.There are not many options. Here is one.Message Exchange between FramesThe most complicated scenario is this:The application is hosted on one domain; the repository CMIS interface is served from another domain. There is no proxy processes on the application server. That is, all communication between the application and the repository has to happen in the browser. This is difficult because the cross-domain-policy prohibits a direct and secure two-way communication between the application and the repository.There is one exception to this rule. HTML windows and frames can exchange (string) messages via postMessage(). The postMessage() operation is defined in HTML 5 but is already supported by all major browsers for several years. We can assume that it is supported in the current and at least one previous version of most browsers. Here is how an application can securely get hold of the session and the secret token:The application embeds a hidden iframe. The content of this iframe is loaded from the repository server and contains JavaScript code that can handle messages.The application sends a message to the iframe, requesting a session and a secret token.The JavaScript code in the iframe receives the message. If the repository doesn’t require any authentication or if the user can be identified in any other way (e.g. SSO), the iframe sends a session and a secret token to the application window. How these tokens are generated and managed (storage, expiration, etc.) is up to the repository. If the repository needs further authentication, it sends a URL to the application windows. The URL should point to a login page.If the application receives the tokens, it should remember them for the rest of session. It could, for example, store them into a cookie.If the application receives a login URL, it can open this page in another iframe or a popup window. It is important that the application window is the parent of the login window. The repository can now do whatever it has to do to authenticate the user. For example, it can present a login form. Finally, it sends a session and a secret token to its parent window, which is the application window or frame.At this point the application has a session and a secret token. GET URLs can be signed (see below) and the two tokens can be added to POST requests to verify the request origin. Signing URLs is common these days. There several different variations but the basic idea is this:Either the whole URL or a least its query parameters are hashed together with the secret token. The session token is added to the URL to identify the session. Note that there is no hash operation in JavaScript. We would have to choose a well-known algorithm with freely available (and fast) JavaScript implementations.How and why is that different from other APIsSigning URLs and adding tokens to POST requests is common practice. The main difference to other APIs is how the required tokens are obtained.Many public APIs require a registration of an application or a developer. During this registration some kind of key or id is issued that then plays a role in the URL signing process.One objective of CMIS is that the repository should not require any code change to support CMIS. A registration process that would require the repository to permanently store keys would be such a change.Moreover, we want applications to connect to CMIS repositories without previous registration. Only the user credentials should be required.Some APIs hide tokens and hashes in HTTP headers. We cannot do that because there is no way in JavaScript to add HTTP headers to requests that are going to a domain other than the application domain. That is, we have to add this information to the URL, respectively the POST payload.ToDosDefine the messages between the application frame and the repository (hidden) frame. We can only use strings, which might restrict the character set that can be used for tokens.Define how the URL signing should work. What should be signed (URL, query parameters) and how (MD5, SHA-1, SHA-256, HMAC ?). There are plenty of examples. We have to pick one that is easy to implement in pure JavaScript.Eventually, implement this and see if it is feasible. ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download