LibWeb: Get the correct CSP navigation type for form submission

This commit is contained in:
Luke Wilde 2024-11-25 17:10:33 +00:00 committed by Alexander Kalenik
commit 8e1ecd25ae
Notes: github-actions[bot] 2025-03-13 15:20:20 +00:00
5 changed files with 21 additions and 25 deletions

View file

@ -311,12 +311,12 @@ WebIDL::ExceptionOr<void> HTMLFormElement::submit_form(GC::Ref<HTMLElement> subm
else
TRY_OR_THROW_OOM(vm, submit_as_entity_body(parsed_action.release_value(), move(entry_list), encoding_type, move(encoding), *target_navigable, history_handling, options.user_involvement));
} else if (scheme.is_one_of("ftp"sv, "javascript"sv)) {
get_action_url(parsed_action.release_value(), *target_navigable, history_handling, options.user_involvement);
get_action_url(parsed_action.release_value(), move(entry_list), *target_navigable, history_handling, options.user_involvement);
} else if (scheme.is_one_of("data"sv, "file"sv)) {
if (method == MethodAttributeState::GET)
TRY_OR_THROW_OOM(vm, mutate_action_url(parsed_action.release_value(), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
else
get_action_url(parsed_action.release_value(), *target_navigable, history_handling, options.user_involvement);
get_action_url(parsed_action.release_value(), move(entry_list), *target_navigable, history_handling, options.user_involvement);
} else if (scheme == "mailto"sv) {
if (method == MethodAttributeState::GET)
TRY_OR_THROW_OOM(vm, mail_with_headers(parsed_action.release_value(), move(entry_list), move(encoding), *target_navigable, history_handling, options.user_involvement));
@ -787,7 +787,7 @@ ErrorOr<void> HTMLFormElement::mutate_action_url(URL::URL parsed_action, Vector<
parsed_action.set_query(query);
// 4. Plan to navigate to parsed action.
plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling, user_involvement);
plan_to_navigate_to(move(parsed_action), Empty {}, move(entry_list), target_navigable, history_handling, user_involvement);
return {};
}
@ -848,16 +848,16 @@ ErrorOr<void> HTMLFormElement::submit_as_entity_body(URL::URL parsed_action, Vec
}
// 3. Plan to navigate to parsed action given a POST resource whose request body is body and request content-type is mimeType.
plan_to_navigate_to(parsed_action, POSTResource { .request_body = move(body), .request_content_type = mime_type, .request_content_type_directives = move(mime_type_directives) }, target_navigable, history_handling, user_involvement);
plan_to_navigate_to(parsed_action, POSTResource { .request_body = move(body), .request_content_type = mime_type, .request_content_type_directives = move(mime_type_directives) }, move(entry_list), target_navigable, history_handling, user_involvement);
return {};
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-get-action
void HTMLFormElement::get_action_url(URL::URL parsed_action, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement)
void HTMLFormElement::get_action_url(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement)
{
// 1. Plan to navigate to parsed action.
// Spec Note: entry list is discarded.
plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling, user_involvement);
plan_to_navigate_to(move(parsed_action), Empty {}, move(entry_list), target_navigable, history_handling, user_involvement);
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mailto-headers
@ -876,7 +876,7 @@ ErrorOr<void> HTMLFormElement::mail_with_headers(URL::URL parsed_action, Vector<
parsed_action.set_query(headers);
// 5. Plan to navigate to parsed action.
plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling, user_involvement);
plan_to_navigate_to(move(parsed_action), Empty {}, move(entry_list), target_navigable, history_handling, user_involvement);
return {};
}
@ -928,12 +928,12 @@ ErrorOr<void> HTMLFormElement::mail_as_body(URL::URL parsed_action, Vector<XHR::
parsed_action.set_query(MUST(query_builder.to_string()));
// 7. Plan to navigate to parsed action.
plan_to_navigate_to(move(parsed_action), Empty {}, target_navigable, history_handling, user_involvement);
plan_to_navigate_to(move(parsed_action), Empty {}, move(entry_list), target_navigable, history_handling, user_involvement);
return {};
}
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plan-to-navigate
void HTMLFormElement::plan_to_navigate_to(URL::URL url, Variant<Empty, String, POSTResource> post_resource, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement)
void HTMLFormElement::plan_to_navigate_to(URL::URL url, Variant<Empty, String, POSTResource> post_resource, Vector<XHR::FormDataEntry> entry_list, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement)
{
// 1. Let referrerPolicy be the empty string.
ReferrerPolicy::ReferrerPolicy referrer_policy = ReferrerPolicy::ReferrerPolicy::EmptyString;
@ -953,18 +953,19 @@ void HTMLFormElement::plan_to_navigate_to(URL::URL url, Variant<Empty, String, P
// 4. Queue an element task on the DOM manipulation task source given the form element and the following steps:
// NOTE: `this`, `actual_resource` and `target_navigable` are protected by GC::HeapFunction.
queue_an_element_task(Task::Source::DOMManipulation, [this, url, post_resource, target_navigable, history_handling, referrer_policy, user_involvement]() {
queue_an_element_task(Task::Source::DOMManipulation, [this, url, post_resource, entry_list = move(entry_list), target_navigable, history_handling, referrer_policy, user_involvement]() {
// 1. Set the form's planned navigation to null.
m_planned_navigation = {};
// 2. Navigate targetNavigable to url using the form element's node document, with historyHandling set to historyHandling,
// referrerPolicy set to referrerPolicy, documentResource set to postResource, and cspNavigationType set to "form-submission".
// referrerPolicy set to referrerPolicy, documentResource set to postResource, and formDataEntryList set to entry list.
MUST(target_navigable->navigate({ .url = url,
.source_document = this->document(),
.document_resource = post_resource,
.response = nullptr,
.exceptions_enabled = false,
.history_handling = history_handling,
.form_data_entry_list = move(entry_list),
.referrer_policy = referrer_policy,
.user_involvement = user_involvement }));
});

View file

@ -120,10 +120,10 @@ private:
ErrorOr<void> mutate_action_url(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
ErrorOr<void> submit_as_entity_body(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
void get_action_url(URL::URL parsed_action, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
void get_action_url(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
ErrorOr<void> mail_with_headers(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
ErrorOr<void> mail_as_body(URL::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, EncodingTypeAttributeState encoding_type, String encoding, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
void plan_to_navigate_to(URL::URL url, Variant<Empty, String, POSTResource> post_resource, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
void plan_to_navigate_to(URL::URL url, Variant<Empty, String, POSTResource> post_resource, Vector<XHR::FormDataEntry> entry_list, GC::Ref<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);
FormAssociatedElement* default_button();
size_t number_of_fields_blocking_implicit_submission() const;

View file

@ -781,7 +781,7 @@ static GC::Ref<NavigationParams> create_navigation_params_from_a_srcdoc_resource
}
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#create-navigation-params-by-fetching
static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation_params_by_fetching(GC::Ptr<SessionHistoryEntry> entry, GC::Ptr<Navigable> navigable, SourceSnapshotParams const& source_snapshot_params, TargetSnapshotParams const& target_snapshot_params, CSPNavigationType csp_navigation_type, UserNavigationInvolvement user_involvement, Optional<String> navigation_id)
static WebIDL::ExceptionOr<Navigable::NavigationParamsVariant> create_navigation_params_by_fetching(GC::Ptr<SessionHistoryEntry> entry, GC::Ptr<Navigable> navigable, SourceSnapshotParams const& source_snapshot_params, TargetSnapshotParams const& target_snapshot_params, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, UserNavigationInvolvement user_involvement, Optional<String> navigation_id)
{
auto& vm = navigable->vm();
VERIFY(navigable->active_window());
@ -1162,7 +1162,7 @@ WebIDL::ExceptionOr<void> Navigable::populate_session_history_entry_document(
UserNavigationInvolvement user_involvement,
Optional<String> navigation_id,
Navigable::NavigationParamsVariant navigation_params,
CSPNavigationType csp_navigation_type,
ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type,
bool allow_POST,
GC::Ptr<GC::Function<void()>> completion_steps)
{
@ -1424,7 +1424,7 @@ void Navigable::begin_navigation(NavigateParams params)
auto& vm = this->vm();
// 1. Let cspNavigationType be "form-submission" if formDataEntryList is non-null; otherwise "other".
auto csp_navigation_type = form_data_entry_list.has_value() ? CSPNavigationType::FormSubmission : CSPNavigationType::Other;
auto csp_navigation_type = form_data_entry_list.has_value() ? ContentSecurityPolicy::Directives::Directive::NavigationType::FormSubmission : ContentSecurityPolicy::Directives::Directive::NavigationType::Other;
// 2. Let sourceSnapshotParams be the result of snapshotting source snapshot params given sourceDocument.
auto source_snapshot_params = source_document->snapshot_source_snapshot_params();
@ -1869,7 +1869,7 @@ GC::Ptr<DOM::Document> Navigable::evaluate_javascript_url(URL::URL const& url, U
}
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#navigate-to-a-javascript:-url
void Navigable::navigate_to_a_javascript_url(URL::URL const& url, HistoryHandlingBehavior history_handling, GC::Ref<SourceSnapshotParams>, URL::Origin const& initiator_origin, UserNavigationInvolvement user_involvement, CSPNavigationType csp_navigation_type, String navigation_id)
void Navigable::navigate_to_a_javascript_url(URL::URL const& url, HistoryHandlingBehavior history_handling, GC::Ref<SourceSnapshotParams>, URL::Origin const& initiator_origin, UserNavigationInvolvement user_involvement, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, String navigation_id)
{
// 1. Assert: historyHandling is "replace".
VERIFY(history_handling == HistoryHandlingBehavior::Replace);

View file

@ -28,11 +28,6 @@
namespace Web::HTML {
enum class CSPNavigationType {
Other,
FormSubmission,
};
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#target-snapshot-params
struct TargetSnapshotParams {
SandboxingFlagSet sandboxing_flags {};
@ -130,7 +125,7 @@ public:
UserNavigationInvolvement user_involvement,
Optional<String> navigation_id = {},
NavigationParamsVariant navigation_params = Navigable::NullOrError {},
CSPNavigationType csp_navigation_type = CSPNavigationType::Other,
ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type = ContentSecurityPolicy::Directives::Directive::NavigationType::Other,
bool allow_POST = false,
GC::Ptr<GC::Function<void()>> completion_steps = {});
@ -204,7 +199,7 @@ protected:
private:
void begin_navigation(NavigateParams);
void navigate_to_a_fragment(URL::URL const&, HistoryHandlingBehavior, UserNavigationInvolvement, GC::Ptr<DOM::Element> source_element, Optional<SerializationRecord> navigation_api_state, String navigation_id);
void navigate_to_a_javascript_url(URL::URL const&, HistoryHandlingBehavior, GC::Ref<SourceSnapshotParams>, URL::Origin const& initiator_origin, UserNavigationInvolvement, CSPNavigationType csp_navigation_type, String navigation_id);
void navigate_to_a_javascript_url(URL::URL const&, HistoryHandlingBehavior, GC::Ref<SourceSnapshotParams>, URL::Origin const& initiator_origin, UserNavigationInvolvement, ContentSecurityPolicy::Directives::Directive::NavigationType csp_navigation_type, String navigation_id);
void reset_cursor_blink_cycle();

View file

@ -655,7 +655,7 @@ TraversableNavigable::HistoryStepResult TraversableNavigable::apply_the_history_
// queue a global task on the navigation and traversal task source given navigable's active window to
// run afterDocumentPopulated.
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(this->heap(), [populated_target_entry, potentially_target_specific_source_snapshot_params, target_snapshot_params, this, allow_POST, navigable, after_document_populated = GC::create_function(this->heap(), move(after_document_populated)), user_involvement] {
navigable->populate_session_history_entry_document(populated_target_entry, *potentially_target_specific_source_snapshot_params, target_snapshot_params, user_involvement, {}, Navigable::NullOrError {}, CSPNavigationType::Other, allow_POST, GC::create_function(this->heap(), [this, after_document_populated, populated_target_entry]() mutable {
navigable->populate_session_history_entry_document(populated_target_entry, *potentially_target_specific_source_snapshot_params, target_snapshot_params, user_involvement, {}, Navigable::NullOrError {}, ContentSecurityPolicy::Directives::Directive::NavigationType::Other, allow_POST, GC::create_function(this->heap(), [this, after_document_populated, populated_target_entry]() mutable {
VERIFY(active_window());
queue_global_task(Task::Source::NavigationAndTraversal, *active_window(), GC::create_function(this->heap(), [after_document_populated, populated_target_entry]() mutable {
after_document_populated->function()(true, populated_target_entry);