lznbuild / my-blog

自己的博客
9 stars 1 forks source link

前端安全 #35

Open lznbuild opened 4 years ago

lznbuild commented 4 years ago

同源策略

  1. 相同的源之间可以相互访问资源和操作dom的

    let pdom = opener.document; // 指向父页面的document
    pdom.body.style.display = "none"
  2. 相同源可以读取cookie,localstorage

  3. XMLHttpRequest发送的请求

    整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息origin,有时还会多出一次附加的请求,但用户不会有感觉。 origin说明本次请求来自哪个源,服务器根据这个值,决定是否同意这次请求。

    如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest的onerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

    如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。

    因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

点击劫持

点击劫持是指在一个Web页面中隐藏了一个透明的iframe,用外层假页面诱导用户点击,实际上是在隐藏的frame上触发了点击事件进行一些用户不知情的操作。

iframe中的内容是由第三⽅来提供的,默认情况下他们不受我们的控制,他们可以在iframe中运行JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端⽤户体验

攻击者构建了一个非常有吸引力的网页 将被攻击的页面放置在当前页面的 iframe 中 使用样式将 iframe 叠加到非常有吸引力内容的上方 将iframe设置为100%透明 你被诱导点击了网页内容,你以为你点击的是***,而实际上,你成功被攻击了。

防止:

X-Frame-Options是微软提出的一个http响应头,专门用来防御利用iframe嵌套的点击劫持攻击

可以设置为以下值:

描述
DENY 拒绝任何域加载
SAMEORIGIN 允许同源域下加载
ALLOW-FROM 可以定义允许frame加载的页面地址

恶意的第三方库

网络劫持+解决方案

DNS劫持: (输⼊京东被强制跳转到淘宝这就属于dns劫持)

HTTP劫持: (访问⾕歌但是⼀直有贪玩蓝⽉的⼴告),由于http明⽂传输,运营商会修改你的http响应内容(即加⼴告)

DNS劫持就是你想去存钱运营商却把你拉到了劫匪手中;而HTTP劫持就是你从服务器买了一包零食电信给你放了一坨屎

DNS劫持由于涉嫌违法,已经被监管起来,现在很少会有DNS劫持,⽽http劫持依然⾮常盛⾏.

最有效的办法就是全站HTTPS,将HTTP加密,这使得运营商⽆法获取明⽂,就⽆法劫持你的响应内容.

中间人攻击

指攻击者与通讯的两端分别创建独⽴的联系, 并交换其所收到的数据, 使通讯的两端认为他们正在通过⼀个私密的连接与对⽅直接对话, 但事实上整个会话都被攻击者完全控制. 在中间⼈攻击中,攻击者可以拦截通讯双⽅的通话并插⼊新的内容

HTTPS 就可以用来防御中间人攻击,但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP 从而实现中间人攻击。

XSS攻击

cross-site-scripting 跨站脚本攻击,是一种代码注入攻击。攻击者在目标网站上注入恶意代码,这些代码可以读取cookie及其他信息。

本质是 恶意代码未经过滤。浏览器无法分辨那些脚本可信,导致恶意代码执行。

可盗取cookie,修改dom,刷浮窗广告等

可分为3种。

存储型(持久性)

恶意脚本永久存储在目标服务器上。当浏览器请求数据时,脚本从服务器传回并执行,影响范围比反射型和DOM型XSS更大。存储型XSS攻击的原因仍然是没有做好数据过滤:前端提交数据至服务端时,没有做好过滤;服务端在接受到数据时,在存储之前,没有做过滤;前端从服务端请求到数据,没有过滤输出。

这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。

攻击者将恶意代码提交到目标网站的数据库中。 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。

前端数据传递给服务器之前,先转义/过滤(防范不了抓包修改数据的情况) 服务器接收到数据,在存储到数据库之前,进行转义/过滤 前端接收到服务器传递过来的数据,在展示到页面前,先进行转义/过滤

防范:

反射型(非持久型)

反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。

防范: 对url的查询参数进行转义后再输出到页面。

app.get('/welcome', function(req, res) {
    //对查询参数进行编码,避免反射型 XSS攻击
    res.send(`${encodeURIComponent(req.query.type)}`); 
});

DOM型

DOM 型 XSS 攻击,实际上就是前端 JavaScript 代码不够严谨,把不可信的内容插入到了页面。在使用 .innerHTML、.outerHTML、.appendChild、document.write()等API时要特别小心,不要把不可信的数据作为 HTML 插到页面上,尽量使用 .innerText、.textContent、.setAttribute() 等。

防范 DOM 型 XSS 攻击的核心就是对输入内容进行转义(DOM 中的内联事件监听器和链接跳转都能把字符串作为代码运行,需要对其内容进行检查)。

  1. 对于url链接(例如图片的src属性),那么直接使用 encodeURIComponent 来转义。

  2. 非url,我们可以这样进行编码:

function encodeHtml(str) {
    return str.replace(/"/g, '"')
            .replace(/'/g, ''')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');
} 
// 对用户的输入进行编码处理 ,向后端发送数据时转换,插入页面时转换 

关于防止XSS攻击的总结:

CSP,content security policy,网页安全政策。 开发者明确告诉客户端(制定比较严格的策略和规则),哪些外部资源是可以加载和执行的 ,即使攻击者发现漏洞,但是它是没办法注入脚本的 实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。

启用csp有两种启用方式:

  1. 通过HTTP头中的Content-Security-Policy

  2. meta标签

例如下面的配置只允许加载同域下的资源

Content-Security-Policy: default-src 'self' 

<meta http-equiv="Content-Security-Policy" content="form-action 'self';">

严格的 CSP 在 XSS 的防范中可以起到以下的作用:

CSRF

Cross-site request forgery 跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

受害者登录A站点,并保留了登录凭证(Cookie)。 攻击者诱导受害者访问了站点B。 站点B向站点A发送了一个请求,浏览器会默认携带站点A的Cookie信息。 站点A接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是无辜的受害者发送的请求。 站点A以受害者的名义执行了站点B的请求。 攻击完成,攻击者在受害者不知情的情况下,冒充受害者完成了攻击。

攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的

攻击通常在第三方网站发起。

CSRF 攻击不需要将恶意代码注入用户的页面,仅仅是利用服务器的漏洞和用户的登录状态来实施攻击。

CSRF 攻击成本也比 XSS 低,用户每天都要访问大量网页,无法确认每一个网页的合法性, 从用户角度来说,无法彻底防止 CSRF 攻击。

防范:

React 怎么处理XSS的

这个属性是symbol值,源码里就是判断typeof是否等于REACT_ELEMENT_TYPE来判断是否是React节点。

https://github.com/YvetteLau/Blog/tree/master/Security (攻击演示)

https://github.com/YvetteLau/Blog/issues/29