Small instructions

Because the text is too casual, was pointed out by a friend in the comment area, especially to remove part of the irrelevant content, so as not to disturb others and confuse the concept

Let’s start with the definition of CSRF

Cross-site request forgery Cross-site request forgery), also known as one-click Attack or Session riding, usually abbreviated to CSRF or XSRF, Is an attack method to trick a user into performing unintended actions on a Web application that is currently logged in. [1] Compared with cross-site code (XSS), XSS exploits the user’s trust in the specified website, while CSRF exploits the website’s trust in the user’s web browser

Simply put, CSRF is the use of the login state of the user to initiate malicious requests.

Introduce CSRF with a story

This is a very vivid example that I saw on Zhihu recently (because it is shared in wechat, I can’t find the link now, let’s add the story directly)

Mother: Keep an eye on my clothes child: Ok

The thief to

Kid: Who are you? Thief: THIS is Zhang SAN. Kid: Mom, someone is stealing clothes. Mom: Who? Child: The thief was caught

Bug: Kid: Who are you? Thief: I’ll play with you. Kid: Mom, someone is stealing clothes. Mom: Who? Child: I’m playing with you. Mother:…

CSRF lets users unknowingly use their identity to make a request thief: your mom asks you to buy laundry detergent

How to attack

Assuming the site has an interface for submitting user comments via Get requests, an attacker could add an image to the phishing site whose address is the comment interface

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>
Copy the code

If the interface is Post submitted, it is relatively cumbersome and requires a form to submit the interface

<html>
    <head>
        <script type="text/javascript">
            function steal()
                {
                &emsp; iframe = document.frames["steal"];
                iframe.document.Submit("transfer");
            }
        </script>
    </head>

    <body onload="steal()">
        <iframe name="steal" display="none">
            <form method="POST" name="transfer"&emsp;action="http://www.myBank.com/Transfer.php">
                <input type="hidden" name="toBankId" value="11">
                <input type="hidden" name="money" value="1000">
            </form>
        </iframe>
    </body>
</html>
Copy the code

How to defense

The following rules can be followed to prevent CSRF:

  1. The Get request does not modify the data
  2. Do not allow third party websites to access user cookies
  3. Block third party websites from requesting interfaces
  4. The request comes with authentication information, such as a verification code or token

SameSite

You can set the SameSite property on the Cookie. This property sets cookies not to be sent with cross-domain requests. This property can significantly reduce CSRF attacks, but this property is not currently compatible with all browsers.

Verify the Referer

For requests that need to be defended against CSRF, we can verify the Referer to determine whether the request was initiated by a third party site.

When a request is received in the background, the Referer request header can be used to determine the source of the request

Token

The server sends a random Token (the algorithm cannot be complex), carries the Token on each request, and the server verifies whether the Token is valid.

Nodes can use cSURF middleware to defend against CSRF attacks

var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')

// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })

// create express app
var app = express()

// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())

app.get('/form', csrfProtection, function (req, res) {
  // pass the csrfToken to the view
  res.render('send', { csrfToken: req.csrfToken() })
})

app.post('/process', parseForm, csrfProtection, function (req, res) {
  res.send('data is being processed')})Copy the code

In the page template view (depending on your template language; The csrfToken value is set to the value of a hidden input field named _csrf:

<form action="/process" method="POST">
  <input type="hidden" name="_csrf" value="{{csrfToken}}">
  
  Favorite color: <input type="text" name="favoriteColor">
  <button type="submit">Submit</button>
</form>
Copy the code

When accessing a protected route through Ajax, the CSRF token needs to be passed in the request. Typically, this is done with a request header, because adding a request header can usually be done in a central location without any payload modifications. The CSRF token is obtained from the server-side req.csrftoken () call. This token needs to be exposed to the client, usually by including it in the initial page content. One possibility is to store it in an HTML tag where the value can be retrieved by JavaScript on request.

<meta name="csrf-token" content="{{csrfToken}}">
Copy the code

Here is an example of sending a CSRF token from a tag on a page to a/process route using the Fetch API:

// Read the CSRF token from the <meta> tag
var token = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

// Make a request using the Fetch API
fetch('/process', {credentials:'same-origin'.// includes cookies in the request
    headers:{
        'CSRF-Token': token // is the csrf token as a header
    },
    method:'POST'.body: {data:'data'}})Copy the code
Token Generation and Resolution (an example)
  • Token =salt-hash, hash= salt-hash

  • Const [salt, hash] = token.split(‘-‘), recalculate the hash= hash function (salt+ password), and compare

The caught

Use HTTPS(HTTPS still transmits information over HTTP, but the information is encrypted over the TLS protocol.) Instead of HTTP, encrypt the transmitted data so that when the requested information is captured by the packet capture tool, the submitted data cannot be modified.

Some other things you need to know about Web security

Password security (salt, symmetric encryption, asymmetric encryption, etc.)

Password security is mostly a back-end affair, but a good front-end programmer needs to be familiar with it as well.

For password storage, it must not be stored in plain text in the database, otherwise once the database is leaked, it will cause great losses to users. In addition, it is not recommended to encrypt the password solely through the encryption algorithm because of the rainbow table.

The password usually needs to be salted and then encrypted several times with different encryption algorithms.

The crypto module is usually used to encrypt passwords in Node. You can read about the crypto module in my previous article

XSS attacks


Just to add a little bit about XSS, XSS is essentially HTML injection, similar to SQL injection. SQL,HTML, and human languages are all mixtures of instructions and data that are subject to injection risks. (Programs identify instructions and data based on delimiters and tags, while humans identify them based on context, semantics, and everyday experience.)

<p> Welcome to new users, Zhang SAN </p>Copy the code

“To the browser. If the user typed

<script>alert('I'm messing with you')</script>
Copy the code

The server will generate

<p> Welcome new user,<script>alert('I'm messing with you')</script></p>
Copy the code

Input user content is recognized by the browser as instruction execution, which is called XSS injection; According to this principle, the thief input a name with special semantics, which is recognized as instruction by other clients, thus accomplishing a beautiful storage XSS injection attack.

XSS details of some content, children can go to the relevant information, here on the temporary not to repeat

conclusion

Thanks for seeing the end. If you like this article, please give me a “like”

The resources

  1. csurf
  2. The strongest interview map on the surface