最佳实践的实践 - API 不应将 HTTP 重定向到 HTTPS

在这里插入图片描述

原文:jviide - 2024.05.23

TL;DR: 与其将 API 调用从 HTTP 重定向到 HTTPS,不如让失败显而易见。要么完全禁用 HTTP 接口,要么返回明确的 HTTP 错误响应,并撤销通过未加密连接发送的 API 密钥。遗憾的是,许多知名的 API 提供商目前并没有这样做。

背景

当用户将网络浏览器指向 HTTP URL 时,服务通常会将请求重定向到相应的 HTTPS 页面。通信流的这一未加密部分有其缺陷。共享网络中的第三方和网络中介可以从最初的 HTTP 流量中嗅探密码和其他机密,甚至通过 MITM 中间人攻击冒充网络服务器。尽管如此,重定向技术在从基本不加密的早期网络向大部分加密的当今网络过渡的过程中,迈出了有用的第一步。

后来的技术进一步加强了安全性。现在,服务器可以在发送 HTTP 到 HTTPS 的初始重定向响应的同时发送 HSTS(HTTP Strict-Transport-Security),告诉用户的浏览器从此只能在该域使用 HTTPS。这就将琐碎的嗅探和 MITM 中间人攻击的机会窗口限制在了第一次请求。随后,浏览器增加了 HSTS 预加载列表和 HTTPS-Only 模式,允许完全跳过初始未加密请求。

从可用性和安全性权衡的角度来看,这一切对于面向用户的网站都是合理的。但有趣的是,重定向方法似乎也被 API 广泛采用。API 主要由其他软件使用,因此同样的可用性论点在这里并不适用。此外,许多 API 客户端往往不会像浏览器一样保留他们所看到的 HSTS 标头状态。

本文认为,由于这些因素,应重新考虑将 API 调用从 HTTP 重定向到 HTTPS 的常见做法。虽然本文主要针对 REST API,但其观点也适用于使用 HTTP(S) 作为传输机制的其他类型的 API。

一个简单的拼写错误就足够了

在工作中,我们正在针对第三方 API 构建一个新的集成。初始代码提交中包含了一个拼写错误的 API 基础 URL,写成了 "http://..." 而不是 "https://..."。这是一个相当容易犯的错误。

这个错误在运行时基本上被掩盖了:第三方 API 对每个请求都会响应 301 重定向到其 HTTPS 端。Node.js 内置的 fetch 功能会愉快且悄悄地 跟随访问这些重定向到 HTTPS 端点。

(注:Go 语言默认的 http.Client 也会自动请求重定向后的端点,除非自定义 CheckRedirect 属性。)

现在,这样的 API 请求都将 API 密钥以明文形式发送到网络上,然后再将其发送到加密端点。一个字母的遗漏可能会在我们不知情的情况下将使用的 API 密钥暴露给第三方。随着集成的进行,代码很有可能会在数年之间,泄露 API 调用中的任何机密。从长远来看,恶意的可能性会不断累积。

幸运的是,我们在代码审查期间发现了这个错误,避免了错误扩散到生产甚至测试中。我们还意识到,我们自己的 API 也进行了类似的 HTTP 到 HTTPS 重定向。

快速失败原则

当 API 将 HTTP 请求重定向到 HTTPS,而 API 客户端默默地跟随访问这些重定向时,它往往会隐藏像上述案例中的拼写错误。一个简单的字母遗漏很容易被忽略,最终进入生产环境,危及整个系统的机密性。

在大多数情况下,最好遵循快速失败原则:未加密的 API 调用应以明显可见的方式失败,这样开发人员可以在开发过程中尽早发现并修复拼写错误。

快速失败最好的解决方案是完全禁用 API 服务器的 HTTP 接口,不再响应对 80 端口的连接尝试。如果初始的未加密连接从未建立,那么就不会发送 API 密钥,从而减轻嗅探攻击的风险,并将 MITM 中间人攻击的机会窗口限制在极小的时间范围内。这种方法适用于以自己的域名(如 api.example.com)托管的 API。

