10.12 beta: App Translocation still happening after moving app using AppleScript

Number:rdar://27656235 Date Originated:02-Aug-2016
Status:Behaves correctly Resolved:
Product:OS X Product Version:10.12 (16A270f)
Classification: Reproducible:Always
One of my apps, when it detects it's running translocated, asks the user to move itself to the Applications folder. If the user confirms, my app starts an AppleScript that tells the Finder to move my app to the Apps folder. That part works fine.

The problem is that this move does not remove the "translocation needed" state from the quarantine attribute. Which means that when my app then gets relaunched in the Apps folder, it again asks the user to move the app to the Apps folder because my app doesn't see itself there, as it's still being translocated to a random path instead.

So, this ends up in an endless loop, confusing my users.

As this issue did not occur with previous OSX versions, and as I cannot see any reason why fixing this would make my app vulnerable to the "dylib hijacking" attack that translocation is supposed to protect against,

I therefore ask that the Finder's AppleScript "move" command gets fixed to perform the same de-quarantining actions that an interactive move in the Finder would do, i.e. remove the app's need to run translocated.

Steps to Reproduce:
Test this on Sierra (10.12).

Download any app that's delivered as a zip file.
I use http://mizage.com/divvy/
It should get downloaded to your Downloads folder.
If it's not yet extracted, double click the zip file to do so.
Do not start it (we won't have to).

Open Terminal. Enter:

xattr -pl com.apple.quarantine ~/Downloads/Divvy.app

Update the name of the downloaded app if you chose another app.

This will show:

com.apple.quarantine: 0083;57a08470;Safari.app;E40D8A37-15F5-4BA2-9609-24F5BF532848

Or something similar. Important is the first (hex) number: 0083. That contains some flags (bits) that indicate the quarantine state of the file. 0083 means it's quarantined (needing verification at start) and needing translocation (on Sierra and later).

Now move the app to the Desktop by dragging with the mouse. Use the same Terminal cmd again, updating the path to the new location on the Desktop:

xattr -pl com.apple.quarantine ~/Desktop/Divvy.app

This time, the first value is 0183 - the 0100 means it doesn't need translocation any more as it's been moved.

So far so good. Now let's move the app with AppleScript instead.

Download and extract the app again. Verify that the xattr state is 0083.

Then open Script Editor and enter:

tell application "Finder"
	move alias (((path to downloads folder) as string) & "Divvy.app") to desktop
end tell

Run it. This should move the app to the Desktop.

Check the quarantine flags with the xattr command again. It's 0083, but should be 0183.

The means that the app will still run translocation after being moved to the Desktop, even though there's no risk of dylib hijacking any more in the way it was when it was downloaded and unzipped in the Downloads folder.


Reply from Apple

This issue behaves as intended based on the following:

Gatekeeper checks nothing about Sandboxing. Developer ID signed Apps pass Gatekeeper but need not opt into Sandboxing. Most Developer ID (not MAS) apps do not opt into Sandboxing.

Finder(DesktopServices)’s ability to opt Apps out of Gatekeeper Path Randomization is conditioned on its ability to detect specific user intention (i.e. the user clicked on a single app bundle and dragged just that app bundle). AppleScript doesn’t constitute user intention. If AppleScript could opt things out of Gatekeeper Path Randomization then a script could be written to re-constitute a dangerous installation package via multiple move requests.

The intention with Gatekeeper Path Randomization is to make the scope of accessible files the same as the Gatekeeper scanning boundary. Allowing a developer to ship an applescript in a zip file along with an app and other things, and then allowing that AppleScript to install things and opt out of Gatekeeper Path Randomization would add a new hole in the protection.

By tempelmann at Aug. 13, 2016, 8:09 a.m. (reply...)

My reply to Apple

Do you realize that the same AppleScript could just add a command to invoke xattr, removing the quarantining? With such a change, your explanation that it's is an intended behavior not to let AppleScript's move command disable Gatekeeper Path Randomization becomes void.

Besides, the AppleScript I've described has to be launched by user interaction, it can't be done automatically, so I don't see what you're trying to prevent by this.

The original attack bringing all this Gatekeeper Path Randomization into existence was about hijacking a zipped file by adding malicious to the unsigned place NEXT to the signed app, and that works only for apps that do side-load code from next to them anyway. The intention here was that the user would then have to move the app away to make it disconnect from the hijacking code next to it. Howver, I've seen apps that get delivered in a folder, and then the user is told to move the entire folder to the Applications folder, which will disable GPR, while the hijacking code still coming along with the app inside the folder.

It seems to me that this entire thing is still quite full of holes. Please tell me if I get this all wrong (a brief hint with pointers is enough, I'll then seek clarification elsewhere).

By tempelmann at Aug. 13, 2016, 8:24 a.m. (reply...)

2nd reply from Apple

This issue behaves as intended based on the following:

The problem with Apple script is that it could be inside the app or outside it next to the app to be moved and nothing would check that the whole package came together as one unit. The important part from our perspective is that, if multiple units of execution are shipped together then they should be signed together (and flat packages or signed disk images are the only supported methods if you don't use a single app bundle and get the users to drag it some where else).

In the case of an app delivered as a folder with stuff in it, dragging the folder to /Applications will not opt out of GKPR for anything in the set.

We do realize that there are ways to strip the quarantine and doing that may or may not work out well depending on what gets stripped in what circumstances. Creating a script to strip quarantine off an app next to it is dangerous and could end up getting blocked in the future.

Applescript telling Finder to move things and opting out of GKPR is something we do not foresee adding support for.

Please update your bug report to let us know if this is still an issue for you.

By tempelmann at Aug. 17, 2016, 10:07 p.m. (reply...)

Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!