Library failure under macOS 12.5

It looks like there’s an issue in macOS 12.5 with loading third-party frameworks via apps, as done with Shane's Script Library Pack.app. For now, the only solution is to embed the relevant script libraries within your own apps for deployment.

The script libraries in question are: BridgePlus, SqLite Lib2 and Myriad Tables. You can export them from Shane's Script Library Pack.app by launching it and clicking the More button.

If applets containing the libraries are saved from Intel Macs, they will also need to be code-signed (all Apple Silicon applets are signed already).

Apologies for any convenience. It’s all beyond my control, alas.

1 Like

Hi Shane,

If I understand you correctly, what you’re saying is that as of 12.5 a codesigned app will not load (unsigned) libraries from /Library/Script Libraries and ~/Library/Script Libraries. Is that right?

If so, I would not categorize that as a “failure” (which implies a macOS bug, to be reported and fixed) but as an intentional change in macOS’s security policy, part of Apple’s general movement toward requiring all executable code is codesigned.

FWIW, I quickly skimmed the 12.5 security notes and didn’t see anything specifically about codesigning and AS libraries, but it does sound like an intentional tightening of security policy around scripting and automation in general, which is both needed and overdue. (Sad to say, but the only real growth industry for AppleScript &co these days is the malware market.) If you know of any official Apple docs mentioning it, please do share.

An “all libraries must be signed” policy [1] makes a lot of sense in light of recurrent supply-chain attacks, where malware authors insert malicious code, not into the apps themselves, but into the 3rd-party libraries used by those apps (and in the libraries used by those libraries, and so on).

Supply-chain attacks are not a new phenomenon. It’s just that the programmer world is taking its sweet time to start addressing it, because it’s a monster they created and they know it will take a lot of hard work to fix now.

So it’s good if Apple is now forcing the issue by requiring all code be signed before it can freely run on anyone’s machines but its authors’.

In essence, a code signature is a binding declaration by that software’s author: “I personally wrote this software, and I take responsibility for everything that it does.” To use a comparison: there’s a good reason why airport customs always asks if you packed your own suitcases, or if someone else packed them for you. Knowing provenance is critical.

Codesigning itself does not guarantee that the code is safe and free of malware (although related processes such as notarization can include checks for some recognized naughties), as a malware author can always sign his own code. But it does:

  1. Guarantee that if signed code is later on tampered with, that tampering is detected; and

  2. Enable software distributors (in this case Apple) to blacklist any program immediately on it being reported to contain malware; and to provisionally suspend or permanently revoke the credentials of any developer found to be accidentally/deliberately malware so that all their other code is immediately blocked from running too.

Tying the code to its authors is a step to making those authors answerable for their code’s [mis]behavior. As I say, retrofitting it now is going to be painful. But it does right by the Users, a nice change from the traditional developer “I’m not responsible” policy.

[1] Mind, it’d have been infinitely less painful and messy had all this user-level security had been built-in from Day One of Personal Computing, instead of it now being retrofitted to free-for-all chaos several decades after. But that’s the historical realities of business economics, 90s processing power, and the 80s not having a crystal ball. It is what it is, and we just have to pay the bill now.

1 Like

No. I’m talking about a script library within a (in this case notarized) app’s /Contents/Libraries/Script Libraries directory. See:

Specifically:

Script libraries may now be located in any installed application bundle, in the Contents/Library/Script Libraries directory of the bundle. This allows distributing libraries that are associated with an application, or creating applications that exist solely to distribute libraries.

The issues with putting them in a standard library folder are (a) you can’t notarize a .scptd file, and (b) there’s no mechanism available in the OS for a user to approve the loading of other than apps.

Sorry, I’m still confused. The above sentence makes it sound as if embedding a 3rd-party library in your app’s bundle is now busted, meaning e.g. this would no longer work:

MyApp.app/Contents/Libraries/Script Libraries/3rdPartyLib.scptd 

But I don’t think that’s what you mean. (And it would be a serious bug if it was.)

I did see the word “framework” in your original post. Are you saying that a codesigned app can still load some (unsigned) AS libraries from /Library/Script Libraries and ~/Library/Script Libraries, but not if those libraries themselves use 3rd-party ObjC frameworks?

This would make sense as macOS is pretty strict nowadays w.r.t. apps that run Swift/ObjC/C++/etc code, requiring all of that code to be codesigned by the app’s author in order to run it, regardless of where it comes from. e.g. If your sqlite AppleScript library keeps its own copy of libsqlite in its .scptd bundle, if an AppleScripter wants to use your library in their codesigned AS app they must embed, and thus re-sign, your library and the libsqlite code contained within it, or else their app will no longer load it.