我们自己的 API 位于 /api 路径下,与我们服务的 Web UI 在同一个域名下。因此,我们对完全禁用 HTTP 接口没有信心,所以选择了第二种方案:所有在 /api 路径下的未加密 HTTP 请求,现在都返回描述性错误信息和 HTTP 状态码 403。在开发过程中可能会出现一些初始明文请求,但开发人员更容易注意到它们。

还有谁?

这解决了我们自己的 API 问题。我们还联系了第三方 API 提供商和几个朋友,让他们检查一下自己的 API。谁知道呢,也许有一些常用的 API 接受 API 密钥(或其他凭证),并且也从 HTTP 重定向到 HTTPS?

我从脑海中列出了一些知名的 API,并做了一个小调查。其中有几个返回 HTTP 错误或完全拒绝连接。这里列出了它们的 cURL 命令,以便查看它们的详细响应:

  1. Stripe API:返回 403 (“Forbidden”) 和一个描述性错误信息。
    curl -i http://api.stripe.com
  2. NPM Registry API:返回 426 (“Upgrade Required”) 和一个描述性错误信息。
    curl -i -X PUT -H 'content-type: application/json' -d '{}' 'http://registry.npmjs.org/-/user/org.couchdb.user:npm'
  3. Fastmail JMAP API:整个 HTTP 接口似乎已被禁用。
    curl -i -H 'Authorization: Bearer foo' http://api.fastmail.com/jmap/session

然而,以下 API 确实 响应了 HTTP 到 HTTPS 的重定向:

  1. Facebook Graph API
    curl -i 'http://graph.facebook.com/me?access_token=foo'
  2. IBM Cloud API
    curl -i "http://iam.cloud.ibm.com/identity/token" -d "apikey=YOUR_API_KEY_HERE&grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey" -H "Content-Type: application/x-www-form-urlencoded" -H "Authorization: Basic Yng6Yng="
  3. OpenAI API — 更新于 2024-05-28,已返回错误。
    curl -i -H "Content-Type: application/json" -H "Authorization: Bearer 123" -d '{}' http://api.openai.com/v1/chat/completions

我没有单独向所有这些 API 提供商报告这些发现。有一些未列出的异常,我确实联系了它们,但结果各不相同。

请谨慎对待每个结果:我不得不在没有有效凭证的情况下测试其中一些 API,或者使用文档示例中的凭证。但总体模式表明,API 将 HTTP 请求重定向到 HTTPS 的习惯非常普遍。为什么会这样呢?

最佳实践也需要实践

当与他人谈论这个话题时,许多人都指出,API 从 HTTP 重定向到 HTTPS 的缺点是显而易见的——事后看来是这样。

面向用户的应用程序的重定向经常在最佳实践列表和备忘录中被提及,例如由 OWASP(开放网络应用安全项目)发布的那些。相反,专门针对 API 的建议似乎很少。我只在 OWASP 网站的深处发现了几处提及,例如一个出色的 PDF 幻灯片集,由 Philippe De Ryck 编写,名为"常见 API 安全陷阱":

在这里插入图片描述

“常见 API 安全陷阱”的第 8 张幻灯片,重点强调了相关部分。

我的 Google 搜索技巧可能不够好。不过,也许每个建议面向用户的网站进行 HTTP 到 HTTPS 重定向的最佳实践项目,都应该附加明确的注意事项,在显著位置建议不要对 API 进行此类重定向。因此,我在 OWASP 的 GitHub 页面上发起了一个议题,建议相应修改 OWASP 的传输层安全备忘单。

额外内容:以明文响应的流行 API

在审查 API 列表时,我碰到了一些既不重定向也不拒绝未加密请求的流行 API。它们只是以未加密的 HTTP 响应回应未加密的 HTTP 请求,没有在任何阶段强制使用 HTTPS。

也许它们有自己的原因,或者只是意外地错误配置了它们的反向代理。不管怎样,考虑到它们都处理潜在的敏感数据,我通过各自的安全渠道联系了这些 API 提供商,并解释了这个问题。

结论

