HTTPS查询字符串安全吗?


351

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

Answers:


452

是的。但是使用GET处理敏感数据是一个坏主意,原因有以下几个:

  • 主要是HTTP引荐来源网址泄漏(目标页面中的外部图像可能会泄漏密码[1])
  • 密码将存储在服务器日志中(这显然是错误的)
  • 浏览器中的历史记录缓存

因此,即使Querystring是安全的,也不建议通过querystring传输敏感数据。

[1]尽管我需要指出RFC指出浏览器不应将引荐来源网址从HTTPS发送到HTTP。但这并不意味着坏的第三方浏览器工具栏或HTTPS站点的外部图像/闪存都不会泄漏它。


4
https到https引荐来源网址呢?如果我正在使用https从第三方网站获取图像?浏览器是否会将我之前的请求中的整个查询字符串发送到第三方服务器?
2013年

4
@ Jus12是的,这没有意义,但是这就是它的设计方式。
博士 邪恶的

2
那么,为什么不建议OAuth2规范在查询参数(在URL中)中发送敏感数据呢?即使建议始终使用TLS(HTTPS)。请参阅tools.ietf.org/html/draft-ietf-oauth-v2-bearer-16#section-4.3 CC 的最后一点@volka
gihanchanuka 2015年

@ dr.evil您能否详细说明问题所在History caches in browsers或为ir添加一些参考?
LCJ

1
要使用最新信息来完成该答案,请访问:securitynewspaper.com/2016/08/01/…(代理PAC hack允许拦截HTTPS URL)
汤姆

78

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

因此,至少应将post用于密码对话框。另外,正如在littlegeek发布的链接中指出的那样,更可能将GET URL写入服务器日志。


48

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

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

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

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

因此,您不会公开敏感数据。但是,使用此方法通过HTTPS会话发送凭据不是最佳方法。您应该采用其他方法。


2
但是请参阅@dr的答案。邪恶的是,quarry字符串可能最终出现在日志文件和缓存中,因此在服务器上可能不安全。
zaph

3
zaph,在HTTPS安全性方面,目标是将数据安全地发送到服务器,而中间的任何人都无法嗅探数据。尽管这是可能的,并且可以回答问题,但实际上很难控制服务器之后的工作。这就是为什么我也提到这不是正确的方法。除此之外,您永远不要从客户端发送您的密码。您应该始终在设备上对其进行哈希处理,然后将哈希值发送到服务器。
Ruchira Randana '16

从安全角度出发,在采石场字符串中发送机密信息并不安全,最好在POST中发送。同样,密码通常在服务器上散列,而不是在客户端上散列。“您永远不应该从客户端发送密码”这样的说法与答案冲突:(e.g http://example.com/login?username=alice&password=12345)
zaph

客户端上的@RuchiraRandana哈希是没有意义的,因为这样可以轻松地从前端检索私钥。
詹姆斯·W

@JamesW“ 然后可以很容易地从前端检索私钥 ”什么密钥?
curiousguy18年

28

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

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


27
安全不仅仅是浏览器和服务器之间的通信,还有更多
JoeBloggs

26

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

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

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

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

最后,可能有人入侵了您的计算机,并安装了键盘记录器或屏幕抓取工具(许多Trojan Horse型病毒也感染了)。由于密码可以直接在屏幕上看到(而不是密码对话框中的“ *”),因此这是另一个安全漏洞。

结论:关于安全性,请始终遵循常规。有太多您不知道,不会想到的东西,它们会折断您的脖子。


3
“浏览器仍将与代理对话”不是很正确,它需要向浏览器提供一个有效的证书,该证书只有在代理拥有对浏览器信任的CA的控制权时,代理才能生成。
Pieter


10

我不同意有关说法[...] HTTP引用泄漏(在目标页面的外部图像可能会泄露密码)斯劳的回应

HTTP 1.1 RFC 明确指出

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

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


2
再次有“应该”这个词。您会使用密码信任每个浏览器的每个版本吗?
JoeBloggs

1
这与GET与POST有什么关系?如果您通过HTTPS使用POST,“每个浏览器的每个版本”是否安全?
Arnout

2
此外,HTTPS网页可能正在通过HTTPS检索外部图像-在这种情况下,浏览器应包含
引荐

3
@Arnout:请阅读此RFC,该RFC告诉您什么不应该表示: ietf.org/rfc/rfc2119.txt 它与MUST NOT不一样,因此您引用的部分并不是真正的无关紧要,浏览器代理可能仍包含引用程序到HTTP。
安迪

8

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


-4

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


11
MD5不适合用作密码的哈希函数。
slawek 2014年

1
无论是散列还是明文形式,在GET参数中发送密码都是一种不好的做法。请参考投票率最高的答案以获取解释。Aaaand ... MD5不再在任何地方使用...
Thomas

不适合用于密码的哈希函数 ”仍然比以明文形式向服务器发送密码要好,大声笑
curiousguy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.