This keyword covers all known keywords together. It is essentially used
to enable or disable all checks at once.
+ - delete-underscore-in-header-name (inbound, request and response)
+ Deletes from requests and responses any header field whose name
+ contains an underscore character ('_' or \x5C). While this character is
+ perfectly permitted, some application frameworks which create automatic
+ variables already turn the dash ('-') into an underscore in variable
+ names, leading to an ambiguity with the underscore which can result in
+ the same variable name. This could be abused to bypass some
+ access-control policy for example. No standard HTTP header uses this,
+ so it is recommended to enable on untrusted listeners. Note that this
+ applies only after "reject-underscore-in-header-name" was accepted.
+
- reject-duplicate-host-header (inbound request)
Rejects requests containing more than one "Host" header field, even if
valid and identical. This is recommended on untrusted listeners. Note that
variable names, leading to an ambiguity with the underscore which can
result in the same variable name. This could be abused to bypass some
access-control policy for example. No standard HTTP header uses this,
- so it is safe to enable on untrusted listeners.
+ so it is safe to enable on untrusted listeners. See also the
+ "delete-underscore-in-header-name" variant.
- reject-underscore-in-trailer-name (inbound, request and response)
Rejects requests and responses in which one tailer field name contains
#define HTTP_HRD_REJ_LCASE_METHOD 0x00000002
#define HTTP_HRD_REJ_USCORE_HDR_NAM 0x00000004
#define HTTP_HRD_REJ_USCORE_TLR_NAM 0x00000008
+#define HTTP_HRD_DEL_USCORE_HDR_NAM 0x00000010
/* insert new masks above this line */
#define HTTP_HRD_ALL 0xFFFFFFFF
break;
}
+ /* we may have to delete headers with underscores
+ * in their names. These ones are already marked
+ * as found when not rejected so we can avoid a
+ * costly lookup in normal times.
+ */
+ if (unlikely(http_hdng_chk.found & HTTP_HRD_REJ_USCORE_HDR_NAM) &&
+ ((h1m->state != H1_MSG_TRAILERS && istlen(istfind(n, '_')) &&
+ http_harden(HTTP_HRD_DEL_USCORE_HDR_NAM)))) {
+ /* skip it, so it won't be added */
+ break;
+ }
+
if (isteqi(n, ist("transfer-encoding"))) {
ret = h1_parse_xfer_enc_header(h1m, v);
if (ret < 0) {
}
/* regular header field in (name,value) */
+
+ /* we may have to delete headers with underscores in their
+ * names. These ones are already marked as found when not
+ * rejected so we can avoid a costly lookup in normal times.
+ */
+ if (unlikely(http_hdng_chk.found & HTTP_HRD_REJ_USCORE_HDR_NAM) &&
+ istlen(istfind(list[idx].n, '_')) && http_harden(HTTP_HRD_DEL_USCORE_HDR_NAM)) {
+ /* skip it, so it won't be added */
+ continue;
+ }
+
if (unlikely(!(fields & H2_PHDR_FND_NONE))) {
/* no more pseudo-headers, time to build the request line */
sl = h2_prepare_htx_reqline(fields, phdr_val, htx, msgf);
}
/* regular header field in (name,value) */
+
+ /* we may have to delete headers with underscores in their
+ * names. These ones are already marked as found when not
+ * rejected so we can avoid a costly lookup in normal times.
+ */
+ if (unlikely(http_hdng_chk.found & HTTP_HRD_REJ_USCORE_HDR_NAM) &&
+ istlen(istfind(list[idx].n, '_')) && http_harden(HTTP_HRD_DEL_USCORE_HDR_NAM)) {
+ /* skip it, so it won't be added */
+ continue;
+ }
+
if (!(fields & H2_PHDR_FND_NONE)) {
/* no more pseudo-headers, time to build the status line */
sl = h2_prepare_htx_stsline(fields, phdr_val, htx, msgf);
goto out;
}
+ /* we may have to delete headers with underscores in their
+ * names. These ones are already marked as found when not
+ * rejected so we can avoid a costly lookup in normal times.
+ */
+ if (unlikely(http_hdng_chk.found & HTTP_HRD_REJ_USCORE_HDR_NAM) &&
+ istlen(istfind(list[hdr_idx].n, '_')) && http_harden(HTTP_HRD_DEL_USCORE_HDR_NAM)) {
+ /* skip it, so it won't be added */
+ ++hdr_idx;
+ continue;
+ }
+
if (isteq(list[hdr_idx].n, ist("host"))) {
struct ist prev_auth = authority;
{ "reject-lowercase-method", HTTP_HRD_REJ_LCASE_METHOD, HTTP_DIR_REQ },
{ "reject-underscore-in-header-name", HTTP_HRD_REJ_USCORE_HDR_NAM, HTTP_DIR_BOTH },
{ "reject-underscore-in-trailer-name", HTTP_HRD_REJ_USCORE_TLR_NAM, HTTP_DIR_BOTH },
+ { "delete-underscore-in-header-name", HTTP_HRD_DEL_USCORE_HDR_NAM, HTTP_DIR_BOTH },
/* insert new hardening options above this line */
{ "all", HTTP_HRD_ALL, HTTP_DIR_BOTH },
{ NULL, 0 }