? XSS(Cross Site Scripting)跨站脚本攻击
Scripting能干什么(危害)
- 获取页面数据
- 获取cookies
- 劫持前端逻辑
- 发送请求
- 偷取网站任意数据
- 偷取用户资料
- 偷取用户密码和登入态
- 欺骗用户
- 反射型
url参数直接注入的方式攻击
- 存储型
存储到数据库后读取后攻击
XSS攻击的注入点
- HTML节点内容
<div> #{content} </div>
这种是通过往HTML标签之间插入script标签的方式进行逻辑操纵从而引起的攻击方式。
防御:可以通过转译标签标记进行防御。转义<
成<
和>
成>
- HTML属性
<img src="#{image}"/> <img src="1" onerror="alert(1)"/>
如上代码,通过提前关闭元素属性的方式进行的XSS攻击。
- Javascript富文本
<script> var data = "#{data}"; var data = "hello"; alert(1);""; </script>
如上代码,通过在js代码中插入代码的方式进行的XSS攻击。
防御:可以通过转译标签标记进行防御。转义\
或者转换成json(推荐)。
- 富文本
黑名单进行过滤,就是用正则去匹配不合法的html标签,然后进行内容过滤,优点是开发简单,缺点是可能过滤不全存在隐患。
白名单进行过滤,就是规定所有允许的标签及属性的范围域,优点是内容过滤可靠,安全,但由于事先需要将内容构建成DOM树(推荐cheerio库),因此效率可能会有一定影响。(第三方过滤模块:js-xss)
防御小结:
- 通过设置响应头的方式触发浏览器的自动防御策略
.set('X-XSS-Protection', 1)
,但这种策略防御有限。 - 通过上述的转译策略。
var escapeHtml = function (str) { if (!str) return ''; str = str.replace(/</g, '<'); str = str.replace(/>/g, '>'); return str; }; var escapeHtmlProperty = function (str) { if (!str) return ''; str = str.replace(/"/g, '&quto;'); str = str.replace(/'/g, '''); str = str.replace(/ /g,' '); return str; };
CSP(Content Security Policy)
- 内容安全策略
- 用于指定哪些内容可以执行
child-src connect-src default-src --> <host-source> <scheme-source> 'self' font-src frame-src img-src --> 'unsafe-inline' 'unsafe-eval" 'none' manifest-src media-src object-src --> 'nonce-<base64-value>' <hash-source> script-src style-src worker-src 'strict-dynamic' 具体参见MDN上CSP的文档信息
? CSRF(Cross Site Request Forgy)跨站请求伪造
XSS与CSRF的区别
- XSS:用户知情的情的情况下,在本网站运行脚本的攻击方式。
- CSRF:用户不知情的情况下,从其他网站对目标服务器网站运行脚本攻击的方式。
CSRF攻击的原理
graph LR; www.a.com后端 -->|2| www.a.com前端 www.a.com前端 -->|1| www.a.com后端 www.b.com前端 -->|3| www.a.com后端
CSRF的危害
- 利用用户登录态
- 用户不知情
- 完成业务请求
- ...
- 盗取用户资金(转账、消费)
- 冒充用户发帖背锅
- 损坏网站名誉
CSRF的防御
- 利用same-site响应头
- 验证码
- token
- referer请求头防御
通过验证 referer 请求头是否来自可信任网站或本网站,从而禁止来自第三方网站的请求。
PS:referer 应该是referrer,这个单词是为数不多的单词错误。
? cookie 安全
cookie特征
- 前端数据存储
- 后端通过http头设置
- 请求时通过http头传给后端
- 前端可读写
- 遵守同源策略: 协议,域名和端口都一样
- 域名
- 有效期
- 路径
- http-only:只允许http的方式使用,比如不允许js操作cookie
- secure:只允许在https的请求中使用
以上特征对应chrome中的cookie的各种参数
cookie的作用
- 存储个性化设置
- 存储未登录时用户的唯一标识
- 存储已登入用户的凭证
- 存储其他业务信息
cookie - 登录用户凭证管理(判断用户是否是在登录态)
- 方案一:cookie存储用户id
这种方案就是当用户登入成功之后在cookie中存储用户id,当用户在之后的请求中判断当前用户。但是这种方案容易被篡改用户I。
- 方案二:cookie存储用ID和签名
这种方案不仅在cookie存储用户id,并且另外存储一个由服务端根据密钥和用户id生成的唯一用户签名。于这种签名都是不可逆的,当用户在之后的请求中都带上这两个信息,由服务端根据用户id重新生成签名并与请求带过来的签名做对比来判断用户是否合法。由于密钥只有服务端有,因此这种方法是安全的。
- 方案三:存储sessionID
这种方案只在cookie中存储当前登入用户的唯一session,这种方案是安全的,因此想要做非法操作的用户只拿到sessionID是没有任何意义的。
? 点击劫持安全问题
点击劫持的特点
- 用户亲手操作
- 盗取用户资金(转账、消费)
- 用户不知情
- 获取用户敏感信息
- 其他
总结来说,点击劫持就是在用户点击网站时,使得劫持者在用户在不知情的情况下引导用户做一些操作。其技术原理是在正常的网站上内嵌iframe框架,并且iframe框架的透明度为0,这样用户在点击页面的时候,因为是在点击看的见内容,实际上在点击看不见的iframe框架的内容,从而使掉进劫持者的trap。
点击劫持的防御
- javascript禁止内嵌
其原理在于当页面中有iframe框架时,top对象和window对象是不一样的,从而top.location对象 window.location对象也是不一样的,因此可以用下面代码来进行禁用。
if(top.location != window.location){ top.location = window.location; }
- X-FRAME-OPTIONS禁止内嵌
可以通过设置http response头的方式进行禁用,
X-FRAME-OPTIONS:DENY
。PS:这个头的其他选项参考官方文档。
- 其他辅助手段
比如加上验证码之类的防御措施。
? 传输安全
传输链路窃听篡改 如下图
graph LR; 浏览器-->代理服务器 代理服务器-->浏览器 subgraph 中间服务器 链路-->代理服务器 代理服务器-->链路 end 链路-->服务器 服务器-->链路
在上图浏览器和服务器之间所有的节点都有能力窃听篡改要转发的信息。
PS:在mac和Linux上可以通过命令traceroute
来追踪请求从发起到目标服务器经过了哪些中间服务器,比如DNS服务器,路由转发服务器等。
http窃听
- 窃听用户密码
- 窃听传输敏感信息
- 非法获取用户个人资料
http篡改
- 插入广告
- 重定向网站
- 无法防御的XSS和CSRF攻击
https进行加密传输。
PS:https使用的是TLS(SSL)加密。TSL是SSL的改进算法。
但是虽然是加密传输,中间服务器没法窃听数据,但是存在中间人却可以进行数据盗取,如下图:
graph LR; 浏览器-->|加密|中间人 中间人-->|加密|服务器 服务器-->|加密|中间人 中间人-->|加密|浏览器
这样,中间人可以伪造服务器,在用户和服务器之间进行信息交互,从而盗取用户信息。因此引入证书机制,证书必须由受信任的的机构(CA)签发。如下入过程:
graph LR; CA-->|2.验证域名 颁发证书|服务器 服务器-->|4.出具证书|浏览器 浏览器-->|0.内置信任列表|CA 浏览器-->|3.发起请求|服务器 浏览器-->|5.验证通过|服务器 服务器-->|1.申请证书|CA
- 证书无法伪造
- 证书私钥不能泄露
- 域名管理权不泄漏
- CA坚持原则
自己往系统中添加证书是很危险的,因为签发此证书的CA并没有被浏览器及其其他机构信任,也就是说此CA不受信任,如果你信任/自己添加了此证书到系统中后,如果此CA又给一个有问题的服务器签发证书后,这样信任这个机构签发证书的机器就有了能面临风险。
SUMMARY:https没有证书也可以正常使用,只是显示不安全。
如何启动https服务器: 申请证书 --> 配置https服务器
? 密码安全
- 密码的作用
证明你是你!
- 密码的存储
- 密码的传输
- 密码的替代方案
- 生物特征密码的问题
指纹解锁,虹膜识别,人脸识别等
密码 - 泄漏渠道
- 数据库被偷
- 服务器被入侵
- 通讯被窃听
- 内部人员泄漏数据
- 其他网站(撞库)
如果一个网站的用户数据泄露,很多用户可能用同一个账号密码去注册不同的网站,这就叫撞库。
密码 - 存储
- 严禁明文存储(防泄露)
- 单向变换(防泄露)
在存储密码的时候,只能由明文向密文变换,反之不可以。
- 变换复杂度要求(防猜测)
- 密码复杂度要求(防猜测)
- 加盐(防猜测)
这是防止用户密码设置的过于简单,在密码进行加密的时候在密码上再增加一串数字,使得加密后的密码更加安全。
哈希算法
- 明文 - 密文一一对应
- 雪崩效应
当明文有一点变换的时候,密文不是改变一点,而是全盘变化。
- 密文 - 明文无法反推
hash算法是一种信息摘要算法,我们没法通过一段信息摘要计算出原始明文。
- 密文固定长度
一般hash算法的结果都是32位字符串
- 常见哈希算法:md5 sha1 sha256
彩虹表破解哈希算法
由于哈希算法是不可逆的,因此网络上可以建立穷举数据库来破解哈希算法,而这种数据库叫做彩虹表。
由于单层哈希加密容易破解(容易被彩虹表穷举),因此可以采用多重哈希增大破解难度。
md5(明文)=密文 md5(md5(明文))=密文 md5(sh1(明文))=密文 md5(sh1(sh256(明文)))=密文
密码 - 变化次数越多越安全
- 加密成本几乎不变(生成密码时速度慢一些)
- 彩虹表失效(数量太大,无法建立通用性)
- 解密成本增大N倍
增大密码传输的安全性
- https传输
- 频率限制
验证码策略限制用户每分钟只能登陆几次,防止穷举破解。
- 前端加密意义有限
首先前端加密并不能保证传输的安全性,窃听者拿到传输的密文后也可以模拟用户请求,从而进行进一步信息盗取,但是前端加密可以保证窃听者不能拿到明文,对撞库效应有一定安全保证,以为每个网站的加密算法是不一样的。
生物特征密码
- 指纹(唇纹)
- 声纹
- 虹膜
- 人脸
生物特征密码的安全性
- 私密性 - 容易泄露
指纹,人脸容易在照片中出现,容易泄露。
- 安全性 - 碰撞
生物特征密码都是通过相似度匹配,并不能完全保证两个很相似的人脸或其他生物特征不会出现碰撞。
- 唯一性 终身唯一 - 无法修改
由于我们的生物特征一般都是唯一的,比如指纹,如果被泄漏,就无法更改。
? 接入层注入问题(sql注入问题)
值得一提的是,sql注入远远比看到的简单实例复杂的多,几乎都可以作为一门学科学习,并且其衍生分支很多。所以其危害是很大的。
一些神奇的 SQL 语法
- select * from table where id="10" and 1=0
- select * from table where id="10" or 1=1
- select * from table where id="10" and mid(version(),1,1)=5
检测服务器环境信息,从而根据环境信息来进行一些非法操作。
- select 1,2,3 from table
检查一个表有多少列。
- select id,1,2,3 from table
- select* from table union select 1,2,3 from table2
- select * from table where mid(username,1,1)="t"
用于猜解用户名密码,我们知道,如果用户名密码特别复杂的情况下,进行穷举破解的成本会非常高,但是如果一位一位的破解的话,则会简单很多,上面的sql则提供了这种功能。
SQL 注入危害
- 猜解密码
- 获取数据
- 删库删表
- 拖库
SQL 注入防御
- 关闭错误输出
- 检查数据类型
- 对数据进行转义
这个方法类似于XSS的黑名单和白名单过滤功能,但是基于sql注入的变种等因素,这种方法并不能很好的防治sql注入。因策功能有限。
- 使用参数化查询
这是sql注入最主要的防御手段,基于数据库提供的参数化查询的功能,其主要原理为:对于一条查询,先将预查询语句给到数据库,比如
select * from table where id=?
,之后再把所缺的参数给到数据库,这样所有注入内容都是简单的参数,也就没有注入执行的危害了。
- 使用 ORM(对象关系映射)
一般ORM框架都会解决注入问题,无论用上面哪种方法。
? 接入层上传问题
上传问题
- 上传文件
- 再次访问上传的文件
- 上传的文件被当成程序解析
上传问题防御
- 限制上传后缀
- 文件类型检查
- 文件内容检查
- 程序输出
以上三种防御功能比较有限,而程序输出是指,当用户再次读取上传的文件的时候,服务器已二进制码的方式给用户,这样就算是可执行文件也没法执行了。
- 权限控制-可写可执行互斥
这种类似Linux下的目录下文件权限,只有读写权限,没有执行权限。
? 信息泄露
- 泄露系统敏感信息
- 泄露用户敏感信息
- 泄露用户密码
信息泄露的途径
- 错误信息失控
当系统报错的时候,由于没有控制好错误堆栈的打印控制,使得一些敏感信息在错误堆栈中暴露,如链接字符串等。
- SQL注入
- 水平权限控制不当
注意和垂直权限控制做区分,垂直权限指的是我们熟悉的管理员/普通用户的区别。而水平权限控制则指的是同一权限的人在进行操作的时候可能出现的信息泄露问题。
- XSS/CSRF
社会工程学
- 你的身份由你掌握的资料确定
- 别人掌握了你的资料
- 别人伪装成你的身份
- 利用你的身份干坏事
其实对于互联网上“谁是我”这个话题,当越来越多的我们方方面面的资料被别人掌握时,攻击者就约可能模拟“真我”去实施一些恶心行为或是盗取“真我”的一些有价值的东西。
利用oAuth思想防止资料泄露
graph LR 敏感资料-->|5. 返回票据对应数据|业务; 业务-->|4. 带票据请求|敏感资料; 业务-->|3. 带票据请求|用户; 用户-->|6. 返回数据|业务; 用户-->|1. 登入|敏感资料; 敏感资料-->|2. 派发票据|用户;
- 用户授权读取资料
当用户未授权的情况下谁也不允许读取资料,这样能更好的方式业务开发人员不当的操作也不轨的行为。因为业务开发人员大大高于用户资料服务的开发人员。
- 无授权的资料不可读取
- 不允许批量获取数据
不允许批量获取资料能更有效的控制大量用户资料被盗的情况。
- 数据接口可风控申纪
当如果真的有用户资料出现丢失的情况下,可以有效的进行事后追踪,确定问题出现的原因。
? 其他安全问题
- 拒绝服务DOS
- 重放攻击
- 模拟正常用户
- 占用大量服务器
- 无法服务正常用户
攻击者通过模拟用户的请求并大量去请求目标服务器使得服务器的负载非常大或者大量占用服务器的带宽,使得正常用户没法进行正常访问。并且如果当大量带宽被占用的时候,宽带提供商为了保证网络信道的通畅,只能将受攻击的服务器下线,因此受攻击的服务器没法为用户提供正常服务。
其攻击形式主要有:
- TCP半连接:就是在三次握手的时候,只是做一次请求链接操作,不做后续的对服务器的响应,导致服务器以为有请求要真的链接它,造成服务器不必要的等待从而进行的攻击。
- HTTP链接:这种就是模拟正常的请求连接进行大连服务请求的形式。
- DNS攻击,DNS服务器的负载能力往往比正常大型服务器低,当大量攻击请求导致DNS服务器没法为正常用户服务的时候,导致没法进行域名解析服务,也就造成DOS的真正攻击出现。
大规模分布式拒绝服务攻击DDOS
- 流量可达几十到上百G
- 分布式(肉鸡,代理)
- 极难防御
这种攻击是攻击者可能通过病毒的方式控制了别人的机器,因此攻击发起地点可能是从不同的地方进行攻击,每个地点的攻击流量可能不大,但是总和却很巨大。这些被控制的机器就叫做“肉鸡”,还有可能通过代理服务器的方式进行攻击。
DOS攻击防御
- 防火墙
- 交换机、路由器
- 流量清洗
- 高防IP
购买云计算厂商的服务,让其作为代理,这样在遇到这种情况的时候,高防IP服务器会预先对请求进行流量清晰等防御操作,之后再将正常的请求分发给自己的服务器。
- 避免重逻辑业务
- 快速失败快速返回
- 防止雪崩机制
尽量避免失败重试,造成恶性滚雪球事件的发生
- 有损服务
这种就是在收到攻击的时候能及时的停掉有问题的服务,保证核心服务能正常运行。
- CDN
通过CDN来减轻服务器的负载,将一部分负载转移到CDN上来完成
- 用户被多次消费
- 用户登录态被盗取
- 多次抽奖
这种攻击就是当有有问题的请求被攻击者拿取到之后,从而进行重复这种请求的一种攻击。还有就是在消费、抽奖等活动中用户重复这种过程导致异常订单的出现等恶性结果。
重放攻击防御
- 加密(HTTPS)
- 时间戳限定请求的有效期
- token(session)
一个请求只能发送一次,当第二次发送token还没有变化,则标记此次请求无效
- nonce:类似token
- 数字签名
- 海报