From b08ae57b235e66d1fce08b348928794fd2e2d5ef Mon Sep 17 00:00:00 2001 From: Smrtnyk Date: Fri, 21 Oct 2022 13:00:04 +0200 Subject: [PATCH] LibWeb: Parse SameSite cookie attribute --- Userland/Libraries/LibWeb/Cookie/Cookie.cpp | 21 ++++++++++++++++++ Userland/Libraries/LibWeb/Cookie/Cookie.h | 10 +++++++++ .../Libraries/LibWeb/Cookie/ParsedCookie.cpp | 22 +++++++++++++++++++ .../Libraries/LibWeb/Cookie/ParsedCookie.h | 2 ++ 4 files changed, 55 insertions(+) diff --git a/Userland/Libraries/LibWeb/Cookie/Cookie.cpp b/Userland/Libraries/LibWeb/Cookie/Cookie.cpp index f4de92571c..a8c9d9abfc 100644 --- a/Userland/Libraries/LibWeb/Cookie/Cookie.cpp +++ b/Userland/Libraries/LibWeb/Cookie/Cookie.cpp @@ -8,6 +8,25 @@ #include #include +namespace Web::Cookie { + +StringView same_site_to_string(SameSite same_site) +{ + switch (same_site) { + case SameSite::Default: + return "Default"sv; + case SameSite::None: + return "None"sv; + case SameSite::Lax: + return "Lax"sv; + case SameSite::Strict: + return "Strict"sv; + } + VERIFY_NOT_REACHED(); +} + +} + bool IPC::encode(Encoder& encoder, Web::Cookie::Cookie const& cookie) { encoder << cookie.name; @@ -21,6 +40,7 @@ bool IPC::encode(Encoder& encoder, Web::Cookie::Cookie const& cookie) encoder << cookie.last_access_time; encoder << cookie.persistent; encoder << cookie.secure; + encoder << cookie.same_site; return true; } @@ -38,5 +58,6 @@ ErrorOr IPC::decode(Decoder& decoder, Web::Cookie::Cookie& cookie) TRY(decoder.decode(cookie.last_access_time)); TRY(decoder.decode(cookie.persistent)); TRY(decoder.decode(cookie.secure)); + TRY(decoder.decode(cookie.same_site)); return {}; } diff --git a/Userland/Libraries/LibWeb/Cookie/Cookie.h b/Userland/Libraries/LibWeb/Cookie/Cookie.h index 758feab3c0..f66ff57693 100644 --- a/Userland/Libraries/LibWeb/Cookie/Cookie.h +++ b/Userland/Libraries/LibWeb/Cookie/Cookie.h @@ -12,6 +12,13 @@ namespace Web::Cookie { +enum class SameSite { + Default, + None, + Strict, + Lax +}; + enum class Source { NonHttp, Http, @@ -20,6 +27,7 @@ enum class Source { struct Cookie { String name; String value; + SameSite same_site; Core::DateTime creation_time {}; Core::DateTime last_access_time {}; Core::DateTime expiry_time {}; @@ -31,6 +39,8 @@ struct Cookie { bool persistent { false }; }; +StringView same_site_to_string(SameSite same_site_mode); + } namespace IPC { diff --git a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp index 206fbd78bb..1a3fca3a3f 100644 --- a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp +++ b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.cpp @@ -25,6 +25,7 @@ static void on_domain_attribute(ParsedCookie& parsed_cookie, StringView attribut static void on_path_attribute(ParsedCookie& parsed_cookie, StringView attribute_value); static void on_secure_attribute(ParsedCookie& parsed_cookie); static void on_http_only_attribute(ParsedCookie& parsed_cookie); +static void on_same_site_attribute(ParsedCookie& parsed_cookie, StringView attribute_value); static Optional parse_date_time(StringView date_string); Optional parse_cookie(String const& cookie_string) @@ -143,6 +144,8 @@ void process_attribute(ParsedCookie& parsed_cookie, StringView attribute_name, S on_secure_attribute(parsed_cookie); } else if (attribute_name.equals_ignoring_case("HttpOnly"sv)) { on_http_only_attribute(parsed_cookie); + } else if (attribute_name.equals_ignoring_case("SameSite"sv)) { + on_same_site_attribute(parsed_cookie, attribute_value); } } @@ -222,6 +225,23 @@ void on_http_only_attribute(ParsedCookie& parsed_cookie) parsed_cookie.http_only_attribute_present = true; } +// https://httpwg.org/http-extensions/draft-ietf-httpbis-rfc6265bis.html#name-the-samesite-attribute-2 +void on_same_site_attribute(ParsedCookie& parsed_cookie, StringView attribute_value) +{ + // 1. Let enforcement be "Default" + // Note: Set as default value in ParsedCookie.h + + // 2. If cookie-av's attribute-value is a case-insensitive match for "None", set enforcement to "None". + if (attribute_value.equals_ignoring_case("None"sv)) + parsed_cookie.same_site_attribute = SameSite::None; + // 3. If cookie-av's attribute-value is a case-insensitive match for "Strict", set enforcement to "Strict". + else if (attribute_value.equals_ignoring_case("Strict"sv)) + parsed_cookie.same_site_attribute = SameSite::Strict; + // 4. If cookie-av's attribute-value is a case-insensitive match for "Lax", set enforcement to "Lax". + else if (attribute_value.equals_ignoring_case("Lax"sv)) + parsed_cookie.same_site_attribute = SameSite::Lax; +} + Optional parse_date_time(StringView date_string) { // https://tools.ietf.org/html/rfc6265#section-5.1.1 @@ -343,6 +363,7 @@ bool IPC::encode(Encoder& encoder, Web::Cookie::ParsedCookie const& cookie) encoder << cookie.path; encoder << cookie.secure_attribute_present; encoder << cookie.http_only_attribute_present; + encoder << cookie.same_site_attribute; return true; } @@ -357,5 +378,6 @@ ErrorOr IPC::decode(Decoder& decoder, Web::Cookie::ParsedCookie& cookie) TRY(decoder.decode(cookie.path)); TRY(decoder.decode(cookie.secure_attribute_present)); TRY(decoder.decode(cookie.http_only_attribute_present)); + TRY(decoder.decode(cookie.same_site_attribute)); return {}; } diff --git a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h index d094504a6a..58df4efb73 100644 --- a/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h +++ b/Userland/Libraries/LibWeb/Cookie/ParsedCookie.h @@ -10,12 +10,14 @@ #include #include #include +#include namespace Web::Cookie { struct ParsedCookie { String name; String value; + SameSite same_site_attribute { SameSite::Default }; Optional expiry_time_from_expires_attribute {}; Optional expiry_time_from_max_age_attribute {}; Optional domain {};