如何构建和设计以确保 API 的安全性

  面对常见的OWASP十大威胁、未经授权的访问、拒绝服务攻击、以及窃取机密数据等类型的攻击,企业需要使用通用的安全框架,来保护其REST API,并保证良好的用户使用体验。本文向您介绍四种类型的API安全保护方式。

  管理好API安全性 API的安全性涉及到各种端到端的数据保护,它们依次包括:来自客户端的请求经由网络到达服务器/后端,由服务器/后端发送相应的响应,响应横跨网络,最后到达客户端,这一系列的过程。因此,API的安全性可以大致分为如下四种不同的类别,我们将逐一进行详细讨论:

  (1)传输中的数据安全

  · 保护客户端与API网关之间的动态数据

  · 保护API网关与后端服务之间的动态数据

  (2)访问控制与抵御拒绝服务(DoS)攻击

  (3)身份验证与授权:使用OAuth2.0或OpenID Connect,来可靠地识别最终用户的信息

  (4)数据保密与屏蔽个人身份信息(Personally Identifiable Information,PII) 1. 传输中的数据安全 对于所有公共且不受保护的API来说,我们必须用到TLS。如今随着硬件的进步,TLS的实施开销几乎可以忽略不计了,而且随着延迟在逐渐减小,越来越多的最终用户会处于安全考虑而选用TLS。总的说来,TLS具有如下主要特点:

  · TLS应当在北向(northbound)和南向(southbound)端点同时实施。

  · 应确保使用TLS的最新版本,并对客户端、API网关和目标后端予以支持。

  · 证书密钥、以及信任凭证的存储都应该受到高度保护和加密。

  · 只有经过授权的用户才能访问证书密钥、以及信任凭证。 2. 访问控制与抵御拒绝服务(DoS)攻击

  (1) 网络级别的防御:如果API网关被托管在云端,则需要使用由云服务商所提供的 DDoS防御机制,例如:由Apigee(Google)所运营的Apigee Edge托管云平台、 GCP(Google云平台)和AWS(Amazon Web),它们都提供了网络级别的DDoS防御。

  (2) 内容交付网络:像Akamai、Neustar和Rackspace之类的CDN,都可以用于缓解那些对于API的DDoS攻击。

  (3) “僵尸”检测:如今各大API管理平台都已经针对僵尸/机器人类型的攻击,推出了检测API流量,识别各种恶意/非必要请求,并生成警报/阻止恶意请求到达的API网关服务。例如:Apigee(Google)提供了一种称为“Apigee Sense”的检测服务。它是一种智能数据驱动的API安全产品,它可以通过自动识别各种可疑的API客户端行为,以提供额外的保护层。同时,管理员也可以在此基础上通过纠正性措施,来保证用户的体验度,以及后端系统的安全性。

  (4) 策略执行:我们应该在位于API客户端和客户后端之间的API代理上,通过强制实施各种策略,以严格管控合法用户对于API的访问。如下策略能够在一定程度上保护API免受恶意黑客的攻击:

  · API速率限制:通过限速,我们可以减少大量导致拒绝服务的API请求,并抑制暴力攻击和服务滥用。特别是在API代理服务器上,我们可以采用如下限速的机制:

  · 基于应用程序或个别API予以限速,以保证每个API或应用程序只能按照固定的请求数配额,去访问对应的服务。

  · 基于GET或POST请求予以限速,当然具体的请求数设定,可以根据不同时段的GET或POST量而有所不同。

  (5) 正则表达式保护:应当根据预定义的正则表达式(如DELETE、UPDATE和EXECUTE)来评估入栈请求的URI路径、查询参数、包头、表格参数、变量、XML有效负载、以及JSON负载。任何匹配上了预定义表达式的请求都将被视为威胁,并被立即拒绝掉。请参阅OWASP top 10(https://www.owasp.org/index.php/Category:OWASP_Top_Ten_Project#OWASP_Top_10_for_2013),以了解具体有关要如何验证正则表达式的信息。

  (6) JSON输入验证:对于PUT/POST/DELETE之类请求的负载,我们应执行JSON验证,以通过指定对于各种JSON结构的限制(如最大深度、对象的最大数量、最长字符串长度的名称、以及数组中所允许的最大元素数等),来最小化可能受到的攻击面。

  (7) XML输入验证:应当对PUT/POSTE/DELETE之类请求的负载执行XML验证。具体可使用如下方法来根据配置的限制,以检测XML负载的各类攻击、以及监控针对XML的威胁:

  · 根据XML的架构(.xsd)来验证消息

  · 根据特定黑名单里的关键字与模式,来评估消息内容 · 在分析消息之前,检测出已损坏或格式错误的消息

  (8) 验证请求 · 验证输入HTTP动词:适当地对那些允许类动词做出限制,而对于其他所有动词,则返回相应的响应代码(如:“403禁止错误”)。

  · 验证包头:应当根据API所支持的功能,显式地验证“内容类型”、“接受”和“内容长度”等包头。此外,还应该执行针对强制性包头(如:授权、以及特定类型的API包头)的验证。

  · 验证入栈内容类型:对于PUT/POST/DELETE之类入栈请求的内容类型(例如:应用/XML或应用/JSON)、以及内容类型的包头值进行验证。对于缺少内容类型的包头、或异常内容类型的包头,应当直接拒绝,并返回“406不可接受”的响应内容。

  · 验证响应类型:不要简单地将“接受”包头复制到响应内容类型的包头中。如果“接受”包头中并没有明确地包含允许的类型,应当直接拒绝该请求,并返回“406不可接受”的响应内容。

  · 处置不支持的资源:适当通过限制资源,只开放可供调用的资源;而对于其他所有未实现的资源,则应返回“未知资源”之类相应的响应代码。

  (9) 访问控制:通过配置策略,只允许来自特定IP地址、域名或区域的请求。而那些未通过此类条件的请求,应当被网关直接拒绝掉。

  3. 身份验证和授权 通常情况下,身份验证和授权是同步发生的。

  · 身份验证常被用于识别最终用户。

  · 授权则被用于授予已识别用户访问某些资源的权限。 在API领域中,OAuth和OpenID Connect是最为常用的机制。它们通过利用现有的IAM架构,并以交换访问令牌的方式,来验证用户的身份,进而保护API的各个端点。通过OAuth和OpenID Connect,我们不需要每次都构建单独的系统,以存储用户名和密码的方式,来匹配用户可以访问的API资源。

  OAuth OAuth通常采用不透明(OPAQUE)令牌,来实现委托访问(Delegated Access)的目的。OAuth2.0授权框架使得第三方应用能够获得对于HTTP服务的有限访问权限。通常,用户不应当为了访问某些存储在第三方的受保护数据,而在公网上传输自己的密码。而OAuth恰好能够为用户访问自己的数据,提供了信任凭据的安全保护。

  OAuth不是一种身份验证协议,而是授权协议。由于身份验证通常发生在颁发访问令牌之前,因此我们很容易理解为在接受访问令牌时,也进行了身份验证。然而,仅凭拥有访问令牌,并不能证明用户的身份。在OAuth中,令牌被设计为对客户端来说是不透明的,客户端仅能从令牌中获取权限信息,而不会涉及到用户名与密码。

  不透明令牌:在许多的具体实现中,OAuth2.0会返回OPAQUE字符串,用以换取被称为访问令牌的用户凭据,而这些令牌将被进一步用于访问各种API的资源。不透明令牌并非用来存储用户身份标识与信息,而是指向了某个数据库里的具体数据项。例如:我们可以用Redis来存储各种键-值(key-value)。而Cassandra之类的NoSQL数据库则非常适合利用内存中的哈希表,根据I/O来查找有效负载。由于用户角色是直接从数据库中被读出的,因此我们可以通过更改后端的角色,来传递并展现给用户。

  OpenID Connect OpenID Connect采用ID令牌和访问令牌,来实现用户识别与委托访问。OpenID Connect是进行用户身份验证的标准。由于直接构建在OAuth2.0之上,因此在大多数情况下,OpenID Connect是与OAuth架构一起被部署的。在交付形式上,它还为客户端提供OpenID Connect令牌。该身份令牌是一个已签名的JSON Web令牌(JWT),它与常规的OAuth访问令牌一起被提交给客户端应用程序。

  · JSON Web令牌:JWT令牌实际上是一个完整的JSON对象。它经历了base64编码之后,使用对称共享密钥、或公/私钥的方式进行签名。JWT可以包含诸如:主题、user_id、令牌颁发时间、以及过期时间等信息。通过密钥签名,它可以确保只对拥有授权访问密钥的系统才能生成令牌。不过值得注意的是,系统在对JWT进行签名时,JWT通常不会被加密(当然,您也可以选择对其进行加密)。那么,这就意味着任何拥有令牌访问权限的人都可以读取令牌里的数据。因此,业界的最佳实践是:只把用户标识(如user_id)放在令牌中,而不是个人身份信息(如电子邮件或社会保障号码)。此外,它们应当通过TLS之类的加密通道来进行传递。

  · JWT限制:鉴于日常对于用户的禁用、以及添加或删除角色往往需要一段时间才能同步生效,而且由于令牌存储在客户端,即使我们在数据库中对其所颁发的JWT用户进行了禁用标记的话,也无法直接让该令牌及时无效。虽然JWT采取了预定义到期的机制,但是用户仍然需要等待到期。显然这会影响到用户的服务架构,特别是那些电商类的应用。

  当然,业界也提供了一些变通的方法。例如:您可以使用带有令牌或user_id的黑名单,但是这需要向数据库引入新的认证机制。因此,一种推荐的方法是:通过黑名单以确保每个令牌都带有一个JTI声明(或带有一个存储在数据库中的JWT Id)。因此,只要您希望注销的令牌数量远小于应用程序中的用户数量,那么操作起来就非常灵活。

  可见,对于那些拥有管理员、项目所有者、服务客户经理等多种角色的企业应用来说,切换用户的不同角色并不会对JWT立即生效。例如:管理员修改了某个授权用户的角色,那么只要他不去刷新JWT,也就无法获悉该变更。

  下面是OpenID Connect的三种实现用例:

  · 出栈方向的Web单一登录(SSO):向企业用户提供对于SaaS应用、以及合作伙伴应用的访问管控,但并不公开本企业的用户名与密码。

  · 入栈方向的Web单一登录:允许社交账号/第三方登录,但无需存储外部用户与密码。

  · 实现各种本地应用的原生单一登录。

  OAuth和OpenID Connect都支持OAuth2规范所指定的四种授权类型,下图描述了其中一种授权流程图。API开发人员可以根据手头项目所需的约束与实现方案,来选用不同的授权类型。

  4. 数据保密与屏蔽个人身份信息 众所周知,由于密码、安全令牌和API密钥包含了不同程度的内部信息,它们不应该出现在URL中,或者被Web服务器的日志所捕获。此外,诸如UserID、密码、帐号、信用卡号码等个人身份信息,也应该处于“被打码”的状态,哪怕是在交易和审计日志中。

  公共API的安全实践 由于独立于任何用户,因此公共API的设计初衷就是为了公开各种非敏感、以及只读的数据(例如天气类API),当然也就不必添加任何身份验证与授权环节。不过,我建议您通过如下的方面,来打造能够应对各种威胁与滥用的API:

  · 在IP地址级别上应用速率限制的相关策略。

  · 使用API密钥验证的方式。通过存储在网关上的方式,保证API的密钥不会被公布给任何客户端。因此,当拒绝服务攻击使用无效密钥访问API、或是在其他策略已无法阻断黑客攻击时,API密钥验证方式能够有效地发挥作用。

  · 采用配额策略(单个或多种配额机制),来实现API的使用限制。

  · 如果API被用于特定地理区域的服务器进行通信,那么就应当在地理级别上(县/区等)采取IP地址的筛选。

  · 开发人员应尽量采用一次性注册的方式,并使用自己的API密钥去调用API。

  结论

  在企业内部、以及企业之间需要集成不同的应用时,开发人员能够通过API来快速且方便地予以实现。不过,如果没有恰当地保护好API,那么就会让整个企业面临各种风险与威胁。因此,我们需要在开发和实施之前,就对API的安全性进行良好的构建和设计,从而提高企业的整体安全态势。

如何构建和设计以确保 API 的安全性的更多相关文章

  1. 如何设计提高服务API的安全性(一)基础介绍

    场景 现今越来越多公司提供了Sass平台服务,大部分也直接提供API.如快递鸟.微信Api.云服务.如何保证这些服务的安全性是一门重要的课题.如快递跟踪.机票查询等很便捷地影响着我们d的生活,对这些技 ...

  2. 如何设计提高服务API的安全性(二)API密钥方式详解

    在上文已经讲述了基础介绍,这篇文章详细讲解API密钥方式. 利用何种加密方式呢? 经过上面加密算法的理解,单向加密不仅性能高,而且有压缩性,即长度一致,有效减少网络传输过程中的字节大小.适合我们这种调 ...

  3. 前阿里P8架构师谈如何设计优秀的API

    随着大数据.公共平台等互联网技术的日益成熟,API接口的重要性日益凸显,从公司的角度来看,API可以算作是公司一笔巨大的资产,公共API可以捕获用户.为公司做出许多贡献.对于个人来说,只要你编程,你就 ...

  4. 如何设计优秀的API(转)

    到目前为止,已经负责API接近两年了,这两年中发现现有的API存在的问题越来越多,但很多API一旦发布后就不再能修改了,即时升级和维护是必须的.一旦API发生变化,就可能对相关的调用者带来巨大的代价, ...

  5. Chris Richardson微服务翻译:构建微服务之使用API网关

    Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关(本文) 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服 ...

  6. 如何设计好的RESTful API之安全性

    保证RESTful API的安全性,主要包括三大方面: a) 对客户端做身份认证 b) 对敏感的数据做加密,并且防止篡改 c) 身份认证之后的授权 1.对客户端做身份认证,有几种常见的做法: 1)在请 ...

  7. 如何为非常不确定的行为(如并发)设计安全的 API,使用这些 API 时如何确保安全

    原文:如何为非常不确定的行为(如并发)设计安全的 API,使用这些 API 时如何确保安全 .NET 中提供了一些线程安全的类型,如 ConcurrentDictionary<TKey, TVa ...

  8. Atitit.论图片类型 垃圾文件的识别与清理  流程与设计原则 与api概要设计 v2 pbj

    Atitit.论图片类型 垃圾文件的识别与清理  流程与设计原则 与api概要设计 v2 pbj 1. 俩个问题::识别垃圾文件与清理策略1 2. 如何识别垃圾图片1 2.1. 体积过小文件<1 ...

  9. Html5 Egret游戏开发 成语大挑战(六)游戏界面构建和设计

    本篇将主要讲解游戏界面的构建和设计,会应用到egret.eui的自定义组件,可以很直观的构建一个游戏整体,这里我们仍然只需要使用EgretWing就可以达到目的,本篇可能是篇幅最少的一个,但是涉及自定 ...

随机推荐

  1. JS移动客户端--触屏滑动事件及js手机拖拽效果

    移动端触屏滑动的效果其实就是图片轮播,在PC的页面上很好实现,绑定click和mouseover等事件来完成.但是在移动设备上,要实现这种轮播的效果,就需要用到核心的touch事件.处理touch事件 ...

  2. 【ABCD组】Scrum meeting 4

    前言 第4次会议在6月16日由组长在教9 405召开. 主要对下一步的工作进行说明安排,时长90min. 主要内容 分配下阶段任务,争取在这阶段完成软件的设计阶段 任务分配 姓名 当前阶段任务 贡献时 ...

  3. VS2015 建立一个C++的MFC简易窗体程序项目

    一开始建立的窗体工程都是带很多窗口,而且自己拉到窗体的控件,一调试就看不到了,是因为新建立工程项目时勾选了太多其他的了,这里记录分享一下建立一个单纯的窗体程序项目步骤给有需要的人也可以学习. 第一步: ...

  4. SBC37x交叉编译平台QT+OPENCV

    一.构建交叉编译器 [随机手册]Angstrom是一个界面友好的嵌入式发行版本,用亍手持设备,机顶盒和网络存储设备等嵌入式设备. 光盘的文件系统是定制的The Angstrom Distributio ...

  5. adchos 文本混淆工具

    #-*- coding:utf-8 -*- import jieba import random import codecs import sys import string import chard ...

  6. Optimization on content service with local search in cloud of clouds

    曾老师的这篇文章发表于Journal of Network and Computer Applications,主要解决的是利用启发式算法决定如何在cloud of clouds中进行副本分发,满足用 ...

  7. 【ACM】poj_2080_Calendar_201307311043

    CalendarTime Limit: 1000MS  Memory Limit: 30000K Total Submissions: 9787  Accepted: 3677 Description ...

  8. D 分组背包

    <span style="color:#3333ff;">/* ---------------------------------------------------- ...

  9. DIV响应式

    @media only screen and (min-width: 100px) and (max-width: 640px) { div { width: 100px; height: 100px ...

  10. 微软继MVC5后,出现ASP.NET VNEXT

    vNext又称MVC 6.0,不再须要依赖System.Web.占用的内存大大降低(从前不管是多么简单的一个请求.System.Web本身就要占用31KB内存). 能够self-host模式执行.站点 ...