Mojave and AppleScript Applets

mojave

(Mark Alldritt) #1

Originally published at: https://latenightsw.com/mojave-and-applescript-applets/

macOS Mojave introduced a number of security changes that make developing AppleScript automations more difficult. Chief among these is the requirement that any application attempting to communicate with another application must get the user’s permission. These changes have a particular impact on AppleScript applets (AppleScript scripts deployed as stand-alone applications).


(Ray Robertson) #2

Mark,

The link in your new post has the title wrong. It reads “Mojave Brings in Bug Security Changes” instead of “Big Security.” I’ll resist making any jokes.

Thanks for posting.

Ray


(Ray Robertson) #3

Hmm…I guess this is another (final?) nail-in-the-coffin for the use of persistent properties in applets. I know we have been warned, and now with code-signing being a virtual requirement, other methods for persistence must be used.


(Shane Stanley) #4

Here you go:


#5

Thank you for the advice on Mojave and AppleScript applets. Is it possible to code sign an applet without paying Apple $99/year ? I’m not a developer – I just have an AppleScript retirement project that I’ve made available online which just a few users. But, I’d like to keep going if I can. It seems that the Apple Developer Program has only one kind of membership which I think is much more than I need for my applet.


(Ed Stockly) #6

I’m on their developer list and don’t pay them a thing. (Although I haven’t set up code signing yet)


#7

Yes, it’s free to gain access to documentation etc. But, I think that to code sign you have to download a certificate from Apple [https://developer.apple.com/support/code-signing/]. To get certificates, one has to be a member of the Apple Developer Program [https://developer.apple.com/support/certificates/]. To join ADP, we have to pay $99/year [How it works - Apple Developer Program].

I can’t see a way around it. It seems like overkill to have to pay $99/year just to stop our AppleScript apps from showing permission dialogs every time they start. Those permission controls are designed to police apps which control other apps - a sensible security measure - but AppleScript is intended to do just that: to control other apps. Of course, we could switch to Swift and avoid controlling other apps but, that would also be overkill for so many smaller projects for which AppleScript is ideal.

I reckon Apple might be expecting AppleScript to wither and die or become the preserve of professional developers who can justify the $99/year. By the way, for me that’s A$135/year. Rather than developing my own app in AppleScript I might as well buy it.


(Shane Stanley) #8

One thingto keep in mind: if developer certificates were free, Joe Blackhat and friends would download them by the thousand and Gatekeeper would essentially be rendered useless.

That said, you shouldn’t be getting asked for permission each launch. That sounds like your code is being altered each time. Try making the .scpt file(s) in your app execute-only (use chmod and a-w or similar).


(Mark Alldritt) #9

Shane, what I’m seeing is that once saved, I can run applets on Mojave and I’m only asked for permission to run once. However, each time I save the applet, I’m prompted once more for permission to run the applet.


(Shane Stanley) #10

Here’s my sample applet:

property praha : 1

set praha to praha + 1
tell application "Finder"
	properties of file 1
end tell

I get prompted each time I run it. If I comment out the set line, I only get prompted after the save.

This suggests to me that @Garry’s problem is that his script is modifying global values each time it is run.

(It’s also the issue I was trying to get at with #1135.)


(Mark Alldritt) #11

Ahh, in my tests I wasn’t altering and properties or global variables. Makes perfect sense now that you’ve pointed it out.


#12

Thank you, yes, I can see that although maybe blackhats are dissuaded by the process more than the fee. I’ve hoped there could be some other arrangement perhaps with extra rules for hobbyists but Apple seem to be pushing hobbyists out of the field.

I don’t understand the significance of the comment about global variables. I do have global variables which store values used in my script and which change – eg. path name to a folder which the user can change. Because they are not constants and need to be available to a number of handlers, I’m declaring them as global variables eg.

global downloadsFolder_Path

at the beginning of the script and setting the values when needed eg.

set downloadsFolder_Path to (POSIX path of ( path to home folder ) & downloadsFolder)

But, I can confirm that although System Preferences show my applet has permission to control Finder and System Events, I have to give permission again each time the script is run.

Would it make any difference if I declared those global variables as local then, passed them to and from each handler ? Also, my applet is not run only. Is that relevant ?

Thanks.

P.S. How do you get colour into these posts ?


(Shane Stanley) #13

When a script is run, if that results in changes to the value of any top-level variables, the script is normally saved back to disk with the new values. (This is how property persistence works.) That means the security system sees the app has changed, and thus needs renewed permission.

One relatively simple way to stop this is to change the permissions of the applet’s embedded main.scpt file.

Yes. But you also need to make sure there are no top-level variables changing.

No.

Wrap any code in lines consisting of three back-tick characters.


Global variables are saved to disk!
#14

Shane, thank you for all that. I’ve vented some rant in another post.

Yes, my script has a pile of global variables. But, in good news, I’ve found that Mojave does not show the permission request every time the app is started – if the user does a logoff and a logon. So, in summary for a non-code signed AppleScript applet:

  • For new version of the applet – Mojave pops the permission request(s) on applet start-up.
  • For each further applet start-up in the same session – Mojave pops the permission request(s).
  • For each further applet start-up in later sessions – Mojave does not pop the permission request(s).

I think I can live with giving new permissions when installing a new version of my applet.

Thanks.


(Luciano Di Croce) #15

Which is the new setting for the permission to avoid this?
Thanks !


#16

See the advice above from Shane Stanley:

The whole thing of logging off and on again to suppress the dialogs is odd to me – if there is a concern about security in this situation, why let a logoff-logon suppress the dialogs ? That might be a bug and so Apple may well change that behaviour in a future release of 10.14.


(Luciano Di Croce) #17

Thanks.
I have set it using Path finder like this (see screenshot):
27

Is this correct?
Thanks !


(Shane Stanley) #18

By default, the scripts in applets are saved with -rw-r--r-- permissions. Could it be that you’re logging in the second time as other than the original file’s owner?


(Shane Stanley) #19

Yes.

Two droplet alternatives:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on open fileList
	repeat with aFile in fileList
		do shell script "chmod a-w " & quoted form of (POSIX path of aFile & "/Contents/Resources/Scripts/main.scpt")
	end repeat
end open

Or:

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions

-- classes, constants, and enums used
property NSFilePosixPermissions : a reference to current application's NSFilePosixPermissions
property NSFileManager : a reference to current application's NSFileManager

on open fileList
	set fileManager to NSFileManager's defaultManager()
	repeat with aFile in fileList
		(fileManager's setAttributes:{NSFilePosixPermissions:292} ofItemAtPath:(POSIX path of aFile & "/Contents/Resources/Scripts/main.scpt") |error|:(missing value)) -- 292 is decimal equivalent of -r--r--r--
	end repeat
end open

(Luciano Di Croce) #20

Thanks for the droplet. It is a good option to speedup the process.