Skip to content

Commit 0dc2fb3

Browse files
kennethmyhratrflynn89
authored andcommitted
LibWeb: Update Fetch's compute the redirect-taint concept
1 parent e9246c1 commit 0dc2fb3

File tree

5 files changed

+58
-29
lines changed

5 files changed

+58
-29
lines changed

Libraries/LibWeb/Fetch/Fetching/Fetching.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -545,9 +545,8 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
545545
if (internal_response->url_list().is_empty())
546546
internal_response->set_url_list(request->url_list());
547547

548-
// 17. If request has a redirect-tainted origin, then set internalResponse’s has-cross-origin-redirects to true.
549-
if (request->has_redirect_tainted_origin())
550-
internal_response->set_has_cross_origin_redirects(true);
548+
// 17. Set internalResponse’s redirect taint to request’s redirect-taint.
549+
internal_response->set_redirect_taint(request->redirect_taint());
551550

552551
// 18. If request’s timing allow failed flag is unset, then set internalResponse’s timing allow passed flag.
553552
if (!request->timing_allow_failed())
@@ -706,8 +705,8 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
706705
// 6. Let responseStatus be 0.
707706
auto response_status = 0;
708707

709-
// 7. If fetchParams’s request’s mode is not "navigate" or response’s has-cross-origin-redirects is false:
710-
if (fetch_params.request()->mode() != Infrastructure::Request::Mode::Navigate || !response.has_cross_origin_redirects()) {
708+
// 7. If fetchParams’s request’s mode is not "navigate" or response’s redirect taint is "same-origin":
709+
if (fetch_params.request()->mode() != Infrastructure::Request::Mode::Navigate || response.redirect_taint() == Infrastructure::RedirectTaint::SameOrigin) {
711710
// 1. Set responseStatus to response’s status.
712711
response_status = response.status();
713712

Libraries/LibWeb/Fetch/Infrastructure/HTTP.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ enum class HttpQuotedStringExtractValue {
4747
Yes,
4848
};
4949

50+
enum class RedirectTaint {
51+
SameOrigin,
52+
SameSite,
53+
CrossSite,
54+
};
55+
5056
[[nodiscard]] String collect_an_http_quoted_string(GenericLexer& lexer, HttpQuotedStringExtractValue extract_value = HttpQuotedStringExtractValue::No);
5157

5258
}

Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -164,44 +164,61 @@ bool Request::is_navigation_request() const
164164
}
165165

166166
// https://fetch.spec.whatwg.org/#concept-request-tainted-origin
167-
bool Request::has_redirect_tainted_origin() const
167+
RedirectTaint Request::redirect_taint() const
168168
{
169-
// A request request has a redirect-tainted origin if these steps return true:
169+
// 1. Assert: request’s origin is not "client".
170+
if (auto const* origin = m_origin.get_pointer<Origin>())
171+
VERIFY(*origin != Origin::Client);
170172

171-
// 1. Let lastURL be null.
173+
// 2. Let lastURL be null.
172174
Optional<URL::URL const&> last_url;
173175

174-
// 2. For each url of request’s URL list:
176+
// 3. Let taint be "same-origin".
177+
auto taint = RedirectTaint::SameOrigin;
178+
179+
// 4. For each url of request’s URL list:
175180
for (auto const& url : m_url_list) {
176181
// 1. If lastURL is null, then set lastURL to url and continue.
177182
if (!last_url.has_value()) {
178183
last_url = url;
179184
continue;
180185
}
181186

182-
// 2. If url’s origin is not same origin with lastURL’s origin and request’s origin is not same origin with lastURL’s origin, then return true.
187+
// 2. If url’s origin is not same site with lastURL’s origin and request’s origin is not same site with
188+
// lastURL’s origin, then return "cross-site".
183189
auto const* request_origin = m_origin.get_pointer<URL::Origin>();
190+
if (!url.origin().is_same_site(last_url->origin())
191+
&& (request_origin == nullptr || !request_origin->is_same_site(last_url->origin()))) {
192+
return RedirectTaint::CrossSite;
193+
}
194+
195+
// 3. If url’s origin is not same origin with lastURL’s origin and request’s origin is not same origin with
196+
// lastURL’s origin, then set taint to "same-site".
184197
if (!url.origin().is_same_origin(last_url->origin())
185198
&& (request_origin == nullptr || !request_origin->is_same_origin(last_url->origin()))) {
186-
return true;
199+
taint = RedirectTaint::SameSite;
187200
}
188201

189-
// 3. Set lastURL to url.
202+
// 4. Set lastURL to url.
190203
last_url = url;
191204
}
192205

193-
// 3. Return false.
194-
return false;
206+
// 5. Return taint.
207+
return taint;
195208
}
196209

197210
// https://fetch.spec.whatwg.org/#serializing-a-request-origin
198211
String Request::serialize_origin() const
199212
{
200-
// 1. If request has a redirect-tainted origin, then return "null".
201-
if (has_redirect_tainted_origin())
213+
// 1. Assert: request’s origin is not "client".
214+
if (auto const* origin = m_origin.get_pointer<Origin>())
215+
VERIFY(*origin != Origin::Client);
216+
217+
// 2. If request’s redirect-taint is not "same-origin", then return "null".
218+
if (redirect_taint() != RedirectTaint::SameOrigin)
202219
return "null"_string;
203220

204-
// 2. Return request’s origin, serialized.
221+
// 3. Return request’s origin, serialized.
205222
return m_origin.get<URL::Origin>().serialize();
206223
}
207224

