8大前端安全问题(上)

当我们说“前端安全问题”的时候,我们在说什么

“安全”是个很大的话题,各种安全问题的类型也是种类繁多。如果我们把安全问题按照所发生的区域来进行分类的话,那么所有发生在后端服务器、应用、服务当中的安全问题就是“后端安全问题”,所有发生在浏览器、单页面应用、Web页面当中的安全问题则算是“前端安全问题”。比如说,SQL注入漏洞发生在后端应用中,是后端安全问题,跨站脚本攻击(XSS)则是前端安全问题,因为它发生在用户的浏览器里。

除了从安全问题发生的区域来分类之外,也可以从另一个维度来判断:针对某个安全问题,团队中的哪个角色最适合来修复它?是后端开发还是前端开发?

总的来说,当我们下面在谈论“前端安全问题”的时候,我们说的是发生在浏览器、前端应用当中,或者通常由前端开发工程师来对其进行修复的安全问题。

8大前端安全问题

按照上面的分类办法,我们总结出了8大典型的前端安全问题,它们分别是:

  • 老生常谈的XSS
  • 警惕iframe带来的风险
  • 别被点击劫持了
  • 错误的内容推断
  • 防火防盗防猪队友:不安全的第三方依赖包
  • 用了HTTPS也可能掉坑里
  • 本地存储数据泄露
  • 缺失静态资源完整性校验

由于篇幅所限,本篇文章先给各位介绍前4个前端安全问题。

老生常谈的XSS

XSS是跨站脚本攻击(Cross-Site Scripting)的简称,它是个老油条了,在OWASP Web Application Top 10排行榜中长期霸榜,从未掉出过前三名。XSS这类安全问题发生的本质原因在于,浏览器错误的将攻击者提供的用户输入数据当做JavaScript脚本给执行了。

XSS有几种不同的分类办法,例如按照恶意输入的脚本是否在应用中存储,XSS被划分为“存储型XSS”和“反射型XSS”,如果按照是否和服务器有交互,又可以划分为“Server Side XSS”和“DOM based XSS”。

无论怎么分类,XSS漏洞始终是威胁用户的一个安全隐患。攻击者可以利用XSS漏洞来窃取包括用户身份信息在内的各种敏感信息、修改Web页面以欺骗用户,甚至控制受害者浏览器,或者和其他漏洞结合起来形成蠕虫攻击,等等。总之,关于XSS漏洞的利用,只有想不到没有做不到。

如何防御

防御XSS最佳的做法就是对数据进行严格的输出编码,使得攻击者提供的数据不再被浏览器认为是脚本而被误执行。例如<script>在进行HTML编码后变成了&lt;script&gt;,而这段数据就会被浏览器认为只是一段普通的字符串,而不会被当做脚本执行了。

编码也不是件容易的事情,需要根据输出数据所在的上下文来进行相应的编码。例如刚才的例子,由于数据将被放置于HTML元素中,因此进行的是HTML编码,而如果数据将被放置于URL中,则需要进行URL编码,将其变为%3Cscript%3E。此外,还有JavaScript编码、CSS编码、HTML属性编码、JSON编码等等。好在现如今的前端开发框架基本上都默认提供了前端输出编码,这大大减轻了前端开发小伙伴们的工作负担。

其他的防御措施,例如设置CSP HTTP Header、输入验证、开启浏览器XSS防御等等都是可选项,原因在于这些措施都存在被绕过的可能,并不能完全保证能防御XSS攻击。不过它们和输出编码却可以共同协作实施纵深防御策略。

你可以查阅OWASP XSS Prevention Cheat Sheet_Prevention_Cheat_Sheet),里面有关于XSS及其防御措施的详细说明。

警惕iframe带来的风险

有些时候我们的前端页面需要用到第三方提供的页面组件,通常会以iframe的方式引入。典型的例子是使用iframe在页面上添加第三方提供的广告、天气预报、社交分享插件等等。

iframe在给我们的页面带来更多丰富的内容和能力的同时,也带来了不少的安全隐患。因为iframe中的内容是由第三方来提供的,默认情况下他们不受我们的控制,他们可以在iframe中运行JavaScirpt脚本、Flash插件、弹出对话框等等,这可能会破坏前端用户体验。

如果说iframe只是有可能会给用户体验带来影响,看似风险不大,那么如果iframe中的域名因为过期而被恶意攻击者抢注,或者第三方被黑客攻破,iframe中的内容被替换掉了,从而利用用户浏览器中的安全漏洞下载安装木马、恶意勒索软件等等,这问题可就大了。

如何防御

还好在HTML5中,iframe有了一个叫做sandbox的安全属性,通过它可以对iframe的行为进行各种限制,充分实现“最小权限“原则。使用sandbox的最简单的方式就是只在iframe元素中添加上这个关键词就好,就像下面这样:

<iframe sandbox src="..."> ... </iframe>

sandbox还忠实的实现了“Secure By Default”原则,也就是说,如果你只是添加上这个属性而保持属性值为空,那么浏览器将会对iframe实施史上最严厉的调控限制,基本上来讲就是除了允许显示静态资源以外,其他什么都做不了。比如不准提交表单、不准弹窗、不准执行脚本等等,连Origin都会被强制重新分配一个唯一的值,换句话讲就是iframe中的页面访问它自己的服务器都会被算作跨域请求。

另外,sandbox也提供了丰富的配置参数,我们可以进行较为细粒度的控制。一些典型的参数如下:

  • allow-forms:允许iframe中提交form表单
  • allow-popups:允许iframe中弹出新的窗口或者标签页(例如,window.open(),showModalDialog(),target=”_blank”等等)
  • allow-scripts:允许iframe中执行JavaScript
  • allow-same-origin:允许iframe中的网页开启同源策略

更多详细的资料,可以参考iframe中关于sandbox的介绍

别被点击劫持了

有个词叫做防不胜防,我们在通过iframe使用别人提供的内容时,我们自己的页面也可能正在被不法分子放到他们精心构造的iframe或者frame当中,进行点击劫持攻击。

