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