调用 CGI 时 Apache2 中是否存在特殊情况并且 URI 包含没有值的单个查询字符串参数?

Is there a special case in Apache2 when calling a CGI and the URI includes a single query string parameter without a value?

今天我遇到了一个错误,很惊讶得到它,因为一切看起来都很好...

我有一个用 C++ 编写的 CGI,它接受带有查询字符串的 URI。查询字符串用于选择页面等。CGI 安装在 Ubuntu 安装的标准位置:

/usr/lib/cgi-bin/snapmanager.cgi

今天我正在完成添加一个登录屏幕,一旦登录,我想添加一个注销 link。 link 只是在 URI 的末尾添加 ?logout

http://www.example.com/cgi-bin/snapmanager.cgi?logout

失败了。

检查错误日志,我得到一个错误说"logout"实际上出现在命令行上。相当令人惊讶,如果你问我!我试过:

http://www.example.com/cgi-bin/snapmanager.cgi?logout=now

一切都按预期进行。命令行上没有注销。

我也试过:

http://www.example.com/cgi-bin/snapmanager.cgi?logout&host=foo

这也奏效了。同样,命令行上没有注销。

但是,如果我切换参数位置,它又会失败:

http://www.example.com/cgi-bin/snapmanager.cgi?host=foo&logout

所以看起来 Apache2 在最后定义一个查询字符串名称时使用 logout 查询字符串作为命令行参数调用我的 CGI。

以防万一,我尝试在名称的开头添加破折号,果然,它在我的日志中显示为命令行开关!

error:snapmanager.cgi: option --logout is not supported.

真吓人。如果您知道可以 "tweak things your way"...

的开关,这将是一个巨大的安全风险

在某处记录了吗?

其实我在第4.4段RFC3875中找到了答案

4.4. The Script Command Line

Some systems support a method for supplying an array of strings to the CGI script. This is only used in the case of an 'indexed' HTTP query, which is identified by a 'GET' or 'HEAD' request with a URI query string that does not contain any unencoded "=" characters. For such a request, the server SHOULD treat the query-string as a search-string and parse it into words, using the rules

 search-string = search-word *( "+" search-word )
 search-word   = 1*schar
 schar         = unreserved | escaped | xreserved
 xreserved     = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "," |
                 "$"

After parsing, each search-word is URL-decoded, optionally encoded in a system-defined manner and then added to the command line argument list.

If the server cannot create any part of the argument list, then the server MUST NOT generate any command line information. For example, the number of arguments may be greater than operating system or server limits, or one of the words may not be representable as an argument.

The script SHOULD check to see if the QUERY_STRING value contains an unencoded "=" character, and SHOULD NOT use the command line arguments if it does.

强调我的