由于 API 的性质,将 HTTP 重定向到 HTTPS 可能弊大于利。与面向用户的网页不同,API 主要由其他软件使用。API 客户端通常会自动跟随重定向,并且不会维护状态或支持诸如 HSTS 之类的安全标头。这可能导致静默故障,即每个 API 请求中的敏感数据最初都是以明文形式在网络上传输的,没有经过加密。

让我们采用“快速失败”的方法,完全禁用 HTTP 接口或对未加密请求返回明确的错误响应。这可以确保开发人员能够快速注意并修复意外的 http:// URL 为 https://。我们应将通过未加密连接发送的 API 凭证视为泄露,并立即自动撤销。

在撰写本文时,一些知名且流行的 API 确实将 HTTP 请求重定向到 HTTPS。这种行为似乎很普遍,也许是时候修改最佳实践,明确建议 API 拒绝处理未加密的请求了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/690575.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GSS7000卫星导航模拟器结合RTKLIB 接收NTRIP网络RTCM数据以输出RS232

本文聚焦,使用GSS7000仿真GNSS NTRIP,利用开源工具RTKLIB 作为NTRIP Client 接受GSS7000仿真的RTCM数据, 并通过STRSVR将收到的RTCM数据通过USB-RS232数据线吐出,并转给DUT,让其获得RTK -FIXED 固定解。 废话不多说&a…

vue3中的ref与reactive的区别

目录 1、两者的区别底层实现响应式引用与响应式对象 2、用法3、vue3中声明的数组/对象3.1 通过reactive 声明的Array/Object,给它重新分配一个全新的对象时,会出错、或失去响应式效果 3.2 解决方案 4、cosnt 说明5、Proxy 与 definePropertyref 浅层响应…

数据结构--二叉树(二)

链式二叉树 链式二叉树是链式树集合中的一种,该树的每个根节点最多只有两个孩子节点,我们一般用左右孩子来称呼,在初学链式二叉树时,由于大家对链式二叉树的结构掌握还不够深入,为了降低本章的学习难度及成本&#xff…

pytorch构建模型训练数据集

pytorch构建模型训练数据集 pytorch构建模型训练数据集1.AlexNet:1.1.导入必要的库:1.2.数据预处理和增强:1.3.加载数据集:1.4.划分测试集和训练集:1.5.创建数据加载器:1.6.加载AlexNet模型:1.7.修改模型以…

Oracle EBS AP发票创建会计科目错误:子分类帐日记帐分录未按输入币种进行平衡

系统版本 RDBMS : 12.1.0.2.0 Oracle Applications : 12.2.6 问题症状: 提交“创建会计科目”请求提示错误信息如下: 中文报错: 该子分类帐日记帐分录未按输入币种进行平衡。请检查日记帐分录行中输入的金额。 英文报错:The subledger journal entry does not balance i…

电机专用32位MCU PY32MD310,Arm® Cortex-M0+内核

PY32MD310是一颗专为电机控制设计的MCU,非常适合用做三相/单相 BLDC/PMSM 的主控芯片。芯片采用了高性能的 32 位 ARM Cortex-M0 内核,QFN32封装。内置最大 64 Kbytes flash 和 8 Kbytes SRAM 存储器,最高48 MHz工作频率,多达 16 …

Suryxin’s ACM退役记

序 我的记忆力很差,经历过的很多事情都已经记不太清了,其中有很多美好回忆也已经消散,我很惋惜没能留存一些照片和声音或是文字供我怀念,这就像《泰坦尼克号》一样,露丝和杰克感人肺腑的爱情故事,最后也仅…

2024年最新的软件测试面试总结(答案+文档)

🍅 点击文末小卡片 ,免费获取软件测试全套资料,资料在手,涨薪更快 测试技术面试题 1、什么是兼容性测试?兼容性测试侧重哪些方面? 参考答案: 兼容测试主要是检查软件在不同的硬件平台、软件平…

[word] 在Word中插入分页符 #经验分享#经验分享#笔记

在Word中插入分页符 在 Word中插入分页符?教大家如何在正文中快速的插入分页符。 ? ? ?1、在正文中选择我们要分页的位置。 ? ? ?2、点击插入,选择分页功能里面的“分页符”功能,即可成功在我们选择的位置进行分页。 ? ? ? ?以上…