Is that correct? Thanks.

1 Like

No. The key sentence you’re missing is applications that exist solely to distribute libraries. Save me some typing and go here:

and download Shane's Script Library Pack.app.

1 Like

OK. Thid was not at all obvious in your previous posts, which talked about “library failures” and “third-party frameworks”.

So you’re talking about an AS library which is embedded in an (otherwise non-functional) app for distribution purposes, as per #8 here. The user downloads that app and installs it on their machine, and AS can now find and use all the libraries embedded within it.

And you’re saying 12.5 no longer allows AppleScripts to import libraries from this installed “library wrapper” app?

Good. I trust that’s an intentional, permanent change by Apple.

This was always a serious misfeature, and a genuine security hole too. It made it easy to smuggle a malicious AppleScript library onto AppleScript’s default search path by tucking it inside an otherwise innocuous app, e.g.:

/Applications/SomeApp.app/Contents/Library/Script Libraries/Text.scpt

would make a library named “Text” visible to all AppleScripts installed on that Mac.

Furthermore, since it’s a native AS library, it executes inside your script’s context (e.g. Script Debugger, FastScripts, ASOC app, or AS applet), thereby escaping the original app’s own sandbox. Yipe!

ISTR (vaguely) voicing my own concern to one of the Chrises at the time. I think originally it was higher in the search hierarchy so app-installed libraries could even mask libraries installed in /Library/Script Libraries and so get loaded first. The final implementation puts app-embedded libraries last on AS search path, which ameliorates that risk—although that still leaves two exploitable holes:

  1. If the user doesn’t already have the real “Text” library installed on their Mac, use script "Text" would end up importing and using the malicious version; and

  2. If two differently-named library-wrapper apps are installed on the same Mac, one containing the legitimate “Text” library and the other with a malicious “Text” library, which of those libraries get be loaded by use script "Text"? It could be either, presumably depending on which app bundle AS searches first.

The only reason that this was never a practical attack vector with known exploits out in the wild is because the number of Mac users who run AppleScripts is tiny, and the number of those users who use third-party libraries miniscule. So any blackhat who’d waste their time making it would have to be extraordinarily bored.

Still, the idea that a globally-importable library could be inserted onto a user’s machine without the user knowingly, intentionally installing it is frightening. In hindsight I should’ve called it out as a Completely Bad Idea and pressed against it being implemented at all, e.g. by filing a Radar report to make Apple’s security team aware of the hole being opened. But I didn’t understand security so well a decade ago.

I’ve spent more time around NPM et al since then, so am more aware now. Still not an expert, but I know enough about the issues to know those big popular languages (Node.js, Python, etc) and their enormous library repositories are a fricking security horror, which 99% of those language users deal with by completely ignoring/being completely ignorant of/denying there is even a problem. (And internet commerce runs on those langs! Our PII and CC numbers, in their hands!)

Addendum: App-embedded AS libraries could have been acceptable, had AS required the library’s location to be explicitly declared in the tell/use statement, e.g.:

use script "Myriad Tables Lib" of application "Shane’s Script Library Pack.app"

Obviously with that there is still the issue of having two different apps of that name on the same Mac, but that’s no different to the issue AppleScripters already have when targeting scriptable apps by name/bundle ID, and there is multiple identically-named/IDd versions of the same app installed (Hello, Adobe Illustrator.app). But at least the code now makes explicit where that library is to be found, making unintentional imports from anywhere else impossible.

Anyway, it would not surprise me if your SLP is the only app on earth to distribute+install AS libraries this way. So it sounds like the right solution is for you to go back to distributing thoaw libraries as simple .scptd files, which AppleScript users can install into their Script Libraries folder the old-fashioned way. (And they can deal with the inevitable pains of codesigning, distributing, etc their own software from there; but that’s a separate problem.)

Or, if you really must have them as .app bundles, you could go really old school and convert them into “Script Servers” (remember those?!): stay-open AS applets that expose their handlers for other scripts to call via Apple events, just like any other scriptable faceless background app.

