aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2022-09-02 14:15:03 +0200
committerLoïc Hoguin <[email protected]>2022-09-02 14:15:03 +0200
commit3475c803d0b39296da953c084b1a804c56c41547 (patch)
tree32c7d99767395e78e53aa9366bf61bd37bbca0ee
parentce6798c6b2e95b6a34c6a76d2489eaf159827d80 (diff)
downloadcowlib-3475c803d0b39296da953c084b1a804c56c41547.tar.gz
cowlib-3475c803d0b39296da953c084b1a804c56c41547.tar.bz2
cowlib-3475c803d0b39296da953c084b1a804c56c41547.zip
Do additional cookie parsing checks based on RFC6265bis
-rw-r--r--src/cow_cookie.erl54
1 files changed, 37 insertions, 17 deletions
diff --git a/src/cow_cookie.erl b/src/cow_cookie.erl
index 93a8e61..953cc25 100644
--- a/src/cow_cookie.erl
+++ b/src/cow_cookie.erl
@@ -173,17 +173,32 @@ parse_cookie_error_test_() ->
-> {ok, binary(), binary(), cookie_attrs()}
| ignore.
parse_set_cookie(SetCookie) ->
- {NameValuePair, UnparsedAttrs} = take_until_semicolon(SetCookie, <<>>),
- {Name, Value} = case binary:split(NameValuePair, <<$=>>) of
- [Value0] -> {<<>>, trim(Value0)};
- [Name0, Value0] -> {trim(Name0), trim(Value0)}
- end,
- case {Name, Value} of
- {<<>>, <<>>} ->
+ case has_non_ws_ctl(SetCookie) of
+ true ->
ignore;
- _ ->
- Attrs = parse_set_cookie_attrs(UnparsedAttrs, #{}),
- {ok, Name, Value, Attrs}
+ false ->
+ {NameValuePair, UnparsedAttrs} = take_until_semicolon(SetCookie, <<>>),
+ {Name, Value} = case binary:split(NameValuePair, <<$=>>) of
+ [Value0] -> {<<>>, trim(Value0)};
+ [Name0, Value0] -> {trim(Name0), trim(Value0)}
+ end,
+ case {Name, Value} of
+ {<<>>, <<>>} ->
+ ignore;
+ _ ->
+ Attrs = parse_set_cookie_attrs(UnparsedAttrs, #{}),
+ {ok, Name, Value, Attrs}
+ end
+ end.
+
+has_non_ws_ctl(<<>>) ->
+ false;
+has_non_ws_ctl(<<C,R/bits>>) ->
+ if
+ C =< 16#08 -> true;
+ C >= 16#0A, C =< 16#1F -> true;
+ C =:= 16#7F -> true;
+ true -> has_non_ws_ctl(R)
end.
parse_set_cookie_attrs(<<>>, Attrs) ->
@@ -194,13 +209,18 @@ parse_set_cookie_attrs(<<$;,Rest0/bits>>, Attrs) ->
[Name0] -> {trim(Name0), <<>>};
[Name0, Value0] -> {trim(Name0), trim(Value0)}
end,
- case parse_set_cookie_attr(?LOWER(Name), Value) of
- {ok, AttrName, AttrValue} ->
- parse_set_cookie_attrs(Rest, Attrs#{AttrName => AttrValue});
- {ignore, AttrName} ->
- parse_set_cookie_attrs(Rest, maps:remove(AttrName, Attrs));
- ignore ->
- parse_set_cookie_attrs(Rest, Attrs)
+ if
+ byte_size(Value) > 1024 ->
+ parse_set_cookie_attrs(Rest, Attrs);
+ true ->
+ case parse_set_cookie_attr(?LOWER(Name), Value) of
+ {ok, AttrName, AttrValue} ->
+ parse_set_cookie_attrs(Rest, Attrs#{AttrName => AttrValue});
+ {ignore, AttrName} ->
+ parse_set_cookie_attrs(Rest, maps:remove(AttrName, Attrs));
+ ignore ->
+ parse_set_cookie_attrs(Rest, Attrs)
+ end
end.
take_until_semicolon(Rest = <<$;,_/bits>>, Acc) -> {Acc, Rest};