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

Strategy needed to handle Apple requirement for app notarization and use of hardened runtime #2861

Open
enquora opened this issue Sep 24, 2019 · 29 comments
Labels
Milestone

Comments

@enquora
Copy link
Contributor

enquora commented Sep 24, 2019

Apple has instituted a grace period (January 2020) for apps to be notarized and use the hardened runtime but this will ultimately affect us. This issue was created to act as a discussion rather than to offer immediate answers.

The immediate effect will be on any pre-compiled binaries we distribute but moving to Node for our JS engine is a greater concern. I've filed an issue there but the project hasn't surfaced any plans yet and seemed not to have been paying attention.

@cappbot cappbot added this to the Someday milestone Sep 24, 2019
@cappbot cappbot added the #new label Sep 24, 2019
@cappbot
Copy link

cappbot commented Sep 24, 2019

Milestone: Someday. Label: #new. What's next? A reviewer should examine this issue.

@mrcarlberg
Copy link
Member

Thanks David for bringing this up. We have to address this and make sure we don't run into any problems.

@mrcarlberg
Copy link
Member

I have not yet tried Cappuccino on Catalina so I don't know what kind of problems we might run into. Can we do a list of what we need to address?

@aljungberg
Copy link
Member

We do have several pre-compiled binaries in our distribution, including fontinfo, imagesize and xcodecapp, don't we?

@mrcarlberg
Copy link
Member

Yes, do we have any more than these three binaries?

@aljungberg
Copy link
Member

Those are the only ones I can think of of the top of my head. Narwhal itself too obviously, but switching to Node fixes that. In fact I bet fontinfo and imagesize could be converted to Node tools too, avoiding those two pre-compiled binaries.

@enquora
Copy link
Contributor Author

enquora commented Sep 25, 2019

Switching to Node JS has the same problem: nodejs/node#29216
Attempting to use the Node JS installer and needing to right-click on the installer to run it brought this into focus.

I've installed Cappuccino from source on multiple betas of Catalina without problem (but not yet the current one, beta 9). afaik the source installation doesn't present problems (yet - Apple is only going to increase security requirements in the future). I haven't looked at the non-source package in ages though.

If we want to offer a 'package' installer this will almost certainly be a problem at some point in the future. And require a development ID/certificate.

Where Apple leads, most other's (Microsoft) are likely to follow.

@enquora
Copy link
Contributor Author

enquora commented Sep 25, 2019

Note that one can bypass Gatekeeper by right-clicking on an installer or app bundle and answering in the affirmative when prompted to proceed. This doesn't seem like a good long-term experience though.

@mrcarlberg
Copy link
Member

Correct me if I am wrong but when you install from source, everything will be built with Xcode on your computer. Will there still be problems with that on Catalina?
If you bootstrap we will install a prebuild version of the imagesize, fontinfo and XcodeCapp binaries. This will cause problems I guess.
Rhino runs on Java. JavaScript core will optionally be built when bootstrapping on Mac. Narwhal is really just a Javascript library.
Can any of these be a problem?

@enquora
Copy link
Contributor Author

enquora commented Sep 25, 2019

Installing from source does not currently present a problem and won't in the future.
The problem is with binaries or other executables. Node JS, for example.

@enquora
Copy link
Contributor Author

enquora commented Sep 25, 2019

We have both a short-term scenario to deal with and a longer-term one.
For the short-term, the problem is with the bootstrapped install rather than the source version.
For the longer-term, the problem is with Node JS, which seems to be the only viable and maintained JS VM which provides access to the system-level API calls we need. The silence of core developers on the Node JS issue is unsettling - although it's difficult to see how something that widely used can avoid notarization.

@aljungberg
Copy link
Member

Here's Apple's list of what's required:

https://developer.apple.com/documentation/security/notarizing_your_app_before_distribution

In order to build a Hardened Runtime of JavaScript core we will need to enable the "JIT" entitlement too.

At a glance it doesn't look very difficult, but the devil is in the details. We could make a 1.0.1 version based on the 1.0.0 branch, or just go ahead and release 1.1 if we feel master is at a good release point. What do you think @mrcarlberg ?

As for the Node version, I assume the Node team will sort Node out quickly once it becomes an active problem, and we shouldn't need to do much on our end. We can focus on the JSC version for now, plus the three binaries we identified.

@enquora
Copy link
Contributor Author

enquora commented Sep 25, 2019