PICRUSt2在微生物功能预测分析中的应用解读

谷禾健康 微生物组学研究现已超越微生物群落组成分析得到更广泛的使用。大量的人类微生物组研究证据表明,肠道微生物组的功能变化对炎症和免疫反应的影响起到关键的影响作用。 16S rRNA分析是微生物组研究作为最常用便捷且具有成本效益的测量技术,用于分…

从技术到产品:以客户为中心的产品研发之路

一、引言 在快速发展的商业环境中,产品作为连接企业与市场的桥梁,其重要性不言而喻。从摸着石头过河搞产品,到广泛传播NPDP(新产品开发流程)理念,产品研发的道路经历了从直觉驱动到系统思维的转变。本文将…

【SpringBoot】SpringBoot整合RabbitMQ消息中间件,实现延迟队列和死信队列

📝个人主页:哈__ 期待您的关注 目录 一、🔥死信队列 RabbitMQ的工作模式 死信队列的工作模式 二、🍉RabbitMQ相关的安装 三、🍎SpringBoot引入RabbitMQ 1.引入依赖 2.创建队列和交换器 2.1 变量声明 2.2 创建…

[经验] 昆山教育网(昆山教育网中小学报名) #媒体#职场发展#微信

昆山教育网(昆山教育网中小学报名) 昆山教育局网站 网站:昆山市教育局 昆山市教育局全面贯彻执行党和国家的教育方针、政策,落实有关教育工作的法律、法规;负责制定本市教育工作的实施意见和措施,并监督…

WEB漏洞服务能提供哪些帮助

在数字化浪潮的推动下,Web应用程序已成为企业展示形象、提供服务、与用户进行交互的重要平台。然而,随着技术的飞速发展,Web应用程序中的安全漏洞也日益显现,成为网络安全的重大隐患。这些漏洞一旦被恶意攻击者利用,可…

C++笔记之一个函数多个返回值的方法、std::pair、std::tuple、std::tie的用法

C++笔记之一个函数多个返回值的方法、std::pair、std::tuple、std::tie的用法 —— 2024-06-08 杭州 code review! 文章目录 C++笔记之一个函数多个返回值的方法、std::pair、std::tuple、std::tie的用法一.从一个函数中获取多个返回值的方法1. 使用结构体或类2. 使用`std::t…

C# MES通信从入门到精通(11)——C#如何使用Json字符串

前言 我们在开发上位机软件的过程中,经常需要和Mes系统进行数据交互,并且最常用的数据格式是Json,本文就是详细介绍Json格式的类型,以及我们在与mes系统进行交互时如何组织Json数据。 1、在C#中如何调用Json 在C#中调用Json相关的对象的话,需要引用Newtonsoft.Json的dl…

三十六篇:未来架构师之道:掌握现代信息系统典型架构

未来架构师之道:掌握现代信息系统典型架构 1. 引言 在企业的数字化转型浪潮中,信息系统架构的角色变得日益重要。它不仅承载了企业的IT战略,更是确保企业在复杂、动态的市场环境中稳定运行的关键。作为信息系统的骨架,一个精心设…

贪心算法学习二

例题一 解法(贪⼼): 贪⼼策略: 由于只能交易⼀次,所以对于某⼀个位置 i ,要想获得最⼤利润,仅需知道前⾯所有元素的最⼩ 值。然后在最⼩值的位置「买⼊」股票,在当前位置「卖出」…

Spring进阶技巧:利用AOP提前介入的巧妙实践

Spring框架中的面向切面编程(AOP)是一种强大的机制,它允许开发者在不修改原有代码的情况下,对程序进行横向切面的功能扩展。AOP提供了一种方式,可以在目标Bean的生命周期早期阶段就实施切面逻辑,这为我们在…

JMS VS AMQP

JMS(Java Message Service)是一个为Java平台设计的API,主要针对Java开发者提供了一套用于企业级消息服务的标准接口。而AMQP(Advanced Message Queuing Protocol)是一个应用层协议,它提供了一个开放的、标准…