Home  >  Article  >  Web Front-end  >  Take a look at these browser interview questions. How many can you answer correctly?

Take a look at these browser interview questions. How many can you answer correctly?

青灯夜游
青灯夜游forward
2022-03-23 10:39:593682browse

This article will share with you some interview questions about browsers. See how many you can answer? Analyze the correct answers and see how many you can get right!

Take a look at these browser interview questions. How many can you answer correctly?

#1. What are the common browser kernels?

The core of the browser can be divided into two parts:

Rendering engine and JS engine (Note: The browser kernel we often refer to refers to the rendering engine)

As the JS engine becomes more and more independent, the kernel refers only to the rendering engine, which is mainly used to request The network page resources are parsed and typed and presented to the user

##Browser/RunTimeKernel (rendering engine)JavaScript engineChromeBlink (28~) Webkit (Chrome 27) V8FireFoxGeckoSpiderMonkeySafariWebkitJavaScriptCoreEdgeEdgeHTMLChakra(For JavaScript)IETrident Chakra (For JScript)OperaPresto->blinkLinear 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: in the user interface and rendering engine Transfer instructions between

  • Rendering engine: used to draw the requested content

  • Network: used to complete network calls, such as http requests, it Has a platform-independent interface and can work on different platforms

  • JavaScript interpreter: used to parse and execute JavaScript code

  • User interface backend : Used to draw basic widgets, such as combo boxes and windows. The bottom layer uses the user interface of the operating system

  • Data storage: It belongs to the persistence layer, and the browser saves similar cookies on the hard disk. For various data, HTML5 defines web database technology, which is a lightweight and complete client-side storage technology

Note : Unlike most browsers, each tab in Google Chrome corresponds to a rendering engine instance. Each tab is an independent process

Take a look at these browser interview questions. How many can you answer correctly?

3. Let’s talk about what happens from inputting the URL to page rendering What?

This question can be said to be the most common question in interviews and can be infinitely difficult. Generally, interviewers ask this question to test the depth of your front-end knowledge.

1. The browser accepts the URL and opens the network request thread (involving: browser mechanism, thread and process, etc.)

2. Open the network thread to issue a complete http request (Involving: DNS query, TCP/IP request, 5-layer network protocol, etc.)

3. Receive the request from the server to the corresponding backend (involving: load balancing, security interception, backend internal processing etc.)

4. HTTP interaction between the backend and the frontend (involving: http headers, response codes, message structures, cookies, etc.)

5. Caching issues (involving: http strong cache Negotiate cache, cache header, etag, expired, cache-control, etc.)

6. The parsing process after the browser receives the http packet (involving html lexical analysis, parsing into a DOM tree, and parsing CSS generation CSSOM trees are merged to generate render rendering trees. Then layout layout, painting rendering, composite layer synthesis, GPU drawing, external link processing, etc.)

7. CSS visual model (involving: element rendering rules, such as: Contains blocks, control boxes, BFC, IFC, etc.)

8. JS engine parsing process (involving: JS parsing phase, preprocessing phase, execution phase to generate execution context, VO (global object), scope chain , recycling mechanism, etc.)

You will find that so many processes will occur between a simple input URL and the rendering of the page. Do you feel that it crashes instantly? (Don’t worry, we won’t do this in this chapter. Let me teach you how to answer this question first. This section will be discussed in a separate article)

  • The browser obtains the IP address of the domain name through the DNS server and requests it from this IP address. HTML text
  • The browser rendering process parses the HTML text and builds the DOM tree
  • While parsing the HTML, if it encounters an inline style or style file, it downloads and builds the style rules. If it encounters JavaScript script, the execution script will be downloaded
  • After the DOM tree and CSSOM are constructed, the rendering process will merge the two into a render tree (render tree)
  • The rendering process begins to lay out the rendering tree. Generate layout tree
  • Rendering tree draws the layout tree and generates drawing records

Take a look at these browser interview questions. How many can you answer correctly?

4. How does the browser parse the code of?

Parsing HTML

