 |
|
Cross-Site Request Forgery
|
| |
Cross-Site Request Forgery (CSRF) is an attack that tricks
the victim into loading a page that contains a malicious
request. It is malicious in the sense that it inherits the
identity and privileges of the victim to perform an undesired
function on the victim's behalf, like change the victim's e-mail
address, home address, or password, or purchase something. CSRF
attacks generally target functions that cause a state change on
the server but can also be used to access sensitive data.
For most sites, browsers will automatically include with such
requests any credentials associated with the site, such as the
user's session cookie, basic auth credentials, IP address,
Windows domain credentials, etc. Therefore, if the user is
currently authenticated to the site, the site will have no way
to distinguish this from a legitimate user request.
In this way, the attacker can make the victim perform actions
that they didn't intend to, such as logout, purchase item,
change account information, retrieve account information, or any
other function provided by the vulnerable website.
Sometimes, it is possible to store the CSRF attack on the
vulnerable site itself. Such vulnerabilities are called Stored
CSRF flaws. This can be accomplished by simply storing an IMG or
IFRAME tag in a field that accepts HTML, or by a more complex
cross-site scripting attack. If the attack can store a CSRF
attack in the site, the severity of the attack is amplified. In
particular, the likelihood is increased because the victim is
more likely to view the page containing the attack than some
random page on the Internet. The likelihood is also increased
because the victim is sure to be authenticated to the site
already.
Synonyms: CSRF attacks are also known by a number of other
names, including XSRF, "Sea Surf", Session Riding, Cross-Site
Reference Forgery, Hostile Linking. Microsoft refers to this
type of attack as a One-Click attack in their threat modeling
process and many places in their online documentation.
How does the attack work?
There are numerous ways in which an end-user can be tricked
into loading information from or submitting information to a web
application. In order to execute an attack, we must first
understand how to generate a malicious request for our victim to
execute. Let us consider the following example: Alice wishes to
transfer $100 to Bob using bank.com. The request generated by
Alice will look similar to the following:
POST http://bank.com/transfer.do HTTP/1.1
...
...
...
Content-Length: 19;
acct=BOB&amount=100
However, Maria notices that the same web application will
execute the same transfer using URL parameters as follows:
GET http://bank.com/transfer.do?acct=BOB&amount=100 HTTP/1.1
Maria now decides to exploit this web application
vulnerability using Alice as her victim. Maria first constructs
the following URL which will transfer $100,000 from Alice's
account to her account:
http://bank.com/transfer.do?acct=MARIA&amount=100000
Now that her malicious request is generated, Maria must trick
Alice into submitting the request. The most basic method is to
send Alice an HTML email containing the following:
<a href="http://bank.com/transfer.do?acct=MARIA&amount=100000">View my Pictures!</a>
Assuming Alice is authenticated with the application when she
clicks the link, the transfer of $100,000 to Maria's account
will occur. However, Maria realizes that if Alice clicks the
link, then Alice will notice that a transfer has occurred.
Therefore, Maria decides to hide the attack in a zero-byte
image:
<img src="http://bank.com/transfer.do?acct=MARIA&amount=100000" width="1" height="1" border="0">
If this image tag were included in the email, Alice would
only see a little box indicating that the browser could not
render the image. However, the browser will still
submit the request to bank.com without any visual indication
that the transfer has taken place.
-
Prevention measures that do
NOT work
- Using a secret cookie
- Remember that all 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. Furthermore, 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.
- Only accepting POST requests
- Applications can be developed to only accept POST
requests for the execution of business logic. The
misconception is that since the attacker cannot construct a
malicious link, a CSRF attack cannot be executed.
Unfortunately, this logic is incorrect. There are numerous
methods in which an attacker can trick a victim into
submitting a forged POST request. The two most common
methods are through the use of phishing sites (sites which
appear to look like another valid site) and through the use
of XMLHTTPRequest in a Cross-Site Scripting attack.
- Add a per-request nonce to URL and all forms in addition
to the standard session. This is also referred to as "form
keys". Many frameworks (ex, Drupal.org 4.7.4+) either have
or are starting to include this type of protection
"built-in" to every form so the programmer does not need to
code this protection manually.
- TBD: Add a per-session nonce to URL and all forms
- TBD: Add a hash(session id, function name, server-side
secret) to URL and all forms
- TBD: .NET - add session identifier to ViewState with MAC
- Checking HTTP referrer details can help mitigate the
attack but does certainly not provide a bullet proof
solution. By ensuring the HTTP posts have come from the
original site means that the attacks from other sites will
not function. However, if the CSRF attack was used in
combination with XSS on the original site then this
mechanism will not provide any protection.
- "Although cross-site request forgery is fundamentally a
problem with the web application, not the user, users can
help protect their accounts at poorly designed sites by
logging off the site before visiting another, or clearing
their browser's cookies at the end of each browser session."
|