Electron-builder: macOS Hardened runtime, notarization, code signing: app crashes and doesn't work at all

Created on 21 Jun 2019  Âˇ  40Comments  Âˇ  Source: electron-userland/electron-builder

Which version of electron-builder are you using?

  • Version: 20.44.4

Which version of electron are you using?

  • Version: 4.2.4

What target are you building for?

  • Target: mac (dmg)

I'm trying to enable notarization in my app to support OSX 10.14.5, but even after following the many related issues submitted by others, the process still doesn't work correctly for me: the notarization process completes successfully (which is even confirmed by spctl -a -v Test.app and codesign --verify -vv Test.app) but when I run the app on a newer mac with OSX 10.14.5 the app crashes with the following error:

Exception Type: EXC_BAD_ACCESS (Code Signature Invalid)
Exception Codes: 0x0000000000000032, 0x00000ae52f684040
Exception Note: EXC_CORPSE_NOTIFY

Termination Reason: Namespace CODESIGNING, Code 0x2
[...]
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 ??? 0x00000ae52f684040 0 + 11979459149888
1 com.github.Electron.framework 0x0000000106ff8a01 0x105c32000 + 20736513

Note that the app runs fine on older OSX versions that do not have the notarization requirement.

What I tried: I followed this guide by @Kilian in the issue #3870 to add the necessary electron-notarize parts. I was already signing with a "Developer ID" key, so I just added entitlements, gatekeeperAssesment and hardenedRuntime to package.json and the notarize script.
I'm building on a Mac Mini with OSX 10.13.6 (according to Apple seems to be the minimum accepted version for notarization support) with yarn 1.16

I even removed all the code from my app, leaving only console.log('Hello World!'); process.exit(0) but the app still crashes with the same error message.
I tried adding every entitlment allowed, but still no progress
I hope some of you can guide me to the correct direction.

backlog

All 40 comments

Having the exact same issue #4040

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

nope,
The issue is still available

stale[bot] notifications@github.com于2019年9月9日 周一11:55写道:

This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/electron-userland/electron-builder/issues/3989?email_source=notifications&email_token=ABQZYV426ZL37VB7ILF6PBDQIXCJHA5CNFSM4H2S47I2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6GFGPY#issuecomment-529290047,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABQZYV756OABZL737X7H5TTQIXCJHANCNFSM4H2S47IQ
.

Has anyone had any luck figuring this out? Our prod build does not launch locally and our mas-dev builds are running into the same EXC_BAD_ACCESS (Code Signature Invalid) error.

We are struggling with this too. Any suggestions would be really appreciated.

I have had these issues, but when I kept the node files out of asar package; it worked fine.

"asarUnpack": [ "**/*.node" ],

Its the hardening that broke it for us. We have a notarised, code signed app, mac not MAS, that now works. After a fashion:

electron-builder/issues/4040#issuecomment-553327682

Hope this helps.

The following entitlements solve the problem for me:

build/entitlements.mac.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.automation.apple-events</key><true/>
    <key>com.apple.security.cs.allow-jit</key><true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
    <key>com.apple.security.cs.disable-library-validation</key><true/>
    <key>com.apple.security.device.audio-input</key><true/>
    <key>com.apple.security.device.bluetooth</key><true/>
    <key>com.apple.security.device.camera</key><true/>
    <key>com.apple.security.device.microphone</key><true/>
    <key>com.apple.security.files.user-selected.read-only</key><true/>
    <key>com.apple.security.files.user-selected.read-write</key><true/>
    <key>com.apple.security.network.client</key><true/>
    <key>com.apple.security.network.server</key><true/>
    <key>com.apple.security.temporary-exception.files.absolute-path.read-only</key><true/>
    <key>com.apple.security.temporary-exception.files.absolute-path.read-write</key><true/>
  </dict>
</plist>

build/entitlements.mac.inherit.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
    <key>com.apple.security.cs.disable-library-validation</key><true/>
    <key>com.apple.security.temporary-exception.apple-events</key><true/>
  </dict>