HTML is parsed line by line, and the browser's rendering engine will parse and convert the HTML document into DOM nodes.

  • Parse HTML into many Tokens
  • Parse Tokens into objects
  • Combine objects into a DOM tree

Parse CSS

The browser will parse the CSS selector from right to left

We know that the DOM tree and the CSSOM tree are merged into The render tree actually attaches the CSSOM to the DOM tree, so the DOM tree needs to be traversed based on the information provided by the selector.

Let’s look at an example:

<style>
.nav .title span {color:blue}
</style>

<div class=&#39;nav&#39;>
  <div class=&#39;title&#39;>
    <span>南玖</span>
  </div>
  <div class="sub_title">前端</header>
</div>

Right-to-left matching:

  • ##First find all the rightmost node spans, for each span , look up for the node div.title

  • From h3 and then look up for the node div.nav

  • Finally find the root element html, then end this branch traversal.

Parsing JS

There is a js parser tool in the browser, which is specially used to parse our js code.

When the browser encounters js code, it immediately calls the "js parser" to work.

The parser will find all variables, functions, parameters, etc. in js, and assign the variable value to undefined.

Take the function out into a function block and store it in the warehouse. After this is done, the code begins to be parsed line by line (from top to bottom, left to right), and then matched with the warehouse.

5.What is the difference between DOMContentLoaded and load?

  • DOMContentLoaded: Triggered only after DOM parsing is completed, excluding style sheets, pictures and other resources.
  • Load: Triggered when all DOM, style sheets, scripts, images and other resources on the page have been loaded.

6. What is the difference between browser redrawing and domain rearrangement?

  • Rearrangement: Part of the rendering tree or the entire rendering tree needs to be reanalyzed and the node size needs to be recalculated, which means regenerating the layout and rearranging elements
  • Redrawing: Due to changes in the geometric properties of nodes or changes in style, such as element background elements, the appearance of some elements is changed

Redrawing is not necessarily Causes reflow, but reflow must lead to redraw

How to trigger redraw and reflow?

Any change to the information used to build the render tree will cause a reflow or redraw:

  • Add, delete, update DOM nodes
  • Hide a DOM node through display: none - trigger reflow and redraw
  • Hide a DOM node through visibility: hidden - only trigger redraw, because there is no geometric change
  • Move or give Add animation to DOM nodes in the page
  • Add a style sheet and adjust style attributes
  • User behavior, such as adjusting window size, changing font size, or scrolling.

How to avoid redrawing or reflowing?

  • Change the style centrally: For example, use class to collectively change the style

  • Use document.createDocumentFragment (): We can create a node outside the DOM tree through createDocumentFragment, then perform batch operations on this node, and finally insert it into the DOM tree, so only one rearrangement is triggered

  • Promote to composition layer

    Promoting elements to composition layer has the following advantages:

    • The bitmap of the composition layer will be handed over to GPU Synthesis, faster than CPU processing

    • When repaint is needed, only repaint itself is required, not Affects other layers

    • For transform and opacity effects, layout and paint will not be triggered

      The best way to enhance a composition layer is to use the CSS will-change property

##7. Why is JS single-threaded?

This is mainly related to the purpose of JS. As the scripting language of the browser, JS was initially mainly used to realize the interaction between the user and the browser and to operate the DOM. This determines that it can only be single-threaded, otherwise it will bring many complex synchronization problems.

For example: If JS is multi-threaded, one thread wants to modify a DOM element, and another thread wants to delete the DOM element, then the browser does not know what to do Who do you listen to? So in order to avoid complexity, JavaScript has been designed to be single-threaded since its birth.

In order to take advantage of the computing power of multi-core CPUs, 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 must not operate the DOM. Therefore, this new standard does not change the single-threaded nature of JavaScript

8. Will CSS loading block the DOM?

First the conclusion

    ##CSS
  • will not blockDOM parsing, but will block the rendering of DOM
  • CSS
  • will block JS execution, but will not block JS Downloading files

