When a user is authenticated with a web service, an attacker can use cross-site request forgery (CSRF) to trick them into making a request to that service to perform a desired action.
If a service uses
GET requests for state-changing operations, the attacker could present the user with a link that triggers an unwanted update.
HTTP methods should be used as intended. Specifically, use
GET for state-changing operations. Assuming that this is the case,
GET requests can be considered safe: even if a request is unintended, its response is just returned harmlessly to the user’s browser.
POST requests can be protected by including a security token, verified by the server, in forms and AJAX requests, as happens in Ruby on Rails.
The same-origin policy
Whilst an attacker cannot use CSRF to steal data returned from a
GET request, they could theoretically do so by executing a script that makes an AJAX request to a third-party service with the user’s credentials and then forwards the response. Happily, browsers enforce the same-origin policy to protect against this.
The origin of a web page is generally the scheme, host and port taken together. Requests to a different origin than that of the requesting page are known as cross-origin requests. When a browser makes a cross-origin request as part of an AJAX call, the same-origin policy ensures that it will raise an error and not share the response with the calling code. The policy is intended to isolate content from different sources within the browser, and prevents AJAX requests from being used to read a user’s data from a third-party service.
‘Simple’ cross-origin requests (
POST, with certain content types) are attempted without preceding checks. Other requests (e.g.
POST with JSON or XML content,
DELETE) are subject to a preflight
OPTIONS request to determine whether or not the request is safe to send. This is mostly to protect older servers that might not be aware that browsers are now able to perform these cross-origin requests. Note that it is still necessary to take measures to protect against cross-origin
POST requests made via AJAX, which have always been possible.
Cross-Origin Resource Sharing (CORS) is a mechanism that allows site owners to selectively relax the same-origin policy by configuring their web server to set certain headers. Setting the
Access-Control-Allow-Origin header to a given origin, for example, will enable the browser to make cross-origin requests from this origin.
For credentials (cookies) to be used in such requests, they must be explicitly included in the request itself, and the
Access-Control-Allow-Credentials header must be set.