你能判断一个页面是否存在,即使它抛出一个 404?

信息安全 linux 阿帕奇
2021-09-08 21:12:22

当一个页面被设计为抛出一个 时,是否可以确定它确实存在404 NOT FOUND

在我的服务器上,当在传递无效参数时发出对脚本的请求时,我会抛出 404 http 状态代码,因为我不希望那些不了解系统的人知道页面(公共 URL)存在。我希望抛出 404 会让攻击者认为脚本不存在。服务器本身没有资源实际上直接指向脚本,它都来自外部请求。

我真正想知道的是,仅从响应中,有人能够分辨出不存在的页面和配置为返回 404 的页面之间的区别吗?

向脚本发出无效请求时的响应标头确实指示http 状态为 404,而不是显示 404 页面的 http 状态为 200。

以下是我发出无效请求时得到的响应标头。

HTTP/1.1 404 Not Found
Date: Fri, 27 Jan 2017 23:32:28 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
X-Powered-By: PHP/5.4.16
X-XSS-Protection: 1; mode=block
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

编辑: 下面是当我点击一个真正不存在的页面时得到的响应标题。

HTTP/1.1 404 Not Found
Date: Tue, 31 Jan 2017 19:08:06 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Content-Length: 203
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
3个回答

为每个无效请求抛出 404 错误可能是有问题的,如果攻击者知道他所针对的服务,他可能会开始特别怀疑这种行为。
这是否有助于保护您的服务?这真的取决于攻击者的毅力。

编辑

如果您没有像服务器那样正确制作 404 响应标头,攻击者可以检测到差异

这是 Java 服务器案例 (Tomcat8) 的 PoC:
这是服务器本身返回的“真实”404 状态任何未找到的资源:

Content-Language:en
Content-Length:1026
Content-Type:text/html;charset=utf-8
Date:Tue, 31 Jan 2017 09:15:54 GMT
Server:Apache-Coyote/1.1

这个由 servlet 返回:

Content-Language:en
Content-Length:992
Content-Type:text/html;charset=utf-8
Date:Tue, 31 Jan 2017 09:18:04 GMT
Server:Apache-Coyote/1.1

在这两种情况下,您都会注意到“Content-length”参数的值,这可能会引起攻击者的注意。

当心,隐藏实际的错误代码有点像混淆。从安全的角度来看,没有什么不好的,但如果有的话,它几乎不会增加安全性。你真的认为攻击者会盲目接受错误码吗?你知道他们可以随意改变,他们也可以。好的,它对脚本小子很有用,但不会面临严重的攻击,所以在这样做之前你应该真正考虑一下你的威胁模型是什么。

这里可能有一个缺点。除非您构建一个记录内部错误的特殊日志系统,否则您的日志将仅包含 404 错误。这意味着已经失去了进行日志分析以试图发现对您的站点的攻击和可能的安全漏洞的任何可能性。恕我直言,错误代码对应用程序的维护者比对攻击者更有用......

同样的想法也适用于用户身份验证。

如您所见,大多数 Web 服务不会告诉您用户名和密码有什么问题。它会给你一个一般提示,说整对的东西是无效的。这使得攻击者不知道用户名不正确、密码不正确或配对本身不正确。

与用户是否存在 相比,确定用户 是否存在以及密码是否正确要快得多一些攻击者在尝试按时间访问系统时会考虑到这一点。

同样,对于 404(未找到)与 403(未授权)也是如此。Web 服务器返回 404 比返回 403 更快,但是这里的时间可能非常小,误差幅度可能会接管。

总是吐出 404 而不是 404/403 并非闻所未闻。诸如 Apache 之类的 Web 服务器可以自定义它对网页请求的响应。更改 HTTP 返回码有点困难,但修改用户看到的页面肯定更容易。就像用户名/密码的想法一样,攻击者有两种情况:

  • 这个资源真的存在吗?
  • 我必须先获得授权才能访问它吗?

现在更常见的是服务器端代码处理授权和身份验证,而无需 Web 服务器返回 404/403 代码。服务器端代码通常会处理此类请求,Web 服务器将简单地返回 200 或 300 代码。页面的内容可能是 403,但 HTTP 代码将是 200 或 300。403 用于 HTTP 身份验证,随着时间的推移已经不受欢迎。