The role of CSSOM

    The first one is provided for JavaScript operations The ability of the style sheet
  • The second is to provide basic style information for the synthesis of the layout tree
  • This CSSOM is reflected in the DOM
  • document.styleSheets

  • We can see from the browser rendering process mentioned before:

    DOM and CSSOM usually is built in parallel, so
  • CSS loading will not block DOM parsing

  • The render tree is dependent on the DOM tree and CSSOM tree, so it must wait until both Rendering cannot be started until loading is complete, so
  • CSS loading will block the rendering of DOM

  • Since JavaScript can operate DOM and CSS, if you modify the attributes of these elements at the same time If the interface is rendered (that is, the JavaScript thread and the UI thread are performed at the same time), the elements obtained before and after the rendering thread may be inconsistent. Therefore, in order to prevent unpredictable rendering results, the browser sets the
  • GUI rendering thread and the JavaScript thread to be mutually exclusive

JS requires Waiting for CSS to be downloaded, why is this? (CSS blocks DOM execution)

If the content of the JS script is to obtain the style of the element, then it must rely on CSS. Because the browser cannot sense what JS is trying to do internally, in order to avoid style acquisition, it has to wait until all previous styles are downloaded before executing JS. However, JS files and CSS files are downloaded in parallel. The CSS file will be loaded and executed before the subsequent JS file is executed, so CSS will block the execution of the subsequent JS

Avoid white screen and improve CSS loading speed

  • Use CDN (CDN will select the nearest node with cached content to provide you with resources based on your network conditions , so the loading time can be reduced)
  • Compress CSS
  • Use cache reasonably
  • Reduce the number of http requests and merge CSS files

9 Will .JS block the page?

First the conclusion

JS will block the parsing of the DOM, so it will also block the loading of the page

This is why we often say that we should put the JS file at the bottom

Since JavaScript can manipulate the DOM, if you modify the attributes of these elements and render the interface at the same time ( That is, the JavaScript thread and the UI thread run at the same time), then the element data obtained before and after the rendering thread may be inconsistent.

Therefore, in order to prevent unexpected rendering results, the browser sets a **"GUI rendering thread and JavaScript engine are mutually exclusive"** relationship.

When the JavaScript engine is executing, the GUI thread will be suspended, and GUI updates will be saved in a queue and executed immediately when the engine thread is idle.

When the browser is executing a JavaScript program, the GUI rendering thread will be saved in a queue and will not be executed until the JS program is completed.

Therefore, if the execution time of JS is too long, it will cause the rendering of the page to be inconsistent, resulting in the feeling that the page rendering and loading are blocked.

10.What is the difference between defer and async?

  • Both load external JS files asynchronously and will not block DOM parsing
  • Async is executed after the external JS loading is completed, when the browser is idle, and before the Load event is triggered. , scripts marked as async are not guaranteed to be executed in the order in which they are specified. This attribute has no effect on inline scripts (that is, scripts without the "src" attribute).
  • defer is executed after the JS is loaded, after the entire document is parsed, and before the DOMContentLoaded event is triggered. If the src attribute (i.e., embedded script) is missing, the The attribute should not be used because it has no effect in this case

11. Browser garbage collection mechanism

Garbage collection is an automatic memory management mechanism. Dynamic memory on your computer should be released when it is no longer needed.

It should be noted that automatic means that the browser can automatically help us recycle memory garbage, but it does not mean that we do not need to care about memory management. If it is not operated properly, memory overflow will still occur in JavaScript, causing system breakdown.

Since strings, arrays, objects, etc. do not have fixed sizes, they need to be dynamically allocated when their sizes are known. 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. When it determines that the object is useless, it knows that the object is no longer needed and can release the memory it occupies. .

There are two methods of garbage collection that browsers usually use: Mark clearing, Reference counting.

Mark clearing

This is the most commonly used garbage collection method in JavaScript

Since 2012 Since 2000, all modern browsers have used the mark-and-sweep garbage collection method, except for lower versions of IE, which still use the reference counting method.

So what is mark removal?

There is a global object in JavaScript. Periodically, the garbage collector will start from this global object, find all the objects referenced from this global object, and then find the objects referenced by these objects. Objects... mark these active objects, this is the marking phase. The clearing stage is to clear those objects that are not marked.

