关于6种Web安全常见的攻防姿势

关于Web安全的问题,是一个老生常谈的问题,作为离用户最近的一层,我们大前端应该把手伸的更远一点。

我们最常见的Web安全攻击有以下几种:

  1. XSS 跨站脚本攻击
  2. CSRF 跨站请求伪造
  3. URL 跳转漏洞
  4. ClickJacking 点击劫持/UI-覆盖攻击
  5. SQL Injection SQL注入
  6. OS Command Injection OS命令注入

一、XSS

XSS (Cross Site Script),中文是跨站脚本攻击;其原本缩写是 CSS,但为了和层叠样式表(Cascading Style Sheet)有所区分,因而在安全领域叫做 XSS。

恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

XSS攻击可以分为3类:

  • 反射型 - 非持久型 Reflected XSS
  • 存储型 - 持久型 Stored XSS
  • 基于DOM或本地的XSS DOM-based or local XSS

【一一帮助安全学习,所有资源获取处一一】

①网络安全学习路线

②20份渗透测试电子书

③安全攻防357页笔记

④50份安全攻防面试指南

⑤安全红队渗透工具包

⑥网络安全必备书籍

⑦100个漏洞实战案例

⑧安全大厂内部视频资源

⑨历年CTF夺旗赛题解析

1. 反射型

反射型 XSS 只是简单地把用户输入的数据 “反射” 给浏览器,这种攻击方式往往需要攻击者诱使用户点击一个恶意链接,或者提交一个表单,或者进入一个恶意网站时,注入脚本进入被攻击者的网站。

假装我是一个恶意链接(Click Me~)
复制代码const http = require('http');

// 启http服务
const server = http.createServer(function (req, res) {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.writeHead(200, {'Content-Type': 'text/html; charset=UTF-8'});
  res.write('');
  res.end();
});

server.listen('8000');

这样就产生了反射型 XSS 攻击。攻击者可以注入任意的恶意脚本进行攻击,可能注入恶作剧脚本,或者注入能获取用户隐私数据(如cookie)的脚本,这取决于攻击者的目的。

2. 存储型

存储型 XSS 会把用户输入的数据 “存储” 在服务器端,当浏览器请求数据时,脚本从服务器上传回并执行。这种 XSS 攻击具有很强的稳定性。

比较常见的一个场景是攻击者在社区或论坛上写下一篇包含恶意 JavaScript 代码的文章或评论,文章或评论发表后,所有访问该文章或评论的用户,都会在他们的浏览器中执行这段恶意的 JavaScript 代码。

复制代码<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>存储型 XSS</title>
</head>

<body>
  <div>Try Me:<input type="text" id="input"></div>
  <button id="btn">Submit</button>

  <script>
    const input = document.getElementById('input');
    const btn = document.getElementById('btn');
    let val;

    input.addEventListener('change', e => {
      val = e.target.value;
    }, false);

    btn.addEventListener('click', e => {
      fetch('http://localhost:8000/save', {
        method: 'POST',
        body: val
      });
    }, false);
  </script>
</body>

</html>
复制代码const http = require('http');

let userInput = '';

function handleReequest (req, res) {
  const method = req.method;
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type')

  if (method === 'POST' && req.url === '/save') {
    let body = '';
    req.on('data', chunk => {
      body += chunk;
    });
    req.on('end', () => {
      if (body) {
        userInput = body;
      }
      res.end();
    });
  } else {
    res.writeHead(200, { 'Content-Type': 'text/html; charset=UTF-8' });
    res.write(userInput);
    res.end();
  }
}

// 启http服务
const server = http.createServer((req, res)=> {
  handleReequest(req, res)
});
server.listen('8000');

3. 基于DOM

基于DOM或本地的XSS其实是一种特殊类型的反射型XSS,它是基于DOM文档对象模型的一种漏洞。可以通过DOM来动态修改页面内容,从客户端获取DOM中的数据并在本地执行。基于这个特性,就可以利用JS脚本来实现XSS漏洞的利用。

