In the recent development of the front-end and back-end separation projects, the problem of CORS requests was frequently encountered. While the train of thought is still clear, make a memo note here.
Some of the contents of this article are referenced from the following sources, and we would like to express our deep thanks: MDN Official Document - Cross-origin Resource Sharing
(CORS) Cross-origin Resource Sharing CORS
Detailed Explanation - Ruan Yifeng's Web Logs
What is CORS?
According to the definition given by MDN:
Cross-origin resource sharing (CORS) (or colloquially translated as cross-origin resource sharing) is an HTTP header-based mechanism that allows the browser to access and load these resources by allowing the server to mark other origins (domains, protocols, and ports) other than its own. Cross-origin resource sharing also checks whether the server will allow genuine requests to be sent through a mechanism that initiates a "preflight" request to a server-hosted cross-origin resource through the browser. In the preflight, the headers sent by the browser are marked with HTTP methods and headers that will be used in real requests.
For example, if the front-end page runs on a http://localhost:8080, when a user accesses a front-end resource, such as http://localhost:8080/index.html, http://localhost:8080/1.html, etc., the request for those resources will not involve cross-domain issues. When the browser needs to access the backend resources running on the http://localhost:8081, the browser will perform cross-origin requests because the port numbers are not the same.
A key concept is involved in the previous definition: Origin, which is what we often call a domain, or source. We can categorize all HTTP requests as same-origin requests and cross-origin requests. We use the following to determine whether a request is cross-domain:
- Protocol type (HTTP/HTTPS)
- domain name
- Port number
Only when the current page and the above three items of the requested resource are consistent, it is a same-origin request, otherwise it will be treated as a cross-origin request. It should be noted here that DNS translation will not occur when the domain name matches, which means that the http://localhost:8080 and http://127.0.0.1:8080 are also not in the same domain.
According to the specific content of the sent request, we can divide HTTP requests into simple requests and non-simple requests. When processing simple requests, the browser does not need to send a preflight request, while when processing a complex request, the browser first sends an OPTION preflight request to the server to obtain whether the server allows access to the resource in CORS mode. We'll cover more about preflight later.
When the HTTP request method is one of the following:
And the HTTP request header only includes the following fields:
When the Content-Type field is one of the three (
text/plain), the request can be regarded as a simple request.
Request and respond to messages
# Request Packet
GET /resources/public-data/ HTTP/1.1
Accept-Language: en-us,en; q=0.5
# Response Packet
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Keep-Alive: timeout=2, max=100
The Origin in the request packet and the
Access-Control-Allow-Origin of the corresponding packet together form the most basic header field. The Origin field indicates the source of the request, and the Access-Control-Allow-Origin returned by the server specifies the cross-domain access source accepted by the server. * indicates acceptance of all external cross-domain access.
The preflight request needs to send an OPTIONS request to the server before the actual request is sent to find out whether the server supports CORS, which Origins it supports, what requests it supports, and what headers it supports.
Request and response headers
# Request header
# Actual request method
# Headers included in the actual request
Access-Control-Request-Headers: X-PINGOTHER, Content-Type
# Response header
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
# Request validity period: During the validity period, the browser does not need to send OPTIONS preflight requests repeatedly
XSS & CSRF attacks
XSS (Cross-site-Script Cross-Site Scripting Attack), usually caused by data with page parseable content being inserted directly into the page without processing. XSS is divided into stored XSS, reflected XSS, and MXSS (also known as DOM XSS) according to the location of the attack script.
It is more common in blogs, forums, and other pages that allow users to enter content. XSS injection scripts are persisted to the database. To take the simplest example, without any processing of user input by the back-end program, user input:
<script>alert("This is low level")</script>
When the browser accepts the data sent back by the backend and parses it into
<script> tag, this code is loaded to implement the attack.
It is more common when an attacker directly provides a URL to the user, directs the user to click and attack. For example:
If the HTML in the web page uses the query parameter, the above attack code will be parsed, thereby exposing the user's cookies.
Common defenses include replacing special characters such as <> with HTMl escape symbols, or matching the parenthesis content and replacing them with regular expressions.
CSRF attack: impersonating the user's hand
The full name of CSRF is Cross Site Request Forgey. It can be understood simply that an attacker has stolen the user's identity and sent malicious requests in the user's name.