</plist>

These entitlements can be used for distributing outside of AppStore. For AppStore com.apple.security.app-sandbox should be added to entitlements.mac.inherit.plist at least. I haven't built yet for AppStore by myself.

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

I believe it is still an issue

I just wanted to say that according to this below linked Apple post from September 3 2019, Apple was using relaxed security until the end of Jan 2020:

https://developer.apple.com/news/?id=09032019a

I ran into this yesterday (first Monday in Feb 2020) when I noticed that notarizing was no longer warning about, e.g. "binary not hardened", and still Approving it. It now instead returned "Not Approved" with errors.

On Friday Jan 30th 2020, the same code signing and notarization process resulted in a distributable app that is working today. Now I'm getting several errors (instead of warnings) "The executable does not have the hardened runtime enabled." in the JSON report returned from Apple's notarize process.

I'm working with Entitlements on our app with the Electron Framework to adjust to their enforced standards. I've not completed it, but I suspect that will resolve the issues once I find out what hardening our binaries is preventing, exactly. For example, it may require allowing JIT:
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_cs_allow-jit

After hardening without Entitlements described, the notarization process passes, but I'm getting the usual crash report for the Electron.Framework thread:
Termination Reason: Namespace CODESIGNING, Code 0x2
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 ??? 0x00002e8722d02040 0 + 51157939527744
1 com.github.Electron.framework 0x000000010d41df26 0x10c316000 + 17858342
2 com.github.Electron.framework 0x000000010d429043 0x10c316000 + 17903683
...

Example errors (formerly warnings) from Apple notarizing process.

  1. I wasn't hardening this particular binary under the Electron.Framework:
    "AppZip.zip/AppName.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/crashpad_handler"
    "The executable does not have the hardened runtime enabled."

  2. I wasn't signing the dylibs under Electron.Framework:
    "NanoCounter.zip/NanoCounter.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib"
    "The binary is not signed."

This seemed to fix the Electron part of our app. Note that maybe I can remove these entitlements if I sign some dylibs included in the app, for example.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
    <key>com.apple.security.cs.disable-library-validation</key><true/>
  </dict>
</plist>

For example, the last thing I codesign is my app's main program, which uses Electron, (inside out, by Apple's rules) I use the entitlements defined above:
codesign -o runtime --entitlement entitlements.plist --verbose --timestamp -s "Developer ID Application: My Company (IDNUMBER)" MyApp.app/Contents/MacOS/MyApp

As for the Electron Framework, I signed it this way. Not sure if the crashpad_handler needs any entitlements yet.

Note that $SIG would be our "Developer ID Application: My Company (IDNUMBER)"

codesign -o runtime --verbose --timestamp -s $SIG "MyApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources/crashpad_handler"
codesign --verbose --timestamp -s $SIG "MyApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib"
codesign --verbose --timestamp -s $SIG "MyApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libEGL.dylib"
codesign --verbose --timestamp -s $SIG "MyApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib"
codesign --verbose --timestamp -s $SIG "MyApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libGLESv2.dylib"
codesign --verbose --timestamp -s $SIG "MyApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib"
codesign --verbose --timestamp -s $SIG "MyApp.app/Contents/Frameworks/Electron Framework.framework"

Note that Apple's notarizing service complained about those dylibs being unsigned, so I specifically signed them.

NOTE: that I haven't actually tried "crashpad_handler" and it almost definitely needs more entitlements. Our app required disk access and some other things before it started fully working.

For example:

    <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
    <key>com.apple.security.files.user-selected.read-write</key><true/>
    <key>com.apple.security.network.client</key><true/>
    <key>com.apple.security.network.server</key><true/>

Information from Apple, concerning whether or not you can have too many entitlements in your plist file, as well as too few:

