]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: http/hardening: turn it to a macro and count matches with COUNT_IF()
authorWilly Tarreau <w@1wt.eu>
Thu, 5 Nov 2026 07:54:06 +0000 (08:54 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 5 Nov 2026 16:03:24 +0000 (17:03 +0100)
Thanks to COUNT_IF() it is quite easy to count the number of times the
condition for a given hardening flag was met, and the number of times it
was enforced. Let's replace the function by a macro for this. In order
to avoid counting multiple times the same match (e.g. many CTL chars in
a header value), the macro takes care of checking both the found and the
rules flags. This way we have at least one found per enforcement, and at
least one per distinct match but not necessarily more if no enforcement
is configured.

include/haproxy/http.h

index 9b862780005946466980705218469fcbbd3fd552..34befa5bdd5be680ca6c8df9c0c339c0f06d002b 100644 (file)
@@ -124,15 +124,25 @@ static inline void http_reset_hardening_check(struct http_hdng_chk *chk)
  *             goto fail;
  *
  * Make sure to pass it single-bit options to keep found/fixed easy to grasp.
+ * Note: this is now written as a macro so that we can count the number of
+ * matches per call place. We try hard not to report multiple matches (e.g.
+ * CTL chars in header values), so we report only once per found type if no
+ * remediation is enabled.
  */
-static inline int http_harden(uint32_t flag)
-{
-       http_hdng_chk.found |= flag;
-       if (!(http_hdng_chk.rules & flag))
-               return 0;
-       http_hdng_chk.fixed |= flag;
-       return 1;
-}
+#define http_harden(flag) ({                                                  \
+       uint32_t _flag = (flag);                                              \
+       int _ret = 0;                                                         \
+       if (unlikely((http_hdng_chk.rules | ~http_hdng_chk.found) & _flag)) { \
+               http_hdng_chk.found |= _flag;                                 \
+               COUNT_IF(1, "hardening " #flag " condition met");             \
+               if (http_hdng_chk.rules & _flag) {                            \
+                       COUNT_IF(1, "hardening " #flag " enforced");          \
+                       http_hdng_chk.fixed |= _flag;                         \
+                       _ret = 1;                                             \
+               }                                                             \
+       }                                                                     \
+       _ret;                                                                 \
+})
 
 /* Match language range with language tag. RFC2616 14.4:
  *