译自:An Overview on API Security。
本文概括了API防护有关的方方面面,从上层视角介绍了API防护中主要注意的点,并给出了相应的建议。本文可以作为一个API防护架构的启发文档。
APIs是访问一个组织功能和数据的入口,但无意间暴露的API可能会对组织的数字资产造成相当大的破环,同时有可能泄露敏感信息。因此,在实现数字化转型项目时,需要重点考虑APIs的安全性。
在上一篇文章中已经讨论了与API认证有关的问题,本文关注与API安全有关的其他重要因素,以及对应的解决方案。
目录
API调用中的访问控制
首先考虑一下APIs的访问控制,它确保只有预定方才能访问API。API访问控制的行业标准是OAuth2.0。图1展示了基于OAuth API调用的两个活动,一个应用需要从一个有效的身份提供程序获取token,然后在每次API调用中发送将其发送到API网关。因此很多访问控制场景都会围绕该token。注意,可以在API控制面实现IDP功能,也可以在API部署中使用独立的IDP。
Figure 1: 基于token的API访问控制简介
通常会基于作用域来实现访问控制。一个OAuth token可以关联任意多个作用域。例如一个仓库管理系统,相关的作用域可能是list_items 和order_item,可以使用如下两个仓库API方法:
- GET hmart.com/warehouse/items — required scope: list_items
- POST hmart.com/warehouse/orders — required scope: order_item
现在,可以在list_items 作用域中使用token_1 ,而在list_items 和order_item 作用域中同时使用token_2 。因此,一个应用可以使用token_1调用 hmart.com/warehouse/items 方法,使用token_2 调用两个API方法。
下面关注一个应用如何获取一个token。OAuth 2.0规范在授予类型中提到了该过程。两种有用的授予类型为:授权代码授予类型和客户凭证授予类型。当使用授权代码授予时,应用必须提供应用凭证以及用户凭证来获取token。当使用客户凭证授予时,只需要提供应用凭证即可获取token。这两种场景下,都需要在请求中指定需要的作用域。
在了解了token,作用域和授予类型后,现在看下,API访问控制如何使用token。基于token的访问控制的使用可以分为两个阶段:(1)token的颁发和(2)API调用。
token颁发过程中的访问控制
在一个基本场景中,我们会使用基于角色的访问控制来表明特定角色的作用域。例如,我们可以使用一个访问控制策略,给warehouse_admin 角色授予list_items 和order_item作用域,但仅给warehouse_staff 角色授予list_items 作用域。为了颁发一个order_item 作用域的token,需要考虑如下三个条件:(1)该用户是否是warehouse_admin 角色,(2)用户是否在HMart总公司工作,(3)源IP是否属于Australia. XACML(可以使用IP实现高级授权策略)。可以使用XACML(可扩展访问控制标记语言) 来实现这类高级授权策略。
可以扩展标准的授予方式或引入新的授予方式,获取token的过程支持很多访问控制场景。例如,可以在发布token时加入审批流程,这样可以在IDP将token发往应用之前,由特定用户进行token请求的审批。这种情况下,由于审批流程时间比较长,通常需要一个独立的通道将token发往应用。图2展示了访问控制策略和token审批流。
Figure 2: token颁发期间基于属性和基于工作流程的授权
在API控制面存储了用户角色以及针对不同角色指定的策略。
API用户可能会在发送实际的token请求前请求作用域,这种情况下,可以使用基于授权策略或审批流程的IDP进行处理。但无论哪种场景,只要授予了作用域请求,IDP就会维护一个用户和授予的作用域之间的映射状态。后续当一个应用代表一个用户请求该作用域的token时,IDP会查找映射,然后决定是否给该请求作用域颁发token。
API调用过程中的访问控制
正如前面提到的,通常需要提供应用凭证和用户凭证来获取token。因此,可以将应用程序和用户帐户与令牌进行关联。当在API调用过程中发送一个token到API网关时,API网关可以在IDP以及相关组件的帮助下授权请求。该授权步骤可能会执行很多无法在token颁发阶段使用的访问控制策略。
在最简单的场景下,网关可以检查token是否有效(如基于签名),是否过期以及token的作用域是否正确。但同时也可以基于运行时的数据执行很多复杂的策略。例如,可以使用一个策略来规定在上班期间,只有IP段为x-y的客户端能够发起特定的API方法。与token颁发阶段类似,可以使用XACML实现这类策略。API网关需要使用API请求的相关信息来联系XACML引擎,并以此执行授权功能。
而且可以结合限流功能实现更高级的策略。例如,可以规定在HMart区域办事处工作的员工每小时可以有10次机会调用warehouse/orders方法。API网关、IDP和限流组件必须通力合作来实现这些策略。如果限流组件提供了限制流量突发的功能,API限流策略(如每天允许2000个请求,每秒的请求数限制为100。)也可以用于防护某些级别的应用层DOS攻击。图3展示了使用限流策略和访问控制策略在API调用阶段对API进行防护。注意这种情景下使用了一个独立的限流组件,并将策略评估引擎放到了API控制面。
另一个安全需求是防护来自使用这些APIs的web应用的攻击。当一个单页应用使用APIs时,它可能在浏览器本地存储或会话存储中保存API token。如果一个用户打开了一个恶意网页(从另外一个站点),则该网页就可以访问API token并调用API。而且,当一个API网关要求在HTTP cookies中发送API token时,在相同的浏览器会话中打开的恶意网页就可以向目标API发送请求。还有一种可能性,即在同一浏览器会话中打开的恶意网页会与IDP一起执行OAuth令牌授予流程,以获取有效令牌。防护上述攻击的最佳方式是对API强制使用跨域资源共享(CORS)策略。CORS策略允许API开发者说明API调用可以使用的域名、HTTP方法、HTTP首部等。例如,HMart API可能使用一个CORS策略来说明仅允许hmart.com 和 abcstore.com站点调用API,因此web浏览器会阻止attacker.com向HMart发起API调用。
消息防护
API安全性的另一个关键点是对API层的消息流进行防护。由于一个组织会通过API层进行交互,因此需要通过消息层面的策略保证不会意外泄露敏感信息,并让正确的接收方接收到正确的信息。
TLS是在传输层实现机密性和完整性的主要方法。通过在客户端应用和API层,以及API层和后端服务之间启用TLS,就可以保证在消息传递过程中不会被篡改或泄露。
但在某些情况下需要更细粒度的内容保护。例如,病人的历史信息只能被分配的医生查看,而名字、电子邮箱等可以被普通的医院员工查看。这种场景下,需要在API层实现策略,这样如果不相关的医生发起API调用时,就可以将病人的历史信息从响应载荷中移除。这种可以从消息载荷中选择性进行移除的处理方式也可以用于在遵守如GDPR之类的法规时,保护个人身份信息(PII)。可以通过对部分内容进行加密来选择性地暴露信息,这样只有授权的应用可以阅读这些信息。
载体防护的另一个关键点是使用定义的策略对其进行校验。一种使用场景是保证载体包含特定格式的所有相关字段。例如,仓库条目列表响应必须包含条目ID,每个条目数目和单价。通常采用XML模式或JSON模式校验消息格式。除了模式校验,API层也应该提供阻止如SQL注入、PHP注入、Javascript注入的有害内容。可以在API网关侧以一组正则表达式的方式实现这类防护。图4描述了在API网关实现了消息级别的防护。
Figure 4: API网关上基于JSON模式、内容移除策略和TLS的载体防护
上图中使用了两组证书,API网关会卸载客户端证书,并使用后端证书加密通信。
API层可以通过使用API网关的私钥签名载体的方式,确保消息内容不会在传输过程中被修改。由于调用API的应用和后端服务都信任API网关的证书,因此API网关的签名可以在大多数场景下确保消息的完整性、如果使用了TLS,则会由传输层保证整个消息载体的完整性。但如果只需要确保载体中特定部分的完整性,则API层可以使用XPath或JSON表达式对选择的载体部分进行签名。
后端服务的安全性
前面章节主要关注API层的安全策略。但由API层暴露的后端服务也可能有各种安全机制。例如,一个后端服务可能是一个使用OAuth防护的API。这种情况下,API层可能作为一个OAuth客户端,并在每个后端调用中提供有效的token。一种方式是在API层中嵌入一个永久的token,但如果token有有效期的话,API层必须使用相关的IDP执行token刷新流程,并在需要时更新token(见图5)。在以集群方式部署API网关时,这类后端token需要使用如共享存储的方式,使之在所有的网关节点上生效。
Figure 5: API层访问使用OAuth 2.0防护的后端服务
API层仅可以基于请求的信息(如API方法,用户信息,源IP,时间戳等)执行访问控制。如果需要根据后端数据执行额外的访问控制,则需要在后端服务中实现这些策略。
基于分析的安全性
API 层是暴露一个组织所有功能的核心。因此,可以在API层的API操作中捕获大量信息,这些信息可以用来洞察安全性并推测可能存在的威胁。
首先,考虑审核方面。多个用户组可以使用API层来执行多种操作。API的创建者会使用API层创建并发布APIs,系统管理员可能为APIs创建不同的策略,应用开发者可能会订阅API并生成密钥,部门管理级用户可能会允许相关APIs的某些操作。API层可以通过记录操作涉及的所有用户、时间戳以及其他细节来创建审计日志。当发生安全问题时,就可以在审计日志中追溯谁创建了API,谁允许该API以及那个应用使用了API。这些审计日志可以写入文件或数据库,后续可以由内置的审计组件处理,也可以将这些审计日志导入分析系统,如ELK或Splunk。
Figure 6: 使用API调用数据来汇总与安全性有关的信息,并触发与安全性有关的事件通知
除了上面提到的API操作,在API层可以捕获到的另外一个重要信息是API调用细节。API调用操作的次数要远远大于API本身的操作次数,通常需要使用单独的、可扩展性更高的分析组件来捕获和处理这些事件。由于每月的API调用次数可以达到百万甚至上亿,通常我们更关注基于这些事件的汇总以及预测。例如,一个应用在过去的3个月内使用IP段X,但
突然从IP段Y发出了一个请求(不在X范围内)。这种情况下,安全分析组件会在常用的模式中探测到这种变更,并阻止该请求或给系统管理员发送一条提醒信息。类似地,如果一个API在过去的6个月内每分钟接收20个请求,但突然增加到每分钟1500个请求,分析组件可以根据常用的模式来通知到系统管理员此次变更。这种基于安全场景的模式可以在分析组件中进行定义(如,当一个API的请求数是过去6个月平均请求数的两倍时发出通知)。也可以集成API分析的机器学习模型,这样可以学习API的调用模式,并在调用出现异常时采取对应的动作。
APIs治理
一个组织可能会在两方面涉及对APIs的治理。首先,作为一个API提供者,必须通过APIs将功能暴露给内部和外部消费者,其次作为一个消费者,各种组织内使用的应用可能会使用内部和外部的APIs。当考虑APIs和应用的安全性时,需要关注所有发布的APIs以及所有应用依赖的API。
举两个API提供者和API消费者的例子。假设一个组织的销售部门为它的合作伙伴维护一个用于批量下单的API。后续部门为了提升该API的功能创建了多个版本,并添加了很多特性。由于部门有很多合作伙伴,且不是所有的合作伙伴都会立即使用最新版本的API,因此需要同时维护多个版本的API。现在假设组织的中央IT部门引入了一个新的策略,该策略要求合作伙伴的APIs仅能使用特定的IP段。如果无法集中跟踪提供给所有合作伙伴的APIs及其版本,那么就很难为所有APIs执行该安全策略,可能会错过一部分API,造成安全隐患。
看下API消费者的场景,假设一个应用开发者为一个保险公司实现了一个医疗保险索赔处理程序。在开发过程中,开发者使用了沙盒版本中的多个API,如CRM API和付款百分比计算API。现在将索赔处理程序转移到生产环境,有可能因为开发者忘记将依赖的APIs转变为生产版本,导致无法执行生产级别的安全策略,这样可能会泄露公司客户的敏感健康信息。
处理这些问题的主要方式是API治理。API治理策略可能会要求所有对内发布的API必须经过对应部门的管理者的同意,对外发布的APIs必须经过管理者和中央IT团队的同意。还可能要求所有的APIs必须遵守特定的安全准则。而且,这些策略可能要求所有的APIs必须发布到一个中央门户中,方便对API进行标记,搜索和分类。因此,当需要引入一个新的安全策略时,通过中央API门户能够发现所有活动的APIs。为了治理应用消费的API,组织可能会强制要求将所有依赖的APIs注册到中央API门户中。这样应用必须向中央API门户订阅API,有助于管理者和IT团队跟踪哪些应用使用APIs,并基于依赖配置策略(如,如果一个应用基于非生产版本的API,则不允许将其部署到生成环境中)。
Figure 7: 使用API管理平台和中央注册表来治理API
上图给出了一个API管理平台架构,包括开发门户、API生命管理、API流程引擎(审核、发布等)以及数据分析等组件。
图7展示了与API治理有关的APIM平台的主要组件。API治理的一个主要特性是支持扩展API生命周期管理。API生命周期管理特性允许管理者定义APIs的各种生命周期阶段(如,创建,审核,发布,废除,重试等)和它们之间的过渡,以及为状态过度关联相应的流程。例如,在将一个API转变到发布状态之前,必须经两个管理级别的用户的同意。此外,在状态过度流程中可以调用外部系统,这样可以在使用多个API管理部署的情况下,允许将APIs发布到一个中央API门户(或一个中央注册表)。
除了API生命周期管理特性外,复杂的API门户在API治理中扮演着一个重要角色。应用开发者可以使用门户来跟踪应用的API依赖,并为应用的API订阅添加基于策略或基于流程的授权。API开发者使用的门户也可以用于控制谁创建、审核或发布了APIs,允许谁查看和编辑APIs,以及基于创建者的角色将API发布到哪个API网关等。如果一个API管理平台没有足够的治理功能,则可能需要使用外部注册表进行治理。但这种情况下,需要考虑API管理平台和注册表之间的集成的数量。
API部署防护
仅使用API管理平台或API网关是无法防护APIs的。对API安全性来说,根据安全架构来部署API平台模块、后端服务和其他组件也是一个重要任务。
Figure 8: 部署API管理组件、后端服务、多身份提供方,并连接到云服务
上图中的每个节点通常是两个或更多实例组成的集群。API层考虑如下组件:API网关,API控制面,密钥管理器,API分析模块和集成模块。
API网关作为后端服务和客户端应用之间的代理,会在网关上执行API调用层面的安全功能。API控制面具有发布APIs、定义策略和订阅APIs的功能。密钥管理器用于颁发和校验API tokens。因此由密钥管理器执行token颁发层面的安全功能。分析模块会从网关收集API调用数据,用于评估限速策略。集成模块可以连接多个后端和云服务,执行必要的消息转换、协议匹配、消息校验和服务编排等。
上面给出了一个API层的组件及其职责的部署案例,实际可以采用多种实现方式。例如,可以将密钥管理其也纳入控制面,将分析模块作为现有分析平台(如ELK)的扩展。这样就可以在API网关上实现集成功能,无需使用单独的模块。但使用单独的模块可以增加部署的灵活性,并在需要时扩展独立的组件。
现在,如果回到部署方面,所有的API层组件都可以部署到组织的内网中,这样任何组件都不能直接访问外部服务。此时在DMZ中安装一个负载均衡器,并允许负载均衡器通过防火墙接通API网关流量。
然而,一个组织可能有多种类型的API消费者。首先会有公共消费者(如在线购物门户的客户),会从因特网络上访问APIs。此外还会有合作伙伴所在的组织从因特网访问APIs。但可以限制合作伙伴的组织数目,并为这些组织分配它们可以使用的IP地址段。此外,不同的地区和国家可能会存在分支机构,可以使用VPN连接这些分支机构。为了给这些消费者暴露一组API是,可以为每个消费类型采用独立的网关集群,仅将该使用者所需的API部署到相应的网关群集中(如图8所示)。然后使用防火墙规则指出仅允许网关1的公网流量,网关2仅限于合作伙伴的IP段。更近一步,可以将网关3限制为分支机构的VPN访问。
密钥管理器组件负责颁发tokens并评估高级运行时策略。例如,可以使用策略配置仅允许warehouse_admin角色的用户才能在6.00 PM之后调用“warehouse/add_item”方法。为了评估这些策略并基于颁发的token执行用户功能,需要将用户存储和密钥管理器关联起来。用户存储可以是一个LDAP存储或自定义的用户存储数据库。一个组织可能会部署一个中央身份中心和访问管理(IAM)系统来管理所有的用户细节。这种情况下API密钥管理组件需要联合IAM系统,这样IAM系统中的用户就可以无缝访问APIs。此外,组织可能期望它的用户使用他们的Google或FaceBook凭证来访问APIs,这类云身份供应商使用了如OpenID Connect、SAML、或自定义的协议。
现在考虑一下后端服务,这些服务可以部署在组织的内部网络或一个独立的网络中。不管那种场景,这类服务都不能不经过API网关或其他防护机制暴露到外部。如果服务部署在一个独立的网络中,需要在API层和第二个网络中使用安全连接(如VPN)。有些服务可能是基于云的服务或由合作伙伴公司提供的服务,这种情况下,这些服务可以使用如OAuth这样的机制进行防护,此时,API层应该作为一个API客户端(正如在对后端服务防护中提到的)。
为了适当地保护API,应该考虑多个领域。有些安全特性是(API管理平台)开箱即用的,而有些需要作为扩展嵌入这些平台。为了与组织的安全策略保持一致,可以将API管理平台和外部工具进行集成,也可以使用与产品部署(而非产品本身)有关的安全策略。因此为了有效防护APIs,需要考虑到方方面面。