最佳实践的实践 - 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 命令,以便查看它们的详细响应:
- Stripe API:返回 403 (“Forbidden”) 和一个描述性错误信息。
curl -i http://api.stripe.com - 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' - Fastmail JMAP API:整个 HTTP 接口似乎已被禁用。
curl -i -H 'Authorization: Bearer foo' http://api.fastmail.com/jmap/session - …
然而,以下 API 确实 响应了 HTTP 到 HTTPS 的重定向:
- Facebook Graph API
curl -i 'http://graph.facebook.com/me?access_token=foo' - 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=" - 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 拒绝处理未加密的请求了。
相关文章:
最佳实践的实践 - API 不应将 HTTP 重定向到 HTTPS
原文:jviide - 2024.05.23 TL;DR: 与其将 API 调用从 HTTP 重定向到 HTTPS,不如让失败显而易见。要么完全禁用 HTTP 接口,要么返回明确的 HTTP 错误响应,并撤销通过未加密连接发送的 API 密钥。遗憾的是,许多知名的 A…...
四种跨域解决方案
文章目录 1.引出跨域1.基本介绍2.具体演示1.启动之前学习过的springboot-furn项目2.浏览器直接访问 [localhost:8081/furns](http://localhost:8081/furns) 可以显示信息3.启动前端项目,取消请求拦截器,这样设置,就会出现跨域4.跨域原因 2.跨…...
移动端投屏到大屏幕的操作详解
如果你懒得折腾电脑、电视或其他大屏设备上的影视软件安装及配置,可以选择直接在手机端上将影片投屏到电脑、电视或其他大屏设备上,这里给大家分享三种手机投屏的方法。 系统自带的投屏功能 不管是安卓、鸿蒙还是苹果操作系统,都自带了无线…...
【环境搭建】3.阿里云ECS服务器 安装Redis
在阿里云的 Alibaba Cloud Linux 3.2104 LTS 64位系统上安装 Redis 可以通过以下步骤完成: 1.更新系统软件包: 首先,更新系统软件包以确保所有软件包都是最新的: sudo yum update -y2.安装编译工具和依赖项: Redis…...
动态语言的开源编译器汇总
对于动态语言而言,我们通常不会使用传统意义上的“编译器”,因为动态语言往往是在运行时解释执行的,或者被转换为中间形式(如字节码),再由虚拟机执行。不过,为了性能考虑,现代动态语…...
Linux防火墙配置001
Linux防火墙主要用于控制网络流量,保护系统安全。在Linux中,有几种不同的防火墙管理工具,其中最常见的是iptables和firewalld。本章主要讲述如何关闭防火墙。 操作系统: CentOS Stream 9 操作步骤: 关闭防火墙&…...
Tomcat概述及部署
目录 一.Tomcat概述 1.介绍 2.使用场景 3.组件构成 4.组件结构 5.请求过程 二.Tomcat部署 1.关闭防火墙 2.下载安装JDK 3.安装启动tomcat 4.部署虚拟主机 4.1.创建 xy101 和 xy102 项目目录和文件 4.2.修改 Tomcat 主配置文件 server.xml 一.Tomcat概述 1.介绍 …...
[Vue3:Vite构建项目]:安装router实现登录页面路由跳转
文章目录 一:前置依赖查看依赖安装vite npm create vitelatest sys-instruction-0607 --template vue-ts安装路由:npm install vue-router4安装elementUI:npm install element-plus --save 二:配置文件:viewsÿ…...
概率论与数理统计,重要知识点——全部公式总结
二、一维随机变量及其分布 五个分布参考另外一篇文章 四、随机变量的数字特征 大数定理以及中心极限定理 六、数理统计...
Spring系列-SpringMvc父子容器启动原理解析
1、Spring整合SpringMVC 特性: 说到Spring整合SpringMVC唯一的体现就是父子容器: 通常我们会设置父容器(Spring)管理Service、Dao层的Bean, 子容器(SpringMVC)管理Controller的Bean .子容器可以访问父容器的Bean, 父容器无法访…...
[ssi-uploader插件]解决如何接收服务器返回数据+修改参数名称
前言 ssi-uploader是一款非常好用的多文件上传插件,源码是开源的,在github上面即可下载: https://github.com/ssbeefeater/ssi-uploader 但是源码有些微小的不足,今天我们解决两点问题: 上传文件完成后,…...
InfiniGate自研网关实现思路七
25.网关Nginx负载模型配置 通过模拟多个HTTP服务配置到 Nginx 做负载均衡,以学习API网关负载的配置和使用 API 网关是用于支撑分布式 RPC 接口协议转换提供 HTTP 调用的一套服务,那么 API 网关系统就需要可横向扩展来满足系统的吞吐量诉求。所以这里需…...
277 基于MATLAB GUI火灾检测系统
基于MATLAB GUI火灾检测系统,可以实现图片和视频的火苗检测。火焰识别的三个特征:1个颜色特征,2个几何特征颜色特征:HSV颜色空间下,对三个通道值进行阈值滤波,几何特征1:长宽比,几何…...
【西瓜书】4.决策树
1 递归返回情况 (1)结点包含样本全为同一类别 (2)属性集为空,没有属性可供划分了 或 有属性,但是在属性上划分的结果都一样 (3)结点为空结点 **结束时判定该结点的类别遵循如下规则&…...
区块链--Ubuntu上搭建以太坊私有链
1、搭建私链所需环境 操作系统:ubuntu16.04,开虚拟机的话要至少4G,否则会影响测试挖矿时的速度 软件: geth客户端 Mist和Ethereum Wallet:Releases ethereum/mist GitHub 2、安装geth客户端 sudo apt-get update …...
菜品信息分页查询——后端SpringBoot
1.分页查询的逻辑: 页面发送ajax请求,将分页查询参数(page,pageSize, name)提交到服务端,获取分页数据; 页面发送请求,请求服务端进行图片下载,用于页面图片展示。 开发菜品信息分页查询功能&a…...
利用GPT和PlantUML快速生成UML图用于设计
在软件开发中,设计阶段可是关键的一步。UML(统一建模语言)图能帮我们更清晰地理解和规划系统结构,但手动画UML图有时会很费时费力。好消息是,通过结合使用ChatGPT和PlantUML,我们可以高效地生成UML图&#…...
web-上传项目文件夹到Git远程仓库
Git初识 概念:一个免费开源,分布式的代码版本控制系统,帮助开发团队维护代码 作用:记录代码内容,切换代码版本,多人开发时高效合并代码内容 检验成功 打开bash终端(git专用)命令…...
使用OpenPCDet训练与测试Transformer模型:如何加载自己的数据集
引言 Transformer架构因其强大的序列处理能力和长距离依赖捕捉能力,在自然语言处理领域取得了巨大成功。近年来,这一架构也被引入3D物体检测领域,如Voxel Transformer等,显著提升了模型在复杂场景下的检测性能。OpenPCDet整合了多…...
四舍五入问题
单纯输出四舍五入可以用 printf("%.nf",num); 但是这个方法有时候会出错 代表输出n位四舍五入小数 而将数四舍五入赋值给变量可以用round()函数 a round(num); 表示将num四舍五入赋值给a 但是这么些只能转换位四舍五入的整数 可以改…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
