浅析 Web 安全与防护

在互联网时代,数据安全与个人隐私受到了前所未有的挑战,各种新奇的攻击技术层出不穷,Web 安全的对于 Web 从业人员来说是一个非常重要的课题,也许你对所有的安全问题都有一定的认识,但最主要的还是在编码设计的过程中时刻绷紧安全那根弦,需要反复推敲每个实现细节,安全无小事。

XSS

XSS (Cross-Site Scripting),跨站脚本攻击,因为缩写和 CSS重叠,所以只能叫 XSS。XSS 的原理是攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

XSS 的攻击方式千变万化,但还是可以大致细分为几种类型:

反射型 XSS

反射型 XSS 一般是通过给别人发送带有恶意脚本代码参数的 URL,当 URL 地址被打开时,特有的恶意代码参数被 HTML 解析、执行。

比如某搜索页面www.xxx.com?search=<script>alert(document.cookie)</script>,然后通常打开URL页面后是默认搜索search参数的内容,但是这里search是一段HTML,导致HTML被浏览器解释并执行。

反射型 XSS 漏洞攻击有以下特征:

  • 即时性,直接构建URL给用户点击,就能拿到用户隐私数据。
  • 隐蔽性,不经过服务器存储,较难发现。
  • 攻击者需要诱骗点击,必须要通过用户点击链接才能发起。

存储型 XSS

持久型 XSS 漏洞,一般发生在用户提交的文本,需要展示在页面上,如文章留言,用户名等,黑客利用 XSS 漏洞,将恶意代码经正常功能提交进入数据库存储,当前端页面获得后端从数据库中读出的注入代码时,恰好将其渲染执行。

比如某用户注册了一个用户名为<script>alert(1)</script>的用户,当其他人打开了显示这个用户名的页面,就会执行script中的恶意代码。

1
2
<p style='color:red'>文章作者:______<p>
<p style='color:red'>文章作者:<script>alert(1)</script><p>

存储型 XSS 漏洞攻击有以下特征:

  • 持久性,当恶意脚本被提交到数据库后,这段代码没被处理会一直存在。
  • 危害面广,所有打开这个页面的用户,都会被执行这段恶意代码。

危害和防护

跨站脚本攻击有可能造成以下影响:

  • 利用虚假输入表单骗取用户个人信息。
  • 利用脚本窃取用户的Cookie或Token,被害者在不知情的情况下,帮助攻击者发送恶意请求。
  • 显示伪造的文章或图片。

如何防护:

  • 使用CSP(Content Security Policy),即内容安全策略,建立白名单,只允许加载和执行指定域下的资源。
  • 使用转义字符,将所有来自用户的文本进行转义,过滤掉危险内容。
  • 在Web应用程序中将cookie设为HttpOnly,禁止前端js获取cookie,可以有效避免cookie被窃取。

CSRF

CSRF(Cross Site Request Forgery),即跨站请求伪造,是一种常见的Web攻击,它利用用户已登录的身份,在用户毫不知情的情况下,以用户的名义完成非法操作。

当我们登入转账页面后,突然收到陌生人发的未知链接,然后手贱不小心点进了该危险的网站,该页面一加载,便会恶意代码发送转账请求,从而将账户里的钱转给黑客。

如何防护:

  • 设置Referer白名单,通过判断HTTP herder中的Referer值,判断请求是否是来自合法的页面发起的。
  • Token,用户登录的之后,不是有cookie,而使用token,由于同源策略,其他页面无法获取带该页面下的cookie。
  • 验证码,用户提交表单的时候,强制用户输入验证码,能够很好地遏制CSRF攻击。

SQL注入

所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

比如有如下的用户登录SQL

1
select * from username = ____ and password=_____

尝试构造一个用户名为test" or ",密码为123456的表单,调用登录结构,最终拼接处的SQL为:

1
select * from username = "test" or ""="" and password="123456"

“” = “” 恒为真,登录成功。

我们会发现SQL注入流程中与正常请求服务器类似,只是黑客控制了数据,构造了SQL查询,而正常的请求不会SQL查询这一步,SQL注入的本质:数据和代码未分离,即数据当做了代码来执行

