Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Permissions.query should return 'prompt' for unique origins #3575

Conversation

youennf
Copy link
Contributor

@youennf youennf commented Aug 23, 2022

fde28e0

Permissions.query should return 'prompt' for unique origins
https://bugs.webkit.org/show_bug.cgi?id=244246
rdar://98990618

Reviewed by Chris Dumez.

Unique origins do not have a host so it is not useful to call the UI delegate to get the permission.
Instead, we do as if the delegate returns prompt.

Coverdd by added API test.

* Source/WebKit/UIProcess/WebPageProxy.cpp:
(WebKit::isOriginUnique):
(WebKit::WebPageProxy::queryPermission):
* Tools/TestWebKitAPI/SourcesCocoa.txt:
* Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* Tools/TestWebKitAPI/Tests/WebKitCocoa/PermissionsAPI.mm: Added.
(-[PermissionsAPIMessageHandler userContentController:didReceiveScriptMessage:]):
(-[PermissionsAPIUIDelegate _webView:queryPermission:forOrigin:completionHandler:]):
(TestWebKitAPI::urlEncodeIfNeeded):
(TestWebKitAPI::TEST):
* Tools/TestWebKitAPI/Tests/WebKitCocoa/UserContentController.mm:

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

8120f61

Misc iOS, tvOS & watchOS macOS Linux Windows
❌ πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  πŸ§ͺ win
βœ… πŸ§ͺ bindings βœ… πŸ›  ios-sim   πŸ›  mac-debug βœ… πŸ›  gtk βœ… πŸ›  wincairo
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ gtk-wk2
βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-gtk
βœ… πŸ›  tv βœ… πŸ§ͺ mac-wk1
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2
βœ… πŸ›  πŸ§ͺ merge βœ… πŸ›  watch βœ… πŸ§ͺ mac-AS-debug-wk2
βœ… πŸ›  watch-sim βœ… πŸ§ͺ mac-wk2-stress

@youennf youennf requested a review from cdumez as a code owner August 23, 2022 12:04
@youennf youennf self-assigned this Aug 23, 2022
@youennf youennf added WebCore Misc. For miscellaneous bugs in the WebCore framework (and not JavaScriptCore or WebKit). WebKit Nightly Build labels Aug 23, 2022
Copy link
Contributor

