web安全
安全性主要分为两大块。 私密性:不被非法获取和利用。 可靠性:不丢失、不损坏、不被篡改
攻击类型
- XSS 跨站脚本攻击
- CSRF 跨站请求伪造
- SQL注入
- 点击劫持
- 中间人攻击
XSS 跨站脚本攻击
XSS ( Cross Site Scripting ) 是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些代码,嵌入到web页面中去。使别的用户访问都会执行相应的嵌入代码。
从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。
XSS攻击的危害包括:
- 获取页面数据
- 获取cookie
- 劫持前端逻辑
- 发送请求
- 偷取网站任意数据
- 偷取用户资料
- 偷取用户密码和登陆态
- 欺骗用户
XSS攻击分类
反射型
通过url参数直接注入。
发出请求时,XSS代码出现在URL中,作为输入提交到服务器端,服务端解析后返回,XSS代码随响应内容一起传回给浏览器,最后浏览器执行XSS代码。这个过程像一次反射,故叫做反射型XSS。
举个例子
一个链接,里面的query字段中包含一个script标签,这个标签的src就是恶意代码,用户点击了这个链接后会先向服务器发送请求,服务器返回时也携带了这个XSS代码,然后浏览器将查询的结果写入Html,这时恶意代码就被执行了。
并不是在url中没有包含script标签的网址都是安全的,可以使用短网址来让网址变得很短。
存储型
存储型XSS会被保存到数据库,在其他用户访问(前端)到这条数据时,这个代码会在访问用户的浏览器端执行。
举个例子
比如攻击者在一篇文章的评论中写入了script标签,这个评论被保存数据库,当其他用户看到这篇文章时就会执行这个脚本。
XSS攻击注入点
- HTML节点内容
- 如果一个节点内容是动态生成的,而这个内容中包含用户输入。
- HTML属性
- 某些节点属性值是由用户输入的内容生成的。那么可能会被封闭标签后添加script标签。
<img src="${image}"/>
<img src="1" onerror="alert(1)" />
- Javascript代码
- JS中包含由后台注入的变量或用户输入的信息。
var data = "#{data}";
var data = "hello"; alert(1);"";
- 富文本
XSS 防御
对于 XSS 攻击来说,通常有两种方式可以用来防御。
- 转义字符
- CSP 内容安全策略
转义字符
普通的输入 - 编码
- 对用户输入数据进行HTML Entity编码(使用转义字符)
- "
- &
- <
- >
- 空格
富文本 - 过滤(黑名单、白名单)
- 移除上传的DOM属性,如onerror等
- 移除用户上传的style节点、script节点、iframe节点等
较正
- 避免直接对HTML Entity解码
- 使用DOM Parse转换,校正不配对的DOM标签和属性
对于会在DOM中出现的字符串(用户数据):
< 转义为 <
转义为 >
对于可能出现在DOM元素属性上的数据
" 转义为 " ' 转义为 &9039; 空格转义为 但这可能造成多个连续的空格,也可以不对空格转义,但是一定要为属性加双引号
& 这个字符如果要转义,那么一定要放在转移函数的第一个来做
避免JS中的插入
var data = "#{data}";
var data = "hello"; alert(1);"";
因为是用引号将变量包裹起来的,而且被攻击也因为引号被提前结束,所以要做的就是将引号转义
先 \\ -> \\\\
再 " -> \\"
富文本
按照黑名单过滤: script等 但是html标签中能执行html代码的属性太多了,比如onclick, onhover,onerror,
function xssFilter = function (html) {
html = html.replace(/<\s*\/?script\s*>/g, '');
html = html.repalce(/javascript:[^'"]/g, '');
html = html.replace(/onerror\s*=\s*['"]?[^'"]*['"]?/g, '');
//....
return html;
}
按照白名单过滤: 只允许某些标签和属性存在
做法:将HTML解析成树状结构,对于这个DOM树,一个一个的去看是否存在合法的标签和属性,如果不是就去掉。
使用cheerio就可以快速的解析DOM
function xssFilter (html) {
const cheerio = require('cheerio');
const $ = cheerio.load(html);
//白名单
const whiteList = {'img': ['src']}
$('*').each((index, elem) => {
if(!whiteList[elem.name]) {
$(elem).remove();
return;
}
for(let attr in elem.attribs) {
if(whiteList[elem.name].indexOf(attr) === -1) {
$(elem).attr(attr, null);
}
}
})
return html;
}
使用npm包来简化操作
CSP 内容安全策略
CSP 本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载和执行。我们只需要配置规则,如何拦截是由浏览器自己实现的。我们可以通过这种方式来尽量减少 XSS 攻击。
通常可以通过两种方式来开启 CSP:
- 设置 HTTP Header 中的 Content-Security-Policy
- 设置 meta 标签的方式
<meta http-equiv="Content-Security-Policy">
以设置 HTTP Header 来举例
- 只允许加载本站资源
Content-Security-Policy: default-src ‘self’
- 图片只允许加载 HTTPS 协议
Content-Security-Policy: img-src https://*
- 允许加载任何来源框架
Content-Security-Policy: child-src 'none'
CSP ( Content Security Policy )
CSRF 跨站请求伪造
(Cross Site Request Forgy) 打开同一浏览器时其他的网站对本网站造成的影响。原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。如果用户是在登录状态下的话,后端就以为是用户在操作,从而进行相应的逻辑。
举个例子,用户同时打开了A网站和钓鱼网站。 假设A网站中有一个通过 GET 请求提交用户评论的接口,那么攻击者就可以在钓鱼网站中加入一个图片,图片的地址就是评论接口。
<img src="http://www.domain.com/xxx?comment='attack'"/>
CSRF攻击原理
- 用户登录A网站
- A网站确认身份(给客户端cookie)
- B网站页面向A网站发起请求(带上A网站身份)
CSRF防御
- Get 请求不对数据进行修改
- 不让第三方网站访问到用户 Cookie
- 阻止第三方网站请求接口
- 请求时附带验证信息,比如验证码或者 Token
- SameSite
- 可以对 Cookie 设置 SameSite 属性。该属性表示 Cookie 不随着跨域请求发送,可以很大程度减少 CSRF 的攻击,但是该属性目前并不是所有浏览器都兼容。
- Token验证
- cookie是发送时自动带上的,而不会主动带上Token,所以在每次发送时主动发送Token
- Referer验证
- 对于需要防范 CSRF 的请求,我们可以通过验证 Referer 来判断该请求是否为第三方网站发起的。
- 隐藏令牌
- 主动在HTTP头部中添加令牌信息
禁止第三方网站带cookies
same-site属性。 设置只有同一站点的请求才能携带cookie
CSRF蠕虫
如果某个用户打开了被攻击网页,并且用户同时访问了攻击者的网页。 那么攻击者的网页就会使用用户的身份发送一些请求,并且常用用户的身份发布一些评论或文章,里面包含攻击者的网页链接。如果其他用户看到了这个用户的这条评论,都甚至可以不点击,其他用户也会被盗用身份发送一些恶意请求。这样病毒的传播就会越来越快,影响越来越大。
CSRF攻击危害
- 利用用户登录态
- 用户不知情
- 完成业务请求
- 盗取用户资金
- 冒充用户发帖背锅
- 损坏网站名誉
SQL 注入
所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,后台执行SQL语句时直接把前端传入的字段拿来做SQL查询。
防御
- 永远不要信任用户的输入
- 永远不要使用动态拼装sql
- 不要把机密信息直接存放
点击劫持
点击劫持是一种视觉欺骗的攻击手段。攻击者将需要攻击的网站通过 iframe 嵌套的方式嵌入自己的网页中,并将 iframe 设置为透明,在页面中透出一个按钮诱导用户点击。
对于这种攻击方式,推荐防御的方法有两种。
- X-FRAME-OPTIONS
- JS 防御
X-FRAME-OPTIONS
X-FRAME-OPTIONS
是一个 HTTP 响应头,在现代浏览器有一个很好的支持。这个 HTTP 响应头 就是为了防御用 iframe 嵌套的点击劫持攻击。
该响应头有三个值可选,分别是
DENY
,表示页面不允许通过iframe
的方式展示SAMEORIGIN
,表示页面可以在相同域名下通过iframe
的方式展示ALLOW-FROM
,表示页面可以在指定来源的iframe
中展示
JS防御
对于某些低版本浏览器来说,并不能支持上面的这种方式,那我们只有通过 JS 的方式来防御点击劫持了。
<head>
<style id="click-jack">
html {
display: none !important;
}
</style>
</head>
<body>
<script>
if (self == top) {
var style = document.getElementById('click-jack')
document.body.removeChild(style)
} else {
top.location = self.location
}
</script>
</body>
中间人攻击
中间人攻击是攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息。
通常来说不建议使用公共的 Wi-Fi,因为很可能就会发生中间人攻击的情况。如果你在通信的过程中涉及到了某些敏感信息,就完全暴露给攻击方了。
当然防御中间人攻击其实并不难,只需要增加一个安全通道来传输信息。HTTPS 就可以用来防御中间人攻击,但是并不是说使用了 HTTPS 就可以高枕无忧了,因为如果你没有完全关闭 HTTP 访问的话,攻击方可以通过某些方式将 HTTPS 降级为 HTTP 从而实现中间人攻击。
你的点赞是我持续输出的动力 希望能帮助到大家 互相学习 有任何问题下面留言 一定回复