@@ -358,25 +375,30 @@ void Request::add_origin_header()
358375
// https://fetch.spec.whatwg.org/#cross-origin-embedder-policy-allows-credentials
359376
bool Request::cross_origin_embedder_policy_allows_credentials() const
360377
{
361-
// 1. If request’s mode is not "no-cors", then return true.
378+
// 1. Assert: request’s origin is not "client".
379+
if (auto const* origin = m_origin.get_pointer<Origin>())
380+
VERIFY(*origin != Origin::Client);
381+
382+
// 2. If request’s mode is not "no-cors", then return true.
362383
if (m_mode != Mode::NoCORS)
363384
return true;
364385

365-
// 2. If request’s client is null, then return true.
386+
// 3. If request’s client is null, then return true.
366387
if (m_client == nullptr)
367388
return true;
368389

369-
// 3. If request’s client’s policy container’s embedder policy’s value is not "credentialless", then return true.
390+
// 4. If request’s client’s policy container’s embedder policy’s value is not "credentialless", then return true.
370391
if (m_policy_container.has<GC::Ref<HTML::PolicyContainer>>() && m_policy_container.get<GC::Ref<HTML::PolicyContainer>>()->embedder_policy.value != HTML::EmbedderPolicyValue::Credentialless)
371392
return true;
372393

373-
// 4. If request’s origin is same origin with request’s current URL’s origin and request does not have a redirect-tainted origin, then return true.
374-
// 5. Return false.
394+
// 5. If request’s origin is same origin with request’s current URL’s origin and request’s redirect-taint is not
395+
// "same-origin", then return true.
396+
// 6. Return false.
375397
auto const* request_origin = m_origin.get_pointer<URL::Origin>();
376398
if (request_origin == nullptr)
377399
return false;
378400

379-
return request_origin->is_same_origin(current_url().origin()) && !has_redirect_tainted_origin();
401+
return request_origin->is_same_origin(current_url().origin()) && redirect_taint() != RedirectTaint::SameOrigin;
380402
}
381403

382404
StringView request_destination_to_string(Request::Destination destination)

Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <LibJS/Heap/Cell.h>
2020
#include <LibURL/Origin.h>
2121
#include <LibURL/URL.h>
22+
#include <LibWeb/Fetch/Infrastructure/HTTP.h>
2223
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
2324
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
2425
#include <LibWeb/HTML/PolicyContainers.h>
@@ -310,7 +311,7 @@ class Request final : public JS::Cell {
310311
[[nodiscard]] bool is_non_subresource_request() const;
311312
[[nodiscard]] bool is_navigation_request() const;
312313

313-
[[nodiscard]] bool has_redirect_tainted_origin() const;
314+
[[nodiscard]] RedirectTaint redirect_taint() const;
314315

315316
[[nodiscard]] String serialize_origin() const;
316317
[[nodiscard]] ByteBuffer byte_serialize_origin() const;

Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <LibJS/Forward.h>
1717
#include <LibJS/Heap/Cell.h>
1818
#include <LibURL/URL.h>
19+
#include <LibWeb/Fetch/Infrastructure/HTTP.h>
1920
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
2021
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
2122
#include <LibWeb/Fetch/Infrastructure/HTTP/Statuses.h>
@@ -103,8 +104,8 @@ class Response : public JS::Cell {
103104
[[nodiscard]] virtual BodyInfo const& body_info() const { return m_body_info; }
104105
virtual void set_body_info(BodyInfo body_info) { m_body_info = body_info; }
105106

106-
[[nodiscard]] bool has_cross_origin_redirects() const { return m_has_cross_origin_redirects; }
107-
void set_has_cross_origin_redirects(bool has_cross_origin_redirects) { m_has_cross_origin_redirects = has_cross_origin_redirects; }
107+
[[nodiscard]] RedirectTaint redirect_taint() const { return m_redirect_taint; }
108+
void set_redirect_taint(RedirectTaint redirect_taint) { m_redirect_taint = move(redirect_taint); }
108109

109110
[[nodiscard]] bool is_aborted_network_error() const;
110111
[[nodiscard]] bool is_network_error() const;
@@ -188,9 +189,9 @@ class Response : public JS::Cell {
188189
// https://fetch.spec.whatwg.org/#response-service-worker-timing-info
189190
// FIXME: A response has an associated service worker timing info (null or a service worker timing info), which is initially null.
190191

191-
// https://fetch.spec.whatwg.org/#response-has-cross-origin-redirects
192-
// A response has an associated has-cross-origin-redirects (a boolean), which is initially false.
193-
bool m_has_cross_origin_redirects { false };
192+
// https://fetch.spec.whatwg.org/#response-redirect-taint
193+
// A response has an associated redirect taint ("same-origin", "same-site", or "cross-site"), which is initially "same-origin".
194+
RedirectTaint m_redirect_taint { RedirectTaint::SameOrigin };
194195

195196
// FIXME is the type correct?
196197
u64 current_age() const;

0 commit comments

Comments
 (0)