【问题标题】:Is a HTTPS query string secure?HTTPS 查询字符串是否安全?
【发布时间】:2010-09-24 07:18:48
【问题描述】:

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

【问题讨论】:

    标签: ssl https query-string


    【解决方案1】:

    是的,是的。 但对敏感数据使用 GET 是个坏主意,原因如下:

    • 主要是 HTTP 引荐来源网址泄漏(目标页面中的外部图像可能会泄漏密码[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.3CC@volka中的最后一点
    • 使用最新信息完成该答案:securitynewspaper.com/2016/08/01/…(代理 PAC 黑客允许拦截 HTTPS URL)
    • @Arthur 它从不说服务器到服务器。 API 一直被浏览器调用。
    【解决方案2】:

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

    因此,至少在密码对话框中使用 post 应该是首选。此外,正如 littlegeek 发布的链接中所指出的,GET URL 更有可能写入您的服务器日志。

    【讨论】:

      【解决方案3】:

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

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

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

      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 会话发送您的凭据并不是最好的方法。您应该采用不同的方法。

      【讨论】:

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

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

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

      【讨论】:

      • 安全性不仅仅是浏览器和服务器之间的通信
      【解决方案5】:

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

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

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

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

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

      结论:在安全方面,请始终依靠老路。有太多你不知道,不会想到,会伤到你的脖子。

      【讨论】:

      • “浏览器仍将与代理通信”不太正确,它需要向浏览器提供一个有效证书,该代理只有在控制浏览器信任的 CA 时才能生成该证书。
      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        我不同意Slough's response中关于[...] HTTP referrer 泄露(目标页面中的外部图片可能泄露密码)的说法

        HTTP 1.1 RFC explicitly states

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

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

        【讨论】:

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

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

        【讨论】:

          【解决方案9】:

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

          【讨论】:

          • MD5 不适合密码的哈希函数。
          • 无论是散列还是明文,在 GET 参数中发送密码都是不好的做法。请参阅投票最多的答案以获取解释。 Aaaand... MD5 不应该再在任何地方使用...
          • "不适合密码的散列函数" 还是比以明文形式向服务器发送密码更好,哈哈
          猜你喜欢
          • 2011-02-07
          • 2011-11-10
          • 1970-01-01
          • 2019-07-22
          • 1970-01-01
          • 2013-07-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多