这是一种欺骗性比较强,同时也需要用户高度参与才能完成的一种攻击。通常的攻击步骤是这样的:

  1. 攻击者精心构造一个诱导用户点击的内容,比如Web页面小游戏
  2. 将我们的页面放入到iframe当中
  3. 利用z-index等CSS样式将这个iframe叠加到小游戏的垂直方向的正上方
  4. 把iframe设置为100%透明度
  5. 受害者访问到这个页面后,肉眼看到的是一个小游戏,如果受到诱导进行了点击的话,实际上点击到的却是iframe中的我们的页面

点击劫持的危害在于,攻击利用了受害者的用户身份,在其不知情的情况下进行一些操作。如果只是迫使用户关注某个微博账号的话,看上去仿佛还可以承受,但是如果是删除某个重要文件记录,或者窃取敏感信息,那么造成的危害可就难以承受了。

如何防御

有多种防御措施都可以防止页面遭到点击劫持攻击,例如Frame Breaking方案。一个推荐的防御方案是,使用X-Frame-Options:DENY这个HTTP Header来明确的告知浏览器,不要把当前HTTP响应中的内容在HTML Frame中显示出来。

关于点击劫持更多的细节,可以查阅OWASP Clickjacking Defense Cheat Sheet

错误的内容推断

想象这样一个攻击场景:某网站允许用户在评论里上传图片,攻击者在上传图片的时候,看似提交的是个图片文件,实则是个含有JavaScript的脚本文件。该文件逃过了文件类型校验(这涉及到了恶意文件上传这个常见安全问题,但是由于和前端相关度不高因此暂不详细介绍),在服务器里存储了下来。接下来,受害者在访问这段评论的时候,浏览器会去请求这个伪装成图片的JavaScript脚本,而此时如果浏览器错误的推断了这个响应的内容类型(MIME types),那么就会把这个图片文件当做JavaScript脚本执行,于是攻击也就成功了。

问题的关键就在于,后端服务器在返回的响应中设置的Content-Type Header仅仅只是给浏览器提供当前响应内容类型的建议,而浏览器有可能会自作主张的根据响应中的实际内容去推断内容的类型。

在上面的例子中,后端通过Content-Type Header建议浏览器按照图片来渲染这次的HTTP响应,但是浏览器发现响应中其实是JavaScript,于是就擅自做主把这段响应当做JS脚本来解释执行,安全问题也就产生了。

如何防御

浏览器根据响应内容来推断其类型,本来这是个很“智能”的功能,是浏览器强大的容错能力的体现,但是却会带来安全风险。要避免出现这样的安全问题,办法就是通过设置X-Content-Type-Options这个HTTP Header明确禁止浏览器去推断响应类型。

同样是上面的攻击场景,后端服务器返回的Content-Type建议浏览器按照图片进行内容渲染,浏览器发现有X-Content-Type-OptionsHTTP Header的存在,并且其参数值是nosniff,因此不会再去推断内容类型,而是强制按照图片进行渲染,那么因为实际上这是一段JS脚本而非真实的图片,因此这段脚本就会被浏览器当作是一个已经损坏或者格式不正确的图片来处理,而不是当作JS脚本来处理,从而最终防止了安全问题的发生。

更多关于X-Content-Type-Options的细节请参考这里

小结

本文对前端安全问题进行了一次梳理,介绍了其中4个典型的前端安全问题,包括它们发生的原因以及防御办法。在下篇文章中,我们将介绍其他的几个前端安全问题,敬请期待。


更多精彩洞见,请关注微信公众号:ThoughtWorks商业洞见

Share

Build Security In PII

引子

很多年前,我沉迷在一款名叫《魔兽世界》的游戏中,不幸的是,我使用了Yahoo的邮箱来注册游戏账号。大约在2013年的某天,因为密码错误,我发现自己已无法登陆,同时,注册游戏账户的邮箱也被人修改了密码。不出所料,经过繁琐的手续找回密码后,发现自己已损失惨重,这直接导致我放弃了这款游戏。

不久就看到“Yahoo丢失了大量账户(一说500万账户被泄露,另一说则高达10亿)”的新闻,对于Yahoo来说,这只是业务江河日下的开始。不幸的是,在我们的生活中,只有危机发生后我们才开始重视,进行补救、修复、挽回、公关等工作,在安全领域预防危机是非常难的,而且也是经常被忽略的。我们常常会被一个简单的逻辑思路所误导:我们的系统看起来没有任何问题,为什么我需要安全保护呢?

作为一个用户,我们每天都在承受隐私被泄露的痛苦:

  • 你的手机是否天天收到垃圾短信?是否被猎头各种骚扰?
  • 你的QQ 、微信是否被广告、微商、奇怪的好友申请围绕?
  • 在使用一个邮件去注册各种服务,该邮箱总会被垃圾广告填满?
  • 只要联系过一次租房中介,每天都会被各种中介的电话亲切的问候?
  • 在某搜索引擎上搜索了贷款,第二天被各种贷款、保险电话骚扰?

诚然,也许对于用户来说,保护自己的隐私或者尽早的适应隐私泄露的生活才是最重要的,但是矛盾之处在于,现代社会是建立在合作分工基础上的,你必须提供自己的身份信息来获取服务。对于服务的提供者(企业),保护个人隐私数据已经是一个社会责任,这会影响到用户的信任、企业的声望,特别是对于金融、审计、房产、航空、医疗等行业。

图 1 – 我们可以为可能到来的无隐私时代做点什么?

PII是什么?

PII是Personal Identifiable Information的全称,也被称为SPI(Sensitive Personal Information),从这个名字中我们可以读出三个关键点:

  • 敏感的
  • 标识的
  • 个人相关

总结就是,PII可以用来识别出个体的信息。直接的PII信息有全名、地址、邮件地址、身份证、信用卡、电话号码等等,也有些信息是潜在的PII信息,比如经过简单的组合就可以识别出个体的信息,全名、省份、街道、年龄、性格、种族等。有这样一个著名的例子:1990年,87%的美国人可以被性别、邮政编码,以及出生年月所识别出。