One problem with mark clearing is that after clearing, the memory space is discontinuous, that is, memory fragmentation occurs. If a relatively large continuous memory space is needed later, it will not meet the requirements. The marking and sorting method can effectively solve this problem.

In the process of marking, the concept of three-color marking is introduced. The three colors are:

  • White: unmarked objects, that is, unreachable objects (not scanned object), can be recycled
  • Gray: The object has been marked (reachable object), but the object has not been scanned yet and cannot be recycled
  • Black: It has been scanned (reachable) Object), non-recyclable

Tag sorting:

The marking phase is no different from the mark and clear method, except that after the marking is completed, the mark and clear method will move the surviving objects to one side of the memory, and finally clean up the boundary memory.

Reference counting

The meaning of reference counting is to track the number of times each value is referenced. When a variable A is assigned a value, the number of references to this value is 1. When variable A is reassigned, the number of references to the previous value is reduced by 1. When the number of references becomes 0, it means that there is no way to access this value anymore, so the memory occupied by this value can be cleared.

Most browsers have abandoned this recycling method

Memory leak

To avoid memory leaks, once the data is no longer used, it is best to release its reference by setting its value to null. This method is called Contact reference

What situations can cause memory leaks? How to avoid it?

Taking Vue as an example, there are usually the following situations:

  • Listening events such as window/body are not unbound
  • The event tied to EventBus is not untied from
  • Vuex's $store, and there is no after watch is removed. unwatch
  • Created using a third-party library and not calling the correct destruction function

Solution: Destroy in time in beforeDestroy

  • Binded events addEventListener and removeEventListener in the DOM/BOM object.
  • Observer mode $on, $off processing.
  • If a timer is used in the component, it should be destroyed.
  • If a third-party library initialization is used in the mounted/created hook, it will be destroyed accordingly.
  • Use weak references weakMap, weakSet.

When are the memories of different types of variables in the browser released?

  • Reference type

    • It is automatically recycled by V8 after there is no reference.
  • Basic type

    • If it is in a closure, it will not be recycled by V8 until there is no reference to the closure.
    • In the case of non-closure, wait for recycling when V8's new generation switches.

12. Talk about the browser’s caching mechanism?

Understand browser cache

When the browser requests a website, it will load various resources. For some resources that do not change frequently, The browser will save them in local memory and load these resources directly the next time you visit to improve access speed.

How to know whether the resource is the requested server or the cache read?

Take a look at these browser interview questions. How many can you answer correctly?

Look at the picture above, the size value of some resources is the size, some are from disk cache, and some are from memory cache, the size shown is the requested server resource, and the latter two are the read cache.

  • disk cache: is to store resources in the disk. There is no need to download them again when waiting for the next access. It can be read directly from the disk. Its direct operation object is CurlCacheManager. (The efficiency is slower than the memory cache, but the storage capacity is large and the storage time is long)
  • memory cache: It means caching the resources into the memory. There is no need to download them again when waiting for the next access. Read from memory. (In terms of efficiency, it is the fastest and in terms of survival time, it is the shortest.)
- memory cache disk cache
Same point Can only store some derived resource files Only Store some derived class resource files
Difference The data will be cleared when exiting the process The data will not be cleared when exiting the process
Storage resources Generally scripts, fonts, and pictures will be stored in memory Generally non-scripts will be stored in memory, such as css, etc.

Browser cache classification

  • Strong cache
  • Negotiation cache

When the browser requests resources from the server, it first determines whether it hits the strong cache. If it fails, it then determines whether it hits the negotiated cache

Strong cache

When the browser loads resources, it will first determine whether the strong cache is hit based on the header of the local cache resource. If it hits, the resource in the cache will be used directly without sending a request to the server. (The information in the header here refers to expires and cache-control)

  • ##Expires

This field is the specification of

http1.0, and its value is a time character in GMT format of absolute time String, such as Expires:Mon,18 Oct 2066 23:59:59 GMT. This time represents the expiration time of this resource. Before this time, the cache is hit. This method has an obvious shortcoming. Since the expiration time is an absolute time, when the time deviation between the server and the client is large, it will cause cache confusion. So this method was quickly abandoned in the later version of HTTP 1.1.

  • Cache-Control

