The author editing | | motor fan deer

Ma Da is proficient in PHP development, Web development, API interface design and platform construction, leading a number of Web products alone. I am currently working in Tencent IEG as an operation and development engineer, responsible for the research and development of privileged products of League of Legends Internet Cafe. I like researching Internet products and have a strong interest in application layer development.

Usually often hear people say not disorderly point link, careful virus. There are elders forward “Oh my god ~XXX conspiracy, all virus”, “XXX shocking virus, the point of the iPhone will explode!” “, “now forwarding hot connection will be arbitrary buckle fee! Don’t!” .

Are they right or wrong, true or false? Below I use easy to understand the language for you to analyze.

A CSRF attack is pretending to cheat

Cross-site Request Forgery (CSRF) one Click Attack/Session Riding (CSRF)

To put it simply, CSRF takes advantage of our login status or authorization status (take advantage, not steal) and does something to our own detriment.

For example, CSRF uses our wechat profile picture and nickname and then asks our parents for money. “Dad, the living expenses are not enough. You hit XXX account “, za dad saw the head picture and nickname think is one’s own, he transfer money. In this way, the fraud succeeded.

CSRF attack caused by GET mode

The elders are right. You can’t just click on a link. Let me give you an example in simple code.

Trust test.com

Let’s say we have a bank account with a login page login.php and a payment page paybill.php, both of which belong to test.com, a site we trust (test.com is virtual).

Set cookies in login.php for login:

<? php setcookie('uid', 1, time()+86400); echo "your uid is {$_COOKIE['uid']}";Copy the code

After paybill.php is authenticated, the deduction is made, but the recipient and the amount of the deduction must be entered:

<? PHP // authentication if (! isset($_COOKIE['uid']) || $_COOKIE['uid']< 0) { die('login error! '); } // Get if (! isset($_GET['money'])) { die('no money'); } // The payee gets if (! isset($_GET['to_who'])) { die('nobody'); } $uid = $_COOKIE['uid']; $money = $_GET['money']; $to_who = $_GET['to_who']; Echo "transfer {$money} yuan to {$to_who}!" ;Copy the code

Refresh login.php to login. (actual user login is more complicated and is simulated here.)

Go to paybill.php in your browser and transfer 1000 yuan to mom.

http://test.com/csrf/paybill.php?money=1000&to_who=mama

Hackers website

When the hacker realizes that Test.com is doing nothing to defend itself, he immediately creates a fake page on his own website B with a link that turns his payee to_who into hacker.

<html> <head> <meta charset="utf-8"> </head> <body> <a href="http://test.com/csrf/paybill.php?money=1000&to_who=hacker" Background-position: initial; background-repeat: initial; "> The biggest picture ever!! <a/> </body> </html>Copy the code

Suppose the link is clicked out of curiosity:

That transfers $1,000 to Hacker

Why is it that we can deduct money from our account when we click on a link from another website? Before clicking on a link, we trust is logged in web site, test.com, and this test.com/csrf/paybill.php?money=1000&to_who=hacker this link is our own send, test.com will identify the current has logged in, and then transfer, Test.com can’t tell who told us to click.

As can be seen from the above example, to complete the CSRF attack flow:

1. The user logs in to the trusted website A and saves the login status

2. Hackers find undefended links on website A and induce clicks through social engineering camouflage.

3. As long as the login status is maintained and the user proactively accesses the target link, the attack succeeds.

Some people say that every time I visit another website, I cancel the previous website. Yes, it works, but is it realistic? We have to log out of a lot of common websites and then have to enter our user name and password the next time we log in. This is definitely not the best way, defense measures should be considered by programmers, users do not click the link is the most important.

CSRF attack channels do not necessarily come from other websites, but can also be advertising mail, Qzone, wechat, Facebook and other social media or software. Imagine if your girlfriend knew this link and she sent it to you on QQ:

After you click on http://test.com/csrf/paybill.php?money=1000&to_who=girlfriend, then turned 1000 yuan for his girlfriend, assume she will money into 10 w, really can’t imagine, you have saved this money, Kneel board. It’s all in your girlfriend’s account.

Good, small white user see here can close, don’t disorderly dot link is right, the money that should give girlfriend or one cent can’t little.

POST can also cause CSRF attacks

The above CSRF can be quite dangerous. Update resources should not use GET. GET should only be used for read operations. Always use POST for updates, especially when it comes to money.

While POST solves most of the CSRF problem, there are still a few smart hackers who can simulate POST requests and fake identities to attack.

Suppose paybill.php is set to POST:

<? php if (! isset($_COOKIE['uid'])) { die('login error! '); } if (! isset($_POST['money'])) { die('no money'); } if (! isset($_POST['to_who'])) { die('nobody'); } $uid = $_COOKIE['uid']; $money = $_POST['money']; $to_who = $_POST['to_who']; if ($uid > 0) { echo "transfer {$money} yuan to {$to_who}!" ; }Copy the code

Visit http://test.com/csrf/paybill.php?money=1000&to_who=girlfriend, suggesting there is no money

But clever hackers also improved the code, using POST submission, and changing money to 2000:

<html> <head> <meta charset="utf-8"> </head> <body> <form action="http://test.com/csrf/paybill.php" method="post"> <input type="hidden" name="money" value="2000"> <input type="hidden" name="to_who" value="girlfriend"> <input Type = "submit" value = "click on the lottery" > < / form > < / body > < / HTML >Copy the code

Click to win the big prize, as follows (and transfer 2000 yuan to his girlfriend) :

Cookie: uid=1 and Money =2000&to_who=girlfriend have both been sent.

