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()
{
  iframe = document.frames["steal"];
iframe.document.Submit("transfer");
}
</script>
</head>
<body onload="steal()">
<iframe name="steal" display="none">
<form method="POST" name="transfer" 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:
- The Get request does not modify the data
- Do not allow third party websites to access user cookies
- Block third party websites from requesting interfaces
- 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
- csurf
- The strongest interview map on the surface