是否应该在查询字符串中传递敏感数据?

信息安全 Web应用程序 网页浏览器
2021-08-14 12:01:28

是否应该通过查询字符串而不是 POST 请求传递敏感数据?我意识到查询字符串将被加密,但是还有其他原因可以避免在查询字符串中传递数据,例如肩冲浪?

4个回答

如果查询字符串是用户可点击链接的目标(与某些 Javascript 中使用的 URL 相反),则在加载相应页面时它将出现在浏览器的 URL 栏中。它有以下问题:

  • 将显示 URL。肩冲浪者可能会看到它并从中学到东西(例如密码)。
  • 用户可以为其添加书签。这可能是一个特征;但这也意味着数据被写入磁盘。
  • 同样,该 URL 将进入“历史记录”,因此无论如何它都会写入磁盘;之后可能会被检索到。例如,如果浏览器是 Chrome,那么午餐时间的攻击者只需键入 Ctrl+H 即可打开“历史记录选项卡”并获取所有查询字符串。
  • 如果页面被打印,URL 将被打印,包括任何敏感信息。
  • 包括查询字符串在内的 URL 也经常记录在 Web 服务器上,这些日志可能没有得到适当的保护。
  • 查询字符串有大小限制,这取决于浏览器和服务器(这里没有真正的标准,但预计会出现超过 4 kB 的问题)。

因此,如果查询字符串是 HTML 页面中的简单链接目标,则敏感数据应作为 POST 表单的一部分传输,而不是在 URL 本身中编码。使用程序下载(AJAX 方式),这不是什么大问题。

除了这里的其他答案之外,查询字符串还存储在网络服务器的日志文件、HTTP 代理中,如果 SSL 与 Bluecoat 等 SSL 监控工具一起使用,甚至可以看到。

,敏感数据不应通过 HTTP“GET”发送,而应始终通过“POST”发送

编辑:

应该使用 POST 的另一个原因是 GET 更容易受到CSRF 攻击

敏感数据应通过以下任一方式传递:

  1. 安全的仅 HTTP cookie(安全意味着仅 SSL;和仅 HTTP 意味着 javascript 无法访问)(例如,标识您已登录的随机令牌),或
  2. POST 变量(通过 SSL)。

三个原因:

  1. 默认情况下,您的计算机通常会记录查询字符串(在浏览器历史记录中),
  2. 另一端的网络服务器默认记录查询字符串。如果说密码被传递,而网络服务器巧妙地只存储带有随机盐的强密钥强化加密散列(例如,bcrypt)以防止密码被攻击者无意中获取,那么这很糟糕。显然,如果需要,记录 POST 变量并不难,但通常不会这样做。
  3. 敏感数据通常仅在基于该敏感数据执行某种操作时才应传递;如果您正在执行某种操作(例如登录;传递要在数据库中存储/操作的安全数据),您应该使用 POST 与 GET。

通常,防止跨站点请求伪造的规则(CSRF 也称为 XSRF)只会在 POST 请求中触发。GET 是预期的 HTTP 请求方法,用于从没有其他影响的 Web 服务器检索数据(除了填充日志文件表示请求此页面的良性内容);POST 是用户发送数据以执行某些操作的协议(例如,从网站订购商品;从您的银行账户转账;更改您的密码)。这是一个随机的 CSRF 令牌,大多数框架通常需要 GET 请求,但通常需要 POST 请求。

(虽然 Thomas Pornin 和 makerofthings7 分别谈到了 1 和 2,但我之前在一个有点相似的问题中提到了这两者。)

如果可以避免,我总是避免它。除非有合法需要允许在查询字符串中传递数据,否则这只是一个应该关闭的攻击面。

您或未来的开发人员也总是有可能无法正确过滤/清理数据,从而扩大攻击面。即使在一个不安全的应用程序中,如果您不小心允许注入,恶意攻击者并将 XSS 和 XSRF 脚本注入您的数据库并使用您的非敏感应用程序攻击其他人,所以最好安全行事。

肩部冲浪是另一个合理的问题,具体取决于环境。如果您的应用程序将在可能的地方使用(图书馆、某人可以查看的隔间以及办公桌面朝错误方向的办公室等),这是一个潜在的问题。如果使用您的应用程序的人都在桌子指向的房间里,这样肩膀冲浪就不是问题,不用担心。但是,如果您不确定这一点,并且您不知道它会一直如此,那就令人担忧了。