MEDIUM: http-ana: Add a proxy option to restrict chars in request header names

The "http-restrict-req-hdr-names" option can now be set to restrict allowed
characters in the request header names to the "[a-zA-Z0-9-]" charset.

Idea of this option is to not send header names with non-alphanumeric or
hyphen character. It is especially important for FastCGI application because
all those characters are converted to underscore. For instance,
"X-Forwarded-For" and "X_Forwarded_For" are both converted to
"HTTP_X_FORWARDED_FOR". So, header names can be mixed up by FastCGI
applications. And some HAProxy rules may be bypassed by mangling header
names. In addition, some non-HTTP compliant servers may incorrectly handle
requests when header names contain characters ouside the "[a-zA-Z0-9-]"
charset.

When this option is set, the policy must be specify:

  * preserve: It disables the filtering. It is the default mode for HTTP
              proxies with no FastCGI application configured.

  * delete: It removes request headers with a name containing a character
            outside the "[a-zA-Z0-9-]" charset. It is the default mode for
            HTTP backends with a configured FastCGI application.

  * reject: It rejects the request with a 403-Forbidden response if it
            contains a header name with a character outside the
            "[a-zA-Z0-9-]" charset.

The option is evaluated per-proxy and after http-request rules evaluation.

This patch may be backported to avoid any secuirty issue with FastCGI
application (so as far as 2.2).

(cherry picked from commit 18c13d3bd88cbcc351a61b1e71881353ab720f67)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit bf65f308da8b2e6d82d2fb2b242d4bb8f82778d0)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/doc/configuration.txt b/doc/configuration.txt
index af41588..c2e8023 100644
--- a/doc/configuration.txt
+++ b/doc/configuration.txt
@@ -3645,6 +3645,7 @@
 option http-keep-alive               (*)  X          X         X         X
 option http-no-delay                 (*)  X          X         X         X
 option http-pretend-keepalive        (*)  X          -         X         X
+option http-restrict-req-hdr-names        X          X         X         X
 option http-server-close             (*)  X          X         X         X
 option http-use-proxy-header         (*)  X          X         X         -
 option httpchk                            X          -         X         X
@@ -8728,6 +8729,33 @@
   See also : "option httpclose", "option http-server-close", and
              "option http-keep-alive"
 
+option http-restrict-req-hdr-names { preserve | delete | reject }
+  Set HAProxy policy about HTTP request header names containing characters
+  outside the "[a-zA-Z0-9-]" charset
+  May be used in sections :   defaults | frontend | listen | backend
+                                 yes   |    yes   |   yes  |   yes
+  Arguments :
+      preserve  disable the filtering. It is the default mode for HTTP proxies
+                with no FastCGI application configured.
+
+      delete    remove request headers with a name containing a character
+                outside the "[a-zA-Z0-9-]" charset. It is the default mode for
+                HTTP backends with a configured FastCGI application.
+
+      reject    reject the request with a 403-Forbidden response if it contains a
+                header name with a character outside the "[a-zA-Z0-9-]" charset.
+
+  This option may be used to restrict the request header names to alphanumeric
+  and hyphen characters ([A-Za-z0-9-]). This may be mandatory to interoperate
+  with non-HTTP compliant servers that fail to handle some characters in header
+  names. It may also be mandatory for FastCGI applications because all
+  non-alphanumeric characters in header names are replaced by an underscore
+  ('_'). Thus, it is easily possible to mix up header names and bypass some
+  rules. For instance, "X-Forwarded-For" and "X_Forwarded-For" headers are both
+  converted to "HTTP_X_FORWARDED_FOR" in FastCGI.
+
+  Note this option is evaluated per proxy and after the http-request rules
+  evaluation.
 
 option http-server-close
 no option http-server-close