在一个房地产应用中,使用服务的人分为两类:中介和客户,大量的用户都有强烈的买房欲望,用户群集中、多样性不高,如果泄露了这些优质用户的联系方式,有竞争关系的中介就会获得一个优质用户的联系列表,并且很可能直接骚扰用户,显而易见的后果是评价降低、带来公关危机、罚款以及用户流失。特别是在北美、欧洲、澳洲等发达地区,健全的法规对企业的约束与惩罚是非常严厉的,罚款往往是一个天文数字。

图2 – email_address 永远是存在最广泛的PII信息,可以思考一下,我们是否可以不需要该字段就完成我们的业务呢?

危害

最近出现的一个新闻就是美国选举人信息泄露问题,由于数据库的错误配置,大约有2亿选民身份被泄露,大约有1.8T的数据量,泄露的身份占美国人口63%。泄露的数据包括姓名、出生日期、住址、电话号码以及选民注册细节信息,很难计算这样的数据泄露所造成的危害,但对于Deep Root Analytics这样的大数据分析的公司,声望的损失无法估量。

所以,当PII泄露后,最大的危害是大量的经济损失,包含有政府管理部门的罚款(往往伴随着法律问题)、对于用户的补偿、以及清理breach的各种成本。公关部门将会彻夜忙碌,开发部门天天加班,而管理人员则需要更新管理规范等,损失所产生的骨牌效应是无法预计的。2011年SONY PSN账户泄露造成了1.71亿美元的损失,SONY为每个用户的数据丢失付出了1.67$的代价。

在Ponemon Institute与IBM的报告《2017 Cost of Data Breach Study》中,每条丢失或被盗的记录的平均成本是$141。而且该报告中并不包括知识产权、商业秘密等高价值信息资产泄露的损失。数据永远是无价的。

即使像ThoughtWorks这样一个提供软件服务的公司,我们也需要为客户应用的安全提供更好的保护,并且如果暴露出隐私问题,很可能会带来法律责任。回到选举人泄露问题,这也说明了很多非专业的客户(政府、银行、保险、医疗等)并没有能力保护好自己的数据,对于一个专业的提供软件服务的公司,我们更需要替客户考虑周到,并且规避风险。

图 3 – 一旦使用用户的信用卡数据, PCI标准便是一条红线,不能让信用卡在你的服务中裸奔

Build Security In PII

我们在和一家审计行业的领先企业的长期合作中培养出了更高的隐私保护意识,资深的业务人员与安全技术人员会不断的分享关于隐私保护的知识,正如同其他的安全措施一样,所有的风险、漏洞都是存在在细节中的,只有意识上重视才能在工作中避免出现问题。

当意识一旦建立完毕后,开发人员、项目管理者等角色会主动引入PII信息保护到具体的业务设计、架构设计等,我们的工程师会主动确认、问询、double check PII。

对于一家审计行业的巨头,保护客户的隐私并且遵守法律的规定是极为重要的,他们也非常乐意与我们在合作中将隐私保护做到最好。同时,也很赞赏我们为隐私保护所作出的努力。我们要在和客户的长期合作中建立出对于PII的重视,在策略、法律、长期合作的基础上做到合理的保护PII。在顶层角度,我们输出两点:

建立意识:

保护PII是一个需要长期建立的意识,特别是对一些长期发展的项目中,需要每一位参与项目的人都要清楚的了解到PII是什么、为什么要保护它,要提高它的重要性,这个意识不应该随着人员流动而变的淡薄。目前在一个房地产信息项目中,如果需要新启动小项目,对项目中PII数据的识别、分析、提出保留策略等都会由组员所提出,并且提醒。在开发、测试等等环节中,参与的人员都需要按照之前讨论的策略对PII进行检查等。这些行为都是自发的,是由重视的意识所驱动的。

解决方案:

我所收集到的解决方案基本涵盖了PII数据的生命周期,有些解决方案关注于顶层策略,在战略层级制定PII的保护策略,有些则是需要开发新的系统、功能来维护数据安全,还有些是清理已有系统中的风险。同样,例如数据库加密,入侵检测等等这些基础设施上的保护功能也是可以帮助我们保护PII的。总体来说,在合适的层级、场景我们都需要有类似的解决方案。也可以把自己作为入侵者,来思考如何保护系统中PII的数据。

图4 – BSI 所提出的方法论

制定 Policy

一般来说,整体考虑PII的问题需要从制定顶层policy做起,首先必须明确一点:企业的雇员必须通过PII数据完成工作,如果雇员不需要用该数据进行工作的话,那么他就不应该接触到PII,进一步讲,就是不需要感知到PII的存在。销售人员需要给不同的客户发送促销通知,那么他就必须要知道用户的邮件地址。所以,将PII数据彻底的清除掉是不现实的。

在2017年6月1日施行的《中华人民共和国网络安全法》中,安全法规定了账号实名的法规,所以很多应用都需要更新以适应。不同的国家和地区对于个人隐私信息都是有明确法律法规的,所以也是必须要考虑的。

制定数据传输的规则和政策也是必要的,特别是在很多应用需要依赖于外部服务的情况下,我们需要考虑哪些数据是可以传输给外部服务的。很多应用都使用了log center来收集应用的日志,往往这些log center是三方所提供的服务,工程师们希望有详细的日志来帮助分析问题,所以很有可能将用户名、密码、邮箱地址等PII信息上传上去。这些PII数据就处于不可控的状态,提高了泄露风险。

我们也需要考虑数据聚合、备份等情况。某公司每天都会backup自己的数据库,但是所dump出的数据库备份,并没有做好权限保护,这也会造成泄露PII的风险(MySQL dump造成了大量的数据泄露,我们往往重视数据库的保护却忽略了备份);Dropbox曾经犯过一个错误,由于错误的保存了用户数据的聚合(一个xlsx表格),某员工的账号被入侵,造成了6800万个账号信息泄露。特别是在扁平化的组织中,员工的账号都有很大的权限,这也为身份安全提出了新的挑战,当然这些挑战在安全领域都有很好的解决方案,很多安全领域的solution都可以帮助我们降低PII泄露的风险,即使该solution不是针对PII的。

