Skip to content

Commit

Permalink
Cherry-pick 267352@main (3b7c510). https://bugs.webkit.org/show_bug.c…
Browse files Browse the repository at this point in the history
…gi?id=260361

    Transient activation should be dropped after evaluating JavaScript, except when required for application compatibility
    https://bugs.webkit.org/show_bug.cgi?id=260361

    Reviewed by Carlos Garcia Campos.

    This is a follow-up to bug #258037 and bug #251276. When a user interacts with
    a web page, the page is said to receive a user gesture and this grants
    additional permissions to the web content until the "transient activation"
    period expires, which in WebKit is 5 seconds. WebKit's API functions that allow
    applications to run JavaScript allow the application to force a user gesture in
    order to execute JS with full permissions. But in this case, the transient
    activation should expire immediately because the user did not really interact
    with the page. Web content should not unexpectedly receive additional
    permissions for 5 seconds whenever the application runs some of its own
    unrelated JS.

    Bug #258037 and bug #251276 fixed this for freshly built applications on
    Cocoa platforms, but left other platforms unchanged because dropping the
    transient activation is not backwards-compatible and coulde possibly
    cause unknown breakage in applications. But the desired behavior is to
    always drop transient activation. Implement this everywhere:

    (1) In RemoteInspectorProtocolHandler.cpp, affecting JS executed by remote
    inspector. This change is surely safe.

    (2) In WebKitWebView.cpp, affecting the GTK and WPE port. This could
    possibly break GTK/WPE applications, so we won't backport it to the 2.40
    stable branch.

    (3) In WKPageRunJavaScriptInMainFrame, affecting non-Cocoa ports. This
    should be safe because the C API is not public except for Windows and
    PlayStation ports, which control the version of WebKit they ship.

    (4) And finally in ScriptController::executeScriptIgnoringException. This
    will affect all ports and could possibly break things.

    * Source/WebCore/bindings/js/ScriptController.cpp:
    (WebCore::ScriptController::executeScriptInWorldIgnoringException):
    * Source/WebKit/UIProcess/API/C/WKPage.cpp:
    (WKPageRunJavaScriptInMainFrame):
    * Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp:
    (webkitWebViewRunJavascriptWithoutForcedUserGestures):
    (webkitWebViewEvaluateJavascriptInternal):
    (webkitWebViewCallAsyncJavascriptFunctionInternal):
    (resourcesStreamReadCallback):
    * Source/WebKit/UIProcess/Inspector/socket/RemoteInspectorProtocolHandler.cpp:
    (WebKit::RemoteInspectorProtocolHandler::runScript):

    Canonical link: https://commits.webkit.org/267352@main

Canonical link: https://commits.webkit.org/266719.24@webkitglib/2.42
  • Loading branch information
