不管是开发Web应用的开发者仍是企图利用Web应用漏洞的攻击者,对于Web程序安全这个话题都给予了愈来愈多的关注。特别是最近CSDN密码泄露事件,更是让咱们对Web安全这个话题更加剧视,全部人都谈密码色变,都开始检测本身的系统是否存在漏洞。那么咱们做为一名Go程序的开发者,必定也须要知道咱们的应用程序随时会成为众多攻击者的目标,并提早作好防范的准备。php
不少Web应用程序中的安全问题都是因为轻信了第三方提供的数据形成的。好比对于用户的输入数据,在对其进行验证以前都应该将其视为不安全的数据。若是直接把这些不安全的数据输出到客户端,就可能形成跨站脚本攻击(XSS)的问题。若是把不安全的数据用于数据库查询,那么就可能形成SQL注入问题,在使用第三方提供的数据,包括用户提供的数据时,首先检验这些数据的合法性很是重要,这个过程叫作过滤,过滤输入和转义输出并不能解决全部的安全问题,与安全加密相关的,可以加强咱们的Web应用程序的强大手段就是加密,CSDN泄密事件就是由于密码保存的是明文,使得攻击拿手库以后就能够直接实施一些破坏行为了。不过,和其余工具同样,加密手段也必须运用得当。加密的本质就是扰乱数据,某些不可恢复的数据扰乱咱们称为单向加密或者散列算法。另外还有一种双向加密方式,也就是能够对加密后的数据进行解密git
什么是CSRFgithub
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。golang
那么CSRF到底可以干吗呢?你能够这样简单的理解:攻击者能够盗用你的登录信息,以你的身份模拟发送各类请求。攻击者只要借助少量的社会工程学的诡计,例如经过QQ等聊天软件发送的连接(有些还假装成短域名,用户没法分辨),攻击者就能迫使Web应用的用户去执行攻击者预设的操做。例如,当用户登陆网络银行去查看其存款余额,在他没有退出时,就点击了一个QQ好友发来的连接,那么该用户银行账户中的资金就有可能被转移到攻击者指定的账户中。web
因此遇到CSRF攻击时,将对终端用户的数据和操做指令构成严重的威胁;当受攻击的终端用户具备管理员账户的时候,CSRF攻击将危及整个Web应用程序。算法
要完成一次CSRF攻击,受害者必须依次完成两个步骤 :sql
1.登陆受信任网站A,并在本地生成Cookie 。
2.在不退出A的状况下,访问危险网站B。
看到这里,读者也许会问:“若是我不知足以上两个条件中的任意一个,就不会受到CSRF的攻击”。是的,确实如此,但你不能保证如下状况不会发生:数据库
CSRF攻击主要是由于Web的隐式身份验证机制,Web的身份验证机制虽然能够保证一个请求是来自于某个用户的浏览器,但却没法保证该请求是用户批准发送的。浏览器
过滤用户数据是Web应用安全的基础。它是验证数据合法性的过程。经过对全部的输入数据进行过滤,能够避免恶意数据在程序中被误信或误用。大多数Web应用的漏洞都是由于没有对用户输入的数据进行恰当过滤所引发的。安全
咱们介绍的过滤数据分红三个步骤:
一、识别数据,搞清楚须要过滤的数据来自于哪里
二、过滤数据,弄明白咱们须要什么样的数据
三、区分已过滤及被污染数据,若是存在攻击数据那么保证过滤以后可让咱们使用更安全的数据
数据过滤在Web安全中起到一个基石的做用,大多数的安全问题都是因为没有过滤数据和验证数据引发的,例如前面小节的CSRF攻击,以及接下来将要介绍的XSS攻击、SQL注入等都是没有认真地过滤数据引发的,所以咱们须要特别重视这部分的内容。
随着互联网技术的发展,如今的Web应用都含有大量的动态内容以提升用户体验。所谓动态内容,就是应用程序可以根据用户环境和用户请求,输出相应的内容。动态站点会受到一种名为“跨站脚本攻击”(Cross Site Scripting, 安全专家们一般将其缩写成 XSS)的威胁,而静态站点则彻底不受其影响。
XSS攻击:跨站脚本攻击(Cross-Site Scripting),为了避免和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。XSS是一种常见的web安全漏洞,它容许攻击者将恶意代码植入到提供给其它用户使用的页面中。不一样于大多数攻击(通常只涉及攻击者和受害者),XSS涉及到三方,即攻击者、客户端与Web应用。XSS的攻击目标是为了盗取存储在客户端的cookie或者其余网站用于识别客户端身份的敏感信息。一旦获取到合法用户的信息后,攻击者甚至能够假冒合法用户与网站进行交互。
XSS一般能够分为两大类:一类是存储型XSS,主要出如今让用户输入数据,供其余浏览此页的用户进行查看的地方,包括留言、评论、博客日志和各种表单等。应用程序从数据库中查询数据,在页面中显示出来,攻击者在相关页面输入恶意的脚本数据后,用户浏览此类页面时就可能受到攻击。这个流程简单能够描述为:恶意用户的Html输入Web程序->进入数据库->Web程序->用户浏览器。另外一类是反射型XSS,主要作法是将脚本代码加入URL地址的请求参数里,请求参数进入程序后在页面直接输出,用户点击相似的恶意连接就可能受到攻击。
什么是SQL注入
SQL注入攻击(SQL Injection),简称注入攻击,是Web开发中最多见的一种安全漏洞。能够用它来从数据库获取敏感信息,或者利用数据库的特性执行添加用户,导出文件等一系列恶意操做,甚至有可能获取数据库乃至系统用户最高权限。
而形成SQL注入的缘由是由于程序没有有效过滤用户的输入,使攻击者成功的向服务器提交恶意的SQL查询代码,程序在接收后错误的将攻击者的输入做为查询语句的一部分执行,致使原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。
不少Web开发者没有意识到SQL查询是能够被篡改的,从而把SQL查询看成可信任的命令。却不知,SQL查询是能够绕开访问控制,从而绕过身份验证和权限检查的。更有甚者,有可能经过SQL查询去运行主机系统级的命令。
也许你会说攻击者要知道数据库结构的信息才能实施SQL注入攻击。确实如此,但没人能保证攻击者必定拿不到这些信息,一旦他们拿到了,数据库就存在泄露的危险。若是你在用开放源代码的软件包来访问数据库,好比论坛程序,攻击者就很容易获得相关的代码。若是这些代码设计不良的话,风险就更大了。目前Discuz、phpwind、phpcms等这些流行的开源程序都有被SQL注入攻击的先例。
这些攻击老是发生在安全性不高的代码上。因此,永远不要信任外界输入的数据,特别是来自于用户的数据,包括选择框、表单隐藏域和 cookie。就如上面的第一个例子那样,就算是正常的查询也有可能形成灾难。
SQL注入是危害至关大的安全漏洞。因此对于咱们日常编写的Web应用,应该对于每个小细节都要很是重视,细节决定命运,生活如此,编写Web应用也是这样。
过去一段时间以来, 许多的网站遭遇用户密码数据泄露事件, 这其中包括顶级的互联网企业–Linkedin, 国内诸如CSDN,该事件横扫整个国内互联网,随后又爆出多玩游戏800万用户资料被泄露,另有传言人人网、开心网、天涯社区、世纪佳缘、百合网等社区都有可能成为黑客下一个目标。层出不穷的相似事件给用户的网上生活形成巨大的影响,人人自危,由于人们每每习惯在不一样网站使用相同的密码,因此一家“暴库”,所有遭殃。
那么咱们做为一个Web应用开发者,在选择密码存储方案时, 容易掉入哪些陷阱, 以及如何避免这些陷阱?
目前用的最多的密码存储方案是将明文密码作单向哈希后存储,单向哈希算法有一个特征:没法经过哈希后的摘要(digest)恢复原始数据,这也是“单向”二字的来源。经常使用的单向哈希算法包括SHA-256, SHA-1, MD5等。
单向哈希有两个特性:
1)同一个密码进行单向哈希,获得的老是惟一肯定的摘要。
2)计算速度快。随着技术进步,一秒钟可以完成数十亿次单向哈希计算。
结合上面两个特色,考虑到多数人所使用的密码为常见的组合,攻击者能够将全部密码的常见组合进行单向哈希,获得一个摘要组合, 而后与数据库中的摘要进行比对便可得到对应的密码。这个摘要组合也被称为rainbow table。
所以经过单向加密以后存储的数据,和明文存储没有多大区别。所以,一旦网站的数据库泄露,全部用户的密码自己就大白于天下。
经过上面介绍咱们知道黑客能够用rainbow table来破解哈希后的密码,很大程度上是由于加密时使用的哈希算法是公开的。若是黑客不知道加密的哈希算法是什么,那他也就无从下手了。
一个直接的解决办法是,本身设计一个哈希算法。然而,一个好的哈希算法是很难设计的——既要避免碰撞,又不能有明显的规律,作到这两点要比想象中的要困难不少。所以实际应用中更多的是利用已有的哈希算法进行屡次哈希。
可是单纯的屡次哈希,依然阻挡不住黑客。两次 MD五、三次 MD5之类的方法,咱们能想到,黑客天然也能想到。特别是对于一些开源代码,这样哈希更是至关于直接把算法告诉了黑客。
没有攻不破的盾,但也没有折不断的矛。如今安全性比较好的网站,都会用一种叫作“加盐”的方式来存储密码,也就是常说的 “salt”。他们一般的作法是,先将用户输入的密码进行一次MD5(或其它哈希算法)加密;将获得的 MD5 值先后加上一些只有管理员本身知道的随机串,再进行一次MD5加密。这个随机串中能够包括某些固定的串,也能够包括用户名(用来保证每一个用户加密使用的密钥都不同)。
上面的进阶方案在几年前也许是足够安全的方案,由于攻击者没有足够的资源创建这么多的rainbow table。 可是,时至今日,由于并行计算能力的提高,这种攻击已经彻底可行。
怎么解决这个问题呢?只要时间与资源容许,没有破译不了的密码,因此方案是:故意增长密码计算所需耗费的资源和时间,使得任何人都不可得到足够的资源创建所需的rainbow table。
这类方案有一个特色,算法中都有个因子,用于指明计算密码摘要所须要的资源和时间,也就是计算强度。计算强度越大,攻击者创建rainbow table越困难,以致于不可继续。
这里推荐scrypt方案,scrypt是由著名的FreeBSD黑客Colin Percival为他的备份服务Tarsnap开发的。
目前Go语言里面支持的库 https://github.com/golang/crypto/tree/master/scrypt
dk := scrypt.Key([]byte("some password"), []byte(salt), 16384, 8, 1, 32)
经过上面的方法能够获取惟一的相应的密码值,这是目前为止最难破解的。
看到这里,若是你产生了危机感,那么就行动起来:
1)若是你是普通用户,那么咱们建议使用LastPass进行密码存储和生成,对不一样的网站使用不一样的密码;
2)若是你是开发人员, 那么咱们强烈建议你采用专家方案进行密码存储。
若是Web应用足够简单,数据的安全性没有那么严格的要求,那么能够采用一种比较简单的加解密方法是base64,这种方式实现起来比较简单
Go语言的crypto里面支持对称加密的高级加解密包有:
crypto/aes包:AES(Advanced Encryption Standard),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
crypto/des包:DES(Data Encryption Standard),是一种对称加密标准,是目前使用最普遍的密钥系统,特别是在保护金融数据的安全中。曾是美国联邦政府的加密标准,但现已被AES所替代。
这小节介绍了几种加解密的算法,在开发Web应用的时候能够根据需求采用不一样的方式进行加解密,通常的应用能够采用base64算法,更加高级的话能够采用aes或者des算法。
这一章主要介绍了如:CSRF攻击、XSS攻击、SQL注入攻击等一些Web应用中典型的攻击手法,它们都是因为应用对用户的输入没有很好的过滤引发的,因此除了介绍攻击的方法外,咱们也介绍了了如何有效的进行数据过滤,以防止这些攻击的发生的方法。而后针对日异严重的密码泄漏事件,介绍了在设计Web应用中可采用的从基本到专家的加密方案。最后针对敏感数据的加解密简要介绍了,Go语言提供三种对称加密算法:base6四、aes和des的实现。go语言在支持防攻击方面已经提供大量的工具包,咱们能够充分的利用这些包来作出一个安全的Web应用。 前面小节介绍了如何存储密码,可是有的时候,咱们想把一些敏感数据加密后存储起来,在未来的某个时候,随需将它们解密出来,此时咱们应该在选用对称加密算法来知足咱们的需求。