Open yihan12 opened 8 months ago
Cross Site Scripting(跨站脚本攻击) 是指攻击者利用网站漏洞将代码注入到其他用户浏览器的攻击方式,又叫跨域脚本。常见类型有:反射型(非持久性)存储型(持久性)DOM 型
同源策略可以隔离各个站点之间的 DOM 交互、页面数据和网络通信。
支持页面中的第三方资源引用和 CORS 也带来了很多安全问题,其中最典型的就是 XSS 攻击。
原理:攻击者通过在 URL 插入恶意代码,其他用户访问该恶意链接时,服务端在URL 取出恶意代码后拼接至 HTML 中返回给用户浏览器。
要点: 通过 URL 插入恶意代码。 有服务端参与。 需要用户访问特定链接。
例子: 攻击者诱导被害者打开链接hzfe.org?name=。被攻击网站服务器收到请求后,未经处理直接将 URL 的 name 字段直接拼接至前端模板中,并返回数据。被害者在不知情的情况下,执行了攻击者注入的脚本(可以通过这个获取对方的Cookie 等)。
原理:攻击者将注入型脚本提交至被攻击网站数据库中,当其他用户浏览器请求数据时,注入脚本从服务器返回并执行。
要点: 恶意代码存储在目标网站服务器上。 有服务端参与。 只要用户访问被注入恶意脚本的页面时,就会被攻击。
例子: 攻击者在目标网站留言板中提交了。目标网站服务端未经转义存储了恶意代码,前端请求到数据后直接通过innerHTML 渲染到页面中。其他用户在访问该留言板时,会自动执行攻击者注入脚本。
原理: 攻击者通过在 URL 插入恶意代码,客户端脚本取出 URL 中的恶意代码并执行。
DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。
要点: 在客户端发生。
例子: 攻击者诱导被害者打开链接hzfe.org?name=。被攻击网站前端取出 URL 的 name 字段后未经转义直接通过 innerHTML 渲染到页面中。被害者在不知情的情况下,执行了攻击者注入的脚本。
存储型 XSS: 持久化,代码是存储在服务器中的
反射型 XSS: 非持久化,需要欺骗用户自己去点击链接才能触发 XSS 代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面
基于 DOM 的 XSS: 不经过后端,纯粹发生在客户端的攻击,属于前端 JavaScript 自身的安全漏洞
Web 安全头支持 浏览器自带的防御能力,一般是通过开启 Web 安全头生效的。具体有以下几个:
一个真实的案例:用户 David 在自己邮箱内点击了黑客恶意伪装的链接。黑客在点击的链接里冒充用户(cookie)向 Gmail 服务器发送邮件自动转发请求,导致 David 的邮件都被自动转发到了黑客的邮箱,从而被黑客利用盗取了用户数据。
原理:攻击者诱导受害者进入第三方网站,在第三方网站中向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的身份凭证,达到冒充用户对被攻击的网站执行某项操作的目的。
常见的攻击方式:
自动发起 Get 请求 GET类型的CSRF利用非常简单,只需要一个HTTP请求,一般会这样利用:
![](https://awps-assets.meituan.net/mit-x/blog-images-bundle-2018b/ff0cdbee.example/withdraw?amount=10000&for=hacker)
在受害者访问含有这个img的页面后,浏览器会自动向http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。
http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker
自动发起 POST 请求 这种类型的CSRF利用起来通常使用的是一个自动提交的表单,如:
<form action="http://bank.example/withdraw" method=POST> <input type="hidden" name="account" value="xiaoming" /> <input type="hidden" name="amount" value="10000" /> <input type="hidden" name="for" value="hacker" /> </form> <script> document.forms[0].submit(); </script>
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。 POST类型的攻击通常比GET要求更加严格一点,但仍并不复杂。任何个人网站、博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许POST上面。
引诱用户点击链接 链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:
<a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank"> 重磅消息!! <a/>
由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问上面的这个PHP页面,则表示攻击成功。
CSRF 攻击的两个必要条件:
1. 目标站点一定要有 CSRF 漏洞; 2. 诱导用户从目标网站,打开一个第三方站点。
CSRF通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对CSRF的防护能力来提升安全性。
上文中讲了CSRF的两个特点:
CSRF(通常)发生在第三方域名。 CSRF攻击者不能获取到Cookie等信息,只是使用。 针对这两点,我们可以专门制定防护策略,如下:
在实现One-Time Tokens时,需要注意一点:并行会话的兼容。如果用户在一个站点上同时打开了两个不同的表单,CSRF保护措施不应该影响到他对任何表单的提交。考虑一下如果每次表单被装入时站点生成一个伪随机值来覆盖以前的伪随机值将会发生什么情况:用户只能成功地提交他最后打开的表单,因为所有其他的表单都含有非法的伪随机值。必须小心操作以确保CSRF保护措施不会影响选项卡式的浏览或者利用多个浏览器窗口浏览一个站点。
中间人攻击是一种通过各种技术手段入侵两台设备通信的网络攻击方法
成功的中间人攻击主要有两个不同的阶段:拦截和解密。
一般我们提交的表单数据(未经过滤的情况下)都会拼接到 SQL 查询语句中的,就例如:
SELECT * FROM users WHERE name='aaa'
其中 name 的参数就是从表单中传过来的数据,如果传的参数是一条 SQL 语句,那么就可能骗过了 SQL 数据库,从而执行了一段恶意的代码,达到了攻击效果。
把应用服务器的数据库权限降至最低,尽可能地减少 SQL 注入攻击带来的危害。
避免网站打印出SQL错误信息,比如类型错误、字段不匹配等,把代码里的SQL语句暴露出来,以防止攻击者利用这些错误信息进行SQL注入。
对进入数据库的特殊字符('"\尖括号&*;等)进行转义处理,或编码转换。
所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。
在测试阶段,建议使用专门的 SQL 注入检测工具进行检测。网上有很多这方面的开源工具,例如sqlmap、SQLninja等。
善用数据库操作库,有些库包可能已经做好了相关的防护,只需阅读其文档,看是否支持相应的功能即可。
概览
XSS
同源策略可以隔离各个站点之间的 DOM 交互、页面数据和网络通信。
支持页面中的第三方资源引用和 CORS 也带来了很多安全问题,其中最典型的就是 XSS 攻击。
类型
反射型(非持久性)
原理:攻击者通过在 URL 插入恶意代码,其他用户访问该恶意链接时,服务端在URL 取出恶意代码后拼接至 HTML 中返回给用户浏览器。
要点:
通过 URL 插入恶意代码。
有服务端参与。
需要用户访问特定链接。
例子:
攻击者诱导被害者打开链接hzfe.org?name=。被攻击网站服务器收到请求后,未经处理直接将 URL 的 name 字段直接拼接至前端模板中,并返回数据。被害者在不知情的情况下,执行了攻击者注入的脚本(可以通过这个获取对方的Cookie 等)。
存储型(持久性)
原理:攻击者将注入型脚本提交至被攻击网站数据库中,当其他用户浏览器请求数据时,注入脚本从服务器返回并执行。
要点:
恶意代码存储在目标网站服务器上。
有服务端参与。
只要用户访问被注入恶意脚本的页面时,就会被攻击。
例子:
攻击者在目标网站留言板中提交了。目标网站服务端未经转义存储了恶意代码,前端请求到数据后直接通过innerHTML 渲染到页面中。其他用户在访问该留言板时,会自动执行攻击者注入脚本。
DOM 型
原理:
攻击者通过在 URL 插入恶意代码,客户端脚本取出 URL 中的恶意代码并执行。
DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。
要点:
在客户端发生。
例子:
攻击者诱导被害者打开链接hzfe.org?name=。被攻击网站前端取出 URL 的 name 字段后未经转义直接通过 innerHTML 渲染到页面中。被害者在不知情的情况下,执行了攻击者注入的脚本。
总结
存储型 XSS: 持久化,代码是存储在服务器中的
反射型 XSS: 非持久化,需要欺骗用户自己去点击链接才能触发 XSS 代码(服务器中没有这样的页面和内容),一般容易出现在搜索页面
基于 DOM 的 XSS: 不经过后端,纯粹发生在客户端的攻击,属于前端 JavaScript 自身的安全漏洞
防范 XSS
Web 安全头支持 浏览器自带的防御能力,一般是通过开启 Web 安全头生效的。具体有以下几个:
Cross-site request forgery(CSRF)
案例
一个真实的案例:用户 David 在自己邮箱内点击了黑客恶意伪装的链接。黑客在点击的链接里冒充用户(cookie)向 Gmail 服务器发送邮件自动转发请求,导致 David 的邮件都被自动转发到了黑客的邮箱,从而被黑客利用盗取了用户数据。
原理
原理:攻击者诱导受害者进入第三方网站,在第三方网站中向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的身份凭证,达到冒充用户对被攻击的网站执行某项操作的目的。
要点:
CSRF 常见的攻击方式与防护策略
常见的攻击方式:
自动发起 Get 请求
GET类型的CSRF利用非常简单,只需要一个HTTP请求,一般会这样利用:
在受害者访问含有这个img的页面后,浏览器会自动向
http://bank.example/withdraw?account=xiaoming&amount=10000&for=hacker
发出一次HTTP请求。bank.example就会收到包含受害者登录信息的一次跨域请求。自动发起 POST 请求
这种类型的CSRF利用起来通常使用的是一个自动提交的表单,如:
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。
POST类型的攻击通常比GET要求更加严格一点,但仍并不复杂。任何个人网站、博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许POST上面。
引诱用户点击链接
链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击,例如:
由于之前用户登录了信任的网站A,并且保存登录状态,只要用户主动访问上面的这个PHP页面,则表示攻击成功。
CSRF 攻击的两个必要条件:
1. 目标站点一定要有 CSRF 漏洞;
2. 诱导用户从目标网站,打开一个第三方站点。
CSRF通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对CSRF的防护能力来提升安全性。
上文中讲了CSRF的两个特点:
CSRF(通常)发生在第三方域名。 CSRF攻击者不能获取到Cookie等信息,只是使用。 针对这两点,我们可以专门制定防护策略,如下:
防范:
在实现One-Time Tokens时,需要注意一点:并行会话的兼容。如果用户在一个站点上同时打开了两个不同的表单,CSRF保护措施不应该影响到他对任何表单的提交。考虑一下如果每次表单被装入时站点生成一个伪随机值来覆盖以前的伪随机值将会发生什么情况:用户只能成功地提交他最后打开的表单,因为所有其他的表单都含有非法的伪随机值。必须小心操作以确保CSRF保护措施不会影响选项卡式的浏览或者利用多个浏览器窗口浏览一个站点。
中间人攻击(MITM)
成功的中间人攻击主要有两个不同的阶段:拦截和解密。
中间人攻击防范
SQL注入
案例
一般我们提交的表单数据(未经过滤的情况下)都会拼接到 SQL 查询语句中的,就例如:
其中 name 的参数就是从表单中传过来的数据,如果传的参数是一条 SQL 语句,那么就可能骗过了 SQL 数据库,从而执行了一段恶意的代码,达到了攻击效果。
防范
把应用服务器的数据库权限降至最低,尽可能地减少 SQL 注入攻击带来的危害。
避免网站打印出SQL错误信息,比如类型错误、字段不匹配等,把代码里的SQL语句暴露出来,以防止攻击者利用这些错误信息进行SQL注入。
对进入数据库的特殊字符('"\尖括号&*;等)进行转义处理,或编码转换。
所有的查询语句建议使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中,即不要直接拼接SQL语句。
在测试阶段,建议使用专门的 SQL 注入检测工具进行检测。网上有很多这方面的开源工具,例如sqlmap、SQLninja等。
善用数据库操作库,有些库包可能已经做好了相关的防护,只需阅读其文档,看是否支持相应的功能即可。