Skip to content

Commit 8676fab

Browse files
committed
Backport from 2.1.
*) Fixed mod_usertrack to not get false positive matches on the user-tracking cookie's name. PR 16661. [Manni Wood <manniwood@planet-save.com>] Reviewed by: Cliff Woolley, Jeff Trawick, Sander Striker git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@101328 13f79535-47bb-0310-9956-ffa450edef68
1 parent a0ab7b5 commit 8676fab

3 files changed

Lines changed: 54 additions & 22 deletions

File tree

CHANGES

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
Changes with Apache 2.0.48
22

3+
*) Fixed mod_usertrack to not get false positive matches on the
4+
user-tracking cookie's name. PR 16661.
5+
[Manni Wood <manniwood@planet-save.com>]
6+
37
*) mod_cache: Fix the cache code so that responses can be cached
48
if they have an Expires header but no Etag or Last-Modified
59
headers. PR 23130.

STATUS

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
APACHE 2.0 STATUS: -*-text-*-
2-
Last modified at [$Date: 2003/09/27 18:17:09 $]
2+
Last modified at [$Date: 2003/09/27 18:24:38 $]
33

44
Release:
55

@@ -324,11 +324,6 @@ PATCHES TO PORT FROM 2.1
324324
modules/generators/mod_info.c r1.151
325325
+1: trawick
326326

327-
* mod_usertrack: use a regex instead of strstr() to fix false-positive
328-
matches on the user tracking cookie's name.
329-
modules/metadata/mod_usertrack.c r1.42
330-
+1: jwoolley, trawick, striker
331-
332327
CURRENT RELEASE NOTES:
333328

334329
* Backwards compatibility is expected of future Apache 2.0 releases,

modules/metadata/mod_usertrack.c

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ typedef struct {
125125
cookie_type_e style;
126126
char *cookie_name;
127127
char *cookie_domain;
128+
char *regexp_string; /* used to compile regexp; save for debugging */
129+
regex_t *regexp; /* used to find usertrack cookie in cookie header */
128130
} cookie_dir_rec;
129131

130132
/* Make Cookie: Now we have to generate something that is going to be
@@ -193,36 +195,48 @@ static void make_cookie(request_rec *r)
193195
return;
194196
}
195197

198+
/* dcfg->regexp is "^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)",
199+
* which has three subexpressions, $0..$2 */
200+
#define NUM_SUBS 3
201+
196202
static int spot_cookie(request_rec *r)
197203
{
198204
cookie_dir_rec *dcfg = ap_get_module_config(r->per_dir_config,
199205
&usertrack_module);
200-
const char *cookie;
201-
const char *value;
206+
const char *cookie_header;
207+
regmatch_t regm[NUM_SUBS];
202208

203209
/* Do not run in subrequests */
204210
if (!dcfg->enabled || r->main) {
205211
return DECLINED;
206212
}
207213

208-
if ((cookie = apr_table_get(r->headers_in,
209-
(dcfg->style == CT_COOKIE2
210-
? "Cookie2"
211-
: "Cookie"))))
212-
if ((value = ap_strstr_c(cookie, dcfg->cookie_name))) {
213-
char *cookiebuf, *cookieend;
214-
215-
value += strlen(dcfg->cookie_name) + 1; /* Skip over the '=' */
216-
cookiebuf = apr_pstrdup(r->pool, value);
217-
cookieend = strchr(cookiebuf, ';');
218-
if (cookieend)
219-
*cookieend = '\0'; /* Ignore anything after a ; */
220-
214+
if ((cookie_header = apr_table_get(r->headers_in,
215+
(dcfg->style == CT_COOKIE2
216+
? "Cookie2"
217+
: "Cookie")))) {
218+
if (!ap_regexec(dcfg->regexp, cookie_header, NUM_SUBS, regm, 0)) {
219+
char *cookieval = NULL;
220+
/* Our regexp,
221+
* ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)
222+
* only allows for $1 or $2 to be available. ($0 is always
223+
* filled with the entire matched expression, not just
224+
* the part in parentheses.) So just check for either one
225+
* and assign to cookieval if present. */
226+
if (regm[1].rm_so != -1) {
227+
cookieval = ap_pregsub(r->pool, "$1", cookie_header,
228+
NUM_SUBS, regm);
229+
}
230+
if (regm[2].rm_so != -1) {
231+
cookieval = ap_pregsub(r->pool, "$2", cookie_header,
232+
NUM_SUBS, regm);
233+
}
221234
/* Set the cookie in a note, for logging */
222-
apr_table_setn(r->notes, "cookie", cookiebuf);
235+
apr_table_setn(r->notes, "cookie", cookieval);
223236

224237
return DECLINED; /* There's already a cookie, no new one */
225238
}
239+
}
226240
make_cookie(r);
227241
return OK; /* We set our cookie */
228242
}
@@ -331,7 +345,26 @@ static const char *set_cookie_name(cmd_parms *cmd, void *mconfig,
331345
{
332346
cookie_dir_rec *dcfg = (cookie_dir_rec *) mconfig;
333347

348+
/* The goal is to end up with this regexp,
349+
* ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+)
350+
* with cookie_name
351+
* obviously substituted with the real cookie name set by the
352+
* user in httpd.conf. */
353+
dcfg->regexp_string = apr_pstrcat(cmd->pool, "^", name,
354+
"=([^;]+)|;[ \t]+", name,
355+
"=([^;]+)", NULL);
356+
334357
dcfg->cookie_name = apr_pstrdup(cmd->pool, name);
358+
359+
dcfg->regexp = ap_pregcomp(cmd->pool, dcfg->regexp_string, REG_EXTENDED);
360+
if (dcfg->regexp == NULL) {
361+
return "Regular expression could not be compiled.";
362+
}
363+
if (dcfg->regexp->re_nsub + 1 != NUM_SUBS) {
364+
return apr_pstrcat(cmd->pool, "Invalid cookie name \"",
365+
name, "\"", NULL);
366+
}
367+
335368
return NULL;
336369
}
337370

0 commit comments

Comments
 (0)