Thank you for clarifying your original post. (And for the fun trip down the old memory path.:slight_smile:

Now we just need Apple to clarify its policies, which studiously remain clear as mud. We live in hope.

I have been using BridgePlus in scripts I run from FastScripts. The script libraries were loaded via the app Shane’s Script Library Pack. This worked up until 12.5, but not now (and not in Ventura). My “solution” since 12.5 has been to open the scripts in Script Debugger and run them from there (after some necessary obnoxious adaptations). It is very very inconvenient and causes additional problems!

I am sorry to say I don’t understand these issues, and I only write or edit AS a few times per year, so I would like to ask:

Is there no simple way I can continue to run scripts (i.e not applets) under FastScripts and which use BridgePlus?

Recomendations? Tips? (provided they are simple!)

They should still run, but you may have to export the BridgePlus lib from the app and put it in your /Library/Script Libraries/ folder. It appears using an app to make them available no longer works.

Will still not work for me!

I put them in ~/Library/Script Libraries/
And I restarted FastScripts (v 2.8.3 which it says is the latest version available).

Stumbles on set SMSForder to load framework

macOS Ventura 13.2.1

The script works from Script Debugger v8.0.4.

Your original post in this thread definitely gave me the impression it would not work unless the libraries were embedded within an app for deployment. Therefore, I never attempted to simply put the libraries in Script Libraries.

I get the gut feeling that Apple simply does not want such libraries/frameworks floating around.
If that is their goal, I will have to bite the bullet and convert to ASObjC.

Just about the only thing I frequently use is:

findMatches: inString: options: captureGroups:

Don’t know how much inconvenience it would be to do it with ASObjC instead.

It works here on v3.2.4.

GREO stuff is pretty easy to do in ASObjC. If you download my RegexAndStuff library, you can probably lift most of the code you need.

Hmmm… Software update notifications for FastScripts seems to have been improved in 3.1.1

https://redsweater.com/fastscripts/whatsnew.html

I suggest downloading and installing the most recent version:

https://redsweater.com/fastscripts/FastScriptsLatest.zip

at

I think the issue might be that 3.x was a paid upgrade.

Ok, did that, and also payed the 20$ upgrade fee for “premium” since I have a fair number of keyboard shortcuts (and it has always been a very good utility, so they deserve some fee for it, and the last payment was 15 years ago!).
Obviously v2.x did not want to recognize the 3.x version as the “latest”, despite it is free if you don’t care about premium.

Now BridgePlus sometimes works!
With sometimes I mean:

I’ve got two extremely similar scripts that use BridgePlus which is invoked in exactly the same way, and with an almost identical handler structure and error handling.

One of the two scripts always work. But the other one is “shaky”: If an error is signaled and taken care of by a display dialog (returning false), then on next invocation of the script it will bail out when trying to get a reference to SMSForder! “Can’t make SMSForder into type reference”, which happens for set SMSForder to load framework. This is despite this situation is handled identically in the two scripts!

The only difference between the two scripts is that the troublesome one also has the line: use script "RegexAndStuffLib" (it uses regex batch and regex search), which is a “regular” script library without embedded frameworks.

Weird!
The “bail out” can be “repaired” by restarting FastScripts!
On next invocation, it usually works (but only usually).

It may seem strange that I use both SMSForder’s findMatches from BridgePlus and regex things from RegexAndStuffLib, but I think it has an historical origin – originally, I used long awkward Perl scripts, then ASObjC Runner, then BridgePlus! Too many migrations!

It appears to me that regex search can do almost the same things as findMatches of the BridgePlus framework(?). The difference is that regex search does not have the “x” option (allow use of white space and comments within patterns), which I sometimes use to make long patterns a bit more readable. Is there any other advantage with findMatches? (Perhaps speed?)

I guess the best solution is to do away with BridgePlus and only use RegexAndStuffLib. Hopefully less trouble and more streamlined, and perhaps more future proof(?)

1 Like

In some cases, yes.

If that’s all you’re using BridgePlus for, then definitely. The sad reality is that Apple could end loading of third-party frameworks tomorrow. I don’t expect them too, but it’s enough to make give up developing any more.

@harald Thanks for purchasing the upgrade! It might be worth noting that among FastScripts 3’s improvements is the inclusion of built-in regex scripting commands. Look in the dictionary for “FastScripts Text Processing”. Perhaps the built in “search text” command would suit your needs.

Yea, I saw that. Nice! But I need the “ms” options, i.e anchors match lines and dot matches all.

I would have wanted also the “x” option, i.e “allow use of white space”, but it is possible to live without that one (albeit ugly and a bit difficult to see the different “chunks” – a workable crutch would be dividing up the pattern with: …" & "…).

Ah! As it happens I am planning to add “anchors match newlines” and “dot matches newlines” in the next update to FastScripts. When you see the next update for FastScripts they should be in there. :slight_smile: I hadn’t considered the “x” option, but I’ll look into that.

An update on this: I just released FastScripts 3.2.5:

It includes new “anchors matching every line” and “dot matching all” parameters that should satisfy the main requirements you described. I am still considering the possibility of a parameter that would serve the same purpose as the “x” flag.

Hope this helps!
Daniel