原创丨志刚(返町)现任美团安全部安全架构师。曾在国内外知名大型互联网公司出任安全专家、架构师等职。在应用系统安全架构评审以及安全方案设计和实施领域拥有丰富的经验。确定一个应用的安全状况,最直接的方法就是安全评审。安全评审可以帮我们发现应用系统中的安全漏洞,也能了解当前系统,乃至整个防护体系中的不足。完整的安全评审会包含安全架构评审、安全代码审核和安全测试三个手段。安全架构评审,着眼于发现安全设计的漏洞,从宏观的视角整体评价一个应用的安全性,快速识别业务系统核心安全需求以及当前安全防护机制是否满足这些需求,是投入产出比最高的活动。因此安全架构评审,直接影响整个安全评审的质量,并为安全编码和安全测试指明重点。
本文通过从方法论到实际模型,对安全架构评审过程进行阐述。不论你是安全从业人员对第三方应用系统进行安全评审,还是作为产品的研发人员、架构师,依据本文提到的方法深入学习、反复实践都能提高自己的架构评审能力。
那么安全架构评审具体看什么? 什么样的安全评审是好的? 是发现越多的漏洞?在解答这些问题之前,我们先简单说一下什么是好的安全架构设计。
安全架构设计是指遵循安全设计的基本原则,在充分理解现有的业务和应用场景,并对面临的攻击威胁充分了解的前提下,正确的部署、使用安全控制技术以满足保护信息资产的安全需求。安全设计的系统不会只着眼于眼前的攻击和已知漏洞,还应该对未知的漏洞0day都具备一定的抵御能力。安全架构评审着眼于设计缺陷,与常规的实现型漏洞存在区别。正本清源,笔者从安全设计基本原则、安全防护框架和安全防护技术栈三个维度说明什么是好的安全架构设计。
安全设计基本原则是网络安全领域经过无数前辈经验的总结,是安全防护理论的高度抽象。他告诉我们,在特定的场景下,什么是正确的做法,为什么这么做。对这些基本的设计原则准确、深入理解,反复在实际工作中实践,是提高架构设计能力的必由之路。纵深防御原则,多年以前就比较盛行,说是防御体系第一原则不为过。具体定义可以参考Cisco的《网络安全架构》以及OWASP的相关定义。其核心思想就是不要依赖单一的防护机制,而要依赖互相补充的多层次、多方位和多角度机制来构建防御体系。这样既能实现防护的灵活性,又能做到防御效果最大化。因为,不管任何一种防御机制,都有其适用场景,也有其局限。这种局限可以表现为其防护的粒度和范围、对使用者的应用和业务的影响以及防护成本,或者运维、效率或者性能方面影响等等。纵深防御体系可以是按照物理-应用不同层级、物理位置不同控制点、外围还是内置、防护时机和阶段等维度部署。良好的部署纵深防御体系,可以保证在一种防护失效时,攻击不轻易得手,或者在部分得手后,损失可控。好的纵深防御系统建设可以给管理者以足够的信心和心理稳定性。
要建立好纵深防御体系,前提是必须对各种防御手段有深入的理解。需要每种防御在其特定的成熟度和指标上能给人以足够的信心,并不是说大家都一锅粥或者认为有了纵深防御,某一部分就可以不做,或者降低要求。我们看到,像Google的纵深防御在每一个细分层次都做到合格乃至极致。即使像Amazon这样业务驱动的公司,也会在每一个环节做到确认和心中有数。
这是一个大家都公认正确,但绝大多数都没有做到的原则。因为从字面上似乎更倾向于管理而非技术手段能实现的。造成这种误解的原因很多,其中主要因素是大家对权限控制还停留在传统的中央集权,人肉申请、审批的认知。随着微服务和DevOps等新框架发展,新型公司在业务上对效率的诉求,使得这种模式不被新兴公司接受。实现最小权限也越来越难。不过随着新一代的权限控制模型ABAC,及与之配套的如Oauth、Federation等控制技术的发展,并在Google、Amazon等大厂的落地,实现分布式、自助或半自动细粒度权限控制成为可能。另外说一句,能否实现最小权限,往往是对一个公司对安全努力程度,以及对应的技术水平的试金石。人是不可靠的,我们更相信机器。默认安全的基本原则就是,让安全一开始就成为内置的属性。如果需要对策略进行放松,你需要额外的工作和努力。这在当下DevOps和微服务架构,处理海量数据、账户以及主机、应用系统场景下尤为重要。因为一个带有漏洞的容器镜像发布出去,可能就意味着几万乃至几十万的主机存在漏洞的副本。默认安全需要大量额外的工作,但这些工作又绝对是值得的。说白了,默认安全更像是一种文化,能给你一个可信的基础架构。这个原则是与纵深防御有关联。在设计安全系统时,需要考虑到你的防护注定会失效,并充分考虑并演练不同的失效场景,确保你的安全性在失效时依然能够得到保证。这点除了通过按纵深防御原则部署你的防控机制外,每个系统事先设计、反复演练失效时的应急预案至关重要。其中保证系统可用性的降级方案,不能牺牲安全性是首先需要考虑的。为了避免安全功能喧宾夺主,你的安全方案设计需要考虑业务生产的实际需要。说到底,安全还是为业务服务的。但注意一点,安全注定要提高成本。然而好的安全性设计,以及应用适当的技术,是能够有效降低这种成本,这也就体现了安全专家的价值。所以,安全要有助于业务,但不是完全为业务让路不作为。另外,有些安全特性本身就是业务,比如隐私、数据保护,本身也是为用户提供保护,提振用户的信心。要想做到适用性,安全专家要充分理解业务和业务所采用的技术,不断学习,与时俱进。这虽然让安全专家这个职业非常具有挑战,但也让安全专家更具有价值和不可替代性。简单说就是不要自创算法。尤其是像加密、认证等关键的安全方案。这里不是说不能创新。外面的算法和实现都已经很成熟,并经历过无数研究、测试。而你自己的东西很大概率没有这方面的积累。当然像Google等顶级公司除外,因为他们可以投入各种专业资源对他们的方案进行验证、测试,而且他们也把一部分开放出来让大家一起验证。即便如此,对于一般的公司,一定不要自创算法。如果真的自创了,那也要经过各种专业的评审、测试。上文所提到的安全原则,最重要的抓手就是安全控制技术,笔者定义为安全武器库。熟悉并构建一套完整、先进强大的武器库是实现良好的安全架构设计的基础。当前有很多框架包括CIS Top20 Controls、OWASP 以及NIST关键基础设施安全框架都给我们列出了控制技术清单。针对安全控制清单,笔者会在后面的章节进一步进行说明。需要说明的是简单的罗列这些技术不是重点,重要的是我们需要准确的评估这些控制技术,并在应用系统,乃至整个企业的场景正确的运用适当控制手段。要想做到这一点,我们需要一套评价体系,对某一特定控制领域的控制技术成熟度进行度量。笔者经过多年安全架构评审和安全体系建设的经验,推荐本章的三大支柱框架。这个框架是笔者的导师,Amazon前首席安全架构师Jesper博士提出的,广泛运用于Amazon内部安全项目、安全架构评审。笔者也在近些年反复实践,融入了自己的理解。这个框架可以通过下图进行说明:这根柱子主要是功能是防控,简称事前。部署好这类安全措施,会防止安全攻击、事件的发生,防患于未然。典型的防护包括防火墙和网络隔离、认证和权限控制、加密等。此外默认安全镜像,标准化配置以及补丁修复,属于清洁保健(hygiene)范畴。这部分是默认安全原则的集中体现。这种防护的效果直接,给防御者最强的信心。但这种方法也是对业务影响最大的:包括业务需要更多的流程,更精细化的访问控制;运维,使用中牺牲一定的便利性和时效性以及安全特性引起额外的工作负载需要更多系统资源,同时导致性能和效率的下降等等。该类控制往往适应成熟度比较高,规则比较清晰的场景。对于灵活度高,动态变化的业务系统,在规则设计中要做到一定平衡。注意,由于其对业务的“负面”影响,又不会看到直接的收益(这部分收益只有做得不好时才会显现出来,例如Facebook今年的用户泄漏事件等等)。这部分需要有安全部门领衔,获得高层的支持,自上而下进行推动。对于快速成长的业务、系统业务逻辑复杂且变化快,安全策略不清晰,防控会大大制约业务的敏捷度、增加运维成本。此时监控将是好的补充。日志、告警和风控系统都属于这个范畴。这类防护的质量主要体现在日志的覆盖率以及告警的响应速度和准确程度。随着大数据和AI技术发展,这类系统在防护体系中作用越来越凸显。再安全的系统,安全事件也不可避免。但通过精心的安全设计,你应该能保证,当单点或者部分防护被攻破时,攻击造成的损失依然可控。例如在加密系统中,按照时间和空间对密钥进行轮换,保证当部分密钥泄漏时只会影响部分数据。或者对账户权限进行细粒度限制,当账户泄漏时,只能影响到部分功能和数据。此外支持SDN的网络隔离机制,无服务器化或者容器化等技术发展,你下掉、隔离被污染的系统、服务的速度和能力,也直接影响你的恢复止损的能力。注意,很多防护技术可能会跨多个领域,如防火墙、认证系统都可以设置成混杂模式。依据纵深防御的原则,你的防护体系设计应该是多重防护并存的。从上图我们看到,越往左,越可控,限制也越大也需要更多的努力;越往右,越灵活,也越混乱。随着业务和安全防护成熟度的提高,应该越发靠近事前防控,事后救火应该越来越少。随着新业务、新特性的引入,这种状态又会发生变化。一个安全系统成熟度越高,表现就在事前防御的比重越大。在评价特定领域特定安全控制技术时,你要清楚评估你的应用和企业当前成熟度水平,这个粒度可以细到具体的每一个细分控制技术或者某一个具体的应用系统。同时针对所面临的风险以及企业的业务需要和企业文化,老板对安全的投入等因素,选择适当的方案。
这里罗列了一些常规的安全控制技术,在关键的信任边界适当的选择这些技术,就能落实应用的安全目标。武器可以自己生产,也可以采购。二者都需要对这些武器具有深入的研究。对应的技术有比较成熟的方案,也有基于新的技术演进。每种技术都有其适用场景,也有自身的缺陷。要想设计出合适的方案,需要在各个领域投入精力研究,并保持与时俱进,知其然还要知其所以然。安全架构评审会帮你发现问题,但这只是安全建设的开始,重点在如何通过可复用的技术解决你的问题。因为每个领域都非常复杂,这里就不展开讨论了,感兴趣的同学可以查询对应领域的专业文献、书籍。● 认证和访问控制:如IAM、会话管理,都属于这一类,是最直接建立网络世界信任的一种机制。原则上,任何跨边界的访问,都需要认证和权限控制。这里又涉及到人机之间的UI和机器间的服务调用两类访问的控制。● 加密:加密是除认证之外数据保护的又一利器,包括传输加密和存储加密。加密方案具有复杂度高、实现难度大、业务影响深的特点。因此加密方案必须精心设计,建议采用外部已经成熟的方案,如TLS/https、KMS/HSM等。此外,加密还是其他防护技术的基础:认证凭据密码、会话ID的创建,保存都需要密码学介入。密码学就提一点,千万别自创算法。● 日志、审计和风控:这块主要属于事中和事后范畴。当下一般企业都有自建日志中心,数据处理能力也都能上升到PB级别。日志能否覆盖所有的访问入口,能否针对异常行为触发告警是一个核心的能力。● 网络隔离:传统的网络防火墙以及主机防火墙,或者网络ACL,这类因为业务无关性,控制效果非常好,但也非常复杂,维护成本高,加上对纵深防御,以及零信任网络理解的偏差,导致很多互联网公司把防火墙边缘化。近年出现的SDN技术,可以通过软件自动对访问规则进行定义编排,实现ACL自助化的趋势,让防火墙又能够产生更好的效果。上篇介绍了安全架构设计的通用原则和方法,这是安全架构评审的理论基础。那么针对一个具体的应用系统面临了哪些威胁,在何处部署哪种防护机制,防护的完整性和强度是否到位,这就是安全架构评审需要回答的问题。本篇为大家介绍安全架构评审模型,是基于微软SDL、威胁建模模型进行了改造,更简单、实用,适合微服务、DevOps等高效开发、快速迭代的模式。该模型的主要流程可以通过下面一张图说明。
安全架构评审说白了就是看安全需求是否得到满足。理想情况,安全需求应该作为非功能需求在应用开发早期提出,并在应用设计和实现中得到实现。然而,绝大多数应用就没有做过安全需求。所以评估初期需要进行安全需求分析,并落在纸面上。后面安全生命周期都会围绕安全需求展开,并且随着评估过程推进,安全需求也会不断更新。安全需求主要包括:依据应用的核心功能,对应用的整体安全目标进行描述,说明应用处理的关键资产,这些资产面临的风险以及安全防护的要求。安全需求描述例子:系统存储的用户姓名、手机号等个人信息,在存储、传输过程中必须得到保护,一旦防护失效,导致大批量泄漏会直接影响用户资产乃至导致公司声誉、业务收到严重影响;数据库root权限一旦泄漏,将导致所有数据泄漏,或者被删除。基于安全策略和安全最佳实践结合业务特点,对通用防护措施的要求包括数据加密和保护要求、身份认证、会话管理、权限控制、日志和审计以及网络隔离等方面的控制要求。常规的安全需求包括:● 身份认证的安全需求
● 会话安全需求
● 权限控制安全需求
● 日志审计安全需求
● 数据加密安全需求
● 网络以及其他隔离安全需求
● 基础设施安全需求
● 安全编码相关需求
关于安全需求业界有很多现成的库可以作为参考。笔者比较推荐的是OWASP的ASVS以及各种安全防护项目主页。OWASP基本涵盖了web应用和常规的安全需求内容。此外还有对应不同类型系统的安全配置标准如NIST和CIS的操作系统、数据库等。虽然外界的权威的参考很多,笔者认为都需要深入研究,需要依据公司的业务特征以及现有的安全方案,形成适合自己的安全需求清单,也叫安全基线。架构评审主要目的是准确、详细的还原应用系统的原貌。我们的方法是通过几张图,对整个应用的组件进行分解,展现互相之间的访问关系。建议安全评审人员参考应用原来的文档,结合访谈,必要时通过查看业务代码、实测,自己画出产品的架构图。系统的架构图是否准确、完整,直接会影响到评审的质量。首先要有一个整体的架构图,具体的架构图可以依据应用的复杂度分层次给出。以下给出图的样本供大家参考。
以服务为粒度画出应用的内外部组件以及相互间的访问关系。对于复杂的系统还要给出更深层次的详细架构图,可以细到微服务,或者单个集群的单个主机,包含所有的中间件如负载均衡、消息队列等。组件说明:
组件名称 |
功能描述 |
采用的技术 |
WebUI |
用户访问入口 |
采用Java开发语言,XX框架;采用Nginx WEB服务器 |
service |
为第三方SOA服务提供功能API接口 |
http/ XX框架/.. |
DB |
保存配置信息 |
MySQL |
Store |
XX数据存储 |
API/CEPH |
IAM |
实现用户认证和权限控制 |
CAS/Oauth/Java |
MQ |
消息队列作为任务数据提供给外部服务消费 |
Kafka |
External
Service1 |
服务客户端,通过服务的(RPC)API接口访问服务资源实现服务调用 |
Java/RPC/… |
应用场景的数据流图
注意,应用场景要尽量全,不仅要涉及日常使用场景,还需要覆盖从服务注册、接入到使用乃至注销变更等生命周期的所有场景都覆盖。(注:可以通过审查系统日志、配置等信息进行确认)。下图是笔者依据Oauth2服务委托场景的一个数据流图。图中每个访问数据流都进行了标记和说明。你也可以把说明放在图后面列出,这样图更简洁。
1. Resource Owner: 资源所有者,实际上就是用户,属于权限委托方;2. User Agent: 用户端设备的应用程序,如浏览器,或者手机的App,也有类似于微信小程序的东东;
3. Client:前端应用,接受用户的一手请求,并要受用户resource owner的委托,代替用户访问其他服务中的属于用户的资源,包括数据资源;
4. Resource Server: 实际存储并提供数据资源的后台应用,他无法和用户直接接触,需要一定途径验证用户的委托行为: 谁Resource owner,委托谁Client 访问什么?这里注意,Oauth 只负责可靠的验证委托关系,但Resource owner 是否具有数据的访问权限,并不负责,这个User – resource 的mapping关系,需要权限控制系统完成。这是我们另外一个项目鉴权服务;
5. Authorization Server: Oauth的核心服务,实现委托申请、验证、发牌、验牌的全过程。
除了画出架构和数据流图,还要列出系统各个组件使用的技术、模块,包括但不局限于操作系统、数据库和其他中间件存储组件,给出技术清单。对于内部依赖的组件,要求必须经过评审;对于外部组件,要求必须进行过扫描和安全配置评审,确保没有漏洞。形成系统处理的数据清单,并明确它的生成、传输、存储是否加密,访问控制是否到位。明确这些数据的密级,以及保护需求。这里要注意,除了业务数据、访问系统的密码、加密的密钥等数据凭证需要作为最核心的资产首先要标示出来。形成应用的资产清单,从域名、微服务ID、主机集群、IP地址,域名,使用的各种组件清单。
此外,还包括应用的研发、项目资源,如代码仓库,制品库,系统镜像。
要深入理解当前安全防护的设计和实现机制。这部分需要安全专家详细评审,并依据安全需求进行一一确认。主要审查以下几项: 安全防护机制是否覆盖所有的访问入口和资源?防护技术采用的算法和具体实现是否存在缺陷?是否有明确的安全策略,配置是否进行过审计?尤其要注意自创的算法和实现方案,往往容易出现漏洞。
● 认证系统相关信息● 权限控制系统相关信息
● 加密方案以及实现机制
▸包括密码和凭据的生成,保存方案
▸业务敏感数据的存储加密方案
▸传输通道的加密方案
● 日志审计和监控方案
● 网络隔离方案
安全架构分析的核心,就是威胁建模。威胁建模是微软2000年左右,作为SDL的核心模块提出并实践的安全架构分析方法。微软当初本想一统软件安全方法论,威胁建模一度成为事实的标准。即使在今天,威胁建模依然是安全领域的主要架构评估方法。但SDL两个问题制约了它的发展:第一个是太重了,流程化的东西太过繁琐、僵化。面对微服务、DevOps等小、快、零的开发模式明显头重脚轻,无法集成到产品的流水线当中;第二是太追求傻瓜化,和微软其他软件理念一样,希望教给一个小白都可以完成安全评审,忽略了安全系统中的复杂性和专业性。
笔者针对互联网公司微服务化,快速迭代等特征,对SDL和威胁建模进行了一定的简化,保留和其核心的攻击面分析以及威胁列表部分元素。威胁建模过程主要分攻击面分析(过程)和威胁列表(结果)两部分。
就像大厦只有入口才会部署门禁和保安一样。数字世界也有墙,也有门。你需要的是识别这些墙和入口。简单来说,信任边界就是数字世界的墙。而Web UI访问接口如API、RPC等网络访问入口就是数字世界的门。识别信任边界和访问入口就是攻击面分析的核心内容。● 网络边界:常用的有Internet、办公网、开发测试网、生产网,或安全生产网(Security Zone)。这些边界往往由防火墙把守,实现四层的隔离。● 应用、服务边界:不论是微服务还是单体架构,服务往往会形成自己的集群,服务内部相当于一个可信区,内部组件可以自由访问。
● 主机边界:主机通常是服务的载体,也是服务实现的原子单位。
● 用户边界:你懂的。
● 租户、项目逻辑边界:对于SaaS层服务,用户资源是共享在一个公用的集群,并没有明显的物理边界,实际的边界是通过基于认证和权限的访问控制隔离的。
能否画出一个架构图中的所有信任边界呢?应该很难。从逻辑架构图上,识别网络边界、服务边界相对容易。但更细粒度进行标记,就会很乱。所以这部分边界你只要记住,在访问入口识别的时候就可以了。正向攻击入口识别很简单。我们之前不是画出所有场景的数据流图了吗?每一个数据流入、流出的入口点就是攻击入口。你需要在每一个数据入口点对应的信任边界识别有哪些必要的防护机制缺失,就能识别出漏洞,生成威胁列表了。把缺失的防护机制补上,就相当于修复了,是不是很简单?威胁列表是整个安全架构评审中重要的产出。笔者凭多年的安全评审经验,奔着简单、实用的原则对威胁列表进行了改造。具体字段和描述如下:● 威胁ID● 威胁描述
▸某某资产对象,在某过程中,未做XX防护或者xx防护缺失,导致XX信息泄漏。
● 威胁分类
▸有多种分类方法,为找出漏洞的共性与解决方案挂钩,笔者做了如下分类。如果公司内部已经有了一套漏洞分类机制,建议整合一下,方便统计。
▸值
•身份认证
•日志审计
•权限控制
•流量加密
•静态或者存储加密
•账户、凭据保护
•服务鉴权
•特权账户或服务保护
•网络隔离
● 威胁等级
▸两个因素: 产生的影响和触发的容易程度,可以参考DREAD模型
▸值:高中低
● 威胁来源
▸这块结合整个安全评审上下文,重点是反映漏洞发现能力的指标
▸值
•架构评审
•代码审核
•安全测试
•外报和渗透测试
● 威胁状态
▸跟踪威胁进度
▸值
•创建
•已确认(代码确认、测试确认、人为确认)
•修复(未验证)
•修复(已验证)
● 修复方案
▸通用问题,需要启动安全控制项目,本字段做项目-漏洞关联
▸值
•更新代码、配置(快速修复)
•解决方案修复(指明解决方案ID)
到输出威胁列表为止,安全架构评审的主要工作算完成了。不过,目前为止威胁列表还是零散的。如果只是单个系统,也就把一个个漏洞都修了算了。但现实情况是,你可能不仅仅有一个应用,而是成百上千、成千上万的应用;单个应用也要不断增加新功能、迭代新版本。因此安全架构评审的目标,不仅仅输出安全的结果,还要输出安全的能力。对严重的、重复出现的安全问题进行根因分析,发掘导致漏洞的背后的原因,可以分析出目前安全建设的主要缺失。主要从安全流程、平台和技术支撑和人员的安全意识和能力几个方面进行复盘,孵化出后面的重点工作和安全项目。并在整体安全原则、安全理念达成共识,制定出总体和细分领域的安全策略、安全基线,构建强大的安全技术栈、安全火药库,从技术上解决问题。
本文给大家介绍了进行安全架构评审的方法,看起来似乎不是很难。的确,按照这个方法,在评审的完整度和覆盖率上会有很大的提高。但要记住,在网络安全的世界,发现问题比解决问题容易。真正的专家是有对问题的闭环能力,就是落实安全解决方案的能力。简单来说,这个方法只是给你的一个皮。如果没有对安全技术的扎实的理解的这个肉,你的评审的准确度、权威性会受到挑战。具体如何扎扎实实的提高安全技术,可以参考一些文献,最重要的是要多学习,多实践。OWASP Top 10OWASP ASVS
构建安全的软件
微软威胁建模
Cisco 网络安全体系结构
Amazon Security
Google Security
DevOps Security
NIST SP800 系列
CIS security Benchmark
Nist Framework for Improving Critical Infrastructure Cybersecurity
CIS Top20 Security Controls
美团安全部的大多数核心人员,拥有多年互联网以及安全领域实践经验,很多同学参与过大型互联网公司的安全体系建设,其中也不乏全球化安全运营人才,具备百万级IDC规模攻防对抗的经验。安全部也不乏CVE“挖掘圣手”,有受邀在Black Hat等国际顶级会议发言的讲者,当然还有很多漂亮的运营妹子。目前,美团安全部涉及的技术包括渗透测试、Web防护、二进制安全、内核安全、分布式开发、大数据分析、安全算法等等,同时还有全球合规与隐私保护等策略制定。我们正在建设一套百万级IDC规模、数十万终端接入的移动办公网络自适应安全体系,这套体系构建于零信任架构之上,横跨多种云基础设施,包括网络层、虚拟化/容器层、Server 软件层(内核态/用户态)、语言虚拟机层(JVM/JS V8)、Web应用层、数据访问层等,并能够基于“大数据+机器学习”技术构建全自动的安全事件感知系统,努力打造成业界最前沿的内置式安全架构和纵深防御体系。
随着美团的高速发展,业务复杂度不断提升,安全部门面临更多的机遇和挑战。我们希望将更多代表业界最佳实践的安全项目落地,同时为更多的安全从业者提供一个广阔的发展平台,并提供更多在安全新兴领域不断探索的机会。
(完)