研发和测试人员应该了解的API网络安全知识

随着越来越多的数据以API方式暴露,API的安全性变得越来越重要。由于API提供了对大量数据的直接访问,绕过了浏览器的预防措施,因此常会有SQL注入和XSS等问题。

API安全性的第一件事是,对你的API进行检测,以检测和阻止常见攻击以及未知的对象。在OWASP安全API列表中,你可以看到常见的API 漏洞和安全风险 。

分页和资源限制不安全

大多数API提供对作为实体列表(例如/users或/widgets)的资源的访问。诸如浏览器之类的客户端,通常会过滤并分页浏览此列表,以限制返回给客户端的数量,如下所示:

First Call: GET /items?skip=0&take=10 
Second Call: GET /items?skip=10&take=10

但是,如果该实体具有任何PII (Personally Identifiable Information, 个人识别信息 ) 或其他敏感信息,则黑客很可能会抓取该端点以获取数据库中信息。这可能是最危险的。这也便于竞争对手了解组织的运行状况,或者为诈骗者提供获取大型电子邮件列表的方式。

初级的保护机制是检查请求数据总量,如果大于100或1000,则会引发业务错误。但这样组,也带来了两个问题:

  1. 对于数据API,合法客户可能需要获取并同步大量记录,例如通过cron任务调度。人为地限制分页大小可能会迫使你的API访问过于频繁,从而降低整体吞吐量。最大限制是为了确保满足内存和可伸缩性要求(并防止某些DDoS攻击),而不是为了保证安全性。
  2. 不能真正防止黑客攻击,黑客使用如下脚本(在重复访问之间随机睡眠)就可以绕过限制。
skip = 0
while True:    response = requests.post('https://api.acmeinc.com/widgets?take=10&skip=' + skip),                      headers={'Authorization': 'Bearer' + ' ' + sys.argv[1]})    print("Fetched 10 items")    sleep(randint(100,1000))    skip += 10

如何防止分页攻击

为了防止分页攻击,你应该跟踪在一定时间段内每个用户或API密钥,访问了单个资源的多少个次。通过在用户级别跟踪API资源访问,你可以在用户或API密钥达到阈值(例如在一个小时内访问1,000,000次)后阻止它们。像验证码一样,这会减慢黑客利用你的API的速度。

API密钥生成不安全

大多数API受某种API密钥或JWT(JSON Web令牌)保护。由于API安全工具可以检测到异常的API行为并自动阻止对API密钥的访问,因此这提供了一种天然的方式来跟踪和保护你的API。但是,黑客会通过生成大量用户和使用大量API密钥来绕过这些机制,就像网络黑客会使用大量IP地址来规避DDoS保护一样。

如何保护API密钥池

抵御此类攻击的最简单方法是要求使用方注册你的服务并生成API密钥。可以使用Captcha和2-Factor身份验证来阻止Bot(机器人)的暴力访问。除非有商业合作需求,否则注册你的服务的新用户不应具有以编程方式生成API密钥的能力。

密钥暴露

使用API的方式会增加密钥暴露的可能性:

  1. 允许API访问的时间段如果不提前设置好,这会增加黑客获得未过期的有效API密钥的可能性。
  2. API的使用者因为可以直接访问密钥,那就会存在将包含API密钥的CURL命令意外地复制/粘贴到公共论坛(如GitHub Issues或Stack Overflow中)的风险。
  3. API密钥通常承载令牌,一旦暴露,用户身份也就容易被获取。

如果由于用户错误而暴露了密钥,那么你可能会以为你是API提供者。因此需要通过添加防止意外暴露的保护措施来帮助他们。

如何防止密钥暴露

防止密钥暴露的最简单方法是利用两个令牌而不是一个。一个刷新令牌被存储为环境变量,并且只能用于生成短暂的访问令牌。与刷新令牌不同,这些短暂的令牌可以访问资源,但是有时间限制,例如数小时或数天。

客户将存储刷新令牌和其他API密钥。然后,你的SDK将在SDK初始化时或最后一个访问令牌到期时生成访问令牌。如果将CURL命令粘贴到GitHub等其他公共论坛中,那么黑客将只能在有限的时间内使用它。

DDoS攻击

API开辟了全新的业务模型,客户能够以编程方式访问你的API平台。但是,这会使DDoS保护变得棘手。大多数DDoS保护,目的是阻止恶意请求,但仍然需要让受信任用户通过。这就需要对HTTP请求进行分析识别,以检查机器人流量看起来像什么。

防止DDoS攻击

关于API的神奇之处在于,几乎每个访问都需要一个API密钥。如果请求没有API密钥,则可以自动拒绝它。

那么,如何处理经过身份验证的请求?最简单的方法是利用每个API密钥的速率限制计数器,例如每分钟处理X个请求,并使用429 HTTP response拒绝超过阈值的那些请求。有多种算法可以做到这一点,例如漏斗和固定窗口计数器。

服务器没有设置正确的SSL

数据可能由于错误配置的SSL证书或允许非HTTPS流量而泄漏。

对于现代应用程序,几乎没有理由接受非HTTPS请求,但是客户可能会错误地从其应用程序或暴露API密钥的CURL发出非HTTP请求。

如何设置正确的SSL

通过Qualys SSL Test或类似工具测试SSL的设置。

你还应该阻止所有在负载均衡器中完成的非HTTP请求。你还应该删除所有HTTP标头,保证只有HTTPS请求才能访问。如果你的API仅由你自己的应用使用,或者只能在服务器端访问。

缓存头设置不正确

对动态数据的访问,API提供可API密钥的范围。因此你的缓存头要真能够正确使用API密钥的范围,以防止交叉污染。例如,具有代理服务器的客户可能使用多个API密钥,一个用于开发,一个用于生产。

如何设置正确的缓存头

你应该确保正确配置了Cache-Control标头。

app.use((req, res, next) => {  res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');  res.setHeader('Pragma', 'no-cache');  // ...
});

记录和监控不足

大多数系统入侵研究表明,检测到数据泄漏的时间超过200天。如果你没有适当的API日志记录和监视,攻击者可以继续使用相同的漏洞,甚至可以探测更多漏洞。

如何正确添加API日志记录

你应该确保API日志记录不仅跟踪API请求本身,而且还应绑定到用户以对用户行为分析,数据并至少存储一年。Moesif API Security之类的解决方案为API产品提供了一整套API监视和分析功能,并且只需几分钟即可开始使用。

没有保护内部端点

不能因为未记录内部端点,而想当然认为黑客无法调用它。因此,除了使用身份验证和授权方案进行保护之外,你还应确保这些内部端点完全不暴露于公网。而这可以在负载均衡器或API网关中完成,提供多级安全性(一种常见的预防策略)。

没有处理授权

虽然大多数API开发人员都会添加诸如API密钥或OAuth之类的全局身份验证方案来验证人员身份,但实现授权却很困难,授权并且需要与身份验证分开进行。授权涉及检查此人(已被识别)是否可以访问特定资源。

因为授权是基于你的应用程序逻辑,因此你的授权标识符具有不规律性,否则黑客可以通过迭代轻松测试不同的id。对于在插入时id自增的SQL数据库尤其如此。

如何修正授权

确保已授权身份验证的用户有权访问所需的资源。这可能涉及检查链接到相关对象的用户ID或访问控制列表(ACL)。

译文链接: https://dzone.com/articles/top-10-api-security-threats-every-api-team-should

posted on 2020-08-24 16:00  Raltu&RealRain  阅读(350)  评论(0编辑  收藏  举报

导航