需要SSL/TLS的请求应该发送什么适当的HTTP响应?

50

我正在设计一个RESTful API,其中一些调用是通过HTTP公开的,而一些需要API密钥和HTTPS加密。 我在考虑如果私有资源接收到HTTP请求时应该发送哪个响应代码。目前唯一显眼的是412 - 先决条件失败,但标准指出先决条件由请求者而不是服务器强加。

是否有适当的响应代码来处理这种情况,还是我只需要采用400

5个回答

30

我不知道这是否被HTTP客户端广泛接受,但严格按照RFC规范,服务器应该做出如下响应:

HTTP/1.1 426 Upgrade Required
Upgrade: TLS/1.0, HTTP/1.1
Connection: Upgrade

来源:
https://www.rfc-editor.org/rfc/rfc2817#section-4.2


3
有趣。 RFC和OWASP在建议方面存在差异。我更喜欢OWASP的版本-不要响应请求,直接丢弃该数据包。采用RFC方法时,中间人可以拦截响应(因为它尚未是https),并将其重定向到伪造的网站。 - Sripathi Krishnan
是的,我同意 - 这绝对是一个漏洞。即使断开连接可能会令人困惑,但安全问题应该优先考虑。此外,请注意,提到的RFC现在实际上已经有10年历史了(在那个时候,安全性可能不像今天这样重要)。 - MicE
你知道吗,仔细看了一下,我意识到这是用于从某个早期版本的SSL升级到TLS。我不使用TLS,所以我不能使用该标头,而且由于规范专门针对TLS,我认为这不合适。不幸的是,我也没有办法断开连接... - gtd
5
众所周知,https 是在 RFC 2818 中规定的(基于 TLS 的 HTTP)。RFC 2817 几乎不会被使用。请注意,IETF 规范将 TLS 称为“TLS”,因为它是一个 IETF 标准(而 SSL 不是):你可以很容易地阅读所有这些规范并以“SSL”为标准(除了确实指向早期版本)。RFC 2817 并不是升级到 TLS(1.x)从 SSLv3,它是关于在同一连接上从纯文本 HTTP 升级到 SSL/TLS 的。 - Bruno
7
即使您的服务器会丢弃HTTP请求,仍然可能发生中间人/拦截攻击。实际上,除非客户端使用https,否则不能保证他们获得的任何响应都不会被篡改。 - Agoston Horvath
4
我会尽力做到最好。以下是需要翻译的内容:肯定认为 MITM 讨论过于深入了。MITM 可以在你甚至没有数据包可丢弃之前进行拦截。如果客户端尝试 HTTP,那么事情就完成了。426 的目的是告诉客户端的开发人员修复他们该死的代码。 - Matthew

9

强制HTTP客户端使用HTTPS的最安全方法是HTTP严格传输安全

以前常见的建议是断开连接,但这种做法已被OWASP网站所支持的HSTS取代(参见)


6
  1. HSTS草案已经被移交至IETF处理。
  2. 阅读它并不能给出对问答者问题的好回答。
- David Moles
2
HSTS强制整个站点使用HTTPS。上述海报希望某些资源可通过HTTP访问,而其他资源仅限于HTTPS。因此,无法使用HSTS,因为它适用于所有资源。 - Fred
2
这并没有回答楼主的问题。他问的是当客户端通过http连接时该怎么办,而不是HSTS头文件,这只有在用户已经通过https连接时才会生效。 - BadZen
您可以在浏览器中预加载HSTS,以防止任何HTTP调用,https://hstspreload.org/ - Eric

7
适当的错误代码应该类似于403.4 - 要求 SSL
虽然在HTTP 1.1 的 RFC中没有明确记录这种行为,但这种行为符合其中概述的要求:
服务器理解了请求,但拒绝满足它。授权无法帮助,不应重复请求。如果请求方法不是 HEAD,并且服务器希望公开为什么未能满足请求,它应该在实体中描述拒绝的原因。如果服务器不希望向客户端提供此信息,则可以使用状态码404(未找到)代替。
在某些情况下,添加自己的子代码(如 SSL 示例)可能会有所帮助,但由于这个子代码对第三方来说没有意义,我建议不要这样做。

因此,您最终的错误消息应该像“403-私有资源”这样。请注意,即使在缺少API密钥的情况下,“401-未经授权”也不应该被使用,除非您的API密钥实际上可以通过WWW-Authenticate头字段传输。


4
请注意,IIS状态码是虚假的。HTTP状态码只由数字组成(恰好为3个)。请参阅http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6.1.1。还要注意,403的原因短语为“Forbidden”,且不可修改。任何进一步的解释都应该写在响应正文中。 - Jan Algermissen
1
是的,虽然子代码很吸引人,但我无法接受它的非标准化特性。 - gtd
4
我同意其他评论者的观点,不应该使用子代码,但可以选择使用普通的403状态码。例如,Twitter在其API中使用403状态码。请参见https://dev.twitter.com/docs/security/using-ssl。 - Chris H.

7
返回一个带有“HTTPS Required”原因短语的403似乎是一个实用的选项,这也是我使用的选项。
参见https://en.wikipedia.org/wiki/HTTP_403 重定向REST API不是一个好主意,特别是当您可能不知道谁或什么正在使用您的服务时。

0

只需发送重定向到相应的https: URI。

更新

这是一个错误的答案 - 请参见下面的评论


2
存在安全风险。来自OWASP SSL最佳实践:“攻击者执行中间人攻击可能会拦截HTTP重定向响应并将用户发送到替代页面”。 - Sripathi Krishnan
2
这并不会阻止用户仍然使用http url,事实上,对于大多数http客户端,他们甚至看不到http重定向发生了。将问题搁置不谈可能不是您想要采取的方法。 - Agoston Horvath
2
是的,抱歉。你们是正确的。发送重定向是错误的做法。感谢指出这一点。 - Jan Algermissen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接