mcatanzaro committed Aug 28, 2023
1 parent ad247f6 commit 13de864
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Source/WebCore/bindings/js/ScriptController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ JSC::JSValue ScriptController::executeScriptIgnoringException(const String& scri

JSC::JSValue ScriptController::executeScriptInWorldIgnoringException(DOMWrapperWorld& world, const String& script, bool forceUserGesture)
{
auto result = executeScriptInWorld(world, { script, URL { }, false, std::nullopt, forceUserGesture, RemoveTransientActivation::No });
auto result = executeScriptInWorld(world, { script, URL { }, false, std::nullopt, forceUserGesture, RemoveTransientActivation::Yes });
return result ? result.value() : JSC::JSValue { };
}

Expand Down
2 changes: 1 addition & 1 deletion Source/WebKit/UIProcess/API/C/WKPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2604,7 +2604,7 @@ void WKPageRunJavaScriptInMainFrame(WKPageRef pageRef, WKStringRef scriptRef, vo
#if PLATFORM(COCOA)
auto removeTransientActivation = shouldEvaluateJavaScriptWithoutTransientActivation() ? RemoveTransientActivation::Yes : RemoveTransientActivation::No;
#else
auto removeTransientActivation = RemoveTransientActivation::No;
auto removeTransientActivation = RemoveTransientActivation::Yes;
#endif

toImpl(pageRef)->runJavaScriptInMainFrame({ toImpl(scriptRef)->string(), URL { }, false, std::nullopt, true, removeTransientActivation }, [context, callback] (auto&& result) {
Expand Down
8 changes: 4 additions & 4 deletions Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4029,7 +4029,7 @@ void webkitWebViewRunJavascriptWithoutForcedUserGestures(WebKitWebView* webView,
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(script);

RunJavaScriptParameters params = { String::fromUTF8(script), URL { }, RunAsAsyncFunction::No, std::nullopt, ForceUserGesture::No, RemoveTransientActivation::No };
RunJavaScriptParameters params = { String::fromUTF8(script), URL { }, RunAsAsyncFunction::No, std::nullopt, ForceUserGesture::No, RemoveTransientActivation::Yes };
webkitWebViewRunJavaScriptWithParams(webView, WTFMove(params), nullptr, RunJavascriptReturnType::JSCValue, adoptGRef(g_task_new(webView, cancellable, callback, userData)));
}

Expand All @@ -4038,7 +4038,7 @@ static void webkitWebViewEvaluateJavascriptInternal(WebKitWebView* webView, cons
g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
g_return_if_fail(script);

RunJavaScriptParameters params = { String::fromUTF8(script, length < 0 ? strlen(script) : length), URL({ }, String::fromUTF8(sourceURI)), RunAsAsyncFunction::No, std::nullopt, ForceUserGesture::Yes, RemoveTransientActivation::No };
RunJavaScriptParameters params = { String::fromUTF8(script, length < 0 ? strlen(script) : length), URL({ }, String::fromUTF8(sourceURI)), RunAsAsyncFunction::No, std::nullopt, ForceUserGesture::Yes, RemoveTransientActivation::Yes };
webkitWebViewRunJavaScriptWithParams(webView, WTFMove(params), worldName, returnType, adoptGRef(g_task_new(webView, cancellable, callback, userData)));
}

Expand Down Expand Up @@ -4174,7 +4174,7 @@ static void webkitWebViewCallAsyncJavascriptFunctionInternal(WebKitWebView* webV
return;
}

RunJavaScriptParameters params = { String::fromUTF8(body, length < 0 ? strlen(body) : length), URL({ }, String::fromUTF8(sourceURI)), RunAsAsyncFunction::Yes, WTFMove(argumentsMap), ForceUserGesture::Yes, RemoveTransientActivation::No };
RunJavaScriptParameters params = { String::fromUTF8(body, length < 0 ? strlen(body) : length), URL({ }, String::fromUTF8(sourceURI)), RunAsAsyncFunction::Yes, WTFMove(argumentsMap), ForceUserGesture::Yes, RemoveTransientActivation::Yes };
webkitWebViewRunJavaScriptWithParams(webView, WTFMove(params), worldName, returnType, adoptGRef(g_task_new(webView, cancellable, callback, userData)));
}

Expand Down Expand Up @@ -4504,7 +4504,7 @@ static void resourcesStreamReadCallback(GObject* object, GAsyncResult* result, g

WebKitWebView* webView = WEBKIT_WEB_VIEW(g_task_get_source_object(task.get()));
gpointer outputStreamData = g_memory_output_stream_get_data(G_MEMORY_OUTPUT_STREAM(object));
RunJavaScriptParameters params = { String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), URL { }, RunAsAsyncFunction::No, std::nullopt, ForceUserGesture::Yes, RemoveTransientActivation::No };
RunJavaScriptParameters params = { String::fromUTF8(reinterpret_cast<const gchar*>(outputStreamData)), URL { }, RunAsAsyncFunction::No, std::nullopt, ForceUserGesture::Yes, RemoveTransientActivation::Yes };
webkitWebViewRunJavaScriptWithParams(webView, WTFMove(params), nullptr, RunJavascriptReturnType::WebKitJavascriptResult, WTFMove(task));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ void RemoteInspectorProtocolHandler::inspect(const String& hostAndPort, Connecti

void RemoteInspectorProtocolHandler::runScript(const String& script)
{
m_page.runJavaScriptInMainFrame({ script, URL { }, false, std::nullopt, false, RemoveTransientActivation::No },
m_page.runJavaScriptInMainFrame({ script, URL { }, false, std::nullopt, false, RemoveTransientActivation::Yes },
[] (auto&& result) {
if (!result.has_value())
LOG_ERROR("Exception running script \"%s\"", result.error().message.utf8().data());
Expand Down

0 comments on commit 13de864

Please sign in to comment.