"Notarization also protects your users if your Developer ID signing key is exposed" - we don't have a developer account for Cappuccino. This has been a problem for other projects I use which are organized on an informal and ad-hoc basis. Membership certainly isn't expensive, but it brings along the problem of what the legal entity behind the developer account actually is.

Depending on a developer account not controlled by the project doesn't seem prudent.

Updated: It isn't clear to me if a path exists for notarization without a developer account. Research needed.

@aljungberg
Copy link
Member

Yeah it could get a little wonky. We don't have a legal entity for the Cappuccino project.

It strikes me that who owns the Developer ID is kind of irrelevant. I could use a private Developer ID, and should I be hit by a bus tomorrow Martin could just use his ID to sign the next release. Sure, different versions of Cappuccino would now be signed by different people. But would our end-users care if it was my name or Martin's name on the release signature?

(As for who pays for it, should it ever become a burden we could do some mini fund raiser.)

@enquora
Copy link
Contributor Author

enquora commented Sep 25, 2019

afaik, Gatekeeper watches for extended attributes written by the downloading agent. It's not clear to me if this is only currently a problem with files downloaded by a web browser, or if it extends to downloading with wget or curl (as examples). My current understanding is removal of the quarantine attribute (xattr -d com.apple.quarantine filename) sidesteps the problem.

If so, this seems something Apple will close sometime (browser breaches sandbox using exploit, silently downloads malware, removes quarantine flag, launches as background process).

@mrcarlberg
Copy link
Member

I agree with Alexander that anyone can code sign it. I do believe we can create an Apple-Id and create a free Apple Developer account that can code sign. I don't know if that will help us in any way and we need to manage the account. I think Alexanders way is simpler.

I tried to read up a little on this and I think we need to make sure we code sign XcodeCapp and the 3 above executables when building Cappuccino on a Mac with jake install. Also when making a release we need to notarizing on all 4 of them. There are for sure some details that needs to looked into here.

This has to be ready before the end of 2019. I don't have any time to spare this fall so we need to find someone that can put some time on it. Any one?

A good plan could be that we do a new Cappuccino release (1.1) around December 1, 2019. We do the first release candidate in the beginning of November.

@enquora
Copy link
Contributor Author

enquora commented Sep 27, 2019

If we have at least two people with committing privileges who are willing to use their Apple IDs, that seems to handle the practical concerns. I'll take proof the notarization process and prepare a guide for release package preparers.

Non-developer account signing of builds is only valid for 7 days. I don't know if such packages can be distributed, even for that short window, or if that short window is sufficient to create a long-lived notarization. It seems unlikely to me, but I will investigate.

This is only a requirement for non-source installations (until a switch to Node is made). I wonder if Oracle will sign/notarize non-current versions of Java? I haven't yet checked that on my own Catalina installation.

@mrcarlberg
Copy link
Member

From what I understand we need to code sign and do notarization only for releases. That is what the Bootstrap will download and install when installing Cappuccino. When someone build from source on a Mac they will build there own build of XcodeCapp and the 3 executables. The best thing should be if they could sign with there own Apple-id. Notarization is not necessary if you build yourself.

@enquora
Copy link
Contributor Author

enquora commented Sep 27, 2019

It is correct we need only notarize for releases. The Javascript execution environment is beyond our reach and we must depend on those authors to deal with the requirement. It is always possible to manually strip the quarantine attribute(s) which Gatekeeper manages, or to right-click on an executable from Finder and allow execution (although this isn't a good user experience, particularly for non-binary executables).

When the release tarball or zip file is downloaded on macOS, the most likely unarchiving step is using the system unarchiver (either because a browser is set to do that automatically or because the user has not set another archiver as the default handler for that mime type and double-clicks the file).

When the system archiver is run, the com.apple.quarantine extended attribute is added to all extracted files. xattr filename will list the extended attributes. Gatekeeper acts on any file with the com.apple.quarantine attribute set.

Our bootstrap.sh will, therefore, not pass Gatekeeper's checks at some point in the future (January 2020 if Apple doesn't revise its policy again).

The version of curl included with Catalina and prior versions does not (afaik) add the quarantine attribute to downloaded files. This could change in the future. Wget is not included in macOS distributions.

Perhaps curl can download our binaries without the quarantine flag being applied and the bootstrap script can certainly strip any quarantine flags it finds. It seems vanishingly unlikely the notarization process will allow this, now or in the future, though. Downloading other unverified assets using a notarized installer would obviously defeat the purpose of notarization.