The POST HTTP / 1.1 Host: http://test.com/csrf/paybill.php test.com Referer: http://hack.com/hack/welcome.php cookies: uid=1 money=2000&to_who=girlfriendCopy the code

As a result, any access method can be attacked. So, it’s not a question of who is more secure, GET or POST, POST just raises the bar and cost of attack (just a few more lines of HTML and JS).

Here’s the main reason CSRF can attack: the server can’t tell if your source is reliable.

The idea of defending CSRF

So there are many ways to defend:

1. Add captcha, for example. But doing so is tedious and affects the user experience.

2. For example, transferring money requires a second password verification, which is what many banks do now.

3. Confirm whether the source is reliable (recommended)

Either defense method 1 or defense method 2 requires the user to reconfirm authorization.

This kind of security precautions should be verified by the program.

According to the idea of reliability verification, the following methods can be used:

Validate the HTTP Referer field

The HTTP protocol defines a field for accessing a source called Referer. The links or forms forged by hackers are on other websites, so we can judge whether the Referer is its own website. If so, access will be allowed; if not, access will be denied.

A visit to paybill.php from our website shows that the Referer does not exist

"HTTP_REFERER"=>""
Copy the code

A visit to paybill.php from the hacker’s website revealed that the Referer came from the hacker’s website

[" HTTP_REFERER "] = > string (35) : "http://hack.com/welcome.php" then the code judgment if (HTTP_REFERER! ="") {die(' Possible CSRF attack, access denied '); } else {die(' allow access '); }Copy the code

So we only need to intercept the Referer to determine whether it is an attack.

But this method is flawed, the above experiment tried, what if the other party sent you a link on QQ? When clicking, it belongs to active clicking, and there is no Referer at this time. The program will classify it as a security request and it will be bypassed. And Referer can be tampered with if some of the older browsers have bugs (IE6, for example), so it’s not perfect.

The server verifies the token consistency of the request

The core principle of CSRF attack is to use user authentication information to store cookies and send requests, so that the server cannot determine the authenticity. Token can be intercepted because it is almost impossible to forge during CSRF attack.

Implementation principle: The server generates a random token and adds it to the HTTP request parameters. The server intercepts the request and checks whether the sent token is consistent with the server. If so, the server allows the request. If not, the request is rejected.

Add token to session (don’t store token in cookie, you know) :

<? php session_start(); $csrf_token = md5(openssl_random_pseudo_bytes(32)); $_SESSION['token']= $csrf_token; ? > <! DOCTYPE HTML > < HTML lang=" en "> <head> <meta Charset ="UTF-8"> <title> CSRF </title> </head> <body> <h1> Transfer </h1> <form action="paybill.php" method="POST"> money:<input type="text" name="money"> to_who:<input type="text" name="to_who"> <input type="hidden" name="token" value="<? php echo $csrf_token ? >"> <input type="submit" value="ok"> </form> </body> </html>Copy the code

Obtain the token from paybill. PHP and check whether the token is the same as the token stored in session:

<? php session_start(); if (! isset($_COOKIE['uid'])) { die('login error! '); } if (! isset($_POST['money'])) { die('no money'); } if (! isset($_POST['to_who'])) { die('nobody'); } if (! isset($_POST['token']) || $_POST['token'] ! = $_SESSION['token']) { die('forbidden'); } $uid = $_COOKIE['uid']; $money = $_POST['money']; $to_who = $_POST['to_who']; if ($uid > 0) { echo "transfer {$money} yuan to {$to_who}!" ; }Copy the code

Form.php:

Request successful:

Each time you visit the form page, you should generate a token:

<input type="hidden" name="token" value="a88f67a7effa917450cff12e179df35d">
Copy the code

We try to access from the hacker website again and display “forbidden” to prove that the token is blocked in the token verification:

In this way, CSRF attacks are effectively defended. This method can be used for requests such as a link and a form, and it belongs to the same principle.

Note: many articles on the Internet do not generate unique or random tokens. They are all the same token, which is problematic. If hackers see this token, they can also forge requests and attack.

Ajax defense CSRF

In fact, the idea of A JAX defense can also take advantage of the token authentication method above.

Read an article on IBM about Ajax defense, customizing attributes in HTTP headers and validating tokens.

Here’s what it says:

Place the token in the HTTP request as a parameter, instead placing it in a custom attribute in the HTTP header. With the XMLHttpRequest class, you can add the CSRFToken HTTP header attribute and put the token value into all of the class requests at once. This eliminates the inconvenience of adding the token to the request in the previous method, and the XMLHttpRequest address is not logged in the browser’s address bar, and the token is not leaked to other sites through the Referer.

Personally, I think there is no need for such trouble and ease of use is not very good. I will directly encapsulate Aajx and add an open_token option. If true, the token will also be sent, otherwise there will be no verification.

It is best to assign the token to a js global variable that can be used throughout the site.

conclusion

CSRF Defense Principles:

  • The GET mode cannot be used to update resources

  • POST request with random token authentication

OWASP’s top 10 security threats for 2017 have been released, and we can see that 2013 and 2017 CSRF is firmly in eighth place.

In a word, CSRF is a common Web security threat. Its attack feature is to use user identity information to disguise, send requests, and cause harm. This kind of attack is extremely cheap, but the site and the user are not paying attention, can be very vulnerable. Of course, what’s more impressive is that hackers use social engineering to trick the masses, which is the most important thing.

If you’re interested in social engineering, I’d like to recommend a movie called Who AM I: There’s No Perfectly Safe System.

Internet security you attack my defense, you gun I shield, there is no always effective method, only learn to attack, in order to resist attack.