Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

前端安全 #35

Open
lznbuild opened this issue Aug 10, 2020 · 0 comments
Open

前端安全 #35

lznbuild opened this issue Aug 10, 2020 · 0 comments

Comments

@lznbuild
Copy link
Owner

lznbuild commented Aug 10, 2020

同源策略

  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 发生,但可以增加 XSS 攻击的难度。

  • 输入内容限制

    对于部分输入,可以限定不能包含特殊字符或者仅能输入数字等正则校验。

  • HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此 Cookie。

反射型(非持久型)

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

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

防范:
对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攻击的总结:

  • 一切用户输入皆不可信,在输出时进行验证
  • 将 HTML 元素内容、属性以及 URL 请求参数、CSS 值进行编码
  • 当编码影响业务时,使用白名单规则进行检测和过滤使用 W3C 提出的 CSP (Content Security Policy,内容安全策略),定义域名白名单设置
  • Cookie 的 HttpOnly 属性

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 的防范中可以起到以下的作用:

  • 禁止加载外域代码,防止复杂的攻击逻辑。
  • 禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
  • 禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
  • 禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
  • 合理使用上报可以及时发现 XSS,利于尽快修复问题。

CSRF

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

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

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

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

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

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

防范:

  • 每个接口都使用token做验证

  • 服务端验证请求来源站点(Referer、Origin),阻止第三方网站请求接口,但可被修改

  • samesite cookie
    表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击

React 怎么处理XSS的

  • 基础的对用户的输入内容进行转义,它会在运行时动态创建DOM节点然后填入文本内容
  • 元素$$typeof属性

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

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

YvetteLau/Blog#29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant