现代应用程序通常是围绕API设计的,API可以让多个不同应用程序能够重用相同业务逻辑,以此加快创新和新业务的上线。
传统的安全架构基于边界思维,假定企业内部是一个“内网”,然后假定存在一个边界对内外网进行隔离,但随着企业的数字化转型,企业大量采用了云计算和大数据技术,大量的业务和数据会通过API的方式对外去进行提供。
API安全性的实现范围很广,不同的场景需要用到不同的方式。通常,API的保护仅采用HTTP基本身份验证,API密钥或基于令牌的身份验证。其中最容易忽略一个主要问题就是:身份。
通常因为身份导致的漏洞占应用漏洞的80%以上,为防止漏洞并获得高效的安全收益,全面的关注身份对于保障API和业务的安全至关重要。
可以说,APIs提供了对外的最有价值的数据或服务的访问,而API又是一个对外开放的服务,因此,API安全将成为一个常见的安全挑战。也需要我们的安全和开发团队给予更多的重视,科学的规划、设计和保护API的安全。
API提供对有价值的数据或服务的访问,因此API通常需要限制对应用的访问。即,应用程序需要正确的身份和授权才能调用API。除了应用程序自身要调用API,还包括应用程序需要代表用户调用API来访问用户拥有的资源,前提是它需要用户的授权同意。
为了更好的描述身份与API安全之间的关系,我们参考API的成熟度模型,将API安全的模型划分为4个等级。
在这个模型中,随着等级升高,安全性和信任度就越高。
级别0的API使用基本身份验证或API密钥来验证API调用。这些值插入在API请求的URL的标头(Header)或正文(Body)中。大多数早期的API都采用这种方式。
例如,一个电子商务商店的应用,它根据用户购买情况对付款API进行API调用。它将身份验证以标头中的API密钥或基本身份验证的形式发送给应用程序,并将其传递给API。将用户的ID放在正文或URL中。在下面的示例中,有两类API:账单类和商品类。由于采用HTTP基本身份验证或API密钥方式,API仅对“商店应用”进行身份验证,因此“商店应用”必须向API传递用户数据。
这个方式实际上是非常基本的方法,没有对于安全的考量。首先,密钥在每次API的访问过程中都携带,这样极为容易泄漏。另外,API密钥验证只是对于(商店应用)机器验证,对用户的身份没有是否篡改的校验,容易被利用。最后,这种方式仅提供了应用的身份验证,即证明断言的行为,而没有包含授权的相关信息。
级别1的API在基于令牌的体系结构中利用访问令牌(Access Token)进行身份验证。访问令牌中的信息可以包含用户的类型(机器,应用程序,用户等)。通过启用特权访问,能够有效的对内部和外部用户的安全级别进行分离,有效的帮助提升安全性。同时,因为用户身份是请求的一部分,便于更好的审计。
例如,继续上面的用例,考虑在电子商店中使用基于访问令牌的身份验证。在此场景下,如果API同时需要支持2个应用的调用,即,除了商店应用以外,还有内部的管理后台时,就会非常的明显。即需要使用自定义逻辑来了解该请求是属于具有特权的后台请求,还是来自外部网络用户对于该网上商店的请求。
在等级1,拥有令牌的任何人都可以修改API,提供了便捷的同时,也意味着特权访问的令牌的风险更高,如果被黑将带来巨大的风险。此外,级别1仅仅涵盖身份验证,而不涉及授权。换句话说,没有策略去限制应用允许做什么不允许做什么?此外,对令牌进行身份验证时,所有授权访问,需要通过自定义代码实现,诸如if语句之类的自定义编码,这无异将权限和业务耦合在了一起。
在第2级和第3级中对此种情况进行了否定,改进的方案可以使用令牌的数据直接进行授权,从而生成授权的逻辑,而无需再业务中去耦合授权控制的逻辑。
为了解决以上级别1的缺陷,在令牌的设计上,级别2在基于令牌认证的体系结构上,引入了授权机制。即,通过描述请求方的特权,询问请求方将被允许做什么?这一思想被应用到Oauth2.0中,作为一种广泛采用的授权标准。
OAuth最大的亮点是在token中包含了作用范围(标准中定义为Scope),范围Scope可以在授权令牌中包含“指定的权限”,即作用范围可以指定用户权限。 这一优点在后续的协议中又得以进一步的规范,如后续的OpenID Connect定义了一组标准的[作用范围],即可以用来生成标准的身份参数。当然,开发者除了标准范围以外,也可以创建[自定义范围]用于自己开发的API。范围可以根据开发者需求包含更多和授权相关的数据,以用于后续的API的授权,这比“ if”语句的编码方式要更为友好和优雅。
这时,让我们再次回顾我们的电子商店的案例。现在,我们引入了通过范围进行授权,因此可以更加容易的实现公共网络的商店和后台可以具有不同的特权。比如,只有管理后台应用才能获取添加商品(AddProduct)的权限。这就有效的区分了不同应用的权限。
但是,此种方案仍然没有尽善尽美,在这个场景下,依然存在些问题。比如,商店应用和管理后台的的某些操作会出现重叠。比如,使用Scope为LIST,用于在账单API中列出发票。 列出发票的ID被包含在URL或作为传递的参数,作为该API的请求参数。因此,可能会出现恶意越权的情况,即一个用户可以操纵篡改传递的ID参数以列出另一个用户的发票。因此,仅仅使用范围是不够的,范围Scope锁定了客户端应用程序被允许做什么操作,但对于对特定用户被允许操作哪些数据没有帮助,因为它们只包含了参数的“名称”,而没有限定“值”。而是应使用Claims,以便将参数“铸造”到令牌中。然后程序就可以很容易地将后台应用特权与公共网络商店应用的特权分开。
级别2的问题:级别2中的一个问题是系统面临着反编译的威胁。如果将身份的信息直接放在在API参数中,通过对于API的访问进行逆向,其中的逻辑错误很容易被发现和利用。 另外,级别2中引入了更高的系统复杂度,因为某些API请求参数可能会依赖其他API响应或其他条件。如果,一个API调用另一个API时失败了,或者,如果数据请求参数中包含了错误,怎么办?我们不能假设数据从一个API传递到下一个API总是正确的。这些现实问题可能会导致一系列的级联信任问题,这种“意大利面条式的信任”,有可能让系统变成一团糟。
通过对以上各级的问题的总结,最终API的安全计划到第3级,可以认为是目前最完善的API安全思想和实践。这种实践引入了使用Claims和签名的JSON Web令牌(JWT)进行集中式信任。
同时,授权的服务作为一项独立的服务,客户端向授权服务器进行请求授权,将授权与业务进行分离,它定义了不同的流来获取令牌,客户端从而能够在不需要知道用户凭证的情况下授予对资源的访问权。通过这样做,我们解决上述所有问题。
什么是JWT?澄清下常见的对于JWT的误解,JWT不是一种协议。JWT是一种使用了签名的数据。 OAuth协议中使用JWT验证交易。 JWT可以用来共享范围和声明?声明本质上是一种断言。例如,如下声明:“特拉维斯(Travis)说雅各布(Jacob)是一位身份专家。”此声明具有声明方(Travis),被声明的主体(Jacob),和主体的属性(身份专家)。如果您信任Travis,那么您相信此声明。主体的身份可以由许多属性可以组成,例如“主体”属性名称,年龄,身高,体重等。对于这些属性,声明方可能为一个官方的机构。当然,也可以有上下文属性,例如情况,时间,位置,天气,等等。与其信任属性本身,不如信任一个可信的声明方。
如果你相信颁发密钥的OAuth授权服务器,那么您可以信任由它签发提出的声明。
至于,验证声明的是未经篡改的真实性,一般流程如下:
1.请求方向声明颁发方发起请求
2.声明颁发方签发返回的声明数据,并用私钥签名
3.请求方携带签名后的声明数据向第三方去请求服务
4.第三方服务使用公钥验证签名合法性
这种方法通过信任令牌的发行者,而不是信任参数本身的方式,有效的解决了各级信任问题。从而达成集中式的授权机制。
以下是当你在设计,测试以及发布你的 API 的时候所需要核对的重要安全措施。
Basic Auth
,请使用标准的认证协议(如 JWT,OAuth)。Authentication
、token generating
和 password storing
,请使用标准库。UUID
代替自增长的 id。JWT Secret
)以增加暴力破解的难度。HS256
或 RS256
)。TTL
,RTTL
)。redirect_uri
,只允许白名单的 URL。response_type=token
)。state
参数来防止跨站请求伪造(CSRF)。HSTS
协议防止 SSL Strip 攻击。GET(读取)
,POST(创建)
,PUT(替换/更新)
以及 DELETE(删除记录)
,如果请求的方法不适用于请求的资源则返回 405 Method Not Allowed
。content-type
字段使用内容验证来只允许支持的格式(如 application/xml
,application/json
等等)并在不满足条件的时候返回 406 Not Acceptable
。content-type
中申明的编码和你收到正文编码一致(如 application/x-www-form-urlencoded
,multipart/form-data
,application/json
等等)。XSS
,SQL-注入
,远程代码执行
等等)。credentials
,Passwords
,security tokens
,or API keys
),而是使用标准的认证请求头。Quota
,Spike Arrest
,Concurrent Rate Limit
)以及动态地部署 APIs resources。/me/orders
替代 /user/654321/orders
。XXE
攻击。Billion Laughs/XML bomb
。X-Content-Type-Options: nosniff
。X-Frame-Options: deny
。Content-Security-Policy: default-src 'none'
。X-Powered-By
,Server
,X-AspNet-Version
等等。content-type
,如果你的请求类型是 application/json
那么你返回的 content-type
就是 application/json
。credentials
,Passwords
,security tokens
。200 OK
,400 Bad Request
,401 Unauthorized
,405 Method Not Allowed
等等)。信任是主观的东西。在设计基于API的安全系统时,我们应该信任密钥、令牌,密码,机器或用户本身吗?答案要比大多数的API设计人员认为的要复杂,但这对于保护您的平台整体至关重要。
本质上,API安全的顶峰是信任声明,而不是属性。如果GitHub存储库中存在重要的密钥,API很容易受到攻击。因此,API提供者必须做出更明智的安全决策,以保护整个平台的完整性。
在网络安全领域,很少鼓励你发明自己的授权规则。为了使集中信任发挥作用,授权系统需要使用稳定的协议。就像街道交通规则一样,身份系统也遵循通用协议。需要它们自己的共享开放标准,正像我们API成熟度逐渐演进过程中定义的一些开发协议或引用的协议,如果JWT、OAuth2.0和OpenID Connect等等。利用这些标准,应用程序可以在JWTs中共享安全的断言数据以进行验证。
正如API安全成熟度模型逐步演进所显示的那样,高度成熟的API只信任很少的源,这些演化的API被信任的令牌的发行者逐渐成为独立的服务——身份服务和授权服务,这不能保证100%的真实性,但最接近于验证请求方的身份。通过标准逐渐固化信任标准过程,可以消除系统开发者在身份授权的自定义代码上浪费的精力。
更多API安全可以扫码添加微信,我们致力于提供身份的标准,通过身份驱动API安全。
关于OneAuth
OneAuth 是国内领先的 iDaaS (身份即服务) 云技术提供商。
OneAuth™ Cloud :联邦身份认证平台,使任何组织能够随时随地通过任何设备安全地将人们与技术联系起来,赋能客户与他们选择的任何流行的应用程序、服务、设备或云厂商集成。
特性:多租户支持,利用国密商用算法对数据加密隔离,在保持计算弹性的同时维护不同租户的身份数据安全。
架构:支持专有云方案,满足金融、保险和银行等行业监管要求。严格遵守法律法规,满足数据销毁、迁移与备份要求。
OneAuth 作为国家高新技术企业,依托公有云强大的硬件与网络能力,结合OneAuth自主知识产权的OneAuth™ Cloud Engine 简称OCE ,共同技术创新驱动产业发展,充分使用云原生、AI等关键技术为各类客户赋能。
欢迎注册,体验现代身份引擎OneAuth™ Cloud
www.oneauth.cn