Created attachment 447017 [details]
Xcode project that replicates bug
Overview: If you download a DMG using WKNavigationResponsePolicy.download and WKDownload and try to open the app inside, you get either the error "You do not have permission to open the application" (macOS 11) or "This application can't be opened" (macOS 12)
Steps to Reproduce: I've included an Xcode project that will automatically open a page that downloads the DMG for Slack.
1. Run the project
2. Wait for the file to complete downloading (It will print "DOWNLOAD COMPLETE")
3. Open the dmg and try to open the Slack app.
Actual Results: An error prompt appears, not allowing the user to open the app at all.
Expected Results: The Slack app will open (with a quarantine dialog first to confirm opening the app)
Build & Hardware: Build 166184.108.40.206.4 on macOS 11.4
The GateKeeper score (i.e. the first number in the com.apple.quarantine extended attribute found through xattr -l /path/to/file.dmg) is 0086. If I change that to 0083 (like Safari) or 0081 (like Chrome), the app opens as expected.
Any ideas why the GateKeeper score of the downloaded file is set to 0086?
No, Gatekeeper score is not implemented by WebKit.
WebKit must be using something which is causing this issue though. As seen in the attached Xcode project, I'm not using anything apart from the built-in WKDownload. If I download it myself using URLSession, then the GateKeeper score is 0082, and it opens correctly.
This is a legitimate WebKit bug that we need to fix.
I just verified we do the same thing as NSURLSession, which makes me less sure that this is something we should change.
The intent is for all valid files downloaded off a web page is to be openable. Currently, that isn't the case. If you use WKDownloads and force open the file (right-click -> Open instead of double-click, but no user really knows about this), the system tells the user that the file was downloaded by com.apple.WebKit.Networking. Not the biggest problem for me, but still a sign that the quarantine extended attribute needs to be modified, one way or the other.
Not using WKDownloads means downloading the files with a URLSessionDownloadTask myself. This works, except for the case where the file needs specific cookies before it will serve it, which is quite a bit more complicated than the case of a simple download. (An extra slight caveat with this method: It will say "This file was downloaded from APP_NAME" when opening instead of "This file was downloaded from the internet". My best guess is because the Gatekeeper score with this method is 0082, and the least significant bit isn't set)
Are you using URLSessionDownloadTask in an app that is code signed? I verified that doing that makes a file that is also unable to be opened.
The com.apple.WebKit.Networking attribute should probably be changed to match the app, but maybe I should clarify that I'm not sure the ability to open is something we (WebKit) should change without coordinating with CFNetwork.
Yes, I'm using it in an app that is code-signed and already deployed to users! I'll try and create a sample project perhaps and attach it in a bit.
Created attachment 460399 [details]
Created attachment 460408 [details]
Saurav, is your app sandboxed?
Yes, it's sandboxed.
Committed r295731 (251736@main): <https://commits.webkit.org/251736@main>
All reviewed patches have been landed. Closing bug and clearing flags on attachment 460408 [details].
Thanks for looking into this!
Just checked out the commit and if I understand correctly, you're only clearing the QTN_FLAG_HARD flag if the app is not sandboxed? What about sandboxed apps using WKDownloads?
(Can confirm that a sandobxed app using URLSessionDownloadTask does not have this quarantine issue)
Just marking as Reopened if that's needed to notify people
I can confirm that this fixes non-sandboxed apps. I think it might depend on your sandbox, but I know there are some sandboxes that don't allow removing QTN_FLAG_HARD.
Hmm, I'm not very familiar with sandboxes. Ours is just enabled by the "App Sandbox" entitlement being set to "YES". I understand why the app shouldn't be able to modify quarantine attributes (or extended file attributes in general) for files, but I don't see why that should apply to the file it's creating internally (especially since that's through WebKit, and a warning shows up before you open anyways).
I have a theory that if URLSessionDownloadTask can make a downloaded application openable then this code ought to be able to remove QTN_FLAG_HARD but I haven't verified that theory yet.