mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-03 16:16:43 +00:00
LibWeb: Update Fetch's compute the redirect-taint concept
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This commit is contained in:
parent
e9246c15d9
commit
0dc2fb3781
Notes:
github-actions[bot]
2025-08-12 11:09:46 +00:00
Author: https://github.com/kennethmyhra
Commit: 0dc2fb3781
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5826
Reviewed-by: https://github.com/trflynn89 ✅
5 changed files with 60 additions and 31 deletions
|
@ -545,9 +545,8 @@ WebIDL::ExceptionOr<GC::Ptr<PendingResponse>> main_fetch(JS::Realm& realm, Infra
|
|||
if (internal_response->url_list().is_empty())
|
||||
internal_response->set_url_list(request->url_list());
|
||||
|
||||
// 17. If request has a redirect-tainted origin, then set internalResponse’s has-cross-origin-redirects to true.
|
||||
if (request->has_redirect_tainted_origin())
|
||||
internal_response->set_has_cross_origin_redirects(true);
|
||||
// 17. Set internalResponse’s redirect taint to request’s redirect-taint.
|
||||
internal_response->set_redirect_taint(request->redirect_taint());
|
||||
|
||||
// 18. If request’s timing allow failed flag is unset, then set internalResponse’s timing allow passed flag.
|
||||
if (!request->timing_allow_failed())
|
||||
|
@ -706,8 +705,8 @@ void fetch_response_handover(JS::Realm& realm, Infrastructure::FetchParams const
|
|||
// 6. Let responseStatus be 0.
|
||||
auto response_status = 0;
|
||||
|
||||
// 7. If fetchParams’s request’s mode is not "navigate" or response’s has-cross-origin-redirects is false:
|
||||
if (fetch_params.request()->mode() != Infrastructure::Request::Mode::Navigate || !response.has_cross_origin_redirects()) {
|
||||
// 7. If fetchParams’s request’s mode is not "navigate" or response’s redirect taint is "same-origin":
|
||||
if (fetch_params.request()->mode() != Infrastructure::Request::Mode::Navigate || response.redirect_taint() == Infrastructure::RedirectTaint::SameOrigin) {
|
||||
// 1. Set responseStatus to response’s status.
|
||||
response_status = response.status();
|
||||
|
||||
|
|
|
@ -47,6 +47,12 @@ enum class HttpQuotedStringExtractValue {
|
|||
Yes,
|
||||
};
|
||||
|
||||
enum class RedirectTaint {
|
||||
SameOrigin,
|
||||
SameSite,
|
||||
CrossSite,
|
||||
};
|
||||
|
||||
[[nodiscard]] String collect_an_http_quoted_string(GenericLexer& lexer, HttpQuotedStringExtractValue extract_value = HttpQuotedStringExtractValue::No);
|
||||
|
||||
}
|
||||
|
|
|
@ -164,14 +164,19 @@ bool Request::is_navigation_request() const
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#concept-request-tainted-origin
|
||||
bool Request::has_redirect_tainted_origin() const
|
||||
RedirectTaint Request::redirect_taint() const
|
||||
{
|
||||
// A request request has a redirect-tainted origin if these steps return true:
|
||||
// 1. Assert: request’s origin is not "client".
|
||||
if (auto const* origin = m_origin.get_pointer<Origin>())
|
||||
VERIFY(*origin != Origin::Client);
|
||||
|
||||
// 1. Let lastURL be null.
|
||||
// 2. Let lastURL be null.
|
||||
Optional<URL::URL const&> last_url;
|
||||
|
||||
// 2. For each url of request’s URL list:
|
||||
// 3. Let taint be "same-origin".
|
||||
auto taint = RedirectTaint::SameOrigin;
|
||||
|
||||
// 4. For each url of request’s URL list:
|
||||
for (auto const& url : m_url_list) {
|
||||
// 1. If lastURL is null, then set lastURL to url and continue.
|
||||
if (!last_url.has_value()) {
|
||||
|
@ -179,29 +184,41 @@ bool Request::has_redirect_tainted_origin() const
|
|||
continue;
|
||||
}
|
||||
|
||||
// 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.
|
||||
// 2. If url’s origin is not same site with lastURL’s origin and request’s origin is not same site with
|
||||
// lastURL’s origin, then return "cross-site".
|
||||
auto const* request_origin = m_origin.get_pointer<URL::Origin>();
|
||||
if (!url.origin().is_same_origin(last_url->origin())
|
||||
&& (request_origin == nullptr || !request_origin->is_same_origin(last_url->origin()))) {
|
||||
return true;
|
||||
if (!url.origin().is_same_site(last_url->origin())
|
||||
&& (request_origin == nullptr || !request_origin->is_same_site(last_url->origin()))) {
|
||||
return RedirectTaint::CrossSite;
|
||||
}
|
||||
|
||||
// 3. Set lastURL to url.
|
||||
// 3. 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 set taint to "same-site".
|
||||
if (!url.origin().is_same_origin(last_url->origin())
|
||||
&& (request_origin == nullptr || !request_origin->is_same_origin(last_url->origin()))) {
|
||||
taint = RedirectTaint::SameSite;
|
||||
}
|
||||
|
||||
// 4. Set lastURL to url.
|
||||
last_url = url;
|
||||
}
|
||||
|
||||
// 3. Return false.
|
||||
return false;
|
||||
// 5. Return taint.
|
||||
return taint;
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#serializing-a-request-origin
|
||||
String Request::serialize_origin() const
|
||||
{
|
||||
// 1. If request has a redirect-tainted origin, then return "null".
|
||||
if (has_redirect_tainted_origin())
|
||||
// 1. Assert: request’s origin is not "client".
|
||||
if (auto const* origin = m_origin.get_pointer<Origin>())
|
||||
VERIFY(*origin != Origin::Client);
|
||||
|
||||
// 2. If request’s redirect-taint is not "same-origin", then return "null".
|
||||
if (redirect_taint() != RedirectTaint::SameOrigin)
|
||||
return "null"_string;
|
||||
|
||||
// 2. Return request’s origin, serialized.
|
||||
// 3. Return request’s origin, serialized.
|
||||
return m_origin.get<URL::Origin>().serialize();
|
||||
}
|
||||
|
||||
|
@ -358,25 +375,30 @@ void Request::add_origin_header()
|
|||
// https://fetch.spec.whatwg.org/#cross-origin-embedder-policy-allows-credentials
|
||||
bool Request::cross_origin_embedder_policy_allows_credentials() const
|
||||
{
|
||||
// 1. If request’s mode is not "no-cors", then return true.
|
||||
// 1. Assert: request’s origin is not "client".
|
||||
if (auto const* origin = m_origin.get_pointer<Origin>())
|
||||
VERIFY(*origin != Origin::Client);
|
||||
|
||||
// 2. If request’s mode is not "no-cors", then return true.
|
||||
if (m_mode != Mode::NoCORS)
|
||||
return true;
|
||||
|
||||
// 2. If request’s client is null, then return true.
|
||||
// 3. If request’s client is null, then return true.
|
||||
if (m_client == nullptr)
|
||||
return true;
|
||||
|
||||
// 3. If request’s client’s policy container’s embedder policy’s value is not "credentialless", then return true.
|
||||
// 4. If request’s client’s policy container’s embedder policy’s value is not "credentialless", then return true.
|
||||
if (m_policy_container.has<GC::Ref<HTML::PolicyContainer>>() && m_policy_container.get<GC::Ref<HTML::PolicyContainer>>()->embedder_policy.value != HTML::EmbedderPolicyValue::Credentialless)
|
||||
return true;
|
||||
|
||||
// 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.
|
||||
// 5. Return false.
|
||||
// 5. If request’s origin is same origin with request’s current URL’s origin and request’s redirect-taint is not
|
||||
// "same-origin", then return true.
|
||||
// 6. Return false.
|
||||
auto const* request_origin = m_origin.get_pointer<URL::Origin>();
|
||||
if (request_origin == nullptr)
|
||||
return false;
|
||||
|
||||
return request_origin->is_same_origin(current_url().origin()) && !has_redirect_tainted_origin();
|
||||
return request_origin->is_same_origin(current_url().origin()) && redirect_taint() != RedirectTaint::SameOrigin;
|
||||
}
|
||||
|
||||
StringView request_destination_to_string(Request::Destination destination)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibURL/Origin.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
|
||||
#include <LibWeb/HTML/PolicyContainers.h>
|
||||
|
@ -310,7 +311,7 @@ public:
|
|||
[[nodiscard]] bool is_non_subresource_request() const;
|
||||
[[nodiscard]] bool is_navigation_request() const;
|
||||
|
||||
[[nodiscard]] bool has_redirect_tainted_origin() const;
|
||||
[[nodiscard]] RedirectTaint redirect_taint() const;
|
||||
|
||||
[[nodiscard]] String serialize_origin() const;
|
||||
[[nodiscard]] ByteBuffer byte_serialize_origin() const;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <LibJS/Forward.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibURL/URL.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Statuses.h>
|
||||
|
@ -103,8 +104,8 @@ public:
|
|||
[[nodiscard]] virtual BodyInfo const& body_info() const { return m_body_info; }
|
||||
virtual void set_body_info(BodyInfo body_info) { m_body_info = body_info; }
|
||||
|
||||
[[nodiscard]] bool has_cross_origin_redirects() const { return m_has_cross_origin_redirects; }
|
||||
void set_has_cross_origin_redirects(bool has_cross_origin_redirects) { m_has_cross_origin_redirects = has_cross_origin_redirects; }
|
||||
[[nodiscard]] RedirectTaint redirect_taint() const { return m_redirect_taint; }
|
||||
void set_redirect_taint(RedirectTaint redirect_taint) { m_redirect_taint = move(redirect_taint); }
|
||||
|
||||
[[nodiscard]] bool is_aborted_network_error() const;
|
||||
[[nodiscard]] bool is_network_error() const;
|
||||
|
@ -188,9 +189,9 @@ private:
|
|||
// https://fetch.spec.whatwg.org/#response-service-worker-timing-info
|
||||
// FIXME: A response has an associated service worker timing info (null or a service worker timing info), which is initially null.
|
||||
|
||||
// https://fetch.spec.whatwg.org/#response-has-cross-origin-redirects
|
||||
// A response has an associated has-cross-origin-redirects (a boolean), which is initially false.
|
||||
bool m_has_cross_origin_redirects { false };
|
||||
// https://fetch.spec.whatwg.org/#response-redirect-taint
|
||||
// A response has an associated redirect taint ("same-origin", "same-site", or "cross-site"), which is initially "same-origin".
|
||||
RedirectTaint m_redirect_taint { RedirectTaint::SameOrigin };
|
||||
|
||||
// FIXME is the type correct?
|
||||
u64 current_age() const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue