Cross Site Attacks Cross Site Scripting (XSS) attack occurs when a malicious user inserts code into a web-page that a user trusts. Cross Site Request Forgery (CSRF) occurs when a malicious web site causes a user’s web browser to execute an unwanted action on a trusted site. The HTML <img> Tag Insert an image into an HTML document. <img src="http://foo.bar/someImage.gif"> This instructs the browser to (silently) download an image using request: GET http://foo.bar/someImage.gif HTTP/1.1 The <img > tag causes an HTTP GET request by the browser regardless of the value of the given URL. The browser does not know beforehand whether the URL is a gif, jpg or something else. It needs to load/GET it into the browser in order to determine this. After all, the image could be generated by some program. <img src="http://foo.bar/getCurrentImage.php"> Alice is authorised to Access the foo.bar Website Suppose that foo.bar provides an application that can be used to set the current image. For example, Alice requests: GET http://foo.bar/setCurrentImage.php?imageID=1234 in order to set the current image to the image 1234. Suppose that website uses HTTP Basic authentication to control who may access/set the image and Alice has access to the website. Malicious Mike does not have access but would like to change the current image to 5678. He needs to trick Alice into submitting the HTTP request: GET http://foo.bar/setCurrentImage.php?imageID=5678 .. Authorization: Basic ...... (Alice’s credentials) Malicious Mike is not authorised to Access foo.bar Suppose that Malicious Mike owns the website evil.com and the web-page index.html on this site includes <img src="http://foo.bar/setCurrentImage.php?imageID=5678"> 1 Alice visits evil.com/index.html and the image tag causes Alice’s browser to silently perform GET http://foo.bar/setCurrentImage.php?imageID=5678 ..... Note that we assume here that Alice has configured her browser to ’remember’ her userid/password from some previous visit to the foo.bar website and that the browser does not prompt her to confirm entry. CSRF and Same Origin Security Policy A Cross Site Request Forgery occurs when an attacker can get a victim to perform an unwanted action on another site (where the victim holds the authorization to carry out the action). A CSRF attack attempts to exploit authorizations that the victim already holds. If the user has logged on to a web-site (and holds session authentication cookies) then the attacker will try to get the user to carry out an action that is authenticated by those cookies. The same origin policy was designed to prevent an attacker from accessing data on a third party site. The policy does not prevent requests from being sent, it only prevents an attack from reading the data returned from the third party server. Since CSRF attacks are the result of the requests sent then the same origin policy does not protect against a CSRF attack. More CSRF Attacks There have been many examples of CSRF based exploits. These include, CSRF vulnerability on ingdirect.com (2008, online banking) whereby an attacker can transfer money out of a victim’s online bank account. For example, <img src=http://www.mybank.com/transfer.do? fromAccount=document.form.frmAcct&toAccount=4590&amount=3434> YouTube.com (2007), whereby an attacker can add videos to the victim’s account, add himself to the friend/family groups of the victim, share victim’s contacts, flag videos, etc. Making changes to home DSL routers (2006). Even if the victim doesn’t know that he can congure his router! Attacker website uses CSRF with default userid/password for router: <img src=http://admin:password@192.168.1.1/> and then re-configures, for example to change the DNS, <img src=http://192.168.1.1/changeDNS?newDNS=143.23.45.1 2 Strategy to Help Avoid CSRF Attack? You want to force users to use your own forms when submitting data to your website. Problem with the above attacks is that the websites allowed GETs whereby the data can be provided in the URL as parameter. Any data that is going to be acted upon by a website should be submitted via a POST. Forms should use POST. Your PHP script should use $ POST and not $ REQUEST in the form processing logic. This still won’t work! The attacker can create an HTML page that includes a POST form with hidden fields for all of the relevant parameters required for the attack and has its target set to the vulnerable URL. JavaScript (or Flash) is used to automatically submit the form when the exploit is loaded. Cookies Alone Won’t Prevent CSRFs If a web-application relies solely on HTTP cookies as its mechanism for transmitting session tokens then it is still at risk from this attack. Cookies, even the secret ones, will be submitted with every request. All authentication tokens will be submitted regardless of whether or not the end-user was tricked into submitting the request. Session identifiers are simply used by the application container to associate the request with a specific session object. The session identifier does not verify that the end-user intended to submit the request. Preventing CSRF Attacks Using Synchronizer Tokens The strategy to avoid CSRF is for the application to include a synchronizer token in the HTML form. This is a secure random value that is stored in a hidden field in the form (often called CSRFToken). Every request for the form yields a different value embedded in the form and the attacker cannot guess the the value in a form presented to another user. <form action="/transfer.do" method="post"> <input type="hidden" name="CSRFToken" value="OWY4NmQwODE4ODRjN2Q2NTlhMmZlYWEwYzU1YWQwMTV hM2JmNGYxYjJiMGI4MjJjZDE1ZDZjMTViMGYwMGEwOA=="> ..... </form> When data, presumably from this form, is submitted to the application then the application must look for and check that the synchronizer token is the value expected. 3 This interaction is simple form of challenge-response protocol whereby the application expects to see its challenge embedded in the form as part of the response from a client. We must be careful how we implement the synchronizer tokens. For example, a naive implementation might maintain a list of issued synchronizer tokens in the application: Check that token in a POST is on this list, List will become very large unless we only keep track of recently issued tokens, and let older tokens expire. Need to relate the token to the session, otherwise a malicious user could first request a form in order to obtain a valid and fresh token which is then used in a CSRF involving the form. But this places a burden (state) on the application. A better strategy is to make it stateless by also ‘embedding’ the synchronizer within the session cookie. On receiving the HTTP request the application then checks that the token provided in the form matches the value embedded in the cookie. The attacker will need to know the cookie value in order to construct a valid looking request and carry out the CSRF attack. Implementing the CSRF Synchronizer in PHP We modify the setCurrentImage form to include a hidden CSRFTokenc field with a randomly generated value. This token is unique to and is stored in the user’s session. (weaker token is md5(uniqid(rand(), TRUE))) <?php session_start(); $CSRFToken = openssl_random_pseudo_bytes(32,True); $_SESSION[’CSRFToken’] = $CSRFToken; $_SESSION[’token_time’] = time(); ?> <form action="setCurrentImage.php" method="post"> <input type="hidden" name="CSRFToken" value="<?php echo $CSRFToken; ?>" /> <p> Symbol: <input type="imageID" name="imageID" /><br /> <input type="submit" value="Set" /> </p> </form> Application setCurrentImage.php can now check a request for the correct token. <?php if ($_POST[’CSRFToken’] == $_SESSION[’CSRFToken’] && time() - $_SESSION[’token_time’] <= 300) { // valid request via the form that was recently 4 // issued to the user in this session } ?> This strategy works so long as the attacker cannot discover the session cookies and synchronizer token transmitted to/from the user/application. Avoiding CSRF At the Server: Allow GET requests to only retrieve data, not modify any data on the server. This protects sites from CSRF attacks using <img > tags or other type of GET requests. Require all POST requests to include a synchronizer token. If really critical, use CAPTCHAs, ... At the Client: Logoff immediately after using a Web application Do not allow your browser to save username/passwords, and do not allow sites to remember your login Do not use the same browser session to access sensitive applications and to surf the Internet freely (tabbed browsing). The use of plugins such as No-Script makes POST based CSRF vulnerabilities difficult to exploit. 5