It seems a certainty we will need to include Cappuccino base and any other now downloaded assets in the installation package itself in order to successfully notarize it - either from the time the notarization requirement is fully enforced or in the near future.

It is not yet clear how the Node project intends to deal with this. At our scale, using a committer's Apple ID to submit a release for notarization is logistically workable, as long as it doesn't bother those committers offering the use of their Apple IDs. For larger projects with more complex testing and release pipelines and more frequent releases it is a complication.

I install from source wherever possible and practicable so this doesn't yet affect my own usage. I had wanted to start converting to Node by rewriting our installer - that created the immediacy. It's not clear to me how this affects distribution via containers (something I prefer to avoid and which isn't practical for us, in any case).

@enquora
Copy link
Contributor Author

enquora commented Sep 27, 2019

For anyone preferring a GUI to look at extended attributes, Howard Oakley has useful tools: https://eclecticlight.co/xattred-sandstrip-xattr-tools/

@enquora
Copy link
Contributor Author

enquora commented Sep 27, 2019

Note: Executing the bootstrapper as single line curl command probably bypasses Gatekeeper entirely (in its current form) - download the bootstrap script itself using a curl one-liner, then execute it. Window doesn't include curl by default (afaik) though. This would entail some additional steps (and complexity) in the bootstrapper - and it's already passed the threshold of undesirable complexity for a shell script.

@daboe01
Copy link
Contributor

daboe01 commented Oct 7, 2019

-#new
+tools

@cappbot cappbot added tools and removed #new labels Oct 7, 2019
@cappbot
Copy link

cappbot commented Oct 7, 2019

Milestone: Someday. Label: tools. What's next? A reviewer should examine this issue.

@enquora
Copy link
Contributor Author

enquora commented Oct 16, 2019

Is the simple answer (in the short term) deprecating the starter bundle and packaged release, installing using the source instructions for everyone (with perhaps a tagged release being downloaded rather than master) - then moving post-haste to a pure javascript environment (including installer) using nodejs?

@mrcarlberg
Copy link
Member

I think we should get the bootstrap.sh working for Catalina on January 1. David, can you put some time on testing what is needed for it to work?

@enquora
Copy link
Contributor Author

enquora commented Oct 20, 2019

bootstrap.sh works just fine, as long as it is retrieved using git, curl, wget or some method other than a browser (which sets the the quarantine xattr).

We have yet to resolve the question of what contexts we are willing to support. My proposal is to immediately deprecate the Rhino/Narwhal dependencies, use curl to fetch and run, modify bootstrap.sh to support either master or the latest tagged release version - and to move on with node js as quickly as possible.

It's possible the installed version of curl will set the quarantine attribute in January, but this would require accounting for the case in which a downloaded asset is run by piping it.

I'm skeptical Apple will notarize a package which downloads other assets and documentation is thin on the ground. Probably the only sure way for clarity is to file a TSR. I have the standard two remaining but would rather not use them this far from my anniversary date (half a year).

@mrcarlberg
Copy link
Member

Ok, good that the bootstrap.sh does not set the quarantine xattr. That gives us more time.
Yes, we would love to deprecate Rhino, and even Narwhal. We do need more work for doing that. Rhino is the first step but we are still dependent of it in for press and flatten. We have a pull request for flatten. We need one for press.
To remove Narwhal is a more complex task. We have to refactor our build system and how all our command line tools are running.

@enquora
Copy link
Contributor Author

enquora commented Jul 1, 2020

We may be able to sidestep this entirely using a NPM package which installs from source (for either current master or release).
Node.js installers are now themselves notarized for both LTS and current versions.

Are they any reasons a user might not want/be able to install a release version this way?

@enquora
Copy link
Contributor Author

enquora commented Mar 21, 2021

This is a problem beyond just installing Cappuccino - on a new installation of Big Sur (on a new volume) permission problems with nib2cib prevent files in /tmp from being deleted except by using sudo. This is after granting 'ibtool, plutil, nib2cib, obj` and a number of other independent utils Developer Tools permissions.

Changing the tmp dir to one in $HOME fixes the problem, but saving a xib still returns an unknown error to XcodeCapp. It looks very much like the XcodeCapp errors are being reported back to it from one of the external tools being run but there is no apparent way to get anything meaningful from the tools, nor determine even which one is raising the error. @mrcarlberg Is it possible to set a global debugging flag on objj, nib2cib, etc and log what's happening?

This is on macOS 11.2.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants