捕获格式错误的路径以重定向至 404,而不是返回 403

捕获格式错误的路径以重定向至 404,而不是返回 403

由于很久以前的一个错误,我们公司的网站一直在提供包含大量空白的图像 URL。

例如

http://www.example.com/                      /assets/ProductPhotos/image.png

浏览器已经以某种方式处理了这个问题(大概是通过删除空白)并且没有人注意到这个问题。

现在我们已经解决了这个问题,但是不那么智能的爬虫程序已经索引了该 URL,并回来尝试再次找到它。

这会导致错误日志中出现一条消息:

[core:error] [pid 5040:tid 1068] (20024)给定的路径格式错误或包含无效字符:[客户端 192.168.128.4:38656] AH00127:无法将 GET /%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20/assets/ProductPhotos/image.png HTTP/1.1 映射到文件

我们看到了很多这样的情况。

Apache 返回一个403 Forbidden,爬虫程序消失并在几天后再次尝试。

我希望拦截这些请求并返回一个404 Not Found,甚至一个410 Gone,或者只是一个,400 Bad Request希望这样能够说服这些爬虫不要打扰我们。

但是,我还没有找到识别错误 URL 的方法。

目前,我已经

#Trap URLs with occurrences of /<22 spaces>/ and redirect to a 404
<if "%{REQUEST_URI} =~ m#/(%20|\s)+/#">

redirect 404 /
</if>

在我的 .htaccess 文件中,但 Apache 仍然返回403 Forbidden。就好像 Apache 解析了 URL,判定它是错误的,并返回了响应,所有这些都是在 .htaccess 查看之前完成的。

(我可以将其放在 vHost 文件中,但这需要重新启动实时服务器。这里不流行!)

有没有办法挑选这些坏的 URL 并处理它们,而不依赖于 Apache 的默认行为?

更新:

服务器:Apache 2.4.12,Windows。

我已经设置了一个 virgin vHost,如下所示:

<VirtualHost *:80>
    <Directory "c:/***********/websites/webtest">
        <RequireAll>
            Require all granted
            Require ip 192.168.0.0/21 192.168.131.0/24
        </RequireAll>
    </Directory>
    
    DocumentRoot "c:/*************/websites/webtest"
    ServerName webtest.*************
    DirectoryIndex index.html
    CustomLog "|./bin/rotatelogs.exe -l C:/***********/apache24/logs/webtest.access.%y%m%d.log 86400" combined
    ErrorLog "|./bin/rotatelogs.exe -l C:/***********/apache24/logs/webtest.error.%y%m%d.log 86400"

    SetEnv WEBSITE_NAME webtest.***********
</VirtualHost>

它有一个文件夹,里面有一些文件,这个文件(与上面相同)的访问文件名在默认部分中ht.conf被覆盖。引用可以理解为无处不在。.htaccess.htaccessht.conf

#Trap URLs with occurrences of /<22 spaces>/ and redirect to a 404
<if "%{REQUEST_URI} =~ m#/(%20|\s)+/#">

redirect 404 /
</if>

assets/f22.jpg它还包括相对于文档根目录的文件夹和文件。

浏览http://webtest.**********/assets/f22.jpg正确返回图像

浏览http://webtest.**********/ /assets/f22.jpg返回

Forbidden

You don't have permission to access / /assets/f22.jpg on this server.the image correctly

答案1

尝试解决此问题.htaccess“为时已晚”。正如您所说,这一切都发生在“.htaccess 进入之前”。

.htaccess文件(和<Directory>容器)仅被处理请求已映射到文件系统。如错误消息“无法将...映射到文件”中所述,错误/响应似乎是在请求映射到文件系统时(或之前)触发的。

对于此类请求,“403 Forbidden”响应不是“正常”响应,因此某物似乎强制返回此响应。通常,我期望 Apache 对此类请求返回常规 404。如果 URL 路径完全“无效”,则 Apache 应响应“400 错误请求”(同样,这是无法在 中覆盖的.htaccess)。

因此,此响应似乎在服务器配置中较早触发。通常,您应该找出 Apache 在哪里/为什么提供此响应。(也许是一个额外的安全模块,如 mod_security?)并相应地修改它,而不是尝试“覆盖”它。但是,由于触发了 403,您可能可以定义自定义 403 ErrorDocument(同样,在服务器配置中,不是 .htaccess) 您可以在其中分析请求并相应地进行覆盖。

浏览器已经以某种方式处理了这个问题(大概是通过删除空白)并且没有人注意到这个问题。

“浏览器”不会删除空格。浏览器会(自动)对空格%20如果它们没有在 HTML 源代码中明确进行 URL 编码)。据我所知,浏览器端在这方面没有任何变化。

因此,你的服务器之前处理过这些请求,但您的服务器上发生了一些变化,导致这些请求被阻止。或者,事实证明,这些格式错误的 URL 从未起作用,而且没有人注意到丢失的图像或查看日志!(?)


更新:在这方面,Windows 和 Linux 的行为可能有所不同。Windows 在文件系统方面有额外的限制,但这不一定会对 Linux 系统产生同样的影响。(在生产环境中,Apache 在 Windows 上运行的情况并不常见。)

而不是使用 Apache<If>表达式(它是合并如果较晚处理,我倾向于使用 mod_rewrite(处理得早)。直接在容器中<VirtualHost>(而不是在<Directory>部分中)尝试以下操作:

RewriteEngine On

# Serve a "410 Gone" for any URL that starts with "spaces"
RewriteRule ^/\s - [G]

或者,将此类请求通过 301 重定向到“正确”的 URL:

# Redirect to remove the "spaces"
RewriteRule ^/\s+(/.*) $1 [R=301,L]

mod_rewrite 指令服务器(或者虚拟主机)上下文被处理该请求被映射到文件系统。

相关内容