The header that appears when Cache-Control is

http1.1 Information is mainly judged by using the max-age value of this field, which is a relative time, such as Cache-Control:max-age=3600 , which means that the validity period of the resource is 3600 seconds. In addition to this field, cache-control also has the following more commonly used setting values:

no-cache: You need to negotiate the cache and send a request to the server to confirm whether to use the cache.

no-store: Disable the use of cache and re-request data every time.

public: Can be cached by all users, including end users and intermediate proxy servers such as CDN.

private: It can only be cached by the end user's browser and is not allowed to be cached by relay cache servers such as CDN.

Cache-Control and Expires can be enabled at the same time in the server configuration. When enabled at the same time, Cache-Control has higher priority.

Negotiation Cache

When the strong cache misses, the browser will send a request to the server, and the server will follow

The information in header is used to determine whether the negotiation cache is hit. If it hits, 304 is returned, telling the browser that the resource has not been updated and the local cache can be used. (The header information here 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, the header returned by the server will Together with Last-Modify, Last-modify is a time that identifies the last modification time of the resource.

When the browser requests the resource again, the request header will contain If-Modify-Since, which is the Last-Modify returned before caching. After the server receives If-Modify-Since, it determines whether the cache is hit based on the last modification time of the resource.

If the cache is hit, 304 is returned, the resource content is not returned, and Last-Modify is not returned.

Disadvantages:

If the resources change in a short period of time, Last-Modified will not change.

Cyclic changes. If this resource is modified back to its original state within a cycle, we think it can be cached, but Last-Modified does not think so, so there is an ETag.

  • ETag/If-None-Match

is different from Last-Modify/If-Modify-Since , Etag/If-None-Match returns a check code. ETag can guarantee that each resource is unique, and resource changes will cause ETag changes. The server determines whether the cache is hit based on the If-None-Match value sent by the browser.

The difference from Last-Modified is that when the server returns a 304 Not Modified response, since the ETag has been regenerated, the ETag will be returned in the response header, even if the ETag has not changed from the previous one.

Last-Modified and ETag can be used together. The server will verify the ETag first. If it is consistent, it will continue to compare Last-Modified and finally decide whether to return 304.

Summary

When the browser accesses an already visited resource, its steps are:

1. First check whether the strong cache is hit. If it hits?, use the cache directly.

2. If the strong cache is not hit, a request will be sent to the server to see if it hits? Negotiate cache

3. If the negotiation cache is hit, the server will return 304 to tell the browser that the local cache can be used

4. If the negotiation cache is not hit, the server will return new resources to the browser

13.什么是浏览器的同源策略,以及跨域?

同源策略

同源策略是浏览器的一种自我保护行为。所谓的同源指的是:协议,域名,端口均要相同

浏览器中大部分内容都是受同源策略限制的,但是以下三个标签不受限制:

<img  src="..." / alt="Take a look at these browser interview questions. How many can you answer correctly?" >
<link href="..." />
<script src="..."></script>

跨域

跨域指的是浏览器不能执行其它域名下的脚本。它是由浏览器的同源策略限制的。

你可能会想跨域请求到底有没有发送到服务器?

事实上,跨域请求时能够发送到服务器的,并且服务器也能过接受的请求并正常返回结果,只是结果被浏览器拦截了。

跨域解决方案(列出几个常用的)

  • JSONP

它主要是利用script标签不受浏览器同源策略的限制,可以拿到从其他源传输过来的数据,需要服务端支持。

优缺点:

兼容性比较好,可用于解决主流浏览器的跨域数据访问的问题。缺点就是仅支持get请求,具有局限性,不安全,可能会受到XSS攻击。

思路:

  • 声明一个回调函数,其函数名(如show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
  • 创建一个<script></script>标签,把那个跨域的API数据接口地址,赋值给script的src,还要在这个地址中向服务器传递该函数名(可以通过问号传参:?callback=show)。
  • 服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是show,它准备好的数据是show('南玖')
  • 最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(show),对返回的数据进行操作。
// front
function jsonp({ url, params, callback }) {
  return new Promise((resolve, reject) => {
    let script = document.createElement(&#39;script&#39;)
    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(&#39;&&#39;)}`
    document.body.appendChild(script)
  })
}
jsonp({
  url: &#39;http://localhost:3000/say&#39;,
  params: { wd: &#39;wxgongzhonghao&#39; },
  callback: &#39;show&#39;
}).then(data => {
  console.log(data)
})
// server 借助express框架
let express = require(&#39;express&#39;)
let app = express()
app.get(&#39;/say&#39;, function(req, res) {
  let { wd, callback } = req.query
  console.log(wd) // Iloveyou
  console.log(callback) // show
  res.end(`${callback}(&#39;关注前端南玖&#39;)`)
})
app.listen(3000)

上面这段代码相当于向http://localhost:3000/say?wd=wxgongzhonghao&callback=show这个地址请求数据,然后后台返回show('关注前端南玖'),最后会运行show()这个函数,打印出'关注前端南玖'

  • 跨域资源共享(CORS)

CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。

CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现

浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。

服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。

虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求复杂请求

简单请求: (满足以下两个条件,就是简单请求)

1.请求方法为以下三个之一:

  • GET
  • POST
  • HEAD

2.Content-Type的为以下三个之一:

  • text-plain
  • multiparty/form-data
  • application/x-www-form-urlencoded

复杂请求:

不是简单请求那它肯定就是复杂请求了。复杂请求的CORS请求,会在正式发起请求前,增加一次HTTP查询请求,称为预检 请求,该请求是option方法的,通过该请求来知道服务端是否允许该跨域请求。

Nginx反向代理

Nginx 反向代理的原理很简单,即所有客户端的请求都必须经过nginx处理,nginx作为代理服务器再将请求转发给后端,这样就规避了浏览器的同源策略。

14.说说什么是XSS攻击

什么是XSS?

XSS 全称是 Cross Site Scripting,为了与css区分开来,所以简称XSS,中文叫作跨站脚本

XSS是指黑客往页面中注入恶意脚本,从而在用户浏览页面时利用恶意脚本对用户实施攻击的一种手段。

XSS能够做什么?

  • 窃取Cookie
  • 监听用户行为,比如输入账号密码后之间发给黑客服务器
  • 在网页中生成浮窗广告
  • 修改DOM伪造登入表单

XSS实现方式

  • 存储型XSS攻击
  • 反射型XSS攻击
  • 基于DOM的XSS攻击

如何阻止XSS攻击?

对输入脚本进行过滤或转码

对用户输入的信息过滤或者转码,保证用户输入的内容不能在HTML解析的时候执行。

利用CSP

该安全策略的实现基于一个称作 Content-Security-Policy的HTTP首部。(浏览器内容安全策略)它的核心思想就是服务器决定浏览器加载那些资源。

  • 限制加载其他域下的资源文件,这样即使黑客插入了一个 JavaScript 文件,这个 JavaScript 文件也是无法被加载的;
  • 禁止向第三方域提交数据,这样用户数据也不会外泄;
  • 提供上报机制,能帮助我们及时发现 XSS 攻击。
  • 禁止执行内联脚本和未授权的脚本;

利用 HttpOnly

由于很多 XSS 攻击都是来盗用 Cookie 的,因此还可以通过使用 HttpOnly 属性来保护我们 Cookie 的安全。这样子的话,JavaScript 便无法读取 Cookie 的值。这样也能很好的防范 XSS 攻击。

通常服务器可以将某些 Cookie 设置为 HttpOnly 标志,HttpOnly 是服务器通过 HTTP 响应头来设置的,下面是打开 Google 时,HTTP 响应头中的一段:

set-cookie: NID=189=M8l6-z41asXtm2uEwcOC5oh9djkffOMhWqQrlnCtOI; expires=Sat, 18-Apr-2020 06:52:22 GMT; path=/; domain=.google.com; HttpOnly

对于不受信任的输入,可以限制输入长度

15.说说什么是CSRF攻击?

什么是CSRF攻击?

CSRF 全称 Cross-site request forgery,中文为跨站请求伪造 ,攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。 CSRF攻击就是黑客利用用户的登录状态,并通过第三方站点来干一些嘿嘿嘿的坏事

几种常见的攻击类型

1.GET类型的CSRF

GET类型的CSRF非常简单,通常只需要一个HTTP请求:

 <img  src="http://bank.example/withdraw?amount=10000&for=hacker"  alt="Take a look at these browser interview questions. How many can you answer correctly?" >

在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。

2.POST类型的CSRF

这种类型的CSRF利用起来通常使用的是一个自动提交的表单,如:

 <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>

访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。

3.链接类型的CSRF

链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:

  <a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
  重磅消息!!
  <a/>

由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问上面的这个PHP页面,则表示攻击成功。

CSRF的特点

  • 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生。
  • 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据。
  • 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”。
  • 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪。

CSRF通常是跨域的,因为外域通常更容易被攻击者掌控。但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击可以直接在本域下进行,而且这种攻击更加危险。

防护策略

Hackers can only use the victim's cookie to defraud the server's trust, but hackers cannot rely on getting **"cookie"**, nor can they see **"cookie" content. In addition, hackers cannot parse the results returned by the server due to the browser's "same-origin policy" restrictions.

This tells us that the objects we want to protect are services that can directly produce data changes, and for services that read data, there is no need to protect

CSRF . The key to protection is "Put information in the request that hackers cannot forge"

Original detection

Since most CSRFs come from third-party websites, we directly prohibit external domains (or untrusted domain names) from making requests to us.

Then the question is, how do we determine whether the request comes from an external domain?

In the HTTP protocol, each asynchronous request carries two Headers, used to mark the source domain name:

    Origin Header
  • Referer Header
These two headers are automatically brought along in most cases when the browser initiates a request, and the content cannot be customized by the front end. The server can determine the source domain of the request by parsing the domain names in these two headers.

Use the Origin Header to determine the source domain name

In some CSRF-related requests, the Origin field will be carried in the requested header. The field contains the requested domain name (excluding path and query).

If Origin exists, just use the fields in Origin to confirm the source domain name.

But Origin does not exist in the following two cases:

  • IE11 Same Origin Policy: IE 11 will not add Origin on cross-site CORS requests header, the Referer header will still be the only identifier. The most fundamental reason is that IE 11’s definition of same origin is different from other browsers. There are two main differences. You can refer to MDN Same-origin_policy#IE_Exceptions
  • ##302 Redirects:
  • The Origin is not included in the redirected request after a 302 redirect because the 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 the Origin to the new server.
Use Referer Header to determine the source domain name

According to the HTTP protocol, there is a field called Referer in the HTTP header, which records the source address of the HTTP request. For Ajax requests, resource requests such as pictures and scripts, the 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 can use the Origin part of the link in the Referer to know the source domain name of the request.

This method is not foolproof. The value of Referer is provided by the browser. Although there are clear requirements on the HTTP protocol, each browser may have different implementations of Referer, and there is no guarantee that the browser will There are no security holes of its own. The method of verifying the Referer value relies on the third party (i.e. the browser) to ensure security. In theory, this is not very safe. In some cases, attackers can hide or even modify the Referer they request.

In 2014, the W3C's Web Application Security Working Group released a Referrer Policy draft, which made detailed provisions on how browsers should send Referer. As of now, most new browsers have supported this draft, and we can finally flexibly control the Referer strategy of our website. The new version of Referrer Policy stipulates five Referrer policies: No Referrer, No Referrer When Downgrade, Origin Only, Origin When Cross-origin, and Unsafe URL. The three existing strategies: never, default, and always have been renamed in the new standard. Their correspondence is as follows:

Policy nameNo ReferrerNo Referrer When DowngradeOrigin OnlyOrigin When Cross OriginUnsafe URL##

根据上面的表格因此需要把Referrer Policy的策略设置成same-origin,对于同源的链接和引用,会发送Referer,referer值为Host不带Path;跨域访问则不携带Referer。例如:aaa.com引用bbb.com的资源,不会发送Referer。

设置Referrer Policy的方法有三种:

  • 在CSP设置

  • 页面头部增加meta标签

  • a标签增加referrerpolicy属性

上面说的这些比较多,但我们可以知道一个问题:攻击者可以在自己的请求中隐藏Referer。如果攻击者将自己的请求这样填写:

 <img  src="http://bank.example/withdraw?amount=10000&for=hacker" referrerpolicy="no-referrer" alt="Take a look at these browser interview questions. How many can you answer correctly?" >

那么这个请求发起的攻击将不携带Referer。

另外在以下情况下Referer没有或者不可信:

1.IE6、7下使用window.location.href=url进行界面的跳转,会丢失Referer。

2.IE6、7下使用window.open,也会缺失Referer。

3.HTTPS页面跳转到HTTP页面,所有浏览器Referer都丢失。

4.点击Flash上到达另外一个网站的时候,Referer的情况就比较杂乱,不太可信。

无法确认来源域名情况

当Origin和Referer头文件不存在时该怎么办?如果Origin和Referer都不存在,建议直接进行阻止,特别是如果您没有使用随机CSRF Token(参考下方)作为第二次检查。

如何阻止外域请求

通过Header的验证,我们可以知道发起请求的来源域名,这些来源域名可能是网站本域,或者子域名,或者有授权的第三方域名,又或者来自不可信的未知域名。

我们已经知道了请求域名是否是来自不可信的域名,我们直接阻止掉这些的请求,就能防御CSRF攻击了吗?

且慢!当一个请求是页面请求(比如网站的主页),而来源是搜索引擎的链接(例如百度的搜索结果),也会被当成疑似CSRF攻击。所以在判断的时候需要过滤掉页面请求情况,通常Header符合以下情况:

Accept: text/html
Method: GET

但相应的,页面请求就暴露在了CSRF的攻击范围之中。如果你的网站中,在页面的GET请求中对当前用户做了什么操作的话,防范就失效了。

例如,下面的页面请求:

GET https://example.com/addComment?comment=XXX&dest=orderId

注:这种严格来说并不一定存在CSRF攻击的风险,但仍然有很多网站经常把主文档GET请求挂上参数来实现产品功能,但是这样做对于自身来说是存在安全风险的。

另外,前面说过,CSRF大多数情况下来自第三方域名,但并不能排除本域发起。如果攻击者有权限在本域发布评论(含链接、图片等,统称UGC),那么它可以直接在本域发起攻击,这种情况下同源策略无法达到防护的作用。

综上所述:同源验证是一个相对简单的防范方法,能够防范绝大多数的CSRF攻击。但这并不是万无一失的,对于安全性要求较高,或者有较多用户输入内容的网站,我们就要对关键的接口做额外的防护措施。

CSRF Token

前面讲到CSRF的另一个特征是,攻击者无法直接窃取到用户的信息(Cookie,Header,网站内容等),仅仅是冒用Cookie中的信息。

而CSRF攻击之所以能够成功,是因为服务器误把攻击者发送的请求当成了用户自己的请求。那么我们可以要求所有的用户请求都携带一个CSRF攻击者无法获取到的Token。服务器通过校验请求是否携带正确的Token,来把正常的请求和攻击的请求区分开,也可以防范CSRF的攻击。

利用Cookie的SameSite属性

可以看看MDN对此的解释:

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie/SameSite

SameSite可以设置为三个值,StrictLaxNone

  • Strict模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com网站只能在sanyuan.com域名当中请求才能携带 Cookie,在其他网站请求都不能。

  • Lax模式,就宽松一点了,但是只能在 get 方法提交表单况或者a 标签发送 get 请求的情况下可以携带 Cookie,其他情况均不能。

  • 在None模式下,Cookie将在所有上下文中发送,即允许跨域发送。

更多编程相关知识,请访问:编程入门!!

Attribute value (new) Attribute value (old)
no-Referrer never
no-Referrer-when-downgrade default
(same or strict) origin origin
(strict) origin-when-crossorigin -
unsafe-url always

The above is the detailed content of Take a look at these browser interview questions. How many can you answer correctly?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete