ChatGPT解决这个技术问题 Extra ChatGPT

HTTPS 查询字符串是否安全?

我正在创建一个使用 HTTPS 的基于 Web 的安全 API;但是,如果我允许用户使用查询字符串来配置它(包括发送密码),这也是安全的还是我应该强制它通过 POST 完成?


3
3 revs, 2 users 89%

是的。但是出于以下几个原因,对敏感数据使用 GET 是一个坏主意:

主要是 HTTP referrer 泄漏(目标页面中的外部图像可能会泄漏密码 [1])

密码将存储在服务器日志中(这显然很糟糕)

浏览器中的历史缓存

因此,即使查询字符串是安全的,也不建议通过查询字符串传输敏感数据。

[1] 虽然我需要注意 RFC 声明浏览器不应将引用者从 HTTPS 发送到 HTTP。但这并不意味着糟糕的第 3 方浏览器工具栏或来自 HTTPS 站点的外部图像/闪存不会泄露它。


https 到 https 的引用者呢?如果我使用 https 从第 3 方网站获取图像?浏览器会将我之前请求的整个查询字符串发送到第 3 方服务器吗?
@Jus12 是的,它会的,它没有意义,但这就是它的设计方式。
那么为什么不建议 OAuth2 规范在查询参数(在 URL 中)中发送敏感数据?尽管建议始终使用 TLS (HTTPS)。参考tools.ietf.org/html/draft-ietf-oauth-v2-bearer-16#section-4.3 CC @volka 中的最后一点
要使用最新信息完成该答案:securitynewspaper.com/2016/08/01/…(代理 PAC 黑客允许拦截 HTTPS URL)
@Arthur 它从不说服务器到服务器。 API 一直被浏览器调用。
V
VolkA

从“嗅探网络数据包”的角度来看,GET 请求是安全的,因为浏览器将首先建立安全连接,然后发送包含 GET 参数的请求。但是 GET url 将存储在用户浏览器历史记录/自动完成中,这不是存储例如密码数据的好地方。当然,这仅适用于可能从浏览器访问服务的更广泛的“Webservice”定义,如果您仅从您的自定义应用程序访问它,这应该不是问题。

因此,至少应该首选将 post 用于密码对话框。同样正如链接 littlegeek 所指出的那样,GET URL 更有可能被写入您的服务器日志。


M
Matthias Braun

是的,您的查询字符串将被加密。

背后的原因是查询字符串是 HTTP 协议的一部分,它是一个应用层协议,而安全性(SSL/TLS)部分来自传输层。首先建立 SSL 连接,然后将查询参数(属于 HTTP 协议)发送到服务器。

建立 SSL 连接时,您的客户端将按顺序执行以下步骤。假设您尝试登录名为 example.com 的站点并希望使用查询参数发送您的凭据。您的完整 URL 可能如下所示:

https://example.com/login?username=alice&password=12345)

您的客户端(例如,浏览器/移动应用程序)将首先使用 DNS 请求将您的域名 example.com 解析为 IP 地址 (124.21.12.31)。查询该信息时,仅使用域特定信息,即仅使用 example.com。现在,您的客户端将尝试使用 IP 地址 124.21.12.31 连接到服务器,并将尝试连接到端口 443(SSL 服务端口不是默认的 HTTP 端口 80)。现在,example.com 上的服务器会将其证书发送给您的客户端。您的客户端将验证证书并开始为您的会话交换共享密钥。成功建立安全连接后,您的查询参数才会通过安全连接发送。

因此,您不会暴露敏感数据。但是,使用此方法通过 HTTPS 会话发送您的凭据并不是最好的方法。你应该采取不同的方法。