SQL注入的危害:

  • 获取数据库信息。
  • 管理员后台用户名和密码。
  • 获取其他数据库敏感信息:用户名、密码、手机号码、身份证、银行卡信息……
  • 整个数据库:脱裤。
  • 获取服务器权限。
  • 植入Webshell,获取服务器后门。
  • 读取服务器敏感文件。

如何防护:

  • 后端代码检查输入的数据是否符合预期,严格限制变量的类型,例如使用正则表达式进行一些匹配处理。
  • 对进入数据库的特殊字符(’,”,\,<,>,&,*,; 等)进行转义处理,或编码转换。
  • 使用数据库提供的参数化查询接口,不要直接拼接 SQL 语句,比如Mybatis的#{param}
  • Mybatis中不要将用户的数据传入${param},${}是简单的字符替换,如果用户构造特殊参数,就会导致SQL注入。
  • 严格限制Web应用的数据库的操作权限,给此用户提供仅仅能够满足其工作的最低权限,最大限度的减少注入攻击对数据库的危害。

中间人攻击

当数据传输发生在一个设备(PC/手机)和网络服务器之间时,攻击者使用其技能和工具将自己置于两个端点之间并截获数据;尽管交谈的两方认为他们是在与对方交谈,但是实际上他们是在与干坏事的人交流,这便是中间人攻击。

当用户连接了不安全的Wi-Fi 无线接入点,并使用未加密的传输协议,中间人攻击者可以将你所有发送给服务端的请求截获和篡改,也可以将服务端的响应截获并篡改,导致用户隐私泄露。

另一种常见的情况是,一些电信运营商,会在用户浏览的页面上插入广告。

如果浏览器和服务器传输中的某个网络节点被攻击这控制了,仅仅是对通信数据加密是没办法抵御的,在web环境下,客户端代码是完全暴露的,秘钥也能会攻击者截获,攻击者就可以模拟浏览器向服务端发送加密数据,然后再模拟服务端返回数据给浏览器。

通常对于web环境来说,最简单有效的防护方式,就是为自己的页面引入HTTPS,能够有效的抵御中间人攻击。

重放攻击

重放攻击的基本原理就是把以前窃听到的数据原封不动地重新发送给接收方。很多时候,网络上传输的数据是加密过的,此时窃听者无法得到数据的准确意义。但如果他知道这些数据的作用,就可以在不知道数据内容的情况下通过再次发送这些数据达到愚弄接收端的目的。

假设某用户在不安全的网络,执行了转账操作,向服务端发送了转账100元的请求,并使用了HTTPS协议加密请求内容,这时攻击者是无法知道请求的内容的也无法篡改的,但是攻击者将整个请求数据保存下来,再次向服务端发送,就可能导致用户再次执行转账操作,遭受经济损失。

如何防护:

  • 加随机数,如发现报文中有以前使用过的随机数,就认为是重放攻击。但需要额外保存使用过的随机数,保存和查询的开销较大。
  • 加时间戳,过期的请求直接丢弃。认证双方需要准确的时间同步,同步越好,受攻击的可能性就越小。但当系统很庞大,跨越的区域较广时,要做到精确的时间同步并不是很容易。 [4]
  • 加流水号,就是双方在报文中添加一个逐步递增的整数,只要接收到一个不连续的流水号报文(太大或太小),就认定有重放威胁,但是必须保证请求有序到达服务端。
  • 在实际中,常将随机数和时间戳组合使用,这样就只需保存某个很短时间段内的所有随机数,而且时间戳的同步也不需要太精确。

文件上传漏洞

文件上传漏洞是指攻击者利用web应用的文件上传接口,上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。

攻击者可以上传一个与网站脚本语言相对应的恶意代码动态脚本,例如(jsp、asp、php、aspx文件后缀)到服务器上,然后访问该文件,服务器就会动态解析脚本文件并执行,最终达到执行恶意代码的效果,影响服务器安全。

如何防护:

  • 判断文件类型,在判断文件类型时,可以结合使用MIME Type、文件后缀检查等方式。最好是采用白名单,防止有未考虑到的格式。
  • 文件上传的目录设置为不可执行,只要web容器无法解析该目录下面的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响。
  • 改写随机文件名和路径,如果应用了随机数改写了文件名和路径,将极大地增加攻击的成本。

HTTPS

// TODO

同源策略

// TODO