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

news2024/11/29 10:33:47

在这里插入图片描述

原文: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 拒绝处理未加密的请求了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小白的学习资料:Spark MLlib 机器学习详细教程

Spark MLlib 机器学习详细教程 Apache Spark 是一个强大的开源分布式计算框架,广泛用于大数据处理和分析。Spark 提供了丰富的库,其中 MLlib 是其机器学习库,专为大规模数据处理设计。本教程将详细介绍 Spark MLlib,包括其主要功…

公司面试题总结(二)

7. 说说 JavaScript 中的数据类型?存储上的差别? • 基本类型: o Number o String o Boolean o Undefined o null o symbol • 引用类型 o Object o Array o Function • 声明变量时不同的内存地址分配: o 简单类型的…

德克萨斯大学奥斯汀分校自然语言处理硕士课程汉化版(第六周) - 预训练模型

预训练模型 1. 预训练模型介绍 1.1. ELMo1.2. GPT1.3. BERT 2. Seq2Seq 2.1. T52.2. BART 3. Tokenization 1. 预训练模型介绍 在预训练语言模型出现之前,统计语言模型(如N-gram模型)是主流方法。这些模型利用统计方法来预测文本中的下一个…

浙江大学蒋明凯研究员《Nature》正刊最新成果!揭示生态系统磷循环响应大气二氧化碳浓度升高关键机制

随着大气二氧化碳浓度的升高,陆地生态系统固存额外碳汇的能力取决于土壤养分的可利用性。前期的研究证据表明,在土壤低磷环境下,大气二氧化碳浓度的升高可以提升成熟森林的光合速率,但是没有产生额外生物量固碳。热带和亚热带森林…

自定义idea插件之hello idea plugin

写在前面 最近一直想研究下自定义idea插件的内容,这样如果是想要什么插件,但又一时找不到合适的,就可以自己来搞啦!这不终于有时间来研究下,但过程可谓是一波三折,再一次切身体验了下万事开头难。那么&…

自然语言处理:第三十二章HippoRAG:性能提高20% - 受海马体启发的RAG

文章链接: HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models 项目地址: OSU-NLP-Group/HippoRAG: HippoRAG is a novel RAG framework inspired by human long-term memory that enables LLMs to continuously integrate knowledge across e…

macbook本地部署 pyhive环境连接 hive用例

前言 公司的测试和生产环境中尚未提供基于Hive的客户端。若希望尝试操作Hive表,目前一个可行的方案是使用Python语言,通过借助pyhive库,您可以对Hive表进行各种操作。以下是一些示例记录供您参考。 一、pyhive是什么? PyHive是一…

电脑提示缺失iUtils.dll文件怎么办,分享几种靠谱的解决方法

在现代科技发展迅猛的时代,电脑已经成为我们生活和工作中不可或缺的工具。然而,随着使用时间的增长,电脑也会出现一些问题,其中之一就是开机时弹出窗口提示找不到iUtils.dll文件。这个问题可能会给用户带来困扰和不便,…

[AIGC] Springboot 自动配置的作用及理由

在详细解释SpringBoot的自动配置之前,先介绍以下背景知识。在创建现代复杂的应用程序时,一个困难的部分是正确地设置您的开发环境。这个问题尤其在Java世界中尤为突出,因为您必须管理和配置许多独立的标准和技术。 当我们谈论Spring Boot的自…

react 基础样式的控制(行内和className)

import ./index.cssconst style{color:red,font-size:150px }function App() {return (<div className"App"><h1>行内样式控制</h1><h1 style{{color:red,font-size:150px}} >asd </h1><span style{style} >asd </span>&l…

二叉排序树--c++

【相关知识】 二叉排序树&#xff08;也称二叉查找树&#xff09;&#xff1a;或者是一棵空的二叉树&#xff0c;或者是具有下列性质的二叉树&#xff1a; ⑴ 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于根结点的值&#xff1b; ⑵ 若它的右子树不空&#xff0c…

基本算法-枚举、模拟、递推(上)

目录 递归实现指数型枚举 题目描述 运行代码 代码思路 递归实现组合型枚举 题目描述 运行代码 代码思路 递归实现排列型枚举 题目描述 运行代码 代码思路 递归实现指数型枚举 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行代码 #include<iostream> …

Java装饰器模式,装饰器模式通常通过创建一个接口和一个或多个实现了该接口的类来开始,然后创建装饰器类,这些类也实现了相同的接口

1、定义一个接口Component public interface Component { void operation(); }2、创建一个实现了Component接口的简单类SimpleComponent public class SimpleComponent implements Component { Override public void operation() { System.out.println("SimpleCom…

【JS重点知识05】正则表达式

本文章目标&#xff1a;学习正则表达式概念及语法&#xff0c;编写简单的正则表达式实现字符查找或检测&#xff1b; 一&#xff1a;正则表达式简介 1 什么是正则表达式 是用于匹配字符串中字符组合的模式。在JS中&#xff0c;正则表达式也是对象 2 正则表达式作用 表单验…

【C#】WinForm关闭新(二级)界面使主程序关闭

参考视频&#xff1a;https://www.bilibili.com/video/BV1JY4y1G7jo?p14&vd_source1c57ab1b2e551da5b65c0dfb0f05a493 1.背景介绍 主程序界面&#xff0c;点击弹出二级界面&#xff08;同时隐藏主界面&#xff09;&#xff0c;不做任何设置&#xff0c;这时关闭二级界面…

FM1202,FM020和利时备品

FM1202,FM020和利时备品,统硬件设备、数据库、控制算法、图形、报表&#xff09;和相关系统参数的设置。对整个系统进行监视和控制。操作员站主要完成以下FM1202,FM020和利时备品,各种监视信息的显示、查询和打印&#xff0c;主要有工艺流程图显示、趋势显示、参数列表显示、报…

将二叉排序树转换成双向链表--c++【做题记录】

【问题描述】 编写程序在不增加结点的情况下&#xff0c;将二叉排序树转换成有序双向链表&#xff08;如下图&#xff09;。 链表创建结束后&#xff0c;按照从前往后的顺序输出链表中结点的内容。 【输入输出】 【输入形式】 第一行输入数字n&#xff0c;第二行输入n个整数…

【CS.SE】浅谈: 程序员的职业素养与成长之路

文章目录 1 引言2 持续学习与自我提升2.1 永无止境的学习之路2.2 真实案例&#xff1a;自学Python 3 团队合作与沟通能力3.1 高效沟通是团队成功的基石 4 责任心与职业道德4.1 责任心&#xff1a;代码背后的承诺4.2 真实案例&#xff1a;修复紧急Bug 5 适应变化与快速反应5.1 适…

Linux安装MySQL教程【带图文命令巨详细】

巨详细Linux安装MySQL 1、查看是否有自带数据库或残留数据库信息1.1检查残留mysql1.2检查并删除残留mysql依赖1.3检查是否自带mariadb库 2、下载所需MySQL版本&#xff0c;上传至系统指定位置2.1创建目录2.2下载MySQL压缩包 3、安装MySQL3.1创建目录3.2解压mysql压缩包3.3安装解…

用Python代码锁定Excel单元格以及行和列

Excel能够帮助用户高效地组织数据&#xff0c;还支持复杂的公式计算和数据分析。而随着团队协作的日益频繁&#xff0c;保护数据的准确性和完整性变得尤为重要。在Excel表格中&#xff0c;我们可以通过锁定特定的单元格或区域&#xff0c;防止对单元格内容进行随意修改&#xf…