复制代码<body>
<input type="text" id="input">
<button id="btn">Submit</button>
<div id="div"></div>
<script>
    const input = document.getElementById('input');
    const btn = document.getElementById('btn');
    const div = document.getElementById('div');
    let val;

    input.addEventListener('change', (e) => {
        val = e.target.value;
    }, false);

    btn.addEventListener('click', () => {
        div.innerHTML = `<a href=${val}>Try Me~</a>`
    }, false);
</script>
</body>

总结: XSS攻击的本质就是,利用一切手段在目标用户的浏览器中执行攻击脚本。

防范: 对于一切用户的输入、输出、客户端的输出内容视为不可信,在数据添加到DOM或者执行了DOM API的时候,我们需要对内容进行HtmlEncode或JavaScriptEncode,以预防XSS攻击。

现在主流的浏览器内置了防范 XSS 的措施,例如 内容安全策略(CSP)。但对于开发者来说,也应该寻找可靠的解决方案来防止 XSS 攻击。

二、CSRF

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

通常情况下,CSRF 攻击是攻击者借助受害者的 Cookie 骗取服务器的信任,可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击服务器,从而在并未授权的情况下执行在权限保护之下的操作。

关于浏览器的Cookie策略请参考[HTTP Cookie]

1. 通过 Cookie 进行 CSRF 攻击

假设有一个BBS站点http://www.a.com:

  1. 当用户登录之后,会设置如下 cookie: res.setHeader('Set-Cookie', ['user=william; expires=Fri, 23 Mar 2019 00:00:00 GMT;'])
  2. 当登录后的用户发起 http://www.a.com/delete?id=666666 请求时,会删除 id 为 666666 的帖子。
  3. CSRF攻击者准备的网站B:
  4. 当登录用户访问攻击者的网站B时,会向 www.a.com 发起一个删除用户帖子的请求。此时若用户在切换到 www.a.com 的帖子页面刷新,会发现ID 为 666666 的帖子已经被删除。

要完成一次CSRF攻击,受害者必须依次完成两个步骤:

  • 登录受信任网站A,并在本地生成Cookie。
  • 在不登出A的情况下,访问危险网站B。

2. CSRF攻击的防范

复制代码1.验证 HTTP Referer 字段
2.添加 token 验证
3.验证码

尽管CSRF听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。

与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性,往往同XSS一同作案!

三、URL跳转漏洞

借助未验证的URL跳转,将应用程序引导到不安全的第三方区域,从而导致的安全问题。

关于6种Web安全常见的攻防姿势_第1张图片

当用户点击后,经过服务器或者浏览器解析后,将会跳到恶意的网站中。

复制代码http://a.baidu.com/index?act=go&url=http://evil.cn/
http://b.baidu.com/safecheck.html?id=1&url=http://evil.cn/
http://c.baidu.com/f/user/passport?jumpUrl=http://evil.cn/

1. 实现方式

  • META标签内跳转
  • Javascript跳转
  • Header头跳转

通过以GET或者POST的方式接收将要跳转的URL,然后通过上面的几种方式的其中一种来跳转到目标URL。一方面,由于用户的输入会进入Meta,javascript,http头所以都可能发生相应上下文的漏洞,如xss等等,但是同时,即使只是对于URL跳转本身功能方面就存在一个缺陷,因为会将用户浏览器从可信的站点导向到不可信的站点,同时如果跳转的时候带有敏感数据一样可能将敏感数据泄漏给不可信的第三方。

2. 防御方案

① referer的限制 如果确定传递URL参数进入的来源,我们可以通过该方式实现安全限制,保证该URL的有效性,避免恶意用户自己生成跳转链接

② 加入有效性验证Token 我们保证所有生成的链接都是来自于我们可信域的,通过在生成的链接里加入用户不可控的Token对生成的链接进行校验,可以避免用户生成自己的恶意链接从而被利用,但是如果功能本身要求比较开放,可能导致有一定的限制。

四、ClickJacking

ClickJacking点击劫持,也叫UI覆盖攻击,攻击者会利用一个或多个透明或不透明的层来诱骗用户支持点击按钮的操作,而实际的点击确实用户看不到的一个按钮,从而达到在用户不知情的情况下实施攻击。

1. iframe覆盖

这种攻击方式的关键在于可以实现页中页的