mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 23:56:57 +02:00
[MEDIUM] cookie: check for maxidle and maxlife for incoming dated cookies
If a cookie comes in with a first or last date, and they are configured on the backend, they're checked. If a date is expired or too far in the future, then the cookie is ignored and the specific reason appears in the cookie field of the logs. (cherry picked from commit faa3019107eabe6b3ab76ffec9754f2f31aa24c6)
This commit is contained in:
parent
c01062bead
commit
f64d1410fc
@ -326,6 +326,8 @@ struct http_txn {
|
|||||||
char *cli_cookie; /* cookie presented by the client, in capture mode */
|
char *cli_cookie; /* cookie presented by the client, in capture mode */
|
||||||
char *srv_cookie; /* cookie presented by the server, in capture mode */
|
char *srv_cookie; /* cookie presented by the server, in capture mode */
|
||||||
char *sessid; /* the appsession id, if found in the request or in the response */
|
char *sessid; /* the appsession id, if found in the request or in the response */
|
||||||
|
int cookie_first_date; /* if non-zero, first date the expirable cookie was set/seen */
|
||||||
|
int cookie_last_date; /* if non-zero, last date the expirable cookie was set/seen */
|
||||||
|
|
||||||
struct http_auth_data auth; /* HTTP auth data */
|
struct http_auth_data auth; /* HTTP auth data */
|
||||||
};
|
};
|
||||||
|
@ -5967,12 +5967,55 @@ void manage_client_side_cookies(struct session *t, struct buffer *req)
|
|||||||
vbar1 = memchr(val_beg, COOKIE_DELIM_DATE, val_end - val_beg);
|
vbar1 = memchr(val_beg, COOKIE_DELIM_DATE, val_end - val_beg);
|
||||||
if (vbar1) {
|
if (vbar1) {
|
||||||
/* OK, so left of the bar is the server's cookie and
|
/* OK, so left of the bar is the server's cookie and
|
||||||
* right is the last seen date.
|
* right is the last seen date. It is a base64 encoded
|
||||||
|
* 30-bit value representing the UNIX date since the
|
||||||
|
* epoch in 4-second quantities.
|
||||||
*/
|
*/
|
||||||
|
int val;
|
||||||
delim = vbar1++;
|
delim = vbar1++;
|
||||||
|
if (val_end - vbar1 >= 5) {
|
||||||
|
val = b64tos30(vbar1);
|
||||||
|
if (val > 0)
|
||||||
|
txn->cookie_last_date = val << 2;
|
||||||
|
}
|
||||||
|
/* look for a second vertical bar */
|
||||||
|
vbar1 = memchr(vbar1, COOKIE_DELIM_DATE, val_end - vbar1);
|
||||||
|
if (vbar1 && (val_end - vbar1 > 5)) {
|
||||||
|
val = b64tos30(vbar1 + 1);
|
||||||
|
if (val > 0)
|
||||||
|
txn->cookie_first_date = val << 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if the cookie has an expiration date and the proxy wants to check
|
||||||
|
* it, then we do that now. We first check if the cookie is too old,
|
||||||
|
* then only if it has expired. We detect strict overflow because the
|
||||||
|
* time resolution here is not great (4 seconds). Cookies with dates
|
||||||
|
* in the future are ignored if their offset is beyond one day. This
|
||||||
|
* allows an admin to fix timezone issues without expiring everyone
|
||||||
|
* and at the same time avoids keeping unwanted side effects for too
|
||||||
|
* long.
|
||||||
|
*/
|
||||||
|
if (txn->cookie_first_date && t->be->cookie_maxlife &&
|
||||||
|
((signed)(date.tv_sec - txn->cookie_first_date) > t->be->cookie_maxlife ||
|
||||||
|
(signed)(txn->cookie_first_date - date.tv_sec) > 86400)) {
|
||||||
|
txn->flags &= ~TX_CK_MASK;
|
||||||
|
txn->flags |= TX_CK_OLD;
|
||||||
|
delim = val_beg; // let's pretend we have not found the cookie
|
||||||
|
txn->cookie_first_date = 0;
|
||||||
|
txn->cookie_last_date = 0;
|
||||||
|
}
|
||||||
|
else if (txn->cookie_last_date && t->be->cookie_maxidle &&
|
||||||
|
((signed)(date.tv_sec - txn->cookie_last_date) > t->be->cookie_maxidle ||
|
||||||
|
(signed)(txn->cookie_last_date - date.tv_sec) > 86400)) {
|
||||||
|
txn->flags &= ~TX_CK_MASK;
|
||||||
|
txn->flags |= TX_CK_EXPIRED;
|
||||||
|
delim = val_beg; // let's pretend we have not found the cookie
|
||||||
|
txn->cookie_first_date = 0;
|
||||||
|
txn->cookie_last_date = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Here, we'll look for the first running server which supports the cookie.
|
/* Here, we'll look for the first running server which supports the cookie.
|
||||||
* This allows to share a same cookie between several servers, for example
|
* This allows to share a same cookie between several servers, for example
|
||||||
* to dedicate backup servers to specific servers only.
|
* to dedicate backup servers to specific servers only.
|
||||||
@ -6008,7 +6051,7 @@ void manage_client_side_cookies(struct session *t, struct buffer *req)
|
|||||||
srv = srv->next;
|
srv = srv->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!srv && !(txn->flags & TX_CK_DOWN)) {
|
if (!srv && !(txn->flags & (TX_CK_DOWN|TX_CK_EXPIRED|TX_CK_OLD))) {
|
||||||
/* no server matched this cookie */
|
/* no server matched this cookie */
|
||||||
txn->flags &= ~TX_CK_MASK;
|
txn->flags &= ~TX_CK_MASK;
|
||||||
txn->flags |= TX_CK_INVALID;
|
txn->flags |= TX_CK_INVALID;
|
||||||
@ -7037,6 +7080,9 @@ void http_init_txn(struct session *s)
|
|||||||
txn->flags = 0;
|
txn->flags = 0;
|
||||||
txn->status = -1;
|
txn->status = -1;
|
||||||
|
|
||||||
|
txn->cookie_first_date = 0;
|
||||||
|
txn->cookie_last_date = 0;
|
||||||
|
|
||||||
txn->req.sol = txn->req.eol = NULL;
|
txn->req.sol = txn->req.eol = NULL;
|
||||||
txn->req.som = txn->req.eoh = 0; /* relative to the buffer */
|
txn->req.som = txn->req.eoh = 0; /* relative to the buffer */
|
||||||
txn->rsp.sol = txn->rsp.eol = NULL;
|
txn->rsp.sol = txn->rsp.eol = NULL;
|
||||||
|
Loading…
Reference in New Issue
Block a user