一旦我们保留PII信息的策略发生变更,我们需要更新User Agreement以通知用户,简单的来说,如果用户不同意我们的策略,我们就不能提供服务。现代应用往往都有很多客户端,怎样将User Agreement推送给用户,并且保证用户阅读并同意是一个关键点。可以参考的是iOS更新,每次更新都会加入User Agreement的改动,并且只有将滚动条移动到最后才能进行升级操作。User Agreement不仅仅是对用户的声明,也可以保护企业规避部分法律风险。

总体来说,制定PII保护的Policy需要有四个步骤:

  1. Find:找到系统中持有的PII数据,以及需要解除或者使用PII数据的角色。
  2. Arrange:分析并整理数据,哪些是必要的,哪些是不必要的,哪些的权限需要更新,而哪些存放在三方服务中等等。
  3. Create:根据整理到的数据建立policy,包含有action。例如:我们不希望在日志中保留用户的信息,应该修改日志记录的内容,同时处理掉已有的数据中的 PII。
  4. Educate:将制定的policy通知给相关的人员,确保所有人都清楚我们的策略。

考虑PII数据的生命周期

之前我们是通过组织结构来规划我们的PII保护策略的,也可以使用另一种角度去达到目的,就是紧跟PII数据的生命周期。我们可以将数据生命周期表示为:存储、处理、传输,PII数据永远都是在这三个状态中进行转换,于是我们提出以下五个步骤来处理PII:

  1. 考虑哪些数据是必要的,收集并持有必要的数据
  2. 根据我们的隐私策略,如何持有、处理这些PII数据(例如加密、权限设置、敏感字符替换等等)
  3. 根据新的风险调整策略,并且演进业务逻辑
  4. 合理的规划保护PII数据的每一个步骤(细化)
  5. 销毁不必要的数据,包括 backup,log甚至audit report

例如我们在开发一个提醒用户房产项目更新的服务时,在项目启动阶段,我们就会考虑到该系统会使用到哪些PII的数据,由于我们要给用户发送邮件和推送,用户的邮件地址与设备id就是PII,而信息中往往也含有用户的全名,我们必须要使用这些数据。所以问题就变成了我们如何持有、消费、销毁这些数据。

最少一个追踪邮件是否送达的数据表中,只需要知道邮件的标记就足够了。对于BA想看到的审计数据,也需要经过处理,例如展示收到邮件最多的地址时,我们可以使用wildcard来替换掉邮件地址中的部分字符。在开发过程中,需要注意的是不要在日志、监控这样的地方泄露PII,部署中也得考虑数据库加密、线上环境的权限配置等等工作。总而言之,在这个服务中,系统是需要知道邮件的目的地址的,而雇员、工程师、其他人则是不需要的,所以PII应该设计为对这些人不可见。

图 5 – dump file永远都是十分危险的,无数数据都是通过mysql dump泄露的

总结

PII数据保护是一个范围很大、优先级很高的事情,最重要的意识是根据大量的教育、分享、实践所build出来的。同时,PII也是信息安全的重要组成部分,我们希望不论是在交付还是在咨询项目中,我们能够考虑到了PII信息,也给出了较好的解决方案,则会提高我们的声望。而PII泄露的事故正如很多信息安全故事一样,如果不出事故则不会被重视,但是一旦出现事故,结果往往则是无法挽回的。保护PII,不仅是保护客户的利益,也是保护我们自己。


更多精彩洞见,请关注微信公众号:思特沃克

Share

在医疗健康领域引入软件开发安全实践

BSI简介

“Build Security in DNA”简称BSI,是在开发过程中内置安全的软件开发实践。 顾名思义,BSI是要将各种安全措施从早期就纳入到软件开发生命周期的每个阶段; 因此,安全是内建的,而不是事后补齐的。通过早期引入这些实践并在整个开发生命周期中进行审查,团队会更早地考虑到安全性的问题并尽早收到反馈。这让团队获得了更多的时间和选项来响应和预防安全问题。

下图描绘了BSI的实现。 我们将安全性作为敏捷开发过程的一部分,在每次迭代中逐步建立和完善我们的安全措施。

通过在软件开发生命周期中添加各种安全措施,安全风险的反馈渠道增加了,安全问题反馈周期缩短了,因此安全问题可以立即得到反馈且进入持续改进的闭环。 通过在业务分析过程中引入威胁建模,可以在某些潜在的安全问题出现之前就主动将其避免掉,从而做到防范于未然。

项目背景

与Clinton Health Access Initiatives(CHAI)合作,我们开发了Electronic Stock Management System(ESMS),这是一个安卓平板APP,其后端对接开源医疗物流平台OpenLMIS,致力于为莫桑比克的患者提供更好的医疗服务。 ESMS有两个主要目标:首先是通过提供用户友好的数字解决方案和自动计算表单来减少医疗工作者的工作量;二是及时、准确的收集药品库存信息,并生成报告,以协助卫生部门来规划、分配、运送药物给卫生站。

如果系统存在安全问题就可能影响到医疗机构运送药物的及时性,进而延缓病人的治疗; 所以确保系统安全是项目团队最重要的工作之一。

引入BSI实践

BSI可以从早期就开始提高软件的安全性,并确保安全问题能得到正确的处理。来看看我们在莫桑比克使用OpenLMIS为CHAI所做的项目的一些例子。该项目在BSI引入时已经处于第二阶段了,其大多数功能已经开发完成。基于这种情况,我们把BSI中的活动重新按优先级排了序,首要做了以下工作。

安全培训工作坊

BSI的主要思想之一是,安全性不仅仅是外部信息安全团队或安全顾问的责任,而是交付团队中的每个人都应该了解的事情。 我们针对Open Web Application Security Project (OWASP)的十大安全问题举办了为期一天的工作坊。ThoughtWorks的安全顾问为项目中的各种角色:开发人员,质量分析师和业务分析师都提供了培训内容。以下是我们向与会者介绍的问题。