@cdumez cdumez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look great. How do we end up with a security origin data that has data members that are empty but not null?
Maybe we should fix that instead?
Having 2 states for security origin data (null & empty) adds complexity and I don't understand why we'd need both (and why we'd need to differentiate them)

@geoffreygaren
Copy link
Contributor

I kind of agree with Chris: What is the null security origin, and how does it differ from the empty security origin? At first glance the distinction is super subtle -- and subtle is not good for security!

@cdumez
Copy link
Contributor

cdumez commented Aug 24, 2022

I kind of agree with Chris: What is the null security origin, and how does it differ from the empty security origin? At first glance the distinction is super subtle -- and subtle is not good for security!

My proposal offline was to:

  1. Do a SecurityOrigin::isUnique() check in WebCore (Permissions::query()) and resolve the promise then
  2. Add a MESSAGE_CHECK() in the UIProcess to make sure the SecurityOriginData is safe for the UIProcess to deal with (i.e. make sure the WebProcess cannot cause the UIProcess to crash with a bad IPC).

@youennf
Copy link
Contributor Author

youennf commented Aug 25, 2022

I kind of agree with Chris: What is the null security origin, and how does it differ from the empty security origin?

Right, this is probably too subtle.
An empty security origin data is derived from a unique security origin.
A null security origin is unexpected and considered invalid.

The patch should probably have added a isUnique instead of isNullOrEmpty.

My proposal offline was to:

  1. Do a SecurityOrigin::isUnique() check in WebCore (Permissions::query()) and resolve the promise then
  2. Add a MESSAGE_CHECK() in the UIProcess to make sure the SecurityOriginData is safe for the UIProcess to deal with (i.e. make sure the WebProcess cannot cause the UIProcess to crash with a bad IPC).

I think a check in UIProcess better integrates with how we handle permission computation.
I'll make it a more specific patch.

@youennf youennf force-pushed the eng/Permissions-query-should-return-prompt-for-unique-origins branch from d176605 to 4ea0d4c Compare August 25, 2022 07:53
@youennf youennf force-pushed the eng/Permissions-query-should-return-prompt-for-unique-origins branch from 4ea0d4c to 8120f61 Compare August 25, 2022 09:45
@youennf youennf requested review from cdumez and szewai August 25, 2022 14:53
@@ -8840,6 +8840,12 @@ void WebPageProxy::revokeGeolocationAuthorizationToken(const String& authorizati
m_geolocationPermissionRequestManager.revokeAuthorizationToken(authorizationToken);
}

static bool isOriginUnique(const SecurityOriginData& origin)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like I mentioned in my previous review, I think we should do the isUnique() check in WebCore's query(), on a SecurityOrigin.

Relying on data members of a SecurityOriginData to be empty (but not null) to determine that the origin is unique is a bit obscure and fragile.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The UIProcess side check can then be a MESSAGE_CHECK and this function can be name something like isValidOrigin().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Besides clarity, another reason for my proposal is that there is no good reason to do IPC or involve the UIProcess for unique/opaque origins. It is more efficient to deal with them in the WebProcess.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is best to return 'denied' if possible (say application does not have the camera entitlement), or reject with NotSupported (say permission name is background-fetch).
This is best done in UIProcess.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what that means, you are returning Prompt unconditionally so...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, whatever decisions about entitlements or not supporting a particular API should be doable at WebProcess-level if we wanted to.

Copy link
Contributor Author

@youennf youennf Aug 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases where WebPageProxy::queryPermission is called but delegate is not called at all (leading to returning denied or rejecting with NotSupportedError depending on the permission name and/or app entitlements).
There are cases where even though delegate returns prompt, we will IPC grant to the WebProcess (camera and microphone).

This is existing logic in WebPageProxy that seems good to keep consistent.
All this patch does is, instead of calling delegate, we make it as if delegate returns Prompt for unique origins.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also have plenty of checks in the WebProcess that resolve/reject the promise early in WebCore's query().

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, we normally don't pass opaque origins to other processes since they are only valid within a single process (requires pointer identity). This is why we have a concept of unique/opaque SecurityOrigin but we don't have one for SecurityOriginData. Relying of SecurityOriginData having non-null / empty data members to make such determination is not robust or clear.

Copy link
Contributor

@cdumez cdumez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM but please add isUnique() member function to SecurityOriginData.

});
};

if (isOriginUnique(clientOrigin.topOrigin)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I discussed it offline with Youenn and it sounds like we want to deal with these unique origins on the UIProcess side because we don't always return "Prompt" for these, unlike what the next line makes it look like. There is some logic above in this function that could cause us to return Granted or Denied for unique origins and we wouldn't want to duplicate that logic in the WebProcess.

I think we should add a isUnique() member function to SecurityOriginData (which makes sure that the members are empty and non-null) instead of this new isOriginUnique() free function. It might be useful in other places as it sounds like we sometimes want to determine in other processes than the WebProcess if an origin is unique (even though we cannot at the moment determine if 2 unique security origins are the same).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I think we should change isEmpty to isNull and add isUnique. Will do it in a follow-up.

@youennf youennf added the merge-queue Applied to send a pull request to merge-queue label Aug 25, 2022
@webkit-early-warning-system webkit-early-warning-system merged commit fde28e0 into WebKit:main Aug 25, 2022
@webkit-early-warning-system webkit-early-warning-system force-pushed the eng/Permissions-query-should-return-prompt-for-unique-origins branch from 8120f61 to fde28e0 Compare August 25, 2022 19:11
@webkit-commit-queue
Copy link
Collaborator

Committed 253785@main (fde28e0): https://commits.webkit.org/253785@main

Reviewed commits have been landed. Closing PR #3575 and removing active labels.

@webkit-commit-queue webkit-commit-queue removed the merge-queue Applied to send a pull request to merge-queue label Aug 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WebCore Misc. For miscellaneous bugs in the WebCore framework (and not JavaScriptCore or WebKit).
Projects
None yet
6 participants