威胁途径与软件安全:保护应用安全
在这个软件安全系列的第3部分中,我们提到了软件环境中有关安全的几个关键要素。设计正确的流程来保证您的网络安全是很重要的。最后一个部分要讨论的是主入口。由于客户可直接访问主入口——即应用本身,因此主入口有时候是最薄弱的环节。
在这篇文章中,我们依旧先从宏观的角度切入,再逐渐深入探讨细节问题。首先我们会了解一下基础配置,接着探讨如何对输入数据进行杀毒、检查,最后我们会回顾一下优秀的成功案例,学习如何为您客户的账户提供安全保障。
SSL与安全
如今,SSL应该是web应用的默认方案了。凭借SSL证书,您可以对浏览器和基础设施之间的数据进行加密,这样数据在互联网上流动时就不会被想要监控流量的人读取。新的浏览器甚至会在您浏览未经SSL加密的网站时发出警告。证书的获取也比以往要容易得多,而且完全免费,只需要使用诸如Let’s Encrypt的网站即可。或者,若您使用的是AWS,您可以通过他们的证书管理器在几秒内获得SSL证书,同样不需要支付任何费用。
不过有一个方面您可能没有考虑过,那就是后端系统之间的数据传输安全。若您配备了相互通信的API,那么最好将这部分数据也一并加密。这样即使应用是在内部网络实现的,若有人想要访问网络,那他就必须投入更多的精力读取数据。这一点同样适用于数据库——内部API应该通过SSL与数据库通信。
阻止跨站点脚本攻击
当有人成功在应用中注入代码,然后该应用又运行了这段代码时,就会发生跨站点脚本攻击。发生跨站点脚本攻击时,攻击者会获得对代码的完全掌控,并可以实施某些恶意行为。因此在接收用户输入时,务必要对其进行“消毒”。消毒是接收输入,确保输入的数据不会在应用程序中形成漏洞的一个过程,通常意味着某些字符会被跳过。
eBay是一个最好的例子。过去,eBay允许脚本在其网站上运行,目的是为卖家提供一种独一无二的使用体验——但代价是他们的客户被迫暴露在风险之中。最终,eBay在众人的呼声中做出了正确的选择,移除了这项特性。
阻止SQL注入攻击
和跨站点脚本攻击类似,SQL注入攻击发生在通过恶意输入获取数据库访问权限的时候。在数据库中运行SQL语句时,有时会获取用户数据(譬如进行搜索时)。而掌握了SQL的攻击者可以通过在文本和其他字段中输入SQL命令将系统和数据暴露出来。这些命令可以返回敏感的用户数据,或者像这幅著名的XKCD漫画一样,删除某些表格。经验告诉我们,不要相信用户。
加密数据
显而易见,敏感数据应该加密。也就是说,不要直接将数据原样存储在磁盘上,而要先将数据转换成人类无法理解的形式后在储存。如果需要将数据重新转换成人类可以理解的形式,则需要使用密钥。这样,若有人在没有密钥的情况下想要访问数据,只能够获得一堆垃圾。无论是在哪里储存数据(数据库或设备文件中),都应该对数据进行加密。
不发送多余的数据
下面这个安全漏洞常常被人忽视:返回数据时,应该问问自己:“应该发送这部分数据吗?”例如,若您的API获取了一整个用户模型,那么返回这个模型有大概率会是一个馊主意,因为这个模型可能包含了身份信息和敏感信息,而这一点是可以避免的。每一个API都应该限制返回数据的范围,即只返回关联性最强的数据块,因为一旦向浏览器发送了数据,这部分数据就基本相当于暴露了。
双因子认证提升安全性
在回顾一些成功案例后,我们会探讨还有哪些措施可以保证用户数据的安全。双因子认证或多因子认证(MFA)是保护用户账户安全的常见做法之一。这项技术会在用户输入密码后要求用户证明自己的身份。如果您有使用网上银行应用程序的经验,那么您大概率已经遇到过这个机制了。用户登录后,这项技术会向用户请求建立一条通道来获取一个验证码——例如:输入文本,或者更理想的是使用像Authy这样的安全应用程序。有了这些工具后,用户在登录时就会被要求提供一个一次性的验证码。这样即便用户的密码泄露,账户也不会被他人非法访问。
在和登录账户有关的问题上,逻辑分析是一个很好的办法。用户是否在最近2秒内登录失败了15次?这些请求来源的IP地址是否和其常规位置相去甚远?这些迹象都可能表明进行登录操作的不是实际用户本人。提示用户进行登录验证,或者在登录发生时告知用户,都是保护用户账户安全的好办法。
给密码加盐
保护用户信息的另一种标准做法是在密码中增加一个随机生成的字符串(又叫“盐值”),然后再进行加密。采取这种做法后,即使用户在您的应用程序和其他应用程序上都使用相同的密码(顺便说一下,这种习惯很不好),您的应用程序也可保证储存的信息的唯一性。
那么,为什么这一点很重要呢?不妨考虑一下这种情形:您的密码在某个网站被泄露了。此时,若其他网站都引入了盐值,那么这个密码就没办法被用于非法用途。实际上,对于加了盐的密码而言,即使您输入的是和以前相同的密码,这个密码也不再是原来的密码了。
小心第三方库
在今天的环境中很难再找到一款没有使用第三方库的应用,任何用户都可以轻松使用开源库中的代码,而这些代码是允许所有人自由查看的。因此,最好的办法是在使用这些代码以前检查这些库是否存在安全漏洞。一个年代久远又缺乏维护的库有大概率是不安全的。
关于安全最后的一些想法
应用程序是业务的组成部分,在某些情况下甚至是最关键的部分。应用程序是客户与您互动的桥梁,也是您与同行拉开差距的手段,但在面对攻击者和用户本身时也是最薄弱的一环。遵循数据加密的标准做法,为用户提供数据保护的选项,就是在为您的业务争取最大的机遇。
最后,安全是团队合作的产物,任何人都不可能仅凭一己之力为您的企业和客户提供安全保障,安全是公司从上到下每一个人的日常。您要在自己的企业内建立起这种习惯和氛围。