You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by wi...@apache.org on 2020/01/10 08:12:59 UTC
[couchdb-mochiweb] 02/32: fix cookie value parsing
This is an automated email from the ASF dual-hosted git repository.
willholley pushed a commit to branch upstream-2.20.0
in repository https://gitbox.apache.org/repos/asf/couchdb-mochiweb.git
commit 458eedf810b7417180a870077dbf957463adf08d
Author: Oleg Nemanov <le...@yandex.ru>
AuthorDate: Mon Mar 4 15:24:50 2019 +0300
fix cookie value parsing
Cookie value(according to RFC6265) can contain US-ASCII characters
excluding CTLs, whitespace, DQUOTE, comma, semicolon and backslash:
cookie-header = "Cookie:" OWS cookie-string OWS
cookie-string = cookie-pair *( ";" SP cookie-pair )
cookie-pair = cookie-name "=" cookie-value
cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
But mochiweb_cookie:parse_cookie() use smaller allowed characters list.
For example, if cookie value is base64 string like MQ==,
then parse_cookie() makes it MQ.
Fix this by using a separate function for value parsing instead of
read_token().
---
src/mochiweb_cookies.erl | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/src/mochiweb_cookies.erl b/src/mochiweb_cookies.erl
index 013dbe0..b6afb65 100644
--- a/src/mochiweb_cookies.erl
+++ b/src/mochiweb_cookies.erl
@@ -39,6 +39,14 @@
C =:= $[ orelse C =:= $] orelse C =:= $? orelse C =:= $= orelse
C =:= ${ orelse C =:= $})).
+%% RFC 6265 cookie value allowed characters
+-define(IS_COOKIE_VAL_ALLOWED(C),
+ (C =:= 33
+ orelse (C >= 35 andalso C =< 43)
+ orelse (C >= 45 andalso C =< 58)
+ orelse (C >= 60 andalso C =< 91)
+ orelse (C >= 93 andalso C =< 126))).
+
%% @type proplist() = [{Key::string(), Value::string()}].
%% @type header() = {Name::string(), Value::string()}.
%% @type int_seconds() = integer().
@@ -208,11 +216,15 @@ read_value([$= | Value]) ->
[?QUOTE | _] ->
read_quoted(Value1);
_ ->
- read_token(Value1)
+ read_value_(Value1)
end;
read_value(String) ->
{"", String}.
+read_value_(String) ->
+ F = fun (C) -> ?IS_COOKIE_VAL_ALLOWED(C) end,
+ lists:splitwith(F, String).
+
read_quoted([?QUOTE | String]) ->
read_quoted(String, []).
@@ -302,6 +314,12 @@ parse_cookie_test() ->
?assertEqual(
[{"foo", "bar"}, {"baz", "wibble"}],
parse_cookie("foo=bar , baz=wibble ")),
+ ?assertEqual(
+ [{"foo", "base64=="}, {"bar", "base64="}],
+ parse_cookie("foo=\"base64==\";bar=\"base64=\"")),
+ ?assertEqual(
+ [{"foo", "base64=="}, {"bar", "base64="}],
+ parse_cookie("foo=base64==;bar=base64=")),
ok.
domain_test() ->