Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

面试官:web常见的攻击方式有哪些?如何防御? #92

Open
huihuiha opened this issue Mar 30, 2021 · 0 comments
Open

面试官:web常见的攻击方式有哪些?如何防御? #92

huihuiha opened this issue Mar 30, 2021 · 0 comments

Comments

@huihuiha
Copy link
Contributor

一、是什么

Web攻击(WebAttack)是针对用户上网行为或网站服务器等设备进行攻击的行为

如植入恶意代码,修改网站权限,获取网站用户隐私信息等等

Web应用程序的安全性是任何基于Web业务的重要组成部分

确保Web应用程序安全十分重要,即使是代码中很小的 bug 也有可能导致隐私信息被泄露

站点安全就是为保护站点不受未授权的访问、使用、修改和破坏而采取的行为或实践

我们常见的Web攻击方式有

  • XSS (Cross Site Scripting) 跨站脚本攻击
  • CSRF(Cross-site request forgery)跨站请求伪造
  • SQL注入攻击

二、XSS

XSS,跨站脚本攻击,允许攻击者将恶意代码植入到提供给其它用户使用的页面中

XSS涉及到三方,即攻击者、客户端与Web应用

XSS的攻击目标是为了盗取存储在客户端的cookie或者其他网站用于识别客户端身份的敏感信息。一旦获取到合法用户的信息后,攻击者甚至可以假冒合法用户与网站进行交互

举个例子:

一个搜索页面,根据url参数决定关键词的内容

<input type="text" value="<%= getParameter("keyword") %>">
<button>搜索</button>
<div>
  您搜索的关键词是:<%= getParameter("keyword") %>
</div>

这里看似并没有问题,但是如果不按套路出牌呢?

用户输入"><script>alert('XSS');</script>,拼接到 HTML 中返回给浏览器。形成了如下的 HTML:

<input type="text" value=""><script>alert('XSS');</script>">
<button>搜索</button>
<div>
  您搜索的关键词是:"><script>alert('XSS');</script>
</div>

浏览器无法分辨出 <script>alert('XSS');</script> 是恶意代码,因而将其执行,试想一下,如果是获取cookie发送对黑客服务器呢?

根据攻击的来源,XSS攻击可以分成:

  • 存储型
  • 反射型
  • DOM 型

存储型

存储型 XSS 的攻击步骤:

  1. 攻击者将恶意代码提交到目标网站的数据库中
  2. 用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作

这种攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等

反射型 XSS

反射型 XSS 的攻击步骤:

  1. 攻击者构造出特殊的 URL,其中包含恶意代码
  2. 用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器
  3. 用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作

反射型 XSS 跟存储型 XSS 的区别是:存储型 XSS 的恶意代码存在数据库里,反射型 XSS 的恶意代码存在 URL 里。

反射型 XSS 漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。

由于需要用户主动打开恶意的 URL 才能生效,攻击者往往会结合多种手段诱导用户点击。

POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见

DOM 型 XSS

DOM 型 XSS 的攻击步骤:

  1. 攻击者构造出特殊的 URL,其中包含恶意代码
  2. 用户打开带有恶意代码的 URL
  3. 用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行
  4. 恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作

DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞

XSS的预防

通过前面介绍,看到XSS攻击的两大要素:

  • 攻击者提交而恶意代码
  • 浏览器执行恶意代码

针对第一个要素,我们在用户输入的过程中,过滤掉用户输入的恶劣代码,然后提交给后端,但是如果攻击者绕开前端请求,直接构造请求就不能预防了

而如果在后端写入数据库前,对输入进行过滤,然后把内容给前端,但是这个内容在不同地方就会有不同显示

例如:

一个正常的用户输入了 5 < 7 这个内容,在写入数据库前,被转义,变成了 5 < 7

在客户端中,一旦经过了 escapeHTML(),客户端显示的内容就变成了乱码( 5 < 7 )

在前端中,不同的位置所需的编码也不同。

  • 5 < 7 作为 HTML 拼接页面时,可以正常显示:
<div title="comment">5 &lt; 7</div>
  • 5 < 7 通过 Ajax 返回,然后赋值给 JavaScript 的变量时,前端得到的字符串就是转义后的字符。这个内容不能直接用于 Vue 等模板的展示,也不能直接用于内容长度计算。不能用于标题、alert 等

可以看到,过滤并非可靠的,下面就要通过防止浏览器执行恶意代码:

在使用 .innerHTML.outerHTMLdocument.write() 时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent.setAttribute()

如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTMLouterHTML 的 XSS 隐患

DOM 中的内联事件监听器,如 locationonclickonerroronloadonmouseover 等,<a> 标签的 href 属性,JavaScript 的 eval()setTimeout()setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免

<!-- 链接内包含恶意代码 -->
< a href=" ">1</ a>

<script>
// setTimeout()/setInterval() 中调用恶意代码
setTimeout("UNTRUSTED")
setInterval("UNTRUSTED")

// location 调用恶意代码
location.href = 'UNTRUSTED'

// eval() 中调用恶意代码
eval("UNTRUSTED")

三、CSRF

CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求

利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目

一个典型的CSRF攻击有着如下的流程:

  • 受害者登录a.com,并保留了登录凭证(Cookie)
  • 攻击者引诱受害者访问了b.com
  • b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带a.com的Cookie
  • a.com接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求
  • a.com以受害者的名义执行了act=xx
  • 攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让a.com执行了自己定义的操作

csrf可以通过get请求,即通过访问img的页面后,浏览器自动访问目标地址,发送请求

同样,也可以设置一个自动提交的表单发送post请求,如下:

<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操作

还有一种为使用a标签的,需要用户点击链接才会触发

访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作

< a href="http://test.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
    重磅消息!!
<a/>

CSRF的特点

  • 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生
  • 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据
  • 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”
  • 跨站请求可以用各种方式:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪

CSRF的预防

CSRF通常从第三方网站发起,被攻击的网站无法防止攻击发生,只能通过增强自己网站针对CSRF的防护能力来提升安全性

防止csrf常用方案如下:

  • 阻止不明外域的访问
    • 同源检测
    • Samesite Cookie
  • 提交时要求附加本域才能获取的信息
    • CSRF Token
    • 双重Cookie验证

这里主要讲讲token这种形式,流程如下:

  • 用户打开页面的时候,服务器需要给这个用户生成一个Token
  • 对于GET请求,Token将附在请求地址之后。对于 POST 请求来说,要在 form 的最后加上
<input type=”hidden” name=”csrftoken” value=”tokenvalue”/>
  • 当用户从客户端得到了Token,再次提交给服务器的时候,服务器需要判断Token的有效性

四、SQL注入

Sql 注入攻击,是通过将恶意的 Sql 查询或添加语句插入到应用的输入参数中,再在后台 Sql 服务器上解析执行进行的攻击

流程如下所示:

  • 找出SQL漏洞的注入点

  • 判断数据库的类型以及版本

  • 猜解用户名和密码

  • 利用工具查找Web后台管理入口

  • 入侵和破坏

预防方式如下:

  • 严格检查输入变量的类型和格式
  • 过滤和转义特殊字符
  • 对访问数据库的Web应用程序采用Web应用防火墙

上述只是列举了常见的web攻击方式,实际开发过程中还会遇到很多安全问题,对于这些问题, 切记不可忽视

参考文献

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants