Django: Cross-domain access and CSRF protection

1. What is cross-domain access?

Traditionally, django generates web page information through the template function, and the related static resources of the web page are also configured and read by django. If the JavaScript file of the static resource uses the Ajax request API interface, then the current request can obtain the data from the API, because the current request and the requested API are the same .
Here we need to mention " 浏览器同源政策SOP(Same origin policy)". This so-called" "refers to" 协议+域名+端口号". Netscape first introduced the same-origin policy to ensure the security of user information and prevent malicious websites from stealing data. For example, webpage B cannot read webpages. A’s cookie and web page B cannot send Ajax requests to non-same-origin servers and other restrictions, reducing XSS, CSFR and other attacks. For more information, please refer to: Browser Same Origin Policy and How to Avoid It .
Here, " " and " " can be understood as one meaning.
From the perspective of the separation of the front and back ends of vue+django, when the project is deployed online, vue and django will be deployed on different servers. Since the " 同源" or " 同域" requirements are not met , the Ajax request sent by vue to the server cannot reach the django API Interface. Obviously this cannot meet the task of data acquisition, so 跨域访问the demand arises.

Second, django sets up cross-domain access

There are many ways to set up Django cross-domain access, the best is to use third-party functional applications django-cors-headers.
Also need to be configured:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    # 'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


#跨域增加忽略
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ORIGIN_WHITELIST = (
    '*'
)
CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
    'VIEW',
)
CORS_ALLOW_HEADERS = (
    'XMLHttpRequest',
    'X_FILENAME',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
    'Pragma',
)

Three, CSRF

1. What is CSRF?

跨站请求伪造CSRFIt is a type of cyber attack that forces end users to perform unwanted operations on currently authenticated web applications. For example, by sending a link via email or chat, the attacker may trick the user of the Web application to perform the action chosen by the attacker. If the victim is a normal user, a successful CSRF attack will force the user to perform a state change request, such as transferring funds, changing their email address, etc. If the victim is an administrative account, CSRF may damage the entire web application.

2. A CSRF example

There are many ways to trick the end user into loading information from or submitting information to the web application. In order to execute an attack, we must first understand how to execute an effective malicious request for the victim. Let us consider the following example: Alice wants to transfer $100 to Bob using the bank.com web application that is vulnerable to CSRF attacks. The attacker Maria wants to induce Alice to send money to Maria. The attack will include the following steps:

  1. Establish an exploit URL or script
  2. Induce Alice to perform an action

1. GET method:
If the application is designed to mainly use GET requests to transmit parameters and perform operations, the remittance operation may be simplified to the following request:

GET http://bank.com/transfer.do?acct=BOB&amount=100HTTP/1.1

Maria used the original URL and replaced the payee name with herself, while increasing the transfer amount:

http://bank.com/transfer.do?acct=MARIA&amount=100000

Next, Maria needs to trick Alice into loading this URL when Alice logs in to the banking application. This is usually done using one of the following techniques:

  1. Send unsolicited emails with HTML content
  2. Put this URL or script on the page that the victim may visit during online banking

In short, the vulnerable URL can be disguised as a normal link, encouraging the victim to click on it:

<img src="http://bank.com/transfer.do?acct=MARIA&amount=100000" width="0" height="0" border="0">

If the image tag is included in the email, Alice will not see anything. However, the browser still submits the request to bank.com without any visual indication that the transfer has occurred.
A real example of using GET to perform CSRF attacks on applications is the uTorrent vulnerability in 2008, which has been used to download malicious software on a large scale.

2. POST method:
The only difference between GET and POST attacks is the way the victim performs the attack. Let us assume that the bank now uses POST:

POST http://bank.com/transfer.do HTTP/1.1
acct=BOB&amount=100

Such requests cannot be passed using standard A or IMG tags, but can be passed using FORM tags:

<form action="http://bank.com/transfer.do" method="POST">

<input type="hidden" name="acct" value="MARIA"/>
<input type="hidden" name="amount" value="100000"/>
<input type="submit" value="View my pictures"/>

</form>

This form will require the user to click the "Submit" button, but this can also be performed automatically using JavaScript:

<body onload="document.forms[0].submit()">

<form...

3. Other HTTP methods:
Modern web application APIs often use other HTTP methods, such as PUT or DELETE. Let us assume that the vulnerable bank uses PUT with a JSON block as a parameter:

`PUT http://bank.com/transfer.do HTTP/1.1`

`{
     
      "acct":"BOB", "amount":100 }`

You can also use JavaScript embedded in the exploit page to execute such requests:

<script>
function put() {
    
    
    var x = new XMLHttpRequest();
    x.open("PUT","http://bank.com/transfer.do",true);
    x.setRequestHeader("Content-Type", "application/json");
    x.send(JSON.stringify({
    
    "acct":"BOB", "amount":100})); 
}
</script>

<body onload="put()">

Of course, the attack method not only uses HTTP to send the request, but also 劫持cookieobtains information through the method.
Fortunately 同源策略, this request will not be executed by modern web browsers due to the restrictions. This restriction is enabled by default, unless the target website uses CORS to explicitly open cross-origin requests from the attacker (or everyone). The header file is: Access-Control-Allow-Origin:

Fourth, django's CSRF protection

In this way, cross-domain access and CSRF protection seem to be contradictory, but Django has a simple but effective protection mechanism.
For example, when submitting a form, django will automatically add hidden form fields in the release form csrfmiddlewaretoken, and csrfmiddlewaretokencheck the correct value of the request by matching it with the backend to increase the protection of cross-site request forgery.
Use two steps:

  1. Configuration 'django.middleware.csrf.CsrfViewMiddleware'
  2. Used where the form using the POST method is{% csrf_token %}
  3. Use RequestContextcontext to render the response (this is the default)

Case 1: Set CSRF protection on the form

templates/index.html:
<html>
<body>
<form action="" method="post">
    {
    
    % csrf_token %}
    <div>用户名:</div>
    <input type="text" name='username'>
    <div>密 码:</div>
    <input type="password" name='password'>
    <div><button type="submit">确定</button></div>
</form>
</body>
</html>

Insert picture description here
Insert picture description here
If you want to cancel the CSRF protection of the form, you need to delete {% csrf_token %} in the template first, and then add @csrf_exempt before the view function, otherwise a 403 exception will occur.

Case 2: Set CSRF protection to the view function

Add @csrf_exempt before the view function.

index/views.py:
# 取消CSRF防护
@csrf_exempt
def index(request):
    return render(request, 'index.html')

Situation 3: CSRF protection for Ajax requests

var csrf = $('input[name="csrfmiddlewaretoken"]'.val());
$.ajaxSetup({
    
     data: {
    
    csrfmiddlewaretoken: ‘{
    
    {
    
     csrf_token }}}, });
$.post


获得:
<QueryDict: {
    
    'csrfmiddlewaretoken': ['h9mYGUqy9Xr2jIPUebtb4qyNfyVNbi5GDD6kSVuH97VJgyzYJ8sGkyiFQ3xo3Nx7'], 'username': ['root'], 'password': ['root']}>
[17/Sep/2020 17:23:41] "POST / HTTP/1.1" 200 898

Guess you like

Origin blog.csdn.net/dangfulin/article/details/108625628