Quantcast
Channel: Serverphorums.com - HAProxy
Viewing all articles
Browse latest Browse all 5112

req.cook_cnt() broken? (no replies)

$
0
0
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.schneller@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

Viewing all articles
Browse latest Browse all 5112

Trending Articles