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?
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
)
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.
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)
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.
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>
跨域
跨域指的是浏览器不能执行其它域名下的脚本。它是由浏览器的同源策略限制的。
你可能会想跨域请求到底有没有发送到服务器?
事实上,跨域请求时能够发送到服务器的,并且服务器也能过接受的请求并正常返回结果,只是结果被浏览器拦截了。
跨域解决方案(列出几个常用的)
它主要是利用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('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)
})
// server 借助express框架
let express = require('express')
let app = express()
app.get('/say', function(req, res) {
let { wd, callback } = req.query
console.log(wd) // Iloveyou
console.log(callback) // show
res.end(`${callback}('关注前端南玖')`)
})
app.listen(3000)
上面这段代码相当于向http://localhost:3000/say?wd=wxgongzhonghao&callback=show
这个地址请求数据,然后后台返回show('关注前端南玖')
,最后会运行show()这个函数,打印出'关注前端南玖'
CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。
CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。
浏览器会自动进行 CORS 通信,实现 CORS 通信的关键是后端。只要后端实现了 CORS,就实现了跨域。
服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
虽然设置 CORS 和前端没什么关系,但是通过这种方式解决跨域问题的话,会在发送请求时出现两种情况,分别为简单请求和复杂请求。
简单请求: (满足以下两个条件,就是简单请求)
1.请求方法为以下三个之一:
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 nameAccording 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 name
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 |
| ##根据上面的表格因此需要把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
可以设置为三个值,Strict
、Lax
和None
。
在Strict
模式下,浏览器完全禁止第三方请求携带Cookie。比如请求sanyuan.com
网站只能在sanyuan.com
域名当中请求才能携带 Cookie,在其他网站请求都不能。
在Lax
模式,就宽松一点了,但是只能在 get 方法提交表单
况或者a 标签发送 get 请求
的情况下可以携带 Cookie,其他情况均不能。
在None模式下,Cookie将在所有上下文中发送,即允许跨域发送。
更多编程相关知识,请访问:编程入门!!