在工作坊期间,安全顾问为每个问题解释了定义、概念、理论、行为和预防性解决方案,然后通过实例说明了这些内容,以便与会者理解这些问题产生的后果。工作坊的内容还包括与会者现场上手实操OWASP ZAP和Burp Suite等工具,以此来体验如何排查安全问题。 这次工作坊为开发阶段引入BSI实践打下了良好的基础。

安全性功能测试

安全性功能测试应该内建在质量保证流程中。安全性功能测试涉及身份验证和授权(登录/退出、忘记密码、用户管理等)。根据工作坊介绍、讨论的概念和工具,团队成员和安全顾问一起进行了安全功能测试,涵盖用户访问控制,会话到期等方面。这些测试是手动进行的,并添加了针对这些场景的自动化测试,以确保未来的改动不会再次引入这些问题。

我们发现在一些最常用的功能中存在安全问题,例如在用户注销后会话没有关闭,或非管理员用户能够查看管理员的内容等。

根据优先级排名中的位置,团队成员修复了这些安全问题,完成了一个问题检测和消除的闭环。

渗透测试

渗透测试用于分析系统以识别弱点、技术缺陷或漏洞。从攻击者的角度检查系统,了解什么可能危及系统的安全性。安全顾问与质量分析师合作分析了所有的用例,发现了更多的问题。 例如,登录功能可能会受到暴力攻击,或者可能会通过提交大量数据来攻击,导致拒绝服务。与安全功能测试活动类似,团队修复了这些发现的问题。

代码安全审查

基于安全顾问引入的安全编程原则和指导,团队进行了安全代码审查。 重点放在以下几个模块上:认证/授权,日志记录,密码保护。发现的所有问题都记录在了Mingle的技术卡或缺陷卡里。然后,团队给这些卡排列了优先级,并采取适当的措施来消除或减轻了问题;例如,如果我们发现密码是使用哈希算法存储但没有加盐(salt),那么团队会建一张技术卡,并给予其高优先级,以便在下一次迭代中首要修复该问题。

结论

每一个软件项目都应该从一开始就考虑安全性问题。现在大多数企业级软件都连接到了互联网上,安全性就尤为重要。联网应用的增多是一种趋势,这就增多了可被攻击的潜在目标,安全风险也会随之而来。在开发阶段没有足够的安全保护措施将对项目的长期运行产生负面影响。

反馈周期过长

一般来说,安全问题是在渗透测试阶段显露出来的,有时甚至是应用程序上线后才发现。这样问题的发现、报告和解决要花费很多的时间。

修复成本高

如果是在软件项目的晚期阶段才发现安全问题,软件体系结构已经定型并实现了,这时修复问题就变得额外困难。

BSI可以在开发阶段提高软件的安全性。BSI的目标是在软件发布前,通过业务与技术的手段来确保安全性。

没有绝对的安全,BSI并不能保证系统是完全安全的。然而,对于会向着更大更复杂方向演进的软件系统而言,BSI的安全软件开发过程肯定可以从源头控制安全风险,大大降低黑客攻击的可能性,并显著降低软件投产后安全问题所造成的损失。

作者:刘庆华、崔鹏飞


更多精彩洞见,请关注微信公众号:思特沃克

Share

为数字化企业注入安全基因

 

企业面临的安全挑战已经发生改变

如今,越来越多的企业选择部署移动技术和数字化来强化自己的业务,传统的业务模式在新的技术革命中面临新的安全问题和挑战。这些挑战集中体现在如下几个方面:

第一,固守网络边界安全难以达到预期的效果。传统的安全思路是,在网络边界实行严格的访问控制、部署网络防火墙、入侵检测以及入侵防御系统等,企业以为这么做足以高枕无忧,但实则是被安全的假象所包围。近年来,黑客渗透进入企业内网,绕过网络防火墙,通过IT系统漏洞获取最高执行权限、下载敏感数据,种植木马病毒等攻击事件层出不穷。

更何况,随着云技术的快速发展和大量使用,传统的企业网络边界正变得越来越模糊,这势必给固守边界安全这种方式带来更大的挑战。

第二,应用防火墙存在天花板效应。和网络防火墙侧重在网络层做防御有所不同,应用防火墙则是在应用层入手,扮演门卫的角色以保护IT应用。但随着企业在数字化道路上的不断前行,企业IT应用数量和业务复杂度都在持续增长,这使得管理维护应用防火墙安全规则的难度也在不断加大。当这种难度大到难以掌控的时候,应用防火墙便遇到了天花板,例如谁也不知道某条安全规则为何存在,谁也不敢轻易去修改安全规则,谁也不敢添加新的安全规则,因为有可能会对正常访问造成误杀等等。此时本来是为企业安全保驾护航的应用防火墙,反而成了企业数字发展的瓶颈。

除了安全规则的管理维护难度大之外,无论是网络防火墙还是应用防火墙,都无法彻底解决漏报和误报的问题。误报对用户体验是种伤害,然而更为严重的是,由于安全的特殊性,一次漏报就有可能造成后续的安全事件。

第三,在提倡持续交付、DevOps以及通过MVP基于市场反馈进行快速改进的开发部门面前,偏好实施安全控制和审计的传统安全部门无法跟上开发部门的快速开发节奏。随着敏捷精益、持续交付、DevOps等理念和技术的发展,开发部门可以做到一天之内数次发布产品。例如,早在2014年的时候,亚马逊平均每秒就有一次以上的产品部署,每天如此。在这种情况下,安全部门如何跟上开发团队的速度?如何在快速变化当中了解即将发布的IT应用的安全情况?

这些挑战使得安全成为了企业数字化转型中“最薄弱的一环”,在日益复杂的未来环境中面临严重风险。大部分企业认为自己有能力抵御网络攻击,可实际情况是,企业安全问题已经迫在眉睫,很多安全公司对企业安全是持悲观态度的。

安全领域的资源投入出现了严重错位