但请参阅@dr 的答案。邪恶,采石场字符串可能最终出现在日志文件和缓存中,因此它在服务器上可能不安全。
嗨 zaph,就 HTTPS 安全性而言,目标是将数据安全地发送到服务器,而中间的任何人都无法嗅出数据。虽然这是可能的,并且回答了这个问题,但很难控制服务器之后的操作。这就是为什么我也提到这不是正确的方法。除此之外,您永远不应该从客户端发送您的密码。您应该始终在设备上对其进行哈希处理并将哈希值发送到服务器。
从安全角度来看,在采石场字符串中发送机密信息是不安全的,最好在 POST 中发送。此外,密码通常在服务器上进行散列,而不是由客户端。 “您永远不应该从客户端发送您的密码”这句话与答案:(e.g http://example.com/login?username=alice&password=12345) 相冲突。
客户端上的@RuchiraRandana 散列是没有意义的,因为私钥很容易从前端检索。
@JamesW“然后很容易从前端检索私钥”什么密钥?
R
Ry-

是的。 HTTPS 会话的整个文本由 SSL 保护。这包括查询和标题。在这方面,POST 和 GET 将完全相同。

至于您的方法的安全性,如果没有适当的检查,就没有真正的说法。


安全性不仅仅是浏览器和服务器之间的通信
A
Aaron Digulla

SSL 首先连接到主机,因此主机名和端口号以明文形式传输。当主机响应并且挑战成功时,客户端将使用实际 URL(即第三个斜线之后的任何内容)加密 HTTP 请求并将其发送到服务器。

有几种方法可以破坏这种安全性。

可以将代理配置为充当“中间人”。基本上,浏览器将连接到真实服务器的请求发送到代理。如果以这种方式配置代理,它将通过 SSL 连接到真实服务器,但浏览器仍将与代理通信。因此,如果攻击者可以访问代理,他可以以明文形式查看流经它的所有数据。

您的请求也将在浏览器历史记录中可见。用户可能会想为该站点添加书签。一些用户安装了书签同步工具,因此密码可能会出现在 deli.ci.us 或其他地方。

最后,可能有人入侵了您的计算机并安装了键盘记录器或屏幕抓取工具(许多特洛伊木马类型的病毒都会这样做)。由于密码直接在屏幕上可见(与密码对话框中的“*”相反),这是另一个安全漏洞。

结论:在安全性方面,始终依靠人迹罕至的道路。有太多你不知道,不会想到的事情,这会伤到你的脖子。


“浏览器仍将与代理通信”并不完全正确,它需要向浏览器提供一个有效证书,只有当它控制浏览器信任的 CA 时,代理才能生成该证书。
A
Ali Afshar

是的,只要没有人在你的肩膀上看着显示器。


C
Community

我不同意 Slough's response 中关于[...] HTTP 引荐来源网址泄露(目标页面中的外部图像可能泄露密码) 的说法。

HTTP 1.1 RFC explicitly states

如果引用页面是使用安全协议传输的,则客户端不应在(非安全)HTTP 请求中包含Referer 头字段。

无论如何,服务器日志和浏览器历史是不将敏感数据放入查询字符串的充分理由。


“应该”这个词又来了。您会使用密码信任每个浏览器的每个版本吗?
这与 GET 与 POST 究竟有什么关系?如果您使用 POST over HTTPS,“每个浏览器的每个版本”是否安全?
此外,HTTPS 网页可能正在通过 HTTPS 检索外部图像 - 在这种情况下,浏览器应该包含引用标头,从而暴露您的密码......
@Arnout:请阅读此 RFC,它告诉您不应表示什么:ietf.org/rfc/rfc2119.txt 它与 MUST NOT 不同,因此您引用的部分并不是真正相关的,浏览器代理可能仍包含 HTTP 的引用。
W
Wim

是的,从您建立 HTTPS 连接的那一刻起,一切都是安全的。作为 POST 的查询字符串 (GET) 通过 SSL 发送。


A
Amareswar

您可以将密码作为 MD5 哈希参数发送,并添加一些盐。在服务器端进行比较以进行身份验证。


MD5 不适合密码的散列函数。
无论是散列还是明文,在 GET 参数中发送密码都是不好的做法。请参阅投票最多的答案以获取解释。 Aaaand... MD5 不应该再在任何地方使用...
“不适合密码的哈希函数”仍然比以明文形式向服务器发送密码更好,哈哈