Hi! According to the documentation
req.cook_cnt([<name>]) : integer Returns an integer value representing the number of occurrences of the cookie <name> in the request, or all cookies if <name> is not specified. it should be possible to do something like this to reject a request if it contains more than <n> cookies total. I do not know the cookie names in advance. I am trying to reject malicious requests with hundreds or thousands of cookies, trying to exhaust memory in my backend servers. Tomcat has a maximum number of cookies per request setting, but I’d like to reject these before they even get to the backends. I thought this would work (for n=2): frontend fe-test bind 0.0.0.0:8070 http-request deny deny_status 400 if { req.cook_cnt() gt 2 } http-request auth realm tomcat default_backend be-test However, it does not work. The count is always 0, hence the ACL always passes and I get a 401 response from the next ACL in line. root@tomcat:~# curl -v -b 'C1=v1; C1=v2; C1=v3' tomcat:8070 * Rebuilt URL to: tomcat:8070/ * Hostname was NOT found in DNS cache * Trying 127.0.1.1... * Connected to tomcat (127.0.1.1) port 8070 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.35.0 > Host: tomcat:8070 > Accept: */* > Cookie: C1=v1; C1=v2; C1=v3 > * HTTP 1.0, assume close after body < HTTP/1.0 401 Unauthorized < Cache-Control: no-cache < Connection: close < Content-Type: text/html < WWW-Authenticate: Basic realm="tomcat" < <html><body><h1>401 Unauthorized</h1> You need a valid user and password to access this content. </body></html> * Closing connection 0 When I change the ACL to include a cookie name, it works: http-request deny deny_status 400 if { req.cook_cnt("C1") gt 2 } root@tomcat:~# curl -v -b 'C1=v1; C1=v2; C1=v3' tomcat:8070 * Rebuilt URL to: tomcat:8070/ * Hostname was NOT found in DNS cache * Trying 127.0.1.1... * Connected to tomcat (127.0.1.1) port 8070 (#0) > GET / HTTP/1.1 > User-Agent: curl/7.35.0 > Host: tomcat:8070 > Accept: */* > Cookie: C1=v1; C1=v2; C1=v3 > * HTTP 1.0, assume close after body < HTTP/1.0 400 Bad request < Cache-Control: no-cache < Connection: close < Content-Type: text/html < <html><body><h1>400 Bad request</h1> Your browser sent an invalid request. </body></html> * Closing connection 0 I tried to figure out what the code does, to see if I am doing something wrong and found this in proto_http.c: ------------------------------------------------------------------------------ /* Iterate over all cookies present in a request to count how many occurrences * match the name in args and args->data.str.len. If <multi> is non-null, then * multiple cookies may be parsed on the same line. The returned sample is of * type UINT. Accepts exactly 1 argument of type string. */ static int smp_fetch_cookie_cnt(const struct arg *args, struct sample *smp, const char *kw, void *private) { struct http_txn *txn; struct hdr_idx *idx; struct hdr_ctx ctx; const struct http_msg *msg; const char *hdr_name; int hdr_name_len; int cnt; char *val_beg, *val_end; char *sol; if (!args || args->type != ARGT_STR) return 0; ------------------------------------------------------------------------------ So without being very C-savvy, this appears to exit early when there is no parameter of type string passed in. I hope someone can shed some light on this. :) Thanks in advance, Daniel -- Daniel Schneller Principal Cloud Engineer CenterDevice GmbH | Hochstraße 11 | 42697 Solingen tel: +49 1754155711 | Deutschland daniel.schnel...@centerdevice.de | www.centerdevice.de Geschäftsführung: Dr. Patrick Peschlow, Dr. Lukas Pustina, Michael Rosbach, Handelsregister-Nr.: HRB 18655, HR-Gericht: Bonn, USt-IdNr.: DE-815299431