]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cache: Add extra "cache-control" value checks
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Thu, 3 Dec 2020 17:19:30 +0000 (18:19 +0100)
committerWilliam Lallemand <wlallemand@haproxy.org>
Fri, 4 Dec 2020 09:21:56 +0000 (10:21 +0100)
The Cache-Control max-age and s-maxage directives should be followed by
a positive numerical value (see RFC 7234#5.2.1.1). According to the
specs, a sender "should not" generate a quoted-string value but we will
still accept this format.

src/cache.c

index cc446507e7da5296bd55c4fd1354d7845043e52c..59a590cb7ceab432a1b09b007d81930452b3e1be 100644 (file)
@@ -551,12 +551,18 @@ int http_calc_maxage(struct stream *s, struct cache *cache, int *true_maxage)
 {
        struct htx *htx = htxbuf(&s->res.buf);
        struct http_hdr_ctx ctx = { .blk = NULL };
-       int smaxage = -1;
-       int maxage = -1;
+       long smaxage = -1;
+       long maxage = -1;
        int expires = -1;
        struct tm tm = {};
        time_t expires_val = 0;
+       char *endptr = NULL;
+       int offset = 0;
 
+       /* The Cache-Control max-age and s-maxage directives should be followed by
+        * a positive numerical value (see RFC 7234#5.2.1.1). According to the
+        * specs, a sender "should not" generate a quoted-string value but we will
+        * still accept this format since it isn't strictly forbidden. */
        while (http_find_header(htx, ist("cache-control"), &ctx, 0)) {
                char *value;
 
@@ -566,7 +572,10 @@ int http_calc_maxage(struct stream *s, struct cache *cache, int *true_maxage)
 
                        chunk_strncat(chk, value, ctx.value.len - 8 + 1);
                        chunk_strncat(chk, "", 1);
-                       smaxage = atoi(chk->area);
+                       offset = (*chk->area == '"') ? 1 : 0;
+                       smaxage = strtol(chk->area + offset, &endptr, 10);
+                       if (unlikely(smaxage < 0 || endptr == chk->area))
+                               return -1;
                }
 
                value = directive_value(ctx.value.ptr, ctx.value.len, "max-age", 7);
@@ -575,7 +584,10 @@ int http_calc_maxage(struct stream *s, struct cache *cache, int *true_maxage)
 
                        chunk_strncat(chk, value, ctx.value.len - 7 + 1);
                        chunk_strncat(chk, "", 1);
-                       maxage = atoi(chk->area);
+                       offset = (*chk->area == '"') ? 1 : 0;
+                       maxage = strtol(chk->area + offset, &endptr, 10);
+                       if (unlikely(maxage < 0 || endptr == chk->area))
+                               return -1;
                }
        }