Web常见安全问题

1,367 阅读11分钟

1.XSS攻击

XSS是指浏览器中执行非官方的恶意脚本,全称为 Cross Site Scripting(即跨站脚本)。既然是非官方的脚本,那攻击者是如何将恶意脚本注入到网站中?加入这些恶意脚本的意图是什么?开发者又该如何防范?

XSS攻击实现方式

反射型

攻击方式:

相关步骤:

  1. 用户点击加入恶意参数的链接
  2. 服务器收到请求,将链接中的参数取出,拼接成html返回给浏览器
  3. 浏览器接收并渲染html,发现script标签并执行恶意代码

恶意url类似这样:

https://xxx.com/search?keyword=<script>alert("game over")</script>

反射型XSS特点:

  • 非持久性
  • 表现形式为请求到达服务器,服务器把未处理或转义的html原样输出到浏览器中,故称它为反射型XSS攻击
  • 反射型XSS通常出现在网站搜索栏、登录处等

存储型

攻击方式:

相关步骤:

  1. 攻击者将恶意脚本提交到网站的数据库中
  2. 用户请求目标网站
  3. 服务器收到请求,将恶意代码从数据库取出,拼接成html返回给浏览器
  4. 浏览器接收并渲染html,发现script标签并执行恶意代码

存储型XSS特点:

  • 持久性,若网站不做处理,则攻击一直存在。
  • 存储型XSS通常出现在评论、留言区等。

DOM-based型

攻击方式:

相关步骤:

  1. 用户点击加入恶意参数的链接
  2. 服务器收到请求,将链接中的参数取出,将html返回给浏览器(这里服务器做了转义措施)
  3. 浏览器接收并渲染html,前端js取出并执行了url参数,相当于执行了恶意脚本

DOM型XSS特点:

  • 非持久性
  • 利用原生js修改页面结构的特点来实现攻击目的

XSS攻击意图

  1. 盗用cookie实现无密码登录

  2. 修改dom伪造表单

  3. 配合csfr攻击发起恶意请求

  4. 破坏页面结构/生成广告

防范方法

原则:前后端都需要做转义措施,永远不要把不可信的数据插入到页面中,这些数据包括用户输入、url参数等

  • 对HTML进行转义

    引用前端安全系列(一):如何防止XSS攻击?转义规则:

    字符 转义后的字符
    & &amp;
    < &lt;
    > &gt;
    " &quot;
    ' &#x27;
    / &#x2F;
  • 引入Content-Security-Policy,使用白名单制度禁止网页上外部脚本注入

  • 添加cookie的httpOnly数据,这样恶意代码不能获取cookie,能防范意图要获取cookie的XSS攻击

  • 预防Dom型XSS时,前端需谨慎使用innerHTMLouterHTMLdocument.write(),尽量使用textContentsetAttribute

2.CSRF攻击

CSRF(Cross-site request forgery),即跨站请求伪造,用户点开钓鱼链接,网站利用用户的登录状态自动发送请求实现攻击。

攻击方式:

相关步骤:

  1. 用户点击加入诱导链接
  2. 进入恶意网站
  3. 利用用户在原网站的登录凭证自动发起恶意请求或继续诱导用户点击请求执行恶意操作

CSRF常见类型

GET类型

有这样一个imgdom标签

<img src="https://xxx.com/pay?money=100000&receiver=jay&user=user">

当用户点击后,浏览器自动发起了请求,执行相应支付恶意操作造成受害者损失

POST类型

黑客伪造了一个自动提交的表单

<form id="form" action="https://xxx.com/pay" method=POST>
  <input type="hidden" name="receiver" value="jay"/>
  <input type="hidden" name="moneny" value="10000"/>
  <input type="hidden" name="user" value="user"/>
</form>
<script> document.getElementById('form').submit(); </script> 

用户访问后,网站自动发起http请求,相当于用户发起的post请求。

链接类型的CSRF

<a href="http://xxx.com/csrf/withdraw.php?amount=1000&for=hacker" taget="_blank">
   即将大涨的股票
<a/>

这种方式需要在第三方网站上放置一个链接诱导用户点击,相比其他两种类型多了一步操作,也可能黑客将链接配合xss攻击直接插入到html中。

防范方法

CSRF攻击一般发生在第三方网站,我们可以阻止外部域名访问来达到防护

  • 利用Cookie的SameSite属性

    攻击者无非是使用用户在A的登录凭证(cookie)进行恶意操作,SameSite可以对cookie携带进行限制。

    其属性是:

    • Strict:禁止第三方请求携带cookie

    • Lax

      引用Cookie 的 SameSite 属性

      大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外,导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单。

    • None:默认属性,相当于不禁止第三方网站携带cookie

  • 使用token

    用户首次登陆时服务端生成token,并将该token植入到html的dom中,客户端发起请求必须带上token,服务端验证后执行后续操作

  • 验证请求来源

    使用Origin HeaderReferer Header标记请求来源,限制非认证的来源请求。不过Origin HeaderReferer Header可以通过请求头修改,安全性较差,一定意义上不能作为防范CSRF攻击的最佳措施

3.DDoS攻击

DDoS(Distributed denial of service),即分布式拒绝服务攻击,不同位置的多个攻击者同时向一个或多个目标发起攻击。先说下DoSDoS攻击是一对一的发起攻击,当攻击者对网站发起DoS攻击(巨量请求)时,网站的服务器因其带宽和资源有限,无法处理这些需要响应的请求,导致服务器崩溃停止运作。DDoS是基于分布式的,其使用多对一或多对多的方式对目标发起攻击,攻击力度和防范难度和DoS相比远不是一个数量级。

所以当一个网站遭遇DDoS攻击,网站服务器接收到来自不同IP的大量合法正常请求,网络中会有大量的等待处理的数据包和tcp连接,造成整个网络拥堵甚至宕机。因此黑客常利用DDoS攻击达到获得利益、打败竞争对手等目的。

防范方法

  • http请求拦截

    识别出发起恶意请求的IP地址,通过防火墙、服务器等方式禁止这些IP访问。

  • 增加带宽

    因为DDoS攻击发起的请求被视为正常的请求,一般情况下很难识别,所以通过增加带宽来消化DDoS的巨量请求。这种方式应对带宽消耗型攻击非常有效,但需要堆叠硬件资源,成本也最大。

  • 购买高防IP,现在很多云服务商提供高防IP,其防御原理就是在受到攻击服务不可用的情况下将流量引流到高防IP,从而保护源站稳定。

  • 隐藏服务器IP,使用CDN服务,CDN服务将网站的静态资源分发到多个服务器,可以抵御一定流量的攻击

4.HTTPS加密技术

现在网络传输应用层已经有了http,为什么还需要https?首先http传输的特点是明文传输,那在传输过程中传输信息可能会被黑客截获,重要的数据如用户名、密码就会泄露,这显然是不安全的。httpshttp多了安全层(Secure),就是让数据传输更加安全,那https如何比http传输更加安全?答案在于https使用加密技术。

对称加密与非对称加密

对称加密就是指通信双方都有相同的钥匙,加密解密都使用这一把钥匙。

非对称加密是指有AB两把钥匙,A加密的数据必须通过B解密,B加密的数据必须要A解密。

我们看看通信双方使用对称加密会是怎样

  1. 客户端请求与服务器连接
  2. 服务器返回密钥给客户端
  3. 客户端使用密钥对数据加密传输给服务器
  4. 服务器使用密钥解密得到数据

对称加密里最重要的是让通信双方都获得密钥,但这里密钥使用明文传输,密钥传输时就可能被中间人截获,最终造成数据泄露,有中间人攻击的流程是

  1. 客户端请求与服务器连接
  2. 服务器返回密钥给客户端
  3. 中间人截取密钥,同样将密钥发给客户端
  4. 客户端使用密钥对数据加密传输给服务器
  5. 中间人截获密文使用密钥解密得到数据
  6. 中间人将密文继续传输给服务器
  7. 服务器使用密钥解密得到数据

那再给明文传输的密钥加密?这就陷入死循环,显然行不通,再看看使用非对称加密的流程

  1. 客户端请求与服务器连接
  2. 服务器返回公钥给客户端
  3. 客户端使用共钥对数据加密传输给服务器
  4. 服务器使用私钥解密得到数据

那中间人还是可以实现攻击,流程是

  1. 客户端请求与服务器连接
  2. 服务器返回公钥给客户端
  3. 中间人截取公钥,同样将公钥发给客户端
  4. 客户端使用公钥对数据加密传输给服务器
  5. 服务器使用私钥解密得到数据
  6. 服务器使用私钥将响应数据加密,返给客户端
  7. 中间人使用截获的公钥对服务器响应数据解密
  8. 将数据继续返回客户端

非对称加密可以保证客户端到服务器数据的安全,中间人没有私钥进行解密操作,但不能保证服务器到客户端数据的安全

我们再看看结合两种方式的加密流程

  1. 客户端请求与服务器连接
  2. 服务器返回公钥给客户端
  3. 客户端生成一个对称加密方法,将这个方法使用公钥加密传给服务器
  4. 服务器使用私钥解密得到客户端的对称加密方法
  5. 服务器使用对称加密方法生成公钥,使用公钥加密数据返回客户端
  6. 客户端使用公钥解密获取数据

结合非对称和对称加密可以保证通信双方传输数据的安全,这种方式避免服务器向客户端传输时数据泄露的现象,因为此时使用了不同的加密方法,但可恶的中间人依然有方法发起攻击,流程是

  1. 客户端请求与服务器连接
  2. 服务器返回公钥给客户端
  3. 中间人截取公钥,同时通过非对称方法生成一对公/私钥
  4. 中间人将自己生成的公钥传给客户端
  5. 客户端生成一个对称加密方法,将这个方法使用公钥加密传给服务器
  6. 中间人使用私钥解密,得到加密方法
  7. 中间人使用之前截取的公钥将加密方法加密返回给服务器

中间人在服务器与客户端确定加密方法的过程中将加密方法截获,使得之后双方的通信都遭到泄露

既然中间人伪造了一对公/私钥,那我们就加入类似派出所的权威机构(Certificate Authority),让这个权威机构颁发给服务器一个身份证明(证书),让服务器在首次发送公钥时带上证书,客户端验证证书有效后再进行后续操作,这样中间人就无法通过伪造实现攻击。再来看看有证书的流程。

  1. 客户端请求与服务器连接
  2. 服务器返回公钥和证书传给客户端
  3. 客户端验证证书,若证书真实有效,则进行后续操作,若是虚假证书,则拒绝连接
  4. 客户端将加密方法使用公钥加密传给服务器
  5. 服务器使用私钥解密得到客户端的对称加密方法
  6. 服务器使用对称加密方法生成公钥,使用公钥加密数据返回客户端

当然服务器首先需要到CA(权威机构)办一张证书,这个证书记录服务器域名、公钥、签发机关等信息。其过程是CA生成一对公/私钥,用私钥将服务器提交的信息通过hash计算得到的hash值(其过程不可逆,即无法通过hash值计算原本的信息)加密生成密文,再把服务器的信息同密文整合到证书上。客户端在收到服务器的CA证书时,用CA的公钥解密得到的hash值和明文信息hash计算后hash值进行对比,若一致则证书合法有效。

推荐阅读