知识点列表: CSRF 攻击 XSS攻击 HTTPS
程序员必须要了解的web安全 - 掘金
若愚:「每日一题」CSRF 是什么?
【基本功】 前端安全系列之一:如何防止XSS攻击?
【基本功】 前端安全系列之二:如何防止CSRF攻击?https://mp.weixin.qq.com/s/Co7tWc5jNtlzWexQyZojtg 你必须要懂的Web安全
一、浅谈CSRF 攻击
1、CSRF 攻击原理
其原理是:攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。如
https://xxxx.com/gift/send?target=someone&giftId=ab231
用户在登录状态下,就能给名为someone的用户赠送礼品ab231
不过有没有一种办法让用户只要看到即使不点击该网站也能自动送礼物给用户?
攻击方法1:可以利用图片标签:添加链接属性的特征,将该url替换成src=""里实现这种诱导,即:
<img src="https://xxxx.com/gift/send?target=someone&giftId=ab231" alt="">
礼物虽然小,但赠送都是有历史记录的,用户查看历史记录肯定会起疑心,能不能帮用户删除这条赠送记录呢?经过测试,发现删除赠送记录的接口地址: https://xxxx.com/gift/deleteRecord 其中,接口类型为post,请求参数为 { giftId:”ab231″},如:
攻击方法2:可以利用表单输入:构造一个可触发该删除赠送记录接口地址的表单页面
<form action = "https://xxxx.com/gift/deleteRecord" id="form" method="post"
target="hiddenIframe">
</form>
其中,用户请求的网址为:
https://xxxx.com/gift/deleteRecord
这个请求被服务端接收后,会被误以为是用户合法的操作。对于 GET 形式的接口地址可轻易被攻击,对于 POST 形式的接口地址也不能保证百分百安全,攻击者可诱导用户进入带 Form 表单可用POST方式提交参数的页面。
设置以下代码触发跳转,原始首页功能,
<script>
document.getElementById('form').submit();
location.href = "http://xxxx.com";
</script>
即跳转到http://xxxx.com,这样用户既在不知情的情况下赠送了礼品,又在不知情的情况下删除了赠送记录。
2、实例
type=hidden隐藏域的作用,结合 CSRF 攻击来说明。
type=hidden隐藏域,作为校验该用户信息的一个隐藏值(判断标准)。当用户打开页面后是看不见type=hidden相应的值,填写用户信息之后点击提交时,用户信息的数据(包括type=hidden值)随即提交后台,打开后台则会展示代码type=hidden所写的相应元素属性值。后台校验type=hidden相应值如果是正确,即用户提交为安全。
埋点(保护的参数)——浏览器提交后台有该参数作为校验标准参考——若显示错值或无值,服务器也将不承认所提交的数据;若为正确值,则说明该用户获取权限,即为合法用户,可防止CSRF攻击
如图所示:
![011f044e57b0e7f2f3535fb18fc3b5e1.png](https://i-blog.csdnimg.cn/blog_migrate/3a9382af1b048ffa461f4a6b58163cfc.jpeg)
二、XSS攻击
参看美团技术团队对XSS的描述:
1、XSS攻击原理
XSS 攻击是页面被注入了恶意的代码
2、XSS 漏洞的发生和修复
案例一:搜索页面插入恶意代码——> 解决办法:HTML 转义,可以防止 XSS 攻击
公司需要一个搜索页面,根据 URL 参数决定关键词的内容。
小明很快把页面写好并且上线。代码如下:
<input type="text" value="<%= getParameter("keyword") %>">
<button>搜索</button>
<div>
您搜索的关键词是:<%= getParameter("keyword") %>
</div>
上线后不久,小明就接到了安全组发来的一个神秘链接
http://xxx/search?keyword="><script>alert('XSS');</script>
小明带着一种不祥的预感点开了这个链接[请勿模仿,确认安全的链接才能点开]。果然,页面中弹出了写着"XSS"的对话框。可恶,中招了!
其中的奥秘:
当浏览器请求 http://xxx/search?keyword="><script>alert('XSS');</script> 时,服务端会解析出请求参数 keyword,得到 "><script>alert('XSS');</script>,拼接到 HTML 中返回给浏览器。形成了如下的 HTML:
<input type="text" value=""><script>alert('XSS');</script>">
<button>搜索</button>
<div>
您搜索的关键词是:"><script>alert('XSS');</script>
</div>
浏览器无法分辨出 <script>alert('XSS');</script> 是恶意代码,因而将其执行。
这里不仅仅 div 的内容被注入了,而且 input 的 value 属性也被注入, alert 会弹出两次。
被攻击原因:这只是浏览器把用户的输入当成了脚本进行了执行。那么只要告诉浏览器这段内容是文本就可以了。
聪明的小明很快找到解决方法,把这个漏洞修复:
<input type="text" value="<%= escapeHTML(getParameter("keyword")) %>">
<button>搜索</button>
<div>
您搜索的关键词是:<%= escapeHTML(getParameter("keyword")) %>
</div>
escapeHTML() 按照如下规则进行转义:
![6cfd7d17c1905a1bd0be133ebcde0f38.png](https://i-blog.csdnimg.cn/blog_migrate/defa141048e36878551930217e909b8e.jpeg)
经过了转义函数的处理后,最终浏览器接收到的响应为:
<input type="text" value=""><script>alert('XSS');</script>">
<button>搜索</button>
<div>
您搜索的关键词是:"><script>alert('XSS');</script>
</div>
恶意代码都被转义,不再被浏览器执行,而且搜索词能够完美的在页面显示出来。
通过这个事件,小明学习到了如下知识:
- 通常页面中包含的用户输入内容都在固定的容器或者属性内,以文本的形式展示。
- 攻击者利用这些页面的用户输入片段,拼接特殊格式的字符串,突破原有位置的限制,形成了代码片段。
- 攻击者通过在目标网站上注入脚本,使之在用户的浏览器上运行,从而引发潜在风险。
- 通过 HTML 转义,可以防止 XSS 攻击。[事情当然没有这么简单啦!请继续往下看]。
案例二:a链接插入javascript: 这样字符串——>解决办法:白名单的方法
小明又收到安全组的神秘链接:http://xxx/?redirect_to=javascript:alert('XSS')。小明不敢大意,赶忙点开页面。然而,页面并没有自动弹出万恶的“XSS”。
小明打开对应页面的源码,发现有以下内容:
<a href="<%= escapeHTML(getParameter("redirect_to")) %>">跳转...</a>
这段代码,当攻击 URL 为 http://xxx/?redirect_to=javascript:alert('XSS'),服务端响应就成了:
<ahref="javascript:alert('XSS')">跳转...</a>
虽然代码不会立即执行,但一旦用户点击 a 标签时,浏览器会就会弹出alert('xss')。
XSS攻击需要注意的:
- 所有用户输入的地方都不安全(任何数据不允许放在页面中任意设置)
- 所有展示用户输入的地方都不安全
- js 里不要用 eval(即把一个字符串在全局环境中当做js运行)
- 不要用 innerHTML
如何构造一个xss攻击
js代码一旦执行会导致cookie的产生,所以只要用户提交的信息变成html去运行,就会造成XSS攻击
假设需要将一些评论进行渲染,那么可以创建一个dom节点,通过dom节点中的innerText将用户输入的信息提交上去,这样一来任何提交信息都会作为html展示在页面上,安全性大大提交
用eval方式解析服务器传来的json数据
三、https
1、还记得提交表单中涉及到的post和get的提交方式吗?
但从安全性上,只要是http请求都不安全
2、数据安全性体现在几个方面
- 我发的数据,不该看的人看不懂
- 我发的数据,不该看的人不能伪造或者修改(修改后接收方可察觉)
- 我发的数据,过期之后不该看的人不能偷偷拿过来继续用
3、https如何保证数据传输的安全?
几种数据加密的方式:
- 对称加密 : 加密和解密数据使用同一个密钥。这种加密方式的优点是速度很快,常见对称加密的算法有 AES;
- 非对称加密: 加密和解密使用不同的密钥,叫公钥和私钥。数据用公钥加密后必须用私钥解密,数据用私钥加密后必须用公钥解密。一般来说私钥自己保留好,把公钥公开给别人,让别人拿自己的公钥加密数据后发给自己,这样只有自己才能解密。 这种加密方式的特点是速度慢,CUP 开销大,常见非对称加密算法有 RSA;
- Hash: hash 是把任意长度数据经过处理变成一个长度固定唯一的字符串(如将这篇文章也可加密成一个字符串),但任何人拿到这个字符串无法反向解密成原始数据(解开你就是密码学专家了),Hash 常用来验证数据的完整性。常见 Hash 算法有 MD5(已经不安全了)、SHA1、SHA256
比如将登录注册的信息通过Hash算法中的SHA1、SHA256进行加密保存在数据库中
4、https原理
浏览器将用户信息加密(AES 加密),此时如果只是浏览器和服务器进行数据交流,则可以通过对称加密的形式。服务器发送公钥,浏览器得到公钥后会生成一个对称加密AES的密钥,浏览器加密后的密钥发给服务器,收到后用服务器的私钥解密,得到浏览器和服务器约定好的对称加密密钥,然后二者用这个只有二者知道的对称密钥加密数据进行交流
假如中间人提供假公钥对浏览器进行攻击。
此时为了中间人破坏,可以采用服务器的公钥信息和公证人背书做成一个信用证书,通过hash(sh256)处理之后,用公证人的私钥进行加密,生成一个信用证书。
浏览器得到信用证书后,先用公证人的公钥对证书上被公证人私钥加密后的字段进行解密,得到元素数据的 Hash。浏览器 再对元素数据进行 Hash和刚刚解密的 Hash 进行比对。如果比对成功表示证书上的信息无误,且是由公证人担保的。这时候浏览器确信证书上的公钥就是服务器的。
即申请https的时候就需要进行信息补充(公司名称、域名),申请后会给你生成证书
若不知道公证人的公钥申请https则造成无人担保的局面,即用https打开页面时会造成一个不安全的私密链接。如12306网站就是实例。