In-depth analysis of CSRF attack mode and defensive course

Source: Internet
Author: User
Tags current time hash http request md5 php code rand unique id csrf attack

What is CSRF?

CSRF (Cross-site request forgery), Chinese name: cross-station requests for forgery, also known as: one click Attack/session Riding, abbreviated as: CSRF/XSRF.

What can csrf do?

You can understand that. CSRF attack: An attacker steals your identity and sends a malicious request in your name. The things that CSRF can do include: Send your email, send a message, steal your account, even buy a product, virtual money transfer ... Problems caused include disclosure of personal privacy and property security.

CSRF Vulnerability Status

CSRF This mode of attack in 2000 has been proposed by foreign security personnel, but at home, until 06 began to be concerned, 08, domestic and foreign large communities and interactive sites broke csrf vulnerabilities, such as: NYTimes.com (New York Times), MetaFilter (a large blog site), YouTube and Baidu Hi ... Now, many sites on the internet are still so defenseless that the security industry calls CSRF a "sleeping giant".

The principle of CSRF

The following figure briefly describes the idea of a CSRF attack:

Csrfyl

As you can see from the diagram above, to complete a csrf attack, the victim must complete two steps in turn:

Log on to the trusted Web site A and generate cookies locally.
Visit dangerous website B without logging out a.
See here, you may say: "If I do not meet one of the above two conditions, I will not be csrf attack." Yes, it does, but you can't guarantee that the following will not happen:

You can't guarantee that after you log in to a website, you will no longer open a tab page and visit another website.
You cannot guarantee that your local cookie expires immediately after you close the browser, and your last session has ended. (In fact, closing a browser does not end a session, but most people will mistakenly think that closing the browser is tantamount to exiting the login/end session ...). )
The so-called attack site on the image above may be a trusted and frequently accessed site with other vulnerabilities.
Above about CSRF attack thought, I will use a few examples to detail the specific CSRF attack, here I take the operation of a bank transfer as an example (just for example, the real bank site is not so silly:>)

Example

Example 1

Bank A, which completes the bank transfer operation with a GET request, such as: http://www.111cn.net/Transfer.php?toBankId=11&money=1000

Dangerous website B, which has a section of HTML code as follows:

Xhtml

First, you log on to bank A, then visit the dangerous site B, oh, then you will find that your bank account is less than 1000 pieces ...

Why is that? The reason is that the bank site a violates the HTTP specification and updates the resource with a GET request. Before visiting the dangerous website B, you have logged on to bank A, while in B requests Third-party resources (the third party in this case is the bank site, which was a legitimate request, but was exploited by outlaws), So your browser will take your bank site a cookie to issue a GET request to obtain the resource "http://www.111cn.net/Transfer.php?toBankId=11&money=1000", As a result, when the bank Web server received the request, it was considered an update resource operation (transfer operation), so the transfer operation was carried out immediately.

Example 2

In order to eliminate the above problem, the bank decided to use POST request to complete the transfer operation.

The Web Form for bank Web A is as follows:

Xhtml

<form action= "transfer.php" method= "POST" >
<p>tobankid: <input type= "text" name= "Tobankid"/></p>
<p>money: <input type= "text" name= "Money"/></p>
<p><input type= "Submit" value= "Transfer"/></p>
</form>
The background processing page transfer.php as follows:

Php

<?php
Session_Start ();
if (Isset ($_request[' tobankid '] && isset ($_request[' money '))
{
Buy_stocks ($_request[' Tobankid '], $_request[' money ']);
}
?>
Dangerous website B, still just contains the sentence HTML code:

Xhtml

As in Example 1, you first log on to bank A, then visit the dangerous website B, and the results ... As with example 1, once again, you are out of 1000 ~t_t, the reason for this accident is that the bank used $_request to get the requested data, and $_request can get the data of the getting request and the POST request. This results in a background handler that cannot tell whether this is the data for a GET request or a POST request. In PHP, you can use $_get and $_post to obtain data for GET requests and post requests, respectively. In Java, the problem of getting request data and post data cannot be distinguished as there is a request for requests.


Example 3

After the first 2 painful lessons, the bank decided to get the request data method also changed, instead of $_post, only get the POST request data, background processing page transfer.php code as follows:

<?php
Session_Start ();
if (Isset ($_post[' tobankid '] && isset ($_post[' money '))
{
Buy_stocks ($_post[' Tobankid '], $_post[' money ']);
}
?>
However, the dangerous website B with the Times, it changed the code:
<script type= "Text/javascript" >
function Steal ()
{
iframe = document.frames["steal"];
Iframe.document.Submit ("transfer");
}
</script>

<body onload= "Steal ()" >
<iframe name= "Steal" display= "None" >
<form method= "POST" name= "transfer" action= "http://www.111cn.net/Transfer.php" >
<input type= "hidden" name= "Tobankid" value= "one" >
<input type= "hidden" name= "Money" value= "1000" >
</form>
</iframe>
</body>
If the user is still on the above operation, unfortunately, the result will be no more than 1000 pieces ... Because here Dangerous website B secretly sent a POST request to the bank!

To summarize the above 3 examples, the main attack mode of CSRF is basically the above 3 kinds, of which the 1th and 2 kinds are the most serious, because the trigger condition is very simple, one is OK, and the 3rd kind is troublesome, need to use JavaScript, So the chances of using it are much less than in front, but either way, as long as the csrf attack is triggered, the consequences can be serious.

Understanding the above 3 attack patterns, in fact, can be seen, CSRF attack is originated from the web's implicit authentication mechanism! Although the authentication mechanism of the Web ensures that a request is from a user's browser, it cannot guarantee that the request was sent by the user.

The defense of the CSRF

I summed up the information to see, CSRF defense can be from the server and client two aspects, the defensive effect is from the service side of the effect is better, now the general CSRF defense is also in the service side.

The service side carries on the CSRF defense

There are many ways to csrf the service side, but the overall idea is consistent, that is, to increase the number of pseudorandom numbers on the client page or to detect whether the access routing is trustworthy.

Cookie hashing (all forms contain the same pseudo-random value)

The first scenario might be the simplest and quickest solution to the problem, since an attacker could not obtain the content of the attacker's cookies and would not be able to construct the appropriate form.

<?php
Constructing the encrypted cookie information
$value = "DEFENSESCRF";
Setcookie ("Cookie", $value, Time () +3600);
?>
Add a hash value to the form to authenticate that this is really a request sent by the user.

<?php
$hash = MD5 ($_cookie[' COOKIE '));
?>
<form method= "POST" action= "transfer.php" >
<input type= "text" name= "Tobankid" >
<input type= "text" name= "Money" >
<input type= "hidden" name= "hash" value= "<?= $hash;? > ">
<input type= "Submit" name= "submit" value= "Submit" >
</form>

Then hash value validation on the server side


<?php
if (Isset ($_post[' check ')) {
$hash = MD5 ($_cookie[' COOKIE '));
if ($_post[' check '] = = $hash) {
Dojob ();
} else {
//...
}
} else {
//...
}
?>
In fact, if we don't consider the fact that users ' cookies are easily stolen because of an XSS leak in the Web site (which we already know is not uncommon), this is a good response to the CSRF solution. This approach can be more secure if we add random cookies to every form request for a user, but this is not a good fit.


HTTP Routing

The easiest way to detect the credibility of access routing is to get the routing information in the HTTP request (that is, the HTTP header named Referer) and check it from within the station or from a remote malicious page: This is a good solution, However, this approach is not effective in preventing attacks because they can be spoofed by the requests that the server obtains to make them appear to be legitimate.

Let's see why this is not the right approach. The following code shows an example of an HTTP Referer implementation method:

check.php

if (eregi ("Www.111cn.net", $_server[' Http_referer ')) {
Do_something ();
} else {
echo "Malicious request!";
}
This test will easily ignore the fake HTTP Referer spoofing from an attacker, and an attacker could use the following code:


Header ("Referer:www.111cn.net");

or other methods that fake HTTP headers in malicious scripts and send them.

Because HTTP Referer is sent by the client browser and not by the server, you should not use the variable as a source of trust.

Verification Code

Another way to solve this problem is to use a random captcha in each form that the user submits, allowing the user to fill in the text box with a random string on the picture and testing it after submitting the form.

This method was previously discarded by people, because the use of the captcha image involves a bug called MHTML that may be affected in some versions of Microsoft IE.

You can get more information about this flaw in the Secunia site: http://secunia.com/advisories/19738/.

Here is Secunia's overview of this bug explanation:

"This flaw is caused by a URL processor redirection that handles" MHTML: ". It can be used to access the current document from another Web site.

In fact, we know that this bug has been solved by Microsoft's release of Windows XP and Windows Vista and its browser IE6.0 's fix pack. Even if he does have security problems, there will be other reliable solutions for a long time to come.


Disposable token

Now let's look at one of the last solutions that I want to introduce: After using these unreliable technologies, I try to do something different and yet more effective.

To prevent Web forms from being attacked by session spoofing (CSRF), I decided to detect every project that could be disguised or falsified. So I need to create a one-time token that will not be able to be guessed or disguised under any circumstances, and these one-off tokens are destroyed after they have finished their work.

Let's start with the generation of the token value:

functions.php

function Gen_token () {
Uniqid () gets a unique ID based on the current time (in milliseconds), which is useful for generating a distinct value
$hash = MD5 (Uniqid (rand (), true);

Gets the MD5 hash of the corresponding ID value, and then we select the 8-bit letter from the hash with a number less than 24 as the starting position.
$n = rand (1, 24);
$token = substr ($hash, $n, 8);

return $token;
}
Now let's generate a session token, which we'll use later in the check.

functions.php

function Gen_stoken () {
Call the function to generate the token
$token = Gen_token ();
Destroy any eventually session Token variable
Destroy_stoken ();
Create the session Token variable
Session_register (Stoken_name);
$_session[stoken_name] = $token;
}
In this function we call the Gen_token () function and use the returned token to copy its value to a new $_session variable.

Now let's look at the function in the launch complete mechanism for generating hidden input fields for our form:

functions.php

function Gen_input () {
Call the function to generate the session Token variable
Gen_stoken ();
Generate the form input code
Echo ' <input type= ' hidden "name=". Ftoken_name. ' "value=". $_session[' Stoken_name ']. ' > ';
}
As we can see, this function calls the Gen_stoken () function and generates the HTML code that contains the hidden fields in the Web form.

Let's look at the function that implements detection of the session token submitted in the hidden domain:

functions.php

function Token_check () {
Check if the session Token exists
if (Is_stoken ()) {
Check if the request has been sent
if (Isset ($_request[ftoken_name])) {
If the Form Token is different from session Token
It ' s a malicious request
if ($_request[ftoken_name]!= $_session[stoken_name]) {
Gen_error (1);
Destroy_stoken ();
Exit ();
} else {
Destroy_stoken ();
}
If it isn ' t then it ' s a malicious request
} else {
Gen_error (2);
Destroy_stoken ();
Exit ();
}
If it isn ' t then it ' s a malicious request
} else {
Gen_error (3);
Destroy_stoken ();
Exit ();
}
}
This function detects the existence of $_session[stoken_name] and $_request[ftoken_name] (I used the $_request method to make the form variables submitted by Get and post two ways acceptable). It then detects whether their values are the same, and therefore determines whether the current form submission is authenticated.

The point of this function is that after each detection step is finished, the token is destroyed and will be regenerated only on the next page of the form.

The use of these functions is very simple, we just need to add some PHP code structure.

The following is a Web form:

form.php

<?php
Session_Start ();
Include ("functions.php");
?>
<form method= "POST" action= "resolve.php" >
<input type= "text" name= "first_name" >
<input type= "text" name= "last_name" >
<!–call the function to generate the hidden input–>
? Gen_input ();?>
<input type= "Submit" name= "submit" value= "Submit" >
</form>
Here is the script code for resolve.php:

resolve.php

<?php
Session_Start ();
Include ("functions.php");

Call the function to make the check
Token_check ();

Your Code
As you can see, implementing such a test is very simple, but it can prevent your user form from being hijacked by attackers to avoid unauthorized data authorization.

Summarize

Your Web application is not as secure as it is now, but you can start to avoid most common attack techniques.

Another important point that I want you to focus on is that Web developers should not overlook general program errors (such as XSS browser vulnerabilities, and so on), and it is a huge mistake not to consider these potential threats to your users: you should always remember that they affect the trust, security, and interoperability of your program

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.