Kindly bumping this during the summer vacation time for potentially new recipients :)
> On 21. Aug. 2017, at 21:14, Daniel Schneller > <daniel.schnel...@centerdevice.com> wrote: > > 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 > >