That’s a surprisingly nuanced question. If you restrict yourself to the hardened runtime exception entitlements (listed in the “Runtime Exceptions” topic on this page), I’m not aware of any specific incompatibilities. Some entitlements subsume others — for example, com.apple.security.cs.allow-jit, com.apple.security.cs.allow-unsigned-executable-memory and com.apple.security.cs.disable-executable-page-protection represent progressively weaker memory protection — but any redundancy doesn’t cause a problem.

Outside of that space, it’s easy to run into problems:

  • Some entitlements have to be whitelisted by a provisioning profile. Adding those entitlements to a product without the appropriate provisioning profile will prevent the code from running.

  • There are some unusual interactions between entitlements. For example, the notary service will not notarise code with the com.apple.security.get-task-allow entitlement unless it also has the com.apple.security.cs.disable-library-validation entitlement. See the “Avoid the Get-Task-Allow Entitlement” section in “Resolving Common Notarization Issues”.

Hope this helps.

Still an issue issue. The crash happens as soon as you use com.apple.security.app-sandbox for me.
See also https://github.com/electron/electron/issues/22656.

Yea. I never got sandbox working because it's outside the scope of our app.

When we go to the Apple App store, that will have to change, and we'll have to figure out sandbox security.

When I did try Sandbox security, I'm 99% sure our app breaks that by using, e.g. ~/Library/Logs/OurApp/ to store logs.

Added detailed information here : electron/electron#22656. It is essentially related to

com.apple.security.app-sandbox

once we add this in entitlement and generate signed app the app crashes on start. I think it means current electron build does not support to upload the apps to mac store. Please correct me if i am wrong ?

That's correct. app-sandbox has to do with porting to the App store and when I started to investigate that I cut it off, because it was apparent that was a lot of work and wasn't our use case.

Edit: Sorry, I meant "Correct" in that it's for porting to app store. Please see @marcj's comment below. Sorry for the confusion.

Okay Thanks for confirming that electron currently does not support mac app store build generation/submission. I would like to know, if there is any plan from Electron team to fix this problem ?

That's not correct. You can in fact publish Electron apps to the Mac App store. But to do so you need the right entitlements in your entitlements.plist when app-sandbox is activated.

Please note: Entitlements for the mac app store are fundamentally different to the non-mac-app-store version you distribute via your website (using notarization).

# electron-builder.json
  "mas": {
    "hardenedRuntime": false,
    "entitlements": "entitlements/mas.plist",
    "entitlementsInherit": "entitlements/mas.inherit.plist"
  },
# entitlements/mas.inherit.plist
<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.inherit</key>
    <true/>
</dict>
</plist>
# entitlements/mas.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.cs.allow-jit</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.application-groups</key>
    <array>
        <string>TEAM_ID.com.company.app-id</string>
    </array>
</dict>
</plist>

If you forget one thing or add not exactly com.apple.security.app-sandbox + com.apple.security.inherit into the mas.inherit.plist because you thought you are smart and add more than necessary, then you did it wrong and the app will crash.

  1. The mas.inherit.plist file in my project exactly matches to yours
  2. mas.plist also matches but i think you missed following
    > com.apple.security.application-groups
    in the file the dictionary object must have the above key.

I tried to investigated the crash and it appears to be a GPU rendering related; but can't be sure. (using Electron v7.1.4 ) I am only able to get around this crash by down grading the electron to v6 and disabling app-sandbox programatically. Not sure if apple is going to like that but we shall see.

@marcj Tried many variations of the entitlements but every time com.apple.security.app-sandbox is added to the .plist files, the app crashes on launch.

This would suggest at present electron-builder does not support mas builds.

@ronghester did you have any luck?

@greenimpala then you're doing something wrong. To find out what you're doing wrong it's best to publish a reproduction as Github repository so people could try it on their machine and see what isn't working.

Also you shouldn't try "many variations" because they are very fixed for basic use-cases. If you add more than necessary or the wrong one you did it wrong and the result is a crash.

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

This is not resolved, actually.

Please reopen this issue.

Many, many people are also having the same issue and it is unresolved...

@lanistor @DominikLevitsky I haven't been keeping up with this problem but I did solve it by:

  • Ensuring sandbox is in my entitlements.
  • Never using hardened runtime for MAS builds.
  • Realising that running valid MAS builds locally WILL give a codesign crash (this is correct behavior!!).
  • You should test MAS builds locally with the mas-dev target and using correct Apple dev certs.
  • ~Important one — Re-writing my plists for both mas and mas-dev (https://github.com/electron/electron-osx-sign/issues/223#issuecomment-611070794) AFTER a build and then RE-signing with electron-osx-sign. This is the weird undocumented issue that needs to be fixed :)~

@greenimpala The latest electron-builder version has repaired the format of Info.plist, it's string format, not binary format, but still crash for mas-dev target.

Using 22.7.0 I no longer need to resign plists and my mas-dev build works locally.

It probably is either your certificates (ensure your provisioning profile is configured for the exact device ID you are testing on) or entitlements (see https://github.com/electron-userland/electron-builder/issues/3989#issuecomment-605298583).

@greenimpala could you by any chance please share a working config? I've been trying to get a working version of my electron app to the mac store for years now without any success...

There really isn't anything special with the config:

mac:
  appId: <mac app store appid>
  icon: icons/mac/app.icns
  target: mas # mas-dev for test
  extraResources:
    <any extra binaries here>
  hardenedRuntime: false
  gatekeeperAssess: false

mas:
  entitlements: scripts/build/mas/entitlements.mas.plist
  entitlementsInherit: scripts/build/mas/entitlements.mas.inherit.plist
  provisioningProfile: scripts/build/mas/Prod.provisionprofile # Dev.provisionprofile for test

@johannesjo I had a look at https://github.com/johannesjo/super-productivity/blob/master/electron-builder.yaml#L69 and it looks fine but you must set hardenedRuntime to false for mas builds. As the enforced sandbox restriction with MAS is essentially providing the necessary OS API restrictions.

@greenimpala thanks for taking a look! I am using two dedicated configs for mas and mas-dev
https://github.com/johannesjo/super-productivity/blob/master/build/electron-builder.mas.yaml
https://github.com/johannesjo/super-productivity/blob/master/build/electron-builder.mas-dev.yaml

Both have set hardenedRuntime to false.But I still get the EXC_BAD_ACCESS (Code Signature Invalid) error when I try to start the app.

I tried a ton of different configuration options and setups up to the point where it gets esoteric :D so any help what's causing this is greatly appreciated!

Using 22.7.0 I no longer need to resign plists and my mas-dev build works locally.

It probably is either your certificates (ensure your provisioning profile is configured for the exact device ID you are testing on) or entitlements (see #3989 (comment)).

Can the mas-dev target package run in your mashine?

@lanistor no same error. I am also pretty sure I tried the suggestion made by markj, but it has been quite a while. I will check again once I have access to my mac.

@johannesjo Couple of things I can see

  • No need to copy across provisioning profile.
  • Are you using a dev provisioning profile configured with the machine ID of your exact machine for mas-dev? Both configs look like they use the same one which won't work.
  • Make sure entitlements.inherit just contains sandbox + inherit.

@greenimpala not sure what fixed the issue in the end to be honest (my guess is that it was adjusting the entitlements.inherit). But now it works. Thank you very much for your help!

@greenimpala not sure what fixed the issue in the end to be honest (my guess is that it was adjusting the entitlements.inherit). But now it works. Thank you very much for your help!

Could you show us your configuration? including the electron-builder's configuration.

Sure!
https://github.com/johannesjo/super-productivity/blob/master/electron-builder.yaml
https://github.com/johannesjo/super-productivity/tree/master/build

Thank you so much.
I tested mas-dev target again using your configuration, failed again. I don't know why.

One simple question: How did you get you MacBook's UUID for mas-dev's 'provisionprofile'? Is like this:
image

@lanistor I believe the mac id is put into the CSR you did create locally which is was used to create the certificates at developer.apple.com.

Was this page helpful?
0 / 5 - 0 ratings