作者:Apifox blog 李C理
前言
伴随互联网革命快速创新发展,API 需求的日益剧增,针对 API 的攻击几乎遍布各个行业,据报道 2022 年全年平均每月遭受攻击的 API 数量超过 21 万,游戏、社交、电商、制造等行业依然是攻击者主要目标。例如社交软件某特,在 2021 年发生数据泄露事件,此次数据泄露影响了多达 540 万用户,产生这场“惨案” 正是攻击者利用了登录 API 端点,产生这一漏洞的原因很可能是 API 过度数据暴露以及安全配置错误(下面我会讲到)。显然无论是 API 攻击整体趋势还是对企业和用户的影响都是不容乐观的。那如何去搭建 API 接口的安全“堡垒”?下面我们将展开探讨。
开始前我们可以先了解下:什么是 API?深入了解 API 的概念和应用
API 接口安全问题
API 攻击事件频发,其根本原因仍是 API 存在安全缺陷,随着 API 在各个生态的快速发展,API 面临的安全缺陷也逐渐凸显,也引起了决策者重视,API 的安全困局也成为了现代IT面临的一个共性问题。下面我举例几个我曾经在开发中常遇到的 API 安全问题 :
未授权访问
这类安全问题会带来极为严重的漏洞,因此小编在开发中尤为重视,API 倾向于暴露那些处理对象识别的端点,同时造成了广泛的攻击表层访问控制问题。一旦遭到攻击,攻击者可轻易获取到管理员的账号密码,并拿到系统的最高权限。大家可以通过白名单的方式来严格控制无需授权的 API 接口的访问;除非资源完全对外开放,否则访问默认都要授权,尤其是访问用户的资源或者受限制资源。
数据泄露过多
为了做到通用实现,一些伙伴往往倾向于公开所有对象属性,不考虑它们各自的敏感性,而是依赖于客户端执行数据过滤,然后再将其显示给用户。在不控制客户端状态的情况下,服务器就会接收越来越多的过滤器,攻击者可能会通过滥用这些过滤器,从而获得访问敏感数据的权限。某特引发数据泄露的一大原因,便是因为 API 端点返回了电子邮件或电话号码等可识别数据。
安全性配置错误
安全配置错误是在日常开发中容易忽略的常见问题,不安全的默认配置、不完整或临时配置、开放的云存储、错误配置的 HTTP 标头,不必要的 HTTP 方法、跨域资源共享(CORS)以及包含敏感信息的冗长错误消息都有可能引起 API 的安全问题。大家一定要注意检测。
注入
当不受信任的数据作为命令或查询的一部分发送到解释器时会发生注入缺陷,例如 SQL、NoSQL 的命令注入等。攻击者的恶意数据可能会诱使解释器执行非预期的命令,或未经授权访问数据。
缺乏资源和速率限制
在 API 的开发中一些小伙伴,不会对客户端/用户可以请求的资源大小或数量施加任何限制。这不仅会影响 API 服务器的性能,从而导致拒绝服务(DoS),而且还为诸如暴力破解之类的身份验证漏洞敞开了大门。我建议还是对资源和速率施加一定的限制,会让我们更有信心保持应用程序健康运行而良好的响应计划。
如何设计并保证 API 接口安全
我相信大家一般不会把大额的钱随身携带。大多数人都会选择把钱存到可信的环境中,在需要支付时采用分开的方式授权和验证支付。API 安全防护与之相似,所以,我们需要一个具有验证和授权策略的可信环境。接下来,我们来聊聊如何去营造这样的一个环境。
Token 方案
大家可以将 Token 形象的理解为“身份证”,由服务端签发与验证,并且在有效期内检测是否具有合法性,根据 Token 具有随机性、不可预测性、时效性、无状态、跨域等特点。Token 在 API 安全中发挥着重要作用,使用 Token 方案的优点是什么?
- Token 完全由应用管理,所以它可以避开同源策略;
- Token 性能高、安全性好,可以避免 CSRF 攻击;
- Token 可以是无状态的,可以在多个服务间共享,解决跨域问题。
Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌
给大家简单叙述一下 Token 的鉴权方式的完整流程,以便于大家更好的理解 Token 在维护 API 安全方面的作用,首先客户端用户通过用户和密码进行首次登录,服务端在接收到用户请求,验证用户名和密码的正确性,登录验证成功后根据自定义规则生成 Token 信息,将生成的 Token 通过响应返回给客户端。
客户端再将 Token 信息存储在本地,在之后的每次请求中携带 Token 信息,服务端针获取请求中的 Token,并根据定义的验证机制判断 Token 合法性,验证成功获取用户信息,保持用户状态,Token 存活时间达到设置的有效期后自动失效,此后用户请求时 Token 验证不通过,就需要用户重新登录验证。
无论是从安全的角度考虑,还是从吊销的角度考虑,Token 都需要设有效期。使用 RefreshToken,它可以避免频繁的读写操作。这种方案中,服务端无需刷新 Token 的过期时间,一旦 Token 过期,就反馈给前端,前端使用 RefreshToken 申请一个全新 Token 继续使用。从而保障信息数据安全。
接口签名
企业在为第三方系统提供接口的时候,肯定要考虑接口数据的安全问题,比如数据是否被篡改,数据是否已经过时,请求是否唯一,数据是否可以重复提交等问题。其中数据是否被篡改相对重要。因而数据传输存在着极大的危险,所以必须接口签名,接口签名可以解决什么问题?
请求是否合法:是否是我规定的那个人;
请求是否被篡改:是否被第三方劫持并篡改参数;
防止重复请求(防重放):是否重复请求。
请求携带参数 appid 和 sign,只有拥有合法的身份 appid 和正确的签名 sign 才能放行。这样就解决了身份验证和参数篡改问题,即使请求参数被劫持,由于获取不到 secret(仅作本地加密使用,不参与网络传输),无法伪造合法的请求。措施依然不是最严谨的,只使用 appid 和 sign,虽然解决了请求参数被篡改的隐患,但是还存在着重复使用请求参数伪造二次请求的隐患。称为重放攻击(replay 攻击),大家可以通过加入 timestamp + nonce 两个参数来控制请求有效性,防止重放攻击。
简单来说一下该方案的签名规则,首先进行线下分配 appid 和 appsecret 针对不同的调用方分配不同的 appid 和appsecret,加入 timestamp (时间戳) 2 分钟内数据有效,再加入流水号 nonce (防止重复提交) 至少 10 位。针对查询接口,流水号只用于日志落地,便于后期日志核查。针对办理类接口需校验流水号在有效期内的唯一性,以避免重复请求。加入 signature,所有数据的签名信息。其中,需要放在请求头的字段: appid、timestamp、nonce、signature。
讲到这里我想大家对这两大方案有了一定的了解,总的来说 Token+ 签名认证两大方案,去维护 API 安全的主要原理是:
★ 通过认证服务,提供一个认证的 WEBAPI,用户先访问它获取对应的 Token;
★ 用户拿着相应的 Token 以及请求的参数和服务器端提供的签名算法计算出签名后再去访问指定的 API;
★ 服务器端每次接收到请求就获取对应用户的 Token 和请求参数,服务器端再次计算签名和客户端签名做对比,如果验证通过则正常访问相应的 API,验证失败则返回具体的失败信息。
当然仅仅使用 Token+ 签名认证两大“根基”,去全面保障 API 安全也是较为困难的,对于我们来说,为了更好的提高 API 安全性,就需要在设计和开发阶段,对 API 的安全性进行良好的构建和设计,这就需要大家遵守 API 安全开发规范进行实施。接下来讲解一下,在我开发日常中认为较为重要的五大规范。
五大安全规范
能见度
作为一名合格的应用程序开发人员和用户,我们需要知道正在发布哪些 API、如何以及何时更新它们、谁在访问它们以及如何访问它们。大家可以通过 Apifox 这类一体化协助平台提供可视化 API 设计,及时了解用户的 API 使用范围,以确保 API 安全的第一步。
Bot 缓解措施
在某些环境中,大量的应用程序流量,例如,账户登录或注册、购物车结账是由自动化 Bot 生成的。必须了解和管理流量配置文件,包括区分好 Bot 和坏 Bot,防止自动攻击的同时又不会阻止合法流量。有效的补充措施包括实施 Bot 白名单、黑名单和速率限制策略,以及特定于用例和相应 API 端点的地理围栏。
访问控制
API 访问权限通常是不受严格控制的,这可能导致意外暴露。确保向不同用户授予适当的 API 访问权限是一项至关重要的安全要求,访问者必须与企业的身份和访问管理(IAM)系统进行协调。
防止漏洞利用
API 通过消除 Web 表单或移动应用程序来简化攻击过程,从而使攻击者更容易利用目标漏洞。因此,保护 API 端点免遭业务逻辑滥用和其他漏洞利用是关键的 API 安全缓解要求。
数据防泄漏
防止由于编程错误或安全控制漏洞而产生的 API 暴露或非授权访问,是防止数据泄露或丢失的一项至关重要的安全要求。许多 API 攻击都是专门为获取对后端服务器和系统提供的关键数据的访问而设计的。
写在最后
事实上 API 作为应用程序之间,应用与用户之间交互的桥梁,承载着企业的业务逻辑和大量用户数据,一旦由 API 安全漏洞引发攻击事件,其后果注定难以承受。因此,建议企业用户通过引用专业的 API 管理工具产品或解决方案,快速建立起真实、有效的 API 安全“堡垒”,通过一体化协作平台高效,及时,准确补全安全上的缺口。
文章写到这里就告一段落了,希望这篇文章可以帮助大家解决一些 API 开发中产生的问题。高效,及时,准确的完成开发,感谢大家阅读。