瀏覽代碼

Browser+LibWeb+WebContent: Track the source of document.cookie requests

To implement the HttpOnly attribute, the CookieJar needs to know where a
request originated from. Namely, it needs to distinguish between HTTP /
non-HTTP (i.e. JavaScript) requests. When the HttpOnly attribute is set,
requests from JavaScript are to be blocked.
Timothy Flynn 4 年之前
父節點
當前提交
c00760c5f9

+ 2 - 2
Userland/Applications/Browser/CookieJar.cpp

@@ -33,7 +33,7 @@
 
 namespace Browser {
 
-String CookieJar::get_cookie(const URL& url)
+String CookieJar::get_cookie(const URL& url, Web::Cookie::Source)
 {
     purge_expired_cookies();
 
@@ -55,7 +55,7 @@ String CookieJar::get_cookie(const URL& url)
     return builder.build();
 }
 
-void CookieJar::set_cookie(const URL& url, const String& cookie_string)
+void CookieJar::set_cookie(const URL& url, const String& cookie_string, Web::Cookie::Source)
 {
     auto domain = canonicalize_domain(url);
     if (!domain.has_value())

+ 2 - 2
Userland/Applications/Browser/CookieJar.h

@@ -46,8 +46,8 @@ struct CookieStorageKey {
 
 class CookieJar {
 public:
-    String get_cookie(const URL& url);
-    void set_cookie(const URL& url, const String& cookie);
+    String get_cookie(const URL& url, Web::Cookie::Source source);
+    void set_cookie(const URL& url, const String& cookie, Web::Cookie::Source source);
     void dump_cookies() const;
 
 private:

+ 4 - 4
Userland/Applications/Browser/Tab.cpp

@@ -242,15 +242,15 @@ Tab::Tab(Type type)
             on_favicon_change(icon);
     };
 
-    hooks().on_get_cookie = [this](auto& url) -> String {
+    hooks().on_get_cookie = [this](auto& url, auto source) -> String {
         if (on_get_cookie)
-            return on_get_cookie(url);
+            return on_get_cookie(url, source);
         return {};
     };
 
-    hooks().on_set_cookie = [this](auto& url, auto& cookie) {
+    hooks().on_set_cookie = [this](auto& url, auto& cookie, auto source) {
         if (on_set_cookie)
-            on_set_cookie(url, cookie);
+            on_set_cookie(url, cookie, source);
     };
 
     hooks().on_get_source = [this](auto& url, auto& source) {

+ 2 - 2
Userland/Applications/Browser/Tab.h

@@ -70,8 +70,8 @@ public:
     Function<void(const URL&)> on_tab_open_request;
     Function<void(Tab&)> on_tab_close_request;
     Function<void(const Gfx::Bitmap&)> on_favicon_change;
-    Function<String(const URL& url)> on_get_cookie;
-    Function<void(const URL& url, const String& cookie)> on_set_cookie;
+    Function<String(const URL& url, Web::Cookie::Source source)> on_get_cookie;
+    Function<void(const URL& url, const String& cookie, Web::Cookie::Source source)> on_set_cookie;
     Function<void()> on_dump_cookies;
 
     const String& title() const { return m_title; }

+ 4 - 4
Userland/Applications/Browser/main.cpp

@@ -219,12 +219,12 @@ int main(int argc, char** argv)
             });
         };
 
-        new_tab.on_get_cookie = [&](auto& url) -> String {
-            return cookie_jar.get_cookie(url);
+        new_tab.on_get_cookie = [&](auto& url, auto source) -> String {
+            return cookie_jar.get_cookie(url, source);
         };
 
-        new_tab.on_set_cookie = [&](auto& url, auto& cookie) {
-            cookie_jar.set_cookie(url, cookie);
+        new_tab.on_set_cookie = [&](auto& url, auto& cookie, auto source) {
+            cookie_jar.set_cookie(url, cookie, source);
         };
 
         new_tab.on_dump_cookies = [&]() {

+ 5 - 0
Userland/Libraries/LibWeb/Cookie/Cookie.h

@@ -31,6 +31,11 @@
 
 namespace Web::Cookie {
 
+enum class Source {
+    NonHttp,
+    Http,
+};
+
 struct Cookie {
     String name;
     String value;

+ 4 - 4
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -821,17 +821,17 @@ void Document::completely_finish_loading()
     dispatch_event(DOM::Event::create(HTML::EventNames::load));
 }
 
-String Document::cookie()
+String Document::cookie(Cookie::Source source)
 {
     if (auto* page = this->page())
-        return page->client().page_did_request_cookie(m_url);
+        return page->client().page_did_request_cookie(m_url, source);
     return {};
 }
 
-void Document::set_cookie(String cookie)
+void Document::set_cookie(String cookie, Cookie::Source source)
 {
     if (auto* page = this->page())
-        page->client().page_did_set_cookie(m_url, cookie);
+        page->client().page_did_set_cookie(m_url, cookie, source);
 }
 
 }

+ 3 - 2
Userland/Libraries/LibWeb/DOM/Document.h

@@ -40,6 +40,7 @@
 #include <LibWeb/CSS/CSSStyleSheet.h>
 #include <LibWeb/CSS/StyleResolver.h>
 #include <LibWeb/CSS/StyleSheetList.h>
+#include <LibWeb/Cookie/Cookie.h>
 #include <LibWeb/DOM/DOMImplementation.h>
 #include <LibWeb/DOM/ExceptionOr.h>
 #include <LibWeb/DOM/NonElementParentNode.h>
@@ -73,8 +74,8 @@ public:
 
     virtual ~Document() override;
 
-    String cookie();
-    void set_cookie(String);
+    String cookie(Cookie::Source = Cookie::Source::NonHttp);
+    void set_cookie(String, Cookie::Source = Cookie::Source::NonHttp);
 
     bool should_invalidate_styles_on_attribute_changes() const { return m_should_invalidate_styles_on_attribute_changes; }
     void set_should_invalidate_styles_on_attribute_changes(bool b) { m_should_invalidate_styles_on_attribute_changes = b; }

+ 1 - 0
Userland/Libraries/LibWeb/Forward.h

@@ -30,6 +30,7 @@
 namespace Web::Cookie {
 struct Cookie;
 struct ParsedCookie;
+enum class Source;
 }
 
 namespace Web::CSS {

+ 4 - 4
Userland/Libraries/LibWeb/InProcessWebView.cpp

@@ -433,17 +433,17 @@ String InProcessWebView::page_did_request_prompt(const String& message, const St
     return {};
 }
 
-String InProcessWebView::page_did_request_cookie(const URL& url)
+String InProcessWebView::page_did_request_cookie(const URL& url, Cookie::Source source)
 {
     if (on_get_cookie)
-        return on_get_cookie(url);
+        return on_get_cookie(url, source);
     return {};
 }
 
-void InProcessWebView::page_did_set_cookie(const URL& url, const String& cookie)
+void InProcessWebView::page_did_set_cookie(const URL& url, const String& cookie, Cookie::Source source)
 {
     if (on_set_cookie)
-        on_set_cookie(url, cookie);
+        on_set_cookie(url, cookie, source);
 }
 
 }

+ 2 - 2
Userland/Libraries/LibWeb/InProcessWebView.h

@@ -111,8 +111,8 @@ private:
     virtual void page_did_request_alert(const String&) override;
     virtual bool page_did_request_confirm(const String&) override;
     virtual String page_did_request_prompt(const String&, const String&) override;
-    virtual String page_did_request_cookie(const URL&) override;
-    virtual void page_did_set_cookie(const URL&, const String&) override;
+    virtual String page_did_request_cookie(const URL&, Cookie::Source) override;
+    virtual void page_did_set_cookie(const URL&, const String&, Cookie::Source) override;
 
     void layout_and_sync_size();
 

+ 1 - 1
Userland/Libraries/LibWeb/Loader/FrameLoader.cpp

@@ -277,7 +277,7 @@ void FrameLoader::resource_did_load()
     // FIXME: Support multiple instances of the Set-Cookie response header.
     auto set_cookie = resource()->response_headers().get("Set-Cookie");
     if (set_cookie.has_value())
-        document->set_cookie(set_cookie.value());
+        document->set_cookie(set_cookie.value(), Cookie::Source::Http);
 
     if (!url.fragment().is_empty())
         frame().scroll_to_anchor(url.fragment());

+ 4 - 4
Userland/Libraries/LibWeb/OutOfProcessWebView.cpp

@@ -365,17 +365,17 @@ void OutOfProcessWebView::notify_server_did_change_favicon(const Gfx::Bitmap& fa
         on_favicon_change(favicon);
 }
 
-String OutOfProcessWebView::notify_server_did_request_cookie(Badge<WebContentClient>, const URL& url)
+String OutOfProcessWebView::notify_server_did_request_cookie(Badge<WebContentClient>, const URL& url, Cookie::Source source)
 {
     if (on_get_cookie)
-        return on_get_cookie(url);
+        return on_get_cookie(url, source);
     return {};
 }
 
-void OutOfProcessWebView::notify_server_did_set_cookie(Badge<WebContentClient>, const URL& url, const String& cookie)
+void OutOfProcessWebView::notify_server_did_set_cookie(Badge<WebContentClient>, const URL& url, const String& cookie, Cookie::Source source)
 {
     if (on_set_cookie)
-        on_set_cookie(url, cookie);
+        on_set_cookie(url, cookie, source);
 }
 
 void OutOfProcessWebView::did_scroll()

+ 2 - 2
Userland/Libraries/LibWeb/OutOfProcessWebView.h

@@ -79,8 +79,8 @@ public:
     void notify_server_did_get_source(const URL& url, const String& source);
     void notify_server_did_js_console_output(const String& method, const String& line);
     void notify_server_did_change_favicon(const Gfx::Bitmap& favicon);
-    String notify_server_did_request_cookie(Badge<WebContentClient>, const URL& url);
-    void notify_server_did_set_cookie(Badge<WebContentClient>, const URL& url, const String& cookie);
+    String notify_server_did_request_cookie(Badge<WebContentClient>, const URL& url, Cookie::Source source);
+    void notify_server_did_set_cookie(Badge<WebContentClient>, const URL& url, const String& cookie, Cookie::Source source);
 
 private:
     OutOfProcessWebView();

+ 2 - 2
Userland/Libraries/LibWeb/Page/Page.h

@@ -111,8 +111,8 @@ public:
     virtual void page_did_request_alert(const String&) { }
     virtual bool page_did_request_confirm(const String&) { return false; }
     virtual String page_did_request_prompt(const String&, const String&) { return {}; }
-    virtual String page_did_request_cookie(const URL&) { return {}; }
-    virtual void page_did_set_cookie(const URL&, const String&) { }
+    virtual String page_did_request_cookie(const URL&, Cookie::Source) { return {}; }
+    virtual void page_did_set_cookie(const URL&, const String&, Cookie::Source) { }
 };
 
 }

+ 2 - 2
Userland/Libraries/LibWeb/WebContentClient.cpp

@@ -199,13 +199,13 @@ void WebContentClient::handle(const Messages::WebContentClient::DidChangeFavicon
 
 OwnPtr<Messages::WebContentClient::DidRequestCookieResponse> WebContentClient::handle(const Messages::WebContentClient::DidRequestCookie& message)
 {
-    auto result = m_view.notify_server_did_request_cookie({}, message.url());
+    auto result = m_view.notify_server_did_request_cookie({}, message.url(), static_cast<Cookie::Source>(message.source()));
     return make<Messages::WebContentClient::DidRequestCookieResponse>(result);
 }
 
 void WebContentClient::handle(const Messages::WebContentClient::DidSetCookie& message)
 {
-    m_view.notify_server_did_set_cookie({}, message.url(), message.cookie());
+    m_view.notify_server_did_set_cookie({}, message.url(), message.cookie(), static_cast<Cookie::Source>(message.source()));
 }
 
 }

+ 2 - 2
Userland/Libraries/LibWeb/WebViewHooks.h

@@ -48,8 +48,8 @@ public:
     Function<void(DOM::Document*)> on_set_document;
     Function<void(const URL&, const String&)> on_get_source;
     Function<void(const String& method, const String& line)> on_js_console_output;
-    Function<String(const URL& url)> on_get_cookie;
-    Function<void(const URL& url, const String& cookie)> on_set_cookie;
+    Function<String(const URL& url, Cookie::Source source)> on_get_cookie;
+    Function<void(const URL& url, const String& cookie, Cookie::Source source)> on_set_cookie;
 };
 
 }

+ 4 - 4
Userland/Services/WebContent/PageHost.cpp

@@ -208,14 +208,14 @@ void PageHost::page_did_request_image_context_menu(const Gfx::IntPoint& content_
     m_client.post_message(Messages::WebContentClient::DidRequestImageContextMenu(content_position, url, target, modifiers, bitmap->to_shareable_bitmap()));
 }
 
-String PageHost::page_did_request_cookie(const URL& url)
+String PageHost::page_did_request_cookie(const URL& url, Web::Cookie::Source source)
 {
-    return m_client.send_sync<Messages::WebContentClient::DidRequestCookie>(url)->cookie();
+    return m_client.send_sync<Messages::WebContentClient::DidRequestCookie>(url, static_cast<u8>(source))->cookie();
 }
 
-void PageHost::page_did_set_cookie(const URL& url, const String& cookie)
+void PageHost::page_did_set_cookie(const URL& url, const String& cookie, Web::Cookie::Source source)
 {
-    m_client.post_message(Messages::WebContentClient::DidSetCookie(url, cookie));
+    m_client.post_message(Messages::WebContentClient::DidSetCookie(url, cookie, static_cast<u8>(source)));
 }
 
 }

+ 2 - 2
Userland/Services/WebContent/PageHost.h

@@ -79,8 +79,8 @@ private:
     virtual String page_did_request_prompt(const String&, const String&) override;
     virtual void page_did_change_favicon(const Gfx::Bitmap&) override;
     virtual void page_did_request_image_context_menu(const Gfx::IntPoint&, const URL&, const String& target, unsigned modifiers, const Gfx::Bitmap*) override;
-    virtual String page_did_request_cookie(const URL&) override;
-    virtual void page_did_set_cookie(const URL&, const String&) override;
+    virtual String page_did_request_cookie(const URL&, Web::Cookie::Source) override;
+    virtual void page_did_set_cookie(const URL&, const String&, Web::Cookie::Source) override;
 
     explicit PageHost(ClientConnection&);
 

+ 2 - 2
Userland/Services/WebContent/WebContentClient.ipc

@@ -25,6 +25,6 @@ endpoint WebContentClient = 90
     DidGetSource(URL url, String source) =|
     DidJSConsoleOutput(String method, String line) =|
     DidChangeFavicon(Gfx::ShareableBitmap favicon) =|
-    DidRequestCookie(URL url) => (String cookie)
-    DidSetCookie(URL url, String cookie) =|
+    DidRequestCookie(URL url, u8 source) => (String cookie)
+    DidSetCookie(URL url, String cookie, u8 source) =|
 }