This article mainly explains the browser related knowledge, the article content is relatively long, knowledge points more, very recommended collection reading ~
preface
If this article is helpful to you, ❤️ attention + like ❤️ to encourage the author, the article public number first, pay attention to the front of nanjiu first time to get the latest article ~
1. What are common browser kernels?
The browser kernel can be divided into two parts:
Rendering engine and JS engine (⚠️ note: when we say browser kernel, we mean rendering engine)
As THE JS engine is becoming more and more independent, the kernel only refers to the rendering engine, the rendering engine is mainly used to request the web page resource analysis layout after rendering to the user
Browser/RunTime | Kernel (rendering engine) | JavaScript engine |
---|---|---|
Chrome | Blink (28~) Webkit (Chrome 27) | V8 |
FireFox | Gecko | SpiderMonkey |
Safari | Webkit | JavaScriptCore |
Edge | EdgeHTML | Chakra (For JavaScript) |
IE | Trident | Chakra (For JScript) |
Opera | Presto->blink | Linear A (4.0-6.1)/Linear B (7.0-9.2)/Futhark (9.5-10.2)/Carakan (10.5-) |
Node.js | – | V8 |
2. What are the main components of a browser?
- User interface: including address bar, forward/back/refresh/bookmark 🔖 and other buttons
- Browser engine: Transmits instructions between the user interface and the rendering engine
- Rendering engine: Used to draw the requested content
- Network: Used to complete network calls, such as HTTP requests, with platform-independent interfaces that work on different platforms
- JavaScript interpreter: Used to parse executing JavaScript code
- User interface back end: Used to draw basic widgets, such as combo boxes and Windows, using the operating system’s user interface underneath
- Data storage: Belongs to the persistence layer, the browser saves all kinds of data like cookies in the hard disk, HTML5 defines the Web Database technology, which is a lightweight complete client storage technology
⚠️ Note: Unlike most browsers, Google (Chrome) has a rendering engine instance for each TAB page. Each TAB is a separate process
3. Tell me what happens from entering the URL to rendering the page.
This question can be said to be the most common interview is also an infinite difficult question, the general interview officer out of this question is to examine your depth of front-end knowledge.
1. Browser accepts URL to open network request thread (involving: browser mechanism, thread and process, etc.)
2. Start the network thread until it sends a complete HTTP request (involving DNS query, TCP/IP request, Layer 5 network protocol, etc.)
3. Received the request from the server to the corresponding background (involving: load balancing, security interception, background internal processing, etc.)
4. HTTP interaction between background and foreground (involving HTTP headers, response codes, packet structures, cookies, etc.)
5. Cache issues (involving HTTP strong and negotiated caches,cache headers, etag,expired,cache-control, etc.)
6. The parsing process after the browser receives HTTP data packets (involving HTML lexical analysis, parsing into DOM tree, parsing CSS to generate CSSOM tree, merging to generate render rendering tree. Then layout, painting and rendering, composite layer composition, GPU drawing, outer chain processing, etc.)
7. CSS visual model (involving: element rendering rules, such as: include block, controller enclosure, BFC, IFC, etc.)
8.JS engine parsing process (involving: JS parsing stage, pretreatment stage, execution stage to generate execution context, VO (global object), scope chain, recycling mechanism, etc.)
You will find that a simple input URL to the page rendering, will occur so much process, is not immediately feel broken 😭 (don’t worry, this chapter we do not go so deep, first teach you how to answer this question, the following section is a separate article about)
- The browser gets the IP address of the domain name from the DNS server and requests HTML text from that IP address
- The browser renderer parses the HTML text and builds the DOM tree
- While parsing HTML, you download and build style rules if you encounter inline styles or style files, and download execution scripts if you encounter JavaScript scripts
- After the DOM tree and CSSOM are built, the render process merges them into a render tree.
- The render process starts to layout the render tree, generating a layout tree.
- Render tree Draws the layout tree to generate a drawing record
4. How does the browser parse code?
Parsing HTML
HTML is parsed line by line, and the browser’s rendering engine parses the HTML document and converts it into DOM nodes.
- Parse HTML into many Tokens
- Tokens become objects
- Group objects into a DOM tree
Parsing the CSS
Browsers parse CSS selectors from right to left
We know that merging the DOM tree with the CSSOM tree into the Render tree is actually attaching the CSSOM to the DOM tree, so we need to traverse the DOM tree based on the information provided by the selector.
Let’s look at an example 🌰 :
<div class='nav'> <div class='title'> <span> </span> </div> <div Class ="sub_title"> </header> </div>Copy the code
Matching from right to left:
- Find all the rightmost nodes span first, and for each span, look up at the node div.title
- Look up from h3 for the node in div. Nav
- Finally finding the root HTML completes the branch.
Parsing JS
There is a JS parser tool in the browser that is dedicated to parsing our JS code.
When the browser encounters JS code, it immediately summons the “JS parser” to work.
The parser finds all the variables, functions, arguments, and so on in JS and assigns variables to undefined (undefined).
Take the function out as a function block and store it in the repository. Once that’s done, start parsing the code line by line (top down, left to right) and then matching it with the repository.
5. The difference between DOMContentLoaded and load?
- DOMContentLoaded: Triggered only after the DOM has been parsed, excluding stylesheets, images, etc.
- Load: Triggered when all the DOM, stylesheets, scripts, images and other resources on the page have been loaded.
6. Browser redraw field rearrangement difference?
- Rearrangement: Part of the render tree or the entire render tree needs to be re-analyzed and node sizes need to be recalculated, in the form of regenerating the layout and rearranging elements
- Redraw: The appearance of some elements is changed due to changes in the geometry or style of the node, such as element background elements
Redrawing does not necessarily lead to rearrangement, but rearrangement always leads to redrawing
How to trigger redraw and rearrangement?
Any changes to the information used to build the render tree will result in a rearrangement or redraw:
- Add, delete, and update DOM nodes
- Hide a DOM node with display: None – triggering rearrangement and redrawing
- Hide a DOM node by visibility: Hidden – only triggers redraw because there are no geometric changes
- Move or animate the DOM nodes in the page
- Add a style sheet and adjust the style properties
- User actions, such as resizing a window, changing font size, or scrolling.
How to avoid redrawing or rearranging?
-
Centralizing style changes: For example, using class to centralize style changes
-
Using document. CreateDocumentFragment () : we can create a free through createDocumentFragment node in the DOM tree, and then on the node batch operation, finally inserted into the DOM tree, so the only trigger a rearrangement
-
Ascend to the synthesis layer
Promoting elements to the composition layer has the following advantages:
-
The bitmap of the composite layer will be synthesized by the GPU faster than the CPU
-
When repaint is required, only repaint itself is required and no other layers are affected
-
Layout and Paint are not triggered for Transform and opacity effects
The best way to improve the composition layer is to use the WILL-change property of CSS
-
7. Why is JS single threaded?
This is mainly related to the use of JS. As the scripting language of the browser, JS is mainly used to realize the interaction between users and browsers and operate DOM. This means that it has to be single-threaded, which can cause a lot of complicated synchronization problems.
For example 🌰 : if JS is multi-threaded and one thread wants to modify a DOM element and another thread wants to delete it, the browser doesn’t know who to listen to. So to avoid complexity, JavaScript was designed from the beginning to be single-threaded.
In order to make use of the computing power of multi-core CPU, HTML5 proposes the Web Worker standard, which allows JavaScript scripts to create multiple threads, but the child threads are completely controlled by the main thread and cannot operate DOM. So, this new standard doesn’t change the single-threaded nature of JavaScript
8. Does CSS loading block DOM?
The first conclusion
CSS
Does not blockDOM
Parsing, but blocksDOM
The rendering ofCSS
blocksJS
Execute, but do not blockJS
File download
The role of the CSSOM
-
The first is to provide JavaScript with the ability to manipulate style sheets
-
The second is the style information that provides the basis for composing layout trees
-
This CSSOM is embodied in the DOM as Document. StyleSheets
From the browser rendering flow we can see:
-
DOM and CSSOM are usually built in parallel, so CSS loading does not block DOM parsing
-
The Render tree relies on both the DOM tree and the CSSOM tree, so it must wait until both are loaded before building the render, so CSS loading blocks DOM rendering
-
Since JavaScript can manipulate DOM and CSS, if you render the interface while modifying the attributes of these elements (i.e., the JavaScript thread and the UI thread work at the same time), the elements obtained before and after the render thread may not be consistent. So to prevent unexpected results from rendering, the browser sets the GUI rendering thread and JavaScript thread to be mutually exclusive
JS needs to wait for CSS to download, why? (CSS blocks DOM execution)
If the content of a JS script is to get the style of an element, it must rely on CSS. Because browsers don’t know what’s going on inside JS, they have to wait until all the previous styles have been downloaded before executing JS to avoid style fetching. However, JS files and CSS files are downloaded in parallel. CSS files will be loaded before the execution of subsequent JS files, so the CSS will block the execution of subsequent JS files
Avoid blank screen and improve CSS loading speed
- Use CDN (CDN will select the nearest node with cached content to provide resources to you according to your network condition, so it can reduce load time)
- Compress the CSS
- Use caching wisely
- Reduce the number of HTTP requests and merge CSS files
9. Does JS block pages?
The first conclusion
JS blocks DOM parsing and therefore page loading
This is why we always say to put JS files at the bottom, right
Because JavaScript is DOM manipulable, if you render the interface while modifying these element attributes (that is, the JavaScript thread and the UI thread are running at the same time), you might get inconsistent element data before and after the render thread.
So to prevent unexpected results from rendering, the browser sets the GUI rendering thread and JavaScript engine to be mutually exclusive.
The GUI thread is suspended while the JavaScript engine is executing, and GUI updates are kept in a queue until the engine thread is idle.
When the browser executes a JavaScript program, the GUI rendering thread is stored in a queue until the JS program completes execution.
Therefore, if the JS execution time is too long, this will cause the page rendering to be inconsistent, resulting in the page rendering load blocking feeling.
10. What is the difference between defer and Async?
- Both load external JS files asynchronously and do not block DOM parsing
- Async is executed after the external JS is loaded, while the browser is idle, and before the Load event is triggered. Scripts marked Async are not guaranteed to be executed in the order specified. This property has no effect on inline scripts (i.e. scripts without the ** “SRC” ** attribute).
- Defer is triggered after the JS has loaded and the entire document has been parsed
DOMContentLoaded
Event before execution if missingsrc
Property (that is, embedded script), which should not be used because it does not work in this case
11. Browser garbage collection
Garbage collection is an automatic memory management mechanism. Dynamic memory on a computer should be released when it is no longer needed.
It should be noted that automatic means that the browser can automatically help us to recycle memory garbage, but it does not mean that we do not care about memory management, if not done properly, JavaScript can still run out of memory, causing the system to crash.
Because strings, arrays, objects, and so on have no fixed size, they need to be known before they can be allocated dynamically. Every time a JavaScript program creates a string, array, or object, the interpreter must allocate memory to store that entity.
The JavaScript interpreter can detect when the program is no longer using an object, and when it determines that the object is useless, it knows that the object is no longer needed and can free up its memory.
There are two common garbage collection methods used by browsers: tag scavenging and reference counting.
Mark clear
This is the most common method of garbage collection in JavaScript
As of 2012, all modern browsers use the garbage collection method of tag scavenging, except for the reference counting method used in earlier versions of Internet Explorer.
So what is tag clearance?
There is a global object in JavaScript, and periodically, the garbage collector will start with the global object, find all the objects referenced from the global object, and find the objects referenced by those objects… This is the tagging phase for these active objects. The clarity stage is the clarity of objects that are not marked.
One problem with token clearing is that after the clearing, the memory space is discontinuous, that is, memory fragmentation occurs. If a large contiguous memory space is required later, it will not suffice. This problem can be solved effectively by the tag arrangement method.
In the process of marking, the concept of three-color marking is introduced, which is:
- White: Unmarked objects, i.e. unreachable objects (objects not scanned), can be collected
- Gray: An object that has been marked (reachable object) but has not been scanned and cannot be collected
- Black: Has been scanned (reachable object) and is not recyclable
Mark finishing:
The markup phase is no different from the markup cleanup, except that after the markup, the markup cleanup moves the surviving objects to one side of memory and finally cleans up the boundary memory.
Reference counting
The meaning of reference counting is to keep track of how many times each value is referenced. When A variable A is assigned, the number of references to the value is 1. When A is reassigned, the number of references to the previous value is reduced by 1. When the number of references becomes zero, there is no way to access the value, so you can clear the memory used by the value.
Most browsers have abandoned this recycling method
A memory leak
To avoid memory leaks, it is best to release references to data once it is no longer in use by setting its value to NULL, a method called touch references
What can cause a memory leak? How to avoid it?
In the case of Vue, there are usually these situations:
- Listening in
window/body
Such events are not untied - Tied to the
EventBus
Events are not untied Vuex
的$store
.watch
Not after.unwatch
- Created using a third-party library without calling the correct destruction function
Workaround: beforeDestroy in time
- The binding
DOM/BOM
Events in objectsaddEventListener
,removeEventListener
. - Observer model
$on
.$off
To deal with. - If a timer is used in a component, it should be destroyed.
- If the
mounted/created
Hooks used in third-party library initialization, corresponding to destruction. - Using weak References
weakMap
,weakSet
.
When are memory for different types of variables released in the browser?
-
Reference types
- After there is no reference, it is automatically reclaimed by V8.
-
Basic types of
- In the case of closures, V8 will not reclaim them until the closure is not referenced.
- Non-closure case, waiting for the V8 generation switch when recycled.
12. What about browser caching?
Understanding the browser cache
When a browser requests a website, it will load various resources. For some resources that do not change frequently, the browser will save them in the local memory, and directly load these resources on the next visit to improve the access speed.
How do you know if the resource is a requesting server or a reading cache?
The size values of some resources are the size, some are from disk cache, some are from memory cache, the size values are the requested server resources, and the latter two values are the read cache.
- Disk cache:A resource is stored in a disk and can be read directly from the disk without re-downloading it for next access. Its direct operation object is
CurlCacheManager
. (Slower efficiency than memory cache, but large storage capacity, long storage time) - Memory cache: Stores resources in the memory and reads them directly from the memory without re-downloading them. (It was the fastest in terms of efficiency and the shortest in terms of survival time.)
– | memory cache | disk cache |
---|---|---|
The same | Only some derived resource files can be stored | Only some derived resource files can be stored |
The difference between | The data is cleared when you exit the process | Data is not cleared when exiting the process |
Storage resources | Scripts, fonts, and images are stored in memory | Generally, non-scripts are stored in memory, such as CSS |
Browser Cache classification
- Strong cache
- Negotiate the cache
When the browser requests resources to the server, it first determines whether the strong cache is hit, and then determines whether the negotiated cache is hit
Strong cache
When loading a resource, the browser checks whether the strong cache is matched based on the header of the local cache resource. If the strong cache is matched, the browser directly uses the cache resource without sending any request to the server. (The header information here refers to Expires and Cache-Control.)
Expires
This field is the HTTP1.0 specification, and its value is a time string in the GMT format of an absolute time, such as Expires:Mon,18 Oct 2066 23:59:59 GMT. This time represents the expiration time of the resource, before which the cache is hit. One obvious disadvantage of this approach is that since the outage time is an absolute time, it can lead to cache clutter when the server and client times diverging significantly. So this approach was quickly abandoned in later versions of HTTP1.1.
Cache-Control
Cache-control :max-age=3600; cache-control :max-age=3600; Indicates that the validity period of the resource is 3600 seconds. Cache-control In addition to this field, there are several common Settings:
No-cache: negotiates the cache and sends a request to the server to confirm whether the cache is used.
No-store: Disables the cache and requests data again each time.
Public: can be cached by all users, including end users and intermediate proxy servers such as CDN.
Private: the device can be cached only by the browser of the terminal user and cannot be cached by a trunk cache server such as the CDN.
Cache-control and Expires can be enabled at the same time in the server configuration, and cache-control has a high priority when both are enabled.
Negotiate the cache
When the strong cache is dead, the browser sends a request to the server, which determines whether the negotiated cache has been hit based on the information in the header. If it hits, 304 is returned, telling the browser that the resource is not updated and that the local cache can be used. (Header information refers to last-modify/if-modify-since and ETag/ if-none-match)
Last-Modify/If-Modify-Since
When the browser requests a resource for the first time, last-modify is added to the header returned by the server. Last-modify is a time that identifies the Last modification time of the resource.
When the browser requests the resource again, the request header contains if-modify-since, which is the last-modify returned before the cache. After receiving if-modify-since, the server determines whether the resource matches the cache based on the last modification time.
If the cache is hit, 304 is returned, the resource content is not returned, and last-modify is not returned.
Disadvantages:
A resource changes over a short period of time, and last-Modified does not change.
Periodic changes. If the resource is Modified back to its original state within a period of time, it is considered acceptable to use the cache, but last-Modified is not, hence the ETag.
ETag/If-None-Match
Unlike last-modify/if-modify-since, Etag/ if-none-match returns a check code. ETag ensures that each resource is unique, and changes in resources lead to changes in ETag. The server determines whether the cache is hit based on the if-none-match value sent by the browser.
Unlike last-Modified, when the server returns a 304 Not Modified response, the response header returns the ETag because it has been regenerated, even though the ETag is unchanged.
Last-modified and ETag can be used together. The server will verify the ETag first. If the ETag is consistent, the server will continue to compare last-Modified, and finally decide whether to return 304.
conclusion
When the browser accesses an already accessed resource, its steps are as follows:
1. Check whether the strong cache is matched. If 🎯 is matched, the cache is used directly
2. If the strong cache fails, a request is sent to the server to check whether the 🎯 negotiation cache is matched
3. If the negotiated cache is hit, the server returns 304 telling the browser that the local cache can be used
4. The server returns a new resource to the browser
13. What is the same origin policy for browsers, and cross domains?
The same-origin policy
The same origin policy is a self-protective behavior of browsers. The same protocol, domain name, and port are all the same
Most content in a browser is restricted by the same origin policy, but the following three tags are not:
<img src="..." /> <link href="..." /> <script src="..." ></script>Copy the code
Cross domain
Cross-domain means that the browser cannot execute scripts under other domain names. It is restricted by the browser’s same-origin policy.
You may be wondering if the cross-domain request is ever sent to the server?
In fact, cross-domain requests can be sent to the server, and the server can accept the request and return the result normally, but the result is blocked by the browser.
Cross-domain solutions (list a few commonly used ones)
JSONP
It uses script tags that are not restricted by the browser’s same origin policy to retrieve data from other sources, requiring server support.
The advantages and disadvantages:
It has good compatibility and can be used to solve the problem of cross-domain data access in mainstream browsers. The disadvantage is that only GET requests are supported, which is limited, insecure, and may be vulnerable to XSS attacks.
Ideas:
- Declare a callback function whose name (such as show) is passed as a parameter value to the server requesting data across domains, and whose parameter is to fetch the target data (the data returned by the server).
- To create a
<script>
Tag, assign the cross-domain API data interface address to script SRC, and pass the function name to the server at that address. The callback = show).
- When the server receives the request, it needs to do something special: concatenate the name of the function passed in with the data it needs to give you into a string, for example: the name of the function passed in is show, and the data it prepares is
Show (' south nine ')
.
- Finally, the server returns the data to the client through HTTP protocol, and the client calls the callback function (show) previously declared to operate on the returned data.
// front function jsonp({ url, params, callback }) { return new Promise((resolve, reject) => { let script = document.createElement('script') window[callback] = function(data) { resolve(data) document.body.removeChild(script) } params = { ... params, callback } // wd=b&callback=show let arrs = [] for (let key in params) { arrs.push(`${key}=${params[key]}`) } script.src = `${url}? ${arrs.join('&')}` document.body.appendChild(script) }) } jsonp({ url: 'http://localhost:3000/say', params: { wd: 'wxgongzhonghao' }, callback: 'show' }).then(data => { console.log(data) })Copy the code
// let express = require('express') let app = express() app.get('/say', function(req, function(req, function(req, function(req, function(req, function(req, function(req, function(req, function)) res) { let { wd, Callback} = req.query console.log(wd) // Iloveyou console.log(callback) // show res.end(' ${callback} ')} app.listen(3000)Copy the code
The above code to http://localhost:3000/say? Wd =wxgongzhonghao&callback=show this address requests data, and then returns show(‘ pay attention to the front end ‘).
Cross-domain Resource Sharing (CORS)
Cross-origin Resource Sharing (CORS) defines how the browser and server must communicate when accessing cross-domain resources. The basic idea behind CORS is to use custom HTTP headers to let the browser communicate with the server to determine whether a request or response should succeed or fail.
CORS requires both browser and backend support. Internet Explorer 8 and 9 need to be implemented through XDomainRequest.
The browser will automatically carry out CORS communication, the key to achieve CORS communication is the back end. As long as the backend implements CORS, cross-domain is achieved.
To enable CORS, set access-Control-allow-Origin on the server. This attribute indicates which domain names can access resources. If a wildcard is set, all websites can access resources.
Although setting up CORS has nothing to do with the front end, solving cross-domain problems in this way can result in two cases of simple and complex requests being sent.
Simple request: (Simple request if the following two conditions are met)
1. The request method is one of the following:
- GET
- POST
- HEAD
2. The content-Type is one of the following three:
- text-plain
- multiparty/form-data
- application/x-www-form-urlencoded
Complex request:
If it’s not a simple request, it must be a complex request. For CORS requests with complex requests, an HTTP query request is added before the request is formally initiated, which is called the precheck request. This request is of the Option method. Through this request, the server can know whether to allow the cross-domain request.
Nginx reverse proxy
The principle of Nginx reverse proxy is very simple, that is, all requests from the client must be processed by Nginx, and Nginx acts as the proxy server to forward the request to the back end, thus circumventing the same origin policy of the browser.
14. What is XSS attack
What is XSS?
XSS stands for Cross Site Scripting. To differentiate it from CSS, XSS is called cross-site Scripting in Chinese
XSS refers to a method by which hackers inject malicious scripts into a page to attack users when they browse the page.
What can XSS do?
- Stealing cookies
- Monitor user behavior, such as entering the account password and sending it to the hacker server
- Generate floating window ads in the web page
- Modified DOM forgery login form
XSS implementation
- Stored XSS attack
- Reflex XSS attack
- DOM based XSS attack
How do I prevent XSS attacks?
Filter or transcode the input script
Filter or transcode the input information to ensure that the input content cannot be executed during HTML parsing.
Using the CSP
The Security Policy is implemented based on an HTTP header called Content-security-Policy. The core idea is that the server decides which resources the browser loads.
- Restrict the loading of resource files in other domains, so that even if a hacker inserts a JavaScript file, the JavaScript file cannot be loaded;
- Do not submit data to third-party domains, so that user data is not leaked.
- Provide a reporting mechanism to help us detect XSS attacks in a timely manner.
- Prohibit execution of inline scripts and unauthorized scripts;
Using the HttpOnly
Since many XSS attacks are designed to steal cookies, we can also secure our cookies by using the HttpOnly attribute. In this case, JavaScript cannot read the value of the Cookie. This is also a good defense against XSS attacks.
The HttpOnly flag is set by the server via the HTTP response header. The following is a section of the HTTP response header when Google is opened:
set-cookie: NID=189=M8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly
Copy the code
For untrusted input, you can limit the input length
15. What is a CSRF attack?
What is a CSRF attack?
CSRF stands for cross-site Request Forgery. An attacker induces the victim to access a third-party website and then sends a cross-site request to the attacked website. Using the victim in the attacked website has obtained the registration certificate, bypassing the background user authentication, to impersonate the user to perform a certain operation on the attacked website. A CSRF attack is when a hacker takes advantage of a user’s login status and uses a third-party site to do something bad.
Several common types of attacks
1. CSRF of GET type
CSRF of GET type is very simple and usually requires only one HTTP request:
<img src="http://bank.example/withdraw? amount=10000&for=hacker" >Copy the code
After the victim to visit the page containing the img, the browser will automatically to http://bank.example/withdraw? Account =xiaoming&amount=10000&for=hacker Sends an HTTP request. Bank.example will receive a cross-domain request containing the victim’s login information.
2. CSRF of POST type
This type of CSRF is typically exploited using an auto-submitted form, such as:
<form action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>
Copy the code
When you visit the page, the form is automatically submitted, simulating a POST operation.
3. CSRF of the link type
Link-type CSRFS are uncommon and require the user to click a link to trigger them, compared to the other two cases where the user opens the page and is caught. This type usually involves embedding malicious links in the pictures published in the forum, or inducing users to be lured in the form of advertisements. Attackers usually trick users into clicking with exaggerated words, such as:
< a href = "http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget = "_blank" > big news!! <a/>Copy the code
Since the user logged in to the trusted website A and saved the login status, as long as the user actively accessed the above PHP page, the attack was successful.
The characteristics of CSRF
- Attacks are generally launched on third party sites, not the site being attacked. The attacked site cannot prevent the attack from happening.
- Attack using the victim’s login credentials in the attacked website, posing as the victim to submit operations; Instead of stealing data directly.
- The attacker can not obtain the login credentials of the victim during the whole process, just “fake”.
- Cross-site requests can be made in a variety of ways: image urls, hyperlinks, CORS, Form submissions, and more. Part of the request can be directly embedded in third-party forums, articles, difficult to track.
CSRF is typically cross-domain because outdomains are usually more easily controlled by attackers. However, if there are easily exploited functions in the local domain, such as forums and comment areas for Posting pictures and links, the attack can be carried out directly in the local domain, and this attack is more dangerous.
Protection strategy
The hacker can only use the victim’s cookie to cheat the trust of the server, but the hacker cannot get ** “cookie” ** by virtue of, nor can he see the content of ** “cookie”. In addition, the result returned by the server cannot be parsed by the hacker due to the same origin policy of the browser.
This tells us that we want to protect the services that can directly change the data, while the services that read the data do not need CSRF protection. The key to protection is to “put information in a request that a hacker cannot forge.”
Homologous detection
Since most CSRFS come from third-party sites, we simply forbid outlands (or untrusted domain names) from making requests to us.
So how do we know if the request is coming from outdomain?
In HTTP, each asynchronous request carries two headers, which mark the domain name of the source:
- Origin Header
- Referer Header
These two headers are carried automatically in most cases when the browser makes a request, and the content cannot be customized by the front end. The server can determine the source domain of the request by resolving the domain names in the two headers.
Use the Origin Header to determine the source domain name
In some CSRF-related requests, the request Header carries the Origin field. The field contains the requested domain name (excluding PATH and Query).
If Origin exists, just use the fields in Origin to identify the source domain name.
But Origin doesn’t exist in two cases:
- Internet Explorer 11 Same-origin policy: Internet Explorer 11 will not add the Origin header on cross-site CORS requests, and the Referer header will remain the unique identifier. The most fundamental reason is that the definition of same-origin in Internet Explorer 11 is different from that in other browsers. There are two major differences, please refer to MDN SAME-origin_policy #IE_Exceptions
- 302 Redirects: After 302 redirects Origin is not included in redirected requests because Origin may be considered sensitive information from other sources. In the case of 302 redirects, the URL is directed to the new server, so the browser does not want to leak Origin to the new server.
Use the Referer Header to identify the source domain name
According to the HTTP protocol, there is a field in the HTTP header called Referer that records the source address of the HTTP request. For Ajax requests, images, and script resource requests, Referer is the page address that initiates the request. For page jumps, Referer is the address of the previous page that opened the page history. Therefore, we use the Origin section of the link in the Referer to get the source domain name of the request.
This method is not foolproof, the Referer value is provided by the browser, although HTTP protocol has clear requirements, but each browser for the specific implementation of the Referer may be different, there is no guarantee that the browser itself does not have security vulnerabilities. The method of verifying the Referer value relies on the security of a third party (i.e. the browser), which in theory is not very secure. In some cases, attackers can hide or even modify the Referer of their own requests.
In 2014, the W3C’s Web Application Security Working Group published a draft Referrer Policy that specifies in detail how browsers should send referers. Now that most of the newer browsers support this draft, we finally have the flexibility to control the Referer policy for our sites. The new Referrer Policy specifies five Referer policies: No Referrer, No Referrer When downgraded, Origin Only, Origin When cross-origin, and Unsafe URL. Three pre-existing policies, never, Default, and always, have been renamed. Their correspondence is as follows:
Name of strategy | Attribute value (New) | Attribute value (old) |
---|---|---|
No Referrer | no-Referrer | never |
No Referrer When Downgrade | no-Referrer-when-downgrade | default |
Origin Only | (same or strict) origin | origin |
Origin When Cross Origin | (strict) origin-when-crossorigin | – |
Unsafe URL | unsafe-url | always |
According to the table above, the Referrer Policy should be set to same-origin. For same-origin links and references, the Referer will be sent with the value of Host without Path. Cross-domain access does not carry Referer. For example: Aaa.com references bbb.com resources and does not send Referer.
There are three ways to set the Referrer Policy:
- In the CSP setting
- Add meta tags to the header of the page
- A tag adds the referrerPolicy attribute
This is a lot, but we can see one problem: attackers can hide referers in their requests. If the attacker filled out his request like this:
<img src="http://bank.example/withdraw? amount=10000&for=hacker" referrerpolicy="no-referrer">Copy the code
Then the attack initiated by this request will not carry the Referer.
In addition, Referer is not or cannot be trusted in the following cases:
1. In IE6 and IE7, when window.location.href= URL is used to jump to the interface, the Referer will be lost.
2. When Windows. Open is used in IE6 and IE7, Referer will also be missing.
3. When the HTTPS page is switched to the HTTP page, the Referer of all browsers is lost.
4. When clicking Flash to reach another website, the Referer’s situation is messy and not credible.
The source domain name situation could not be confirmed
What happens when the Origin and Referer headers do not exist? If neither Origin nor Referer exists, it is recommended to block it directly, especially if you are not using a random CSRF Token (see below) as a second check.
How do I block outfield requests
Through Header verification, we can know the source domain name of the request, which may be the site’s own domain, or a sub-domain, or an authorized third party domain name, or from an untrusted unknown domain name.
We already know if the requested domain name is from an untrusted domain name, can we prevent CSRF attacks by simply blocking these requests?
Wait a minute! When a request is a page request (such as the homepage of a website) and the source is a link from a search engine (such as baidu search results), it can also be considered as a suspected CSRF attack. Therefore, you need to filter out the page request when judging. Usually, the Header meets the following conditions:
Accept: text/html
Method: GET
Copy the code
In turn, page requests are exposed to CSRF attacks. If your site does something to the current user in a GET request on the page, the defense will fail.
For example, the following page request:
GET https://example.com/addComment?comment=XXX&dest=orderId
Copy the code
Note: This is not strictly a risk of CSRF attacks, but there are still many sites that often implement product features by putting parameters on main document GET requests, but doing so is a security risk of its own.
In addition, as mentioned earlier, CSRFS mostly come from third-party domain names, but local domain initiation cannot be ruled out. If an attacker has permission to post comments (including links and images, collectively referred to as UGC) in the local domain, it can directly launch attacks in the local domain. In this case, the same-origin policy cannot protect against attacks.
To sum up: Homologous authentication is a relatively simple defense method that can prevent the vast majority of CSRF attacks. But it’s not foolproof. For sites with high security requirements or a lot of user input, we need to put extra safeguards on key interfaces.
CSRF Token
Another feature of CSRF mentioned above is that attackers cannot directly steal the user’s information (cookies, headers, website content, etc.), but only use the information in cookies.
The CSRF attack succeeds because the server mistook the request sent by the attacker for the user’s own request. Then we can require all user requests to carry a Token that a CSRF attacker cannot obtain. By verifying whether the request carries the correct Token, the server can distinguish the normal request from the attack request and defend against CSRF attacks.
Take advantage of the SameSite property of the Cookie
Take a look at MDN’s explanation of this
SameSite can be set to three values, Strict, Lax, and None.
- in
Strict
In this mode, the browser does not allow third-party requests to carry cookies. Such as requestsanyuan.com
The website can only be accessedsanyuan.com
Cookies can only be carried by requests in domain names, not requests on other sites. - in
Lax
Mode, a little bit looser, but only inThe get method submits the form
Conditions orThe A tag sends a GET request
Can carry cookies in other cases. - In None mode, cookies are sent in all contexts, that is, across domains.
Likes, likes and comments
I am Front-end Nanjiu, thank you for your “likes, concerns and comments”, we will see you next time!
Welcome to join the front-end communication group 928029210, where there are many like-minded front-end developers to communicate with us