根据企业规模和行业的不同,安全在IT投资中的占比也不同。一般而言安全投资的比例会占到5%-8%,金融行业略有不同。大部分的资源被投入到了IT基础设施安全(例如,网络、服务器、数据安全)。而安全风险越来越突出的应用安全方面,却存在着严重的不足。

伴随投入占比失衡的问题,更加突出的是安全技术的变化,现在的安全威胁已经由传统的病毒木马、系统漏洞、缓冲区溢出攻击转变为虚拟机安全,激动安全,APT攻击,DDoS攻击等。这些攻击带来的安全风险和威胁也随之加剧。比如携程网信用卡泄露事件,从表面上看是Web页面上的漏洞所致,漏洞的产生主要是由于产品在其App端调试的过程中便开发了整个目录的遍历,由于开发过程中安全控制不足,上线后黑客能够巧妙的绕过服务器的权限访问到文件系统的其他部分。此次安全漏洞可导致用户个人信息、银行卡信息等泄露。由于发现及时,最后得以控制和限制。但这件事给越来越多的成长中的企业以警示。使得更多的企业在面临数字化创新、求新求变的同时,将安全放在重中之重的地位。

金融行业是安全风险和攻击出现的重灾区,以银行行业为例,银行为了更多地吸引客户和方便客户,开通了网上银行业务,由于任何用户都可以通过互联网访问业务系统,因此网上银行系统存在来自互联网各种攻击的安全风险,这种风险在P2P行业盛行的中国尤为突出。

图1:安全风险和对应的投资呈现出严重错位

企业中的绝大多数数据访问都是通过应用程序进行访问的 。根据Gartner统计,现有的攻击中80%的网络攻击也是发生在应用层。面对新的安全形势,企业若不采取有效措施加以应对,应用程序中的安全漏洞一旦被公之于众,必将对业务造成破坏性影响,使企业陷入竞争不利的局面。一般应对此类安全问题的措施是采用应用层防火墙做一些基础性的防护,系统性地测试和扫描所有应用,通过特征库来区分安全威胁和风险,这种控制的方式存在误报率高、问题发现不彻底的缺陷。要解决应用层安全的问题,最佳的方式是在软件开发的过程中,根据软件和应用的特性,在应用开发的过程中解决安全风险。

另外一个普遍的现象是,虽然有不少常见的安全措施可以采纳,但其实大多数企业依然是在依靠防火墙来阻挡攻击,用渗透测试来暴露安全漏洞。随着安全挑战的变化,这些传统措施的抵御力越来越低。

防火墙的主要职责是阻挡攻击,为开发团队争取修复漏洞的时间,而并非取代漏洞的修复工作。换言之,只要应用中导致安全问题的代码没有被修复,漏洞就会一直存在,一旦防火墙规则被绕过,或者配置不当,反而会将应用置于更高的安全风险当中。此外,误报和漏报始终是防火墙无法彻底解决的问题。

至于上线后的渗透测试,它确实能发现安全漏洞,但是也存在着明显的不足。通常而言,渗透测试会被安排在应用上线发布之前进行,此时如果检查出安全漏洞,企业反而会面临两难的境地:修复安全漏洞之后再发布应用可能导致项目延期,错失市场机会;如果强行发布含有安全漏洞的应用,又将提高被黑客攻击利用的风险。

数字化企业,需要注入安全基因

为了更好的应对新的安全挑战,做好应用的安全防护势在必行。不过,在介绍具体做法之前,让我们先看看为何企业采纳了众多安全措施,可开发出来的应用中依然存在不少安全漏洞,就像顽疾一样无法彻底根除。

应用中的安全漏洞是在开发过程中由于各种原因被引入的,然而回顾现有的安全措施就会发现,许多措施并没有被作用于开发过程中。例如防火墙、安全监控发生在应用上线之后,渗透测试需要在开发完毕后才能进行,而安全培训、安全规范只能起到预防作用。正因如此,安全问题从引入到被发现,间隔很长,使得安全问题不能被及时的反馈给开发团队。

建议的做法是,在开发团队中建立起一个高效的安全反馈机制,在开发过程中引入安全活动,尽早开始收集安全反馈信息,加快获取安全反馈的速度,在整个开发过程中持续关注应用的安全性,与此同时团队成员共同来承担安全职责。ThoughtWorks将这些在实践中总结出来的经验命名为©Build Security In DnA(下文简称BSI,http://www.buildsecurityin.net),从源头上尽早、尽快、持续性的、以团队共同协作的方式发现并解决安全问题。

图2:Build Security In 内检安全基因

越早获取到安全反馈信息,越有利于开发团队以更低的成本将其修复。与其依赖于项目后期的渗透测试,不如在开发过程当中引入一些适当的安全实践,比如在分析业务需求的同时主动分析安全需求,将其作为质量验收标准在团队内明确出来,再比如,对代码进行安全评审、测试人员在测试业务功能的同时还对安全性进行验证。通过这种方式,使得团队能够尽快的知应用的安全状况,而不必依赖于很晚才能提供安全反馈的渗透测试。

图3:在开发过程当中引入安全实践

对于常规的安全测试完全可以借助工具以自动化的方式进行,不仅能够以更快的速度得到安全性反馈,还能在一定程度上弥补由于人员安全技能不足所造成的安全测试不够全面的问题。此外,自动化带来的另外的好处是,它可以集成入CI服务器,从而让开发团队可以利用CI流水线在第一时间发现应用的常规安全问题并及时修复。

收集安全反馈不是一次性的活动,高效的安全反馈机制和持续集成秉持相同的理念:除了尽早集成、尽快集成之外,很重要的一点就是让集成活动能够持续性的发生。类似的,对于建立高效的安全反馈机制而言,在能够尽早、快速的获取安全反馈的同时,还需要让这个反馈循机制在应用开发过程中持续地运行下去。

图4:对安全保持持续性的关注

实施BSI的挑战

我们将BSI在多个大型金融企业里进行了实践探索,而在实施BSI的过程中,我们遇到了各种各样的挑战,其中比较典型的三个如下:

挑战一:安全活动排不上高优先级

企业完全认同IT应用的安全性是数字化战略中不可或缺的一部分,但是具体到BSI实施落地层面,却发现安全活动排不上高优先级,总是会被各种原因不断的往后延期。其中一个常见的说法是,开发团队面临着很大的交付压力,要在规定的发布日期到来前完成计划中的业务功能已经实属不易,没有充足的时间执行安全活动。

出现这样的情况并非是因为开发团队不清楚安全的重要性,这背后潜藏的原因是,某些传统安全活动给开发团队留下了一些不太好的印象,比如说,需要耗费开发团队比较多的时间,或者某些传统安全活动过程繁琐、流于形式,难以产生实际有效价值。再加上实现业务功能永远是开发团队的第一优先级,因此安全活动难以推进执行也是必然的结果。

从我们的实战经验来看,要解决这一挑战,企业可以精心挑选一个试点团队,将其打造成BSI的样板工程,以成功案例的方式让更多的开发团队进一步了解BSI,明白它能够最大限度的借助自动化,提高开发团队在安全活动上的投入产出比,用相对而言更少的时间,更有效的提高IT应用的安全性。

挑战二:传统安全团队的焦虑

传统的IT应用安全运作模式是,每次IT应用在发布上线前,开发团队将其交给安全团队做扫描,安全团队将扫描结果汇总成安全报告并提供给开发团队做修复。在这一模式中,安全团队报告的安全漏洞数量越多,严重性越高,越能体现出自身的价值。

而在实施了BSI后,开发团队承担了更多的安全职责,将原本由安全团队才有能力报告的安全漏洞及时发现并修复了,这使得传统安全团队感到一丝焦虑。想象一下,如果某次安全扫描后,没有在IT应用中发现任何安全漏洞,安全团队到底是应该欢喜雀跃,还是黯然神伤?

BSI是IT应用安全发展的必然趋势,在这个大趋势下,安全团队需要重新思考和调整自己的定位,将关注点从安全漏洞数量,转移到为开发团队提供自动化、自助化的安全服务上来。

挑战三:安全活动如何可视化?

在实施BSI的过程中,我们经常被开发团队问到的一个问题是:我们做了这么多安全活动,仅仅只是我们自己知道它非常有帮助是不够的,如何才能把它可视化出来?

BSI中的每个安全活动都有着明确的产出物,我们可以通过收集整理这些产出物,将其作为基础,通过图表的方式进行可视化。比如,威胁建模会产出一系列安全需求,它们会随着开发的进行逐个被实现。在这一过程中,开发团队可以将当前已完成的安全需求、未完成的安全需求的数量以燃尽图的形式展示出来。再比如,开发团队可以持续统计通过自动化安全测试发现的安全漏洞数量,依然以图表的形式进行可视化。

通过BSI安全成熟度模型来对企业或者某个开发团队的安全实践进行评估,并且将其结果可视化出来也是一个不错的选择。不仅如此,企业还能通过这个办法,从中识别出当前面临的安全短板,为开发团队设立安全改进目标提供帮助。

在数字化革命面前,金融企业业务的正常运转必然将高度依赖于IT应用的可靠运行,IT应用的安全性将对企业产生重大影响。企业有必要通过BSI这种内建安全的方式,尽早发现安全问题,利用自动化的优势缩短安全问题的反馈周期,持续的、以共同协作的方式主动预知并化解安全问题。

 

作者介绍:

马伟:ThoughtWorks高级咨询师、企业应用安全高级咨询顾问,BSI的实践者。

杨璐:ThoughtWorks首席咨询师,曾服务于IBM和埃森哲咨询部门,为多家跨国公司和机构提供过安全咨询服务。

 

Share

别再依赖安全扫描了

本文中的“安全扫描”是指开发团队在距离产品上线日期比较近的时候,通过公司里的安全团队或者外部第三方安全公司对产品进行安全扫描,团队基于安全扫描报告,对产品中存在的安全漏洞进行修复的过程。不同的公司,不同的开发团队对它的称呼可能不一样,有人把它叫做渗透测试,也有人把它叫做安全审查、安全评估、安全检查等等。

如果不做安全扫描会怎样?

想象一下,你所在的开发团队正在开发一款互联网金融产品,所有的核心业务功能基本开发完毕。此时此刻,离计划中的上线日期只有不到三周时间。通常而言,这时候安全扫描就会介入进来,扫出一堆问题扔给团队修复。

safe

不过这次不一样,如果我提议,不必给产品做安全扫描,就这样直接上线可好?我想,绝大多数人的反应会是下面这样的:

“神马?!不做安全扫描?那我怎么知道产品安不安全?万一出问题了怎么办?”

“我知道我们产品中一定会有安全问题,安全扫描正好可以帮助我们把这些问题暴露出来,将其修复之后再上线才是万无一失的选择。”

“虽然每次安全扫描都会扫出一堆问题来,搞得团队压力山大,但如果不做扫描,我们到是轻松了,可产品的安全性却又是个问题。”

“安全扫描可是我们安全团队的杀手锏,不让我们给开发团队做扫描,那我们的价值怎么体现出来?”

“公司规范里说了,不做安全扫描不准上线。”

“年少轻狂的年轻人,我以过来人的经验告诉你,这么做是要付出代价的。”

反应越是激烈,说明团队越是依赖安全扫描。甚至可以说,安全扫描在你的团队里,是保证产品安全的最后一道屏障,也是唯一的手段。

安全扫描是陈旧落后的手段

有人会说,最后一道屏障又怎样,唯一的手段又如何,不管红猫黑猫,抓到耗子的都是好猫。

1123-b

先不谈这样做是好是坏,我们先来换个角度思考一下,如果把“安全问题”这几个字换成“功能缺陷”或者“Bug”,你还会认同这种在临近产品上线之前做一次性的、运动式的大检查,然后期待着开发团队在所剩无几的时间里快速修复掉所有Bug,还不能引入新Bug的做法吗?

答案显然是否定的。大家都明白,功能缺陷越早发现越好,否则修复成本将会非常高,越往后拖越对团队不利。

现如今,还有哪个开发团队敢说,在开发过程中不需要对软件做测试,等到最后上线前做一次集中式的测试就够了?开发团队也是极尽所能的快速响应软件质量问题,例如进行测试驱动开发,编写大量的自动化测试并且通过CI持续的对软件质量进行监控。

安全问题是如此的重要,它也是软件质量的一部分,只不过换了个名字,变了种表现形式而已,而我们却用如此落后的方式来对待它,显然不合理。

提前做安全扫描可能是空中楼阁

foam

又有人说,安全扫描不就是太晚了一点嘛,我们把扫描时间点往前提一些不就好了吗?

思路是对的,但很可惜,要做到这一点却几乎是不可能的。因为安全扫描有一定前提条件,它只能对已经开发完成了的功能进行扫描,这也就意味着,那些还处于开发过程中的功能是覆盖不到的。而且随着开发的进行,软件功能会有所调整,之前做过的安全扫描很可能会失去意义,最终还是得等到所有功能都开发完毕了,在上线之前再做一次最终的安全扫描。于是这又回到了上面那个问题。

安全扫描的短板不止一处

安全扫描除了上面讲到的时间太晚的问题之外,还有不少短板。首当其冲的就是速度太慢,跟不上开发团队的节奏。尽管有自动化工具的帮助,但是一次全面、细致、深入的安全扫描,往往需要好几天,甚至更长时间。在如今追求快速开发上线,迅速调整以响应市场变化的环境下,开发团队没有这么多时间和耐心来等待扫描结果。

某些采用敏捷或者精益开发方式的团队,每个迭代甚至每天都有新功能上线和旧功能调整、问题修复等等,而等到几天甚至几周后,团队拿到安全扫描报告的时候,被扫描的功能可能早就被废弃了,这么做简直是在浪费资源。

sgonot_bloombergfinal_15_2048

其次,留给安全扫描的时间窗口十分有限,它往往只能在产品功能完成之后,最终上线之前才能进行,在这种情况下,往往只有一次机会进行扫描,也只能给团队提供一次性的安全反馈。但实际情况却是,业务需求在不断发展和变化,开发团队也在持续对产品功能做出调整,除非每次产品功能发生变化之后立即进行一次安全扫描,否则以现有的模式,是没有办法及时给开发团队提供安全性反馈的。

最后,安全扫描的成本也是不得不考虑的因素。购买外部安全公司的安全扫描服务到是很方便,可是动不动就是几十万的支出不是任何团队都能承受得起的。通过自有安全团队做安全扫描看上去可能更加经济实惠,毕竟是公司内部资源,但是别忘了,自建安全团队也是有成本的,而且要招到杰出的安全工程师也不是件容易的事情。

既然安全扫描有这么多缺点,那为什么还有如此多的团队在用它?

抛开安全问题暴露出来之后,解决起来是如何痛苦这件事情不谈,其实安全扫描也并非一无是处。

尽管安全扫描在时间上晚了一些,速度上慢了一点,还不可持续,但由于软件开发本身是个复杂的过程,开发团队在产品安全性上总有疏忽大意的时候,只要进行安全扫描,大多数时候都会有所“收获”。这样的话,一方面安全扫描帮开发团队发现了问题,另一方面安全团队也体现出了自身价值,正是在这样的背景下,安全扫描无论是对于开发团队还是安全团队而言,都具有难以抗拒的诱惑力。

此外,有时候做安全扫描也是一种无奈之举,因为有些开发团队不见黄河不死心,除非你把安全问题明确的摆在他们面前,否则他们意识不到问题的严重性,不会轻易的主动去关注安全问题。

除了安全扫描,还有别的什么办法?

既然安全问题这么重要,安全扫描又是如此的低效,那我们该怎么做才能更好的解决这个问题呢?答案其实早就摆在眼前了,软件的安全性是软件质量的一部分,为何不尝试一下把它和功能需求一样,都当做头等公民来看待呢?那些用于保证软件质量的最佳实践对于软件安全性同样适用。

更具效率的做法是,在产品开发的全生命周期里,直接植入安全最佳实践,我们把它叫做Build Security In(简称BSI)。例如,在分析业务需求的时候,主动去分析安全需求,给用户故事建立安全验收标准;在开发过程中时刻关注安全,通过自动化的安全测试持续性的关注产品安全;在测试过程中,不仅测试产品看其是否满足了业务需求,还基于安全验收标准设计并执行安全测试用例。

1-bsi

传统的安全扫描是从后外前推,倒逼着开发团队做改变,而BSI的做法则是从前往后梳理,融入到日常的开发过程中。正是因为提前并且持续性的关注产品安全,所以在后续的开发中,团队才会有意识的去做安全防御,使得最后开发出来的软件默认就已经具备了不错的安全性,给团队带来的冲击和压力也是最小的。

迈出改变的第一步

安全扫描已经深深的烙在了很多开发团队的骨髓里,突然之间要改变这一切势必不容易,但是我们还是可以做很多尝试来逐渐改变这个现状。在这里我推荐一些比较好的切入点,开发团队可以作为参考,迈出改变的第一步。

每当在创建用户故事的时候,多问几个和安全相关的问题,比如:

  • 这个业务需求面临着哪些威胁?
  • 和这个业务需求相关联的安全需求是什么?
  • 有没有什么东西是应该被保护起来的?
  • 应该提前做些什么以应对可能的黑客攻击?

然后,团队共同给这个用户故事设定安全相关的验收标准。

开发人员在每日代码审查的时候,多问一下:“这样设计,或者代码这么写,有没有什么安全风险?安全验收标准满足了吗?”

每当测试人员拿到一张用户故事对其进行测试的时候,也问问自己:“除了测试产品看其是否正确实现了业务需求之外,还需要基于安全验收标准设计并执行哪些安全测试用例?”

上面这些提问看似简单,但是当你在团队里问出这些问题的时候,你一定会惊讶于它们带来的影响力。试试呗。

Share