浅谈 Web 安全

1,403 阅读6分钟

作者介绍

七望,专有钉钉前端团队成员,负责专有钉钉 PC 客户端的端上应用、模块化应用、小程序开发。

背景

前一段时间,网络上出现了一则有关部门通报境外黑客利用 SonarQube 和 Vue.js 对我国重要企企业单位实施网络攻击探测的信息;然后 Vue.js 作者尤雨溪在了解这个消息后做了相关的回应 --- 关于近日涉及 SonarQube 和 Vue 的漏洞通知;所以今天我想和大家简单探讨一下前端 Web 安全。

安全一直是一个长久且出现在方方面面的问题,例如豪绅为了钱财的安全,会做各种复杂的保险箱防止被盗,为了自身安全,会雇佣武装人员保护自己;同理,在出现互联网之后,互联网的安全问题也逐渐暴露出来。Web 作为互联网兴盛的代表之一,也是被攻击的重点之一。

浏览器同源策略

同源策略是一个重要的安全策略,它用于限制一个 origin 的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。可以说同源策略在一定程度上规避了大部分的安全问题。

下表给出了与 URL store.company.com/dir/page.ht… 的源进行对比的示例:

URL结果原因
store.company.com/dir2/other.…同源只有路径不同
store.company.com/dir/inner/a…同源只有路径不同
store.company.com/secure.html失败协议不同
store.company.com:81/dir/etc.htm…失败端口不同 ( http:// 默认端口是80)
news.company.com/dir/other.h…失败主机不同

接下来我们看下常见的 Web 漏洞攻击。

1. SQL 注入

SQL 注入攻击是黑客对数据库进行攻击的常用手段之一。随着 B/S 模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多。但是由于程序员的水平及经验参差不齐,一部分程序员在编写代码的时候,没有对用户输入数据的合法性进行判断,使应用程序存在安全隐患。用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的 SQL Injection,即 SQL 注入。

SQL 语法

# 以下是简单的 SQL 注入需要用到的 SQL 语法及关键字
# SELECT 选取数据
select <列名称> from <表名称> where <列> <运算符> <值>

# SQL 注释符号: # 井号之后的部分都会被注释

# SQL 注入可能使用到的语法
1 = 1

# SQL 运算符
# and / or

以登录为例,目前普遍的后台 Web 系统都存在账号系统,如果没有正确的账号与密码,是无法正常登录系统的,这保证了系统最基本的安全。

image.png

如上图所示,我们输入账号和密码之后,前端会将数据提交到服务端,服务端基于账号和密码查询数据库,数据库返回查询结果,服务端处理结果后返回登录成功或者失败信息,最后前端处理服务端的响应结果,登录系统或者提示错误。

image.png

在以上流程中,我们可以发现,登录账号的核心是数据库,而 SQL 是面向数据库的语法,并且部分依赖前端的输入,也就是说我们能在一定程度上控制 SQL 语句(PS: 本文的后端设计是以支持 SQL 注入攻击的方式开发的);

function signIn(username, password) {
  const sql = `select * from users where username='${username}' and password=${password}`
  
	Mysql.query(sql);
}

正常情况下,服务端基于正确的账号和密码拼出的 SQL 在执行时,肯定能够查询出存在的数据,使得成功登录;反之,错误的账号密码肯定无法登录;但是,如果网站存在 SQL 注入攻击的漏洞,只要输入一些特殊字符,在不需要知道账号的情况下也可以正常登录。

我们在页面的登录框中输入如下信息即可完成在不需要正确账号密码的情况完成登录:

账号: 'or 1=1#
密码: aaaaaaa

目前来说,SQL 注入攻击的危险性已经不太高,数据库服务端都有很好的防范措施;从前端的角度来讲,如果需要也可以做一些防范错误;例如对非法字符进行正则校验等。

2. Cross-SiteScripting (XSS 跨站脚本攻击)

XSS 攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是 JavaScript,但实际上也可以包括 Java、 VBScript、ActiveX、 Flash 或者甚至是普通的 HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和 cookie 等各种内容

存储型 XSS

攻击者通过文本框将恶意代码提交到服务器,而当服务器将该数据发放到其他用户时,恶意代码会在浏览器中执行造成损害。

# XSS 恶意代码
<img src="xss.png" onerror="alert('xss')" />

# 将以上代码提交后,我们就会看到浏览器执行了 alert 方法

image.png

防范措施:将 HMTL/Script 代码转义后提交到服务端。

反射型 XSS

在 Web 提交给服务端的数据,立刻用于解析和显示该用户的结果页面,例如分享的链接,诱导用户点击完成获取用户的信息。

防范措施:服务端对数据进行处理

DOM 型 XSS

DOM—based XSS 漏洞是基于文档对象模型(Document Objeet Model,DOM)的一种漏洞;与反射型 XSS 类似,DOM XSS 是不经过服务端的 Web 端攻击,Web 端不对 URL 上的数据做处理并动态插入到 HTML 中,导致了该攻击。

防范措施:前端对 HTML / Script 代码进行转义。

3. Cross Site Request Forgery (CSRF 跨站点请求伪造)

跨站请求伪造攻击,原理就是攻击者构造出一个后端请求地址,诱导用户点击或者通过某些途径自动发起请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,冒充用户执行某些操作;

image.png

从以上可以看出 CSRF 攻击是源于 Web 的隐式身份验证机制。Web 的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!

防范措施

  1. 验证 HTTP Referer 字段
  2. 在请求地址中添加 token 并验证
  3. 在 html 头自定义属性并验证,与 2 类似,只是位置不同,它在 HTTP 头中自定义的属性里,在所有请求的 Request Headers 里加上 csrftoken 这个 HTTP 头属性

浏览器的同源策略 --- MDN

内容安全策略( CSP ) --- MDN

附源码📎web-securite.zip