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

Hardened runtime causes app to crash on open. (Signed and notarized) #4040

Closed
UdaraJay opened this issue Jul 10, 2019 · 149 comments
Closed

Hardened runtime causes app to crash on open. (Signed and notarized) #4040

UdaraJay opened this issue Jul 10, 2019 · 149 comments

Comments

@UdaraJay
Copy link

@UdaraJay UdaraJay commented Jul 10, 2019

  • Versions:
    electron: 5.0.6
    electron-builder: 21.0.11
    electron-notarize: 0.1.1
    electron-webpack: 2.7.4
    Working on: MacOS Catalina 10.15 Beta 3 (19A501i)
    Xcode: Xcode 11 beta 3

  • What I'm trying to do:
    Sign and notarize an electron, web-packed, react desktop application for distribution outside the mac store.

  • Problem and exact case of error:

  1. Build the app unsigned, unnotarized, no hardened runtime: runs
  2. Build the app signed, no hardened runtime: runs
  3. Build the app signed, hardened runtime: (build and sign successful) error below when opening app
  4. Build the app signed, hardened runtime, notarize: (build, sign and notatrize successful) error below when opening app
  • In both the error cases I've run:
    1/ Verify code signing
test.app: valid on disk
test.app: satisfies its Designated Requirement

2/ Verify code notarization

test.app: accepted
source=Notarized Developer ID
origin=Developer ID Application: XXX, Inc. (XXXXXXXXXX)
  • Entitlements for mac
<?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/>
  </dict>

  • Target: darwin

  • Error dump

Process:               Test [7467]
Path:                  /Users/USER/Documents/*/Test.app/Contents/MacOS/Test
Identifier:            ai.XXXX.desktop
Version:               0.0.4 (0.0.4)
Code Type:             X86-64 (Native)
Parent Process:        ??? [1]
Responsible:           Test [7467]
User ID:               501

Date/Time:             2019-07-10 16:44:52.073 -0400
OS Version:            Mac OS X 10.15 (19A501i)

Time Awake Since Boot: 27000 seconds
Time Since Wake:       11000 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

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

Termination Reason:    Namespace CODESIGNING, Code 0x2

...

Logical CPU:     6
Error Code:      0x00000015 (invalid protections for user instruction write)
Trap Number:     14
@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 11, 2019

Confirmed same issue happening to us. I'm not sure what to even do to work around this.

@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 11, 2019

is this the fix? #3926

@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 11, 2019

Further info:

You need at least the following entitlements:

<?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-jit</key>
    <true/>
    <key>
com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>
com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
  </dict>
</plist>

Further info from https://medium.com/@TwitterArchiveEraser/notarize-electron-apps-7a5f988406db

Make sure to try out starting the app after this process, if some entitlements are missing, the app might be broken after notarization.

@UdaraJay
Copy link
Author

@UdaraJay UdaraJay commented Jul 11, 2019

@itsthisjustin tried all sorts of entitlements, including the ones above, not the fix. Also tried gatekeeper access to false and afterSign hook to notarize before making the DMG; still not the fix. The only variable that fixes this is turning hardened runtime off; but that means you can't notarize.

  1. I've tried this entire process on a non-webpacked electron app and that seems to work fine; feels like it could be connected.

  2. I've also tried setting the sandboxed entitlement; while the app opens in this scenario and the Code Signature Invalid error goes away, but it leads to a different crash error. Expected since the app I'm working on is not ready to be sandboxed yet.

@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 11, 2019

@UdaraJay entitlements got rid of the sign error but yeah my UI crashes on start now

@UdaraJay
Copy link
Author

@UdaraJay UdaraJay commented Jul 11, 2019

Hey, @itsthisjustin - wondering what MacOS you use? and Xcode version? Curious if it's an xcode issue.

@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 11, 2019

@UdaraJay I installed the latest Xcode beta today actually in order to get notarization working. So 11 beta 3. I'm on OSX 10.14.5. I have this running in Travis CI as well.

Update: Tested on xcode 10.2 and same issue

@matteotomasoni
Copy link

@matteotomasoni matteotomasoni commented Jul 11, 2019

Yes, the issue I'm having in #3989 seems exactly the same, except I'm still using electron 4.2.6 and I'm building on an older Mac (OSX 10.13.6, according to Apple's own documentation this is the minimum version able to notarize apps - and I verified that using Xcode to build a simple native app it works perfectly well). Also, my app doesn't use webpack but only simple old-school html/css/js.

Both signature and notarization seems ok on my app, and even the error report seems the same:

Process:               TestApp [4615]
Path:                  /Applications/TestApp.app/Contents/MacOS/TestApp
Identifier:            com.mycompany.test-app
Version:               1.4.4 (1.4.4)
Code Type:             X86-64 (Native)
Parent Process:        ??? [1]
Responsible:           TestApp [4615]
User ID:               501

Date/Time:             2019-07-10 18:02:04.255 +0200
OS Version:            Mac OS X 10.14.5 (18F132)
Report Version:        12
Anonymous UUID:        516B346A-7835-6066-F0D6-F79409DF2C59

[...]

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

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

Termination Reason:    Namespace CODESIGNING, Code 0x2

kernel messages:

VM Regions Near 0x2f36dcf86660:
    Memory Tag 255         00002f36dcf83000-00002f36dcf84000 [    4K] ---/rwx SM=NUL  
--> Memory Tag 255         00002f36dcf84000-00002f36dcfff000 [  492K] r-x/rwx SM=COW  
    Memory Tag 255         00002f36dcfff000-00002f36e4f69000 [127.4M] ---/rwx SM=NUL  

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   ???                           	0x00002f36dcf86660 0 + 51912682006112
1   com.github.Electron.framework 	0x00000001016b9a41 0x1002f3000 + 20736577
2   com.github.Electron.framework 	0x00000001016b9778 v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) + 152
3   com.github.Electron.framework 	0x0000000101a7d4fc v8::Script::Run(v8::Local<v8::Context>) + 492
4   com.github.Electron.framework 	0x00000001050c63af 0x1002f3000 + 81605551
5   com.github.Electron.framework 	0x00000001050c5f0f node::LoadEnvironment(node::Environment*) + 191
6   com.github.Electron.framework 	0x0000000102067968 0x1002f3000 + 30886248
7   com.github.Electron.framework 	0x0000000101fed395 0x1002f3000 + 30385045
8   com.github.Electron.framework 	0x0000000100d0042a 0x1002f3000 + 10540074
9   com.github.Electron.framework 	0x0000000100d05afa 0x1002f3000 + 10562298
10  com.github.Electron.framework 	0x0000000100cffb38 0x1002f3000 + 10537784
11  com.github.Electron.framework 	0x0000000101f582f8 0x1002f3000 + 29774584
12  com.github.Electron.framework 	0x000000010334dbbd 0x1002f3000 + 50703293
13  com.github.Electron.framework 	0x0000000101f573a4 0x1002f3000 + 29770660
14  com.github.Electron.framework 	0x00000001002f5d54 AtomMain + 84
15  com.mycompany.test-app           	0x00000001002e9f10 0x1002e9000 + 3856
16  libdyld.dylib                 	0x00007fff603583d5 start + 1

[...]

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x00002f36dcf86660  rcx: 0x0000000000000000  rdx: 0x00001a9d74082201
  rdi: 0x00001a9d052026f1  rsi: 0x00001a9da082e1f9  rbp: 0x00007ffeef915f90  rsp: 0x00007ffeef915ee8
   r8: 0x0000000000000000   r9: 0x0000000000000000  r10: 0x0000000000000000  r11: 0x0000000106b6bd68
  r12: 0x00007fa71d03b878  r13: 0x0000000106b65000  r14: 0x00001a9da082e1f9  r15: 0x00001a9d74082201
  rip: 0x00002f36dcf86660  rfl: 0x0000000000010246  cr2: 0x00002f36dcf86660
  
Logical CPU:     0
Error Code:      0x00000015
Trap Number:     14

[...]

I tried adding all these entitlements, but with no success:

<!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.allow-jit</key>
		<true/>
		<key>com.apple.security.cs.allow-dyld-environment-variables</key>
		<true/>
		<key>com.apple.security.cs.disable-library-validation</key>
		<true/>
		<key>com.apple.security.cs.disable-executable-page-protection</key>
		<true/>
	</dict>
</plist>

I also verified that the correct entitlements are embedded in the application.

Last week I opened a DTS at Apple but even with their help we've not found a solution yet.

@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 11, 2019

@UdaraJay Alright, I've finally got it working. The trick was two fold.

First:

Set both entitlements and entitlementsInherit in your mac build settings. Here's mine:

"mac": {
      "hardenedRuntime": true,
      "gatekeeperAssess": false,
      "artifactName": "${productName}-${version}-${arch}.${ext}",
      "entitlements": "mac_config/entitlements.mac.plist",
      "entitlementsInherit": "mac_config/entitlements.mac.plist",
      "target": [
        "dmg",
        "zip"
      ],

Then, in my entitlements file, I stripped it down to only what I need.

<?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.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
	<true/>
	<key>com.apple.security.device.audio-input</key>
	<true/>
	<key>com.apple.security.files.user-selected.read-only</key>
	<true/>
</dict>
</plist>

com.apple.security.cs.allow-unsigned-executable-memory is really the key one here. Others mentioned adding another one, but I was back to the signing crash when I did that.

@matteotomasoni
Copy link

@matteotomasoni matteotomasoni commented Jul 11, 2019

I've tried your same entitlements, but unfortunately my application still crashes with the same symptoms

@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 11, 2019

@matteotomasoni is there any other entitlements you might need? Ive basically found this:

If you don't do the entitlementsInherit thing, your app won't load. If you mess up the entitlements with too many or too few, it'll crash with the signing error.

For instance if I add the sandbox entitlement I crash with the sign error

@matteotomasoni
Copy link

@matteotomasoni matteotomasoni commented Jul 12, 2019

@itsthisjustin is there a reason for the com.apple.security.device.audio-input entitlement? Does your app really use the audio input?
My app doesn't do anything fancy at all, but I use a couple of libraries that are like a black box to me.
If the problem is on entitlements, then is there a way (or better, a tool) to know exactly what entitlements an application needs?

@itsthisjustin
Copy link

@itsthisjustin itsthisjustin commented Jul 12, 2019

@matteotomasoni ha yeah we are building https://yac.chat. So definitely needs audio.

I had the same fear as you and I think ultimately just got lucky. That’s also why the inherit property is so important. I’m not sure who at Apple thinks it’s normal to just crash an app if the entitlements are wrong though.

@UdaraJay
Copy link
Author

@UdaraJay UdaraJay commented Jul 12, 2019

@itsthisjustin glad you figured it out! I've tried those entitlements and other combination (for both the entitlements and the inheritedEntitlements) with no luck. But I didn't realize having too many entitlements could cause signing errors too, that's important to note!

And yea! Truly, I wish there was a way to access more specific errors on code-signing, or at least fail more elegantly.

@staifan
Copy link

@staifan staifan commented Jul 17, 2019

Hello,
Do you find a solution?
I encounter exactly the same problem.
I've been trying for more than a week for just about every possible configuration ...
I even tried to do some tests with the basic application of electron (https://electronjs.org/docs/tutorial/first-app#electron-development-in-a-nutshell) and unfortunately, I get always the same result:
All this is correct, I get each time the apple mail that says: "Your Mac software has been notarized. You can now export this software and distribute it directly to users".
The application installs correctly, and at launch I get the message inexorably:

Date/Time:             2019-07-17 10:54:31.390 +0200
OS Version:            Mac OS X 10.14.5 (18F203)
Report Version:        12
Anonymous UUID:        1984F4B3-87AC-D6FD-4C5D-6A3242112EE9


Time Awake Since Boot: 1600 seconds

System Integrity Protection: enabled

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

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

Termination Reason:    Namespace CODESIGNING, Code 0x2

For now I have no idea ... So if someone at a track, I'm interested
Thank you

@starkos
Copy link

@starkos starkos commented Jul 17, 2019

This suggestion from @itsthisjustin got me past the startup crash. I'm still having other issues (unable to access web content for starters) but at least things are running.

@HeberLemus
Copy link

@HeberLemus HeberLemus commented Jul 20, 2019

i too am having a similar problem. cant get past startup crash.
i tried using the same entitlement settings with no dice
i also tried other entitlement lines and combinations of them with no luck either.
the error log starts as /Volume/VOLUME/ because i was running it off a flash drive, both the .app file itself and the .dmg file
feeling terrible that im so close to getting the app to run yet being denied so hard

Process: Appname [874]
Path: /Volumes/VOLUME/*/Appname.app/Contents/MacOS/Appname
Identifier: com.appname.desktopapp
Version: 1.0.0 (1.0.0)
Code Type: X86-64 (Native)
Parent Process: ??? [1]
Responsible: Appname [874]
User ID: 501

Date/Time: 2019-07-19 15:27:26.821 -0700
OS Version: Mac OS X 10.14.5 (18F2058)
Report Version: 12
Anonymous UUID: A4DA30A6-09EA-9677-95CD-EA316769DD4D

Sleep/Wake UUID: CC4B1217-0165-46A8-846E-BFA4D38C58E6

Time Awake Since Boot: 16000 seconds

System Integrity Protection: enabled

Crashed Thread: 0 Dispatch queue: com.apple.main-thread

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

Termination Reason: Namespace CODESIGNING, Code 0x2

kernel messages:

VM Regions Near 0x108a00082040:
Memory Tag 255 0000108a00081000-0000108a00082000 [ 4K] ---/rwx SM=NUL
--> Memory Tag 255 0000108a00082000-0000108a000ff000 [ 500K] r-x/rwx SM=COW
Memory Tag 255 0000108a000ff000-0000108a07fbe000 [126.7M] ---/rwx SM=NUL

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 ??? 0x0000108a00082040 0 + 18184892063808
1 com.github.Electron.framework 0x0000000103ffdad8 0x10273b000 + 25963224
2 com.github.Electron.framework 0x0000000103ffc6ce 0x10273b000 + 25958094

@UdaraJay
Copy link
Author

@UdaraJay UdaraJay commented Jul 20, 2019

@starkos @HeberLemus if you don't need any specific entitlements, try removing the entitlements files and let electon-builder set the default one. That's the only way I got signing and notarizing to work on my end. (still not perfect; but it at-least gets the application to run)

@HeberLemus
Copy link

@HeberLemus HeberLemus commented Jul 21, 2019

@UdaraJay tried that just now, removed the properties "entitlements" and "entitlementsInherit" from the package json under the mac key, still the exact same error

also, running "codesign -d --ent :- "Appname.app/Contents/MacOS/Appname" doesnt give back anything if its supposed to set default entitlements
what are the defaults?

update: nevermind, the defaults are being set.

in the end, my build is loading with the default entitlements. the other issue i had was that i had set mac: {type: "development"}

@UdaraJay
Copy link
Author

@UdaraJay UdaraJay commented Jul 22, 2019

Perfect! @HeberLemus did it start working?

@HeberLemus
Copy link

@HeberLemus HeberLemus commented Jul 22, 2019

@UdaraJay yes, no build issues, no startup issues and no later issues thus far. guess my problem really was that one property just like for this

update: actually there is one problem. while the file works fine when downloaded to a flashdrive and then mounted onto the mac, the .pkg isnt getting signed so when attempting to open said file it comes back as unidentified developer when attempting to download from the net

going to try and see if the AfterAllArtifactBuild hook may let me sign and notarize the .pkg beofre its done

update two: so it would seem that signing and getting it notarized works, but stapling does not
Error:

electron-notarize notarization was successful +0ms
electron-notarize attempting to staple app: /pathToFile/Appname-1.0.0.pkg +0ms
⨯ Failed to staple your application with code: 66

Processing: /pathToFile/Appname-1.0.0.pkg
Properties are {
NSURLIsDirectoryKey = 0;
NSURLIsPackageKey = 0;
NSURLIsSymbolicLinkKey = 0;
NSURLLocalizedTypeDescriptionKey = "Installer package";
NSURLTypeIdentifierKey = "com.apple.installer-package-archive";
"_NSURLIsApplicationKey" = 0;
}
Could not find an appropriate "code signature" in the Appname-1.0.0.pkg installer package.
Cannot download ticket. CDHash must be set.

my method was
const cp = require('child_process');
const path = require('path');
const {notarize} = require('electron-notarize');

exports.default = async function (context) {
if (process.platform !== 'darwin') return; //dont bother if a windows build
const { artifactPaths, outDir } = context;
for (let i = 0; i< artifactPaths.length; i++) {
const APP_PATH = artifactPaths[i];
const ENTITLEMENTS_PATH = path.join(outDir, '../build/mac/entitlements.mac.plist');
const cmd =codesign -s "${process.env.MAC_DEVELOPER_ID}" -f --entitlements "${ENTITLEMENTS_PATH}" "${APP_PATH}";
await cp.execSync(cmd, {stdio: "inherit"});
await notarize({
appBundleId:com.appname.desktopapp,
appPath: APP_PATH,
appleId: process.env.APPLEID,
appleIdPassword: process.env.APPLEIDPASS,
});
await cp.execSync(spctl -a -t exec -vv "${APP_PATH}", {stdio: "inherit"});
}
console.log('Build Complete');
};

if someone can suggest a cleaner way to do this i greatly appreciate it.

update 3: despite Apples documentation that even if a file doesnt have its notarization ticket stapled to it, that it should be able to get the notarization clearance from the net as stated here

After notarization completes successfully, the next time any user attempts to run your app on macOS 10.14 or later, Gatekeeper finds the ticket online...

the .pkg still refuses to open. any ideas?

@UdaraJay
Copy link
Author

@UdaraJay UdaraJay commented Jul 23, 2019

@HeberLemus so I had this problem too. If signing and notarizing works anything like dmgs, then you can leave the pkg unsigned and unnotarized and the OS should see the signed and notarized application inside. I couldn't get my pkg to notarize; but I'm using a DMG for distribution currently.

@HeberLemus
Copy link

@HeberLemus HeberLemus commented Jul 24, 2019

@UdaraJay i also swapped back to dmg, as i asked a coworker to try and use the .pkg and his system refused to open saying unknown developer, much in the same way as if its not notarized. if i downloaded the pkg to a flash and then open the pkg from the flash on the mac after transferring it to a mac, then it would open. but if downloaded from the internet it refused

ive run into a different problem now. anytime i attempt to set entitlements other than let the defaults be set the app refuses to run. but i need the camera entitlement for my app to access webcam and audio entitlement to access microphone. any recommendations?

@UdaraJay
Copy link
Author

@UdaraJay UdaraJay commented Jul 27, 2019

@HeberLemus this may be a real issue, I can't seem to get signing to work using any custom entitlements either. One thing you could try would be to look at what the exact default entitlements are and then try using those + the camera entitlements?

@patrickmichalina
Copy link

@patrickmichalina patrickmichalina commented Jul 29, 2019

WOW! Thanks for this thread. Totally saved me. Couldn't figure out why navigator.mediaDevices.getUserMedia() wasn't working after bundling for production. I used a custom entitlements file and it works just great! Thanks!

<?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-jit</key><true/>
  <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
  <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
  <key>com.apple.security.device.audio-input</key><true/>
  <key>com.apple.security.device.camera</key><true/>
</dict>
</plist>

@HeberLemus
Copy link

@HeberLemus HeberLemus commented Jul 29, 2019

@patrickmichalina did you assign that to both entitlements and entitlementsInherit keys?

@patrickmichalina
Copy link

@patrickmichalina patrickmichalina commented Jul 29, 2019

I used both but should it be different?

 "mac": {
  "entitlements": "entitlements.mac.plist",
  "entitlementsInherit": "entitlements.mac.plist"
}

@davidleee
Copy link

@davidleee davidleee commented Dec 31, 2019

@Blightysoft hi, did you find a way to sign with hardened runtime and runs fine eventually?

Since Apple is going to stop apps without hardened runtime from opening after February 2020, it's worrying me very much...

@davidleee
Copy link

@davidleee davidleee commented Dec 31, 2019

@Blightysoft hi, did you find a way to sign with hardened runtime and runs fine eventually?

Since Apple is going to stop apps without hardened runtime from opening after February 2020, it's worrying me very much...

Finally, the app went blank after hardened runtime code sign because my entitlements miss a key-value pair:

<key>com.apple.security.cs.disable-library-validation</key>
<true/>

Spent couples of days trying every possible solution...hope this would help someone like me.

@xurenzhong
Copy link

@xurenzhong xurenzhong commented Mar 4, 2020

com.apple.security.files.user-selected.read-write com.apple.security.cs.allow-unsigned-executable-memory

this is my entitlements. If I delete dylib in project and set "hardenedRuntime": false, it work. but add dylib, it crash on open.

@gtamas
Copy link

@gtamas gtamas commented Mar 10, 2020

Hi all!

Two questions:

My MAS app builds and runs fine if I don't add this to the entitlements.plist

com.apple.security.app-sandbox

Is this this required or not? Can I submit the app to App Store without it?

The MAS builds seems to generate an executable AND an installer (PKG). However, the latter uses default icons, text etc and I don't see any options in electron builder docs to set these.
I mean, the options available for "PKG" builds are not available for MAS. Can customize the generated pkg installer somehow?

@marcj
Copy link

@marcj marcj commented Mar 11, 2020

@gtamas

To upload a macOS app to be notarized, you must enable the Hardened Runtime capability. For more information about notarization, see Notarizing macOS Software Before Distribution.

To distribute a macOS app through the Mac App Store, you must enable the App Sandbox capability.

Please read the documentation of apple carefully, then you'll understand it.

@lanistor
Copy link

@lanistor lanistor commented Apr 2, 2020

Resolved? I'm facing the same problem. I haved changed my entitlements files many times, added lots of entitlements, but useless.

Here is my entitlements.mas.parent.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.application-groups</key>  
    <array> 
      <string>XXX.com.aaa.bbb</string>  
    </array>
    <key>com.apple.application-identifier</key>
    <string>XXX.com.aaa.bbb</string>
    <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.cs.allow-jit</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
  </dict>
</plist>

Error Message:

Logical CPU:     2
Error Code:      0x00000015 (invalid protections for user instruction write)
Trap Number:     14

@Blightysoft
Copy link

@Blightysoft Blightysoft commented Apr 18, 2020

Solved! We now have the MAC (not MAS) hardened runtime working on Apple macOS. I hope this review might help others:

The Apple notarising process was spewing out false positives, so there was officially no problem, until our application died when running on a Mac, and created a dump file. Then it was difficult for Apple support to work out what the problem was.

Sometime on or before 10th April 2020, Apple (finally) did some upgrading work on their notarising process, an Apple Tech Support chap told me. It meant that we finally got some meaningful error messages, although over a couple of days (9th / 10th) the messages altered. Each run seemed to wipe out the previous 'https://osxapps-ssl.itunes.apple.com/...' logs and made them show the latest results as though they are their own?!

The Apple logs eventually had the error "Embedded entitlements are invalid: syntax error near line 1". Their docs claim this means the entitlements file is in a binary format. In order to help the support engineer by providing the binary to which the entitlements had been applied, we had to create a new stand alone Azure (macOS) pipeline since you can't export artefacts from their releases pipelines. And this new pipeline worked like a charm! Notarising passed, and the software opened correctly on the Mac.

It seems as though passing the code over from the main Azure (Windows) pipeline to the releases (macOS) pipeline somehow damaged the entitlements.plist file? There is a nagging suspicion that in 6 months time, Apple will suddenly say that there is no problem.

One curious anomaly, is that although we're using the exact same Azure pipeline agent specification as before, 10.15, Taccy previously though that the software had been build on macOS 10.13 and now thinks it is 10.15. Or perhaps that is a reflection on the version used by Apple itself to notarise?

So the problem is solved. One of the things we've found incredibly frustrating is that Apple do not provide engineer tools to work out what is going on, hence the use of Taccy et al. Frankly, their ecosystem support is nowhere near as good as Microsoft.

Our final entitlements file:

<dict>
    <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.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
    <key>com.apple.security.device.camera</key>
    <true/>
    <key>com.apple.security.device.microphone</key>
    <true/>
</dict>

What did help:

Making sure the path to the entitlements file was relative './...'
Removing comments from the plist file might have helped (?)

What didn't fix it for us:

Endlessly changing the entitlements
Downgrading the Electron version to 6.x or 7.x

Hope this is of some use!

@monoto
Copy link

@monoto monoto commented Jun 6, 2020

Has any one been able to narrow down what caused this crash? Same misery here. Mac Build, Electron-Builder 22.7.0, hardenedRuntime=true, Crash with code signature invalid on app launch.

@monoto
Copy link

@monoto monoto commented Jun 7, 2020

Got it to build and notarized. Have to use the default entitlement for both main and inherit.

Electron-builder: 22.7.0
Traget: mac
hardenedRuntime = true.

<?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>
    <!-- https://github.com/electron/electron-notarize#prerequisites -->
    <key>com.apple.security.cs.allow-jit</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <!-- https://github.com/electron-userland/electron-builder/issues/3940 -->
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
  </dict>
</plist>

Any other setting causes code signature invalid error.
Looks like building for mas is a whole new can of worms.

@rakista112
Copy link

@rakista112 rakista112 commented Jul 15, 2020

Had the same issue but @monoto 's fix for the lists worked for me.
I'm building for pkg.
Thanks @monoto

@Aurora12
Copy link

@Aurora12 Aurora12 commented Aug 5, 2020

Thanks guys! I was starting to go bald already.

This is what was happening for me in a project completely unrelated to Electron: I had some binaries (go-flutter-desktop actually) and they loaded a dylib bundled along with them in a .dmg which caused the .app to crash on start when signed for hardened runtime.

It transpired this action requires Allow Unsigned Executable Memory Entitlement during the codesign operation with options=runtime enabled. Without this entitlement the app just crashed on start with no intelligible error message.

Thanks to you lot I figured which entitlement was missing by trial and error.

@SweetPapa
Copy link

@SweetPapa SweetPapa commented Aug 16, 2020

Incase this helps anyone else, I was having issues with this where I was able to successfully notarize and sign my app but it would crash and close upon opening.

I was letting Electron-Builder sign my app for me, but using a custom script after the fact to sign additional files that Apple's notarization would complain about. (As well build and sign a PKG file containing my Electron app.)

I realized my script was replacing the existing code signing done by Electron, and was not re-applying the entitlements that I had setup via the package.json file in my Electron workflow.

Ultimately I got things working by not using the Electron signing process at all (You can totally get this working via Electron-Builder, I just didn't want to move my automation scripts from my current workflow.). Here are all my settings:

Pacakge.json configurations: (build => mac)

"mac": {
      "icon": "./build/icon.icns",
      "gatekeeperAssess": false,
      "hardenedRuntime": true,
      "entitlements": "build/entitlements.mac.inherit.plist",
      "entitlementsInherit": "build/entitlements.mac.inherit.plist",
      "target": ["zip"]
    },

Entitlements File: (inside my 'build' folder, located at root of my project)

<!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.allow-jit</key>
		<true/>
		<key>com.apple.security.cs.allow-dyld-environment-variables</key>
		<true/>
		<key>com.apple.security.cs.disable-library-validation</key>
		<true/>
		<key>com.apple.security.cs.disable-executable-page-protection</key>
		<true/>
                <key>com.apple.security.files.user-selected.read-write</key>
                <true/>
               <key>com.apple.security.files.user-selected.read-only</key>
               <true/>
	</dict>
</plist>

Command for Building App via Electron: (Again, I was not using Electron Builder for signing, to use electron builder remove the '-c.mac.identity=null' part. '-m' specifies to build specifically for Mac platform)

electron-builder -m -c.mac.identity=null

My Signing Script Process:

In addition to signing the main .app file, I sign all of the following files individually first (deep sign does not seem to do this for me):

  • distro/mac/myApp.app/Contents/MacOS/DiNG 4.0
    
  • distro/mac/myApp.app/Contents/Resources/app/node_modules/fsevents/build/Release/.node
    
  • distro/mac/myApp.app/Contents/Resources/app/node_modules/watchpack/node_modules/fsevents/fsevents.node
    
  • distro/mac/myApp.app/Contents/Resources/app/node_modules/node-sass/vendor/darwin-x64-64/binding.node
    
  • distro/mac/myApp.app/Contents/Resources/app/node_modules/fsevents/build/Release/fse.node
    
  • distro/mac/myApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libEGL.dylib
    
  • distro/mac/myApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libEGL.dylib
    
  • distro/mac/myApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libvk_swiftshader.dylib
    
  • distro/mac/myApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libGLESv2.dylib
    
  • distro/mac/myApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libswiftshader_libGLESv2.dylib
    
  • distro/mac/myApp.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Libraries/libffmpeg.dylib
    
  • distro/mac/myApp.app/Contents/Frameworks/Squirrel.framework/Versions/A/Resources/ShipIt
    

For each of these files I sign, I use this command:
codesign --force --deep --options runtime --sign "My Signing ID" "Path/to/My/App"

For the main executable I use:
codesign --entitlements "Path/to/My/EntitlementsFile" --force --deep --options runtime --sign "My Signing ID" "Path/to/My/App"

I think the entitlements get inherited from the main app, which is why it seems to work for me not applying the entitlements to all the framework and executable files.

Then, to verify:
codesign -vvv --deep --strict "Path/to/My/App"

Some Notes About my App's Functionality:

  • My app does not do anything too fancy, it does not need access to anything like the camera or microphone. For those sort of things, you need to add the proper respective entitlements.
  • My app writes files to disk on the Electron end, and runs commands via Terminal
  • I am unsure if I need all of the entitlements I have present, I may be able to remove some of them, but have not tried that yet.
  • I use the 'serial-number' npm module, which does some queries against Terminal too, I'd guess.
  • I run a built version of my Vue app for the UI

Some Links That Were Helpful:
Runtime Entitlements and Explanations: https://developer.apple.com/documentation/security/hardened_runtime
Electron Options for Mac: https://www.electron.build/configuration/mac
Signing with Entitlements via Command Line: https://stackoverflow.com/questions/36888535/how-do-i-resign-app-with-entitlements

@softwarenerd
Copy link

@softwarenerd softwarenerd commented Aug 22, 2020

I was experiencing this problem for over two days and I couldn't find the solution for it online, and I tried everything that I read.

Finally, out of desperation, I downloaded the source code for electron-osx-sign and tried to find answers there. What I found was that I could enable debugging by adding this export:

export DEBUG=electron-osx-sign*

Scrutinizing the debug output, I saw this warning:

electron-osx-sign:warn No `entitlements` passed in arguments: 
 * Provide `entitlements` to specify entitlements file for codesign.

So, I added the following argument to electron-osx-sign to provide my entitlements:

--entitlements=./build/entitlements.mac.plist

Running electron-osx-sign again, I saw two new warnings:

  electron-osx-sign:warn No `entitlements-inherit` passed in arguments: 
 * Entitlements file for enclosed app files is default to: /Users/Brian/Code/my-app/node_modules/electron-osx-sign/default.entitlements.darwin.inherit.plist +1ms

  electron-osx-sign:warn No `entitlements-loginhelper` passed in arguments: 
 * Entitlements file for login helper is default to: ./build/entitlements.mac.plist +4ms

So, I added the following arguments to electron-osx-sign to provide my entitlements-inherit and entitlements-loginhelper:

--entitlements-inherit=./build/entitlements.mac.plist
--entitlements-loginhelper=./build/entitlements.mac.plist

It appears that I could have skipped adding -entitlements-loginhelper=./build/entitlements.mac.plist because it was defaulted to my ./build/entitlements.mac.plist entitlements, but I wanted to remove the warning for a clean run.

After doing this, all the warnings went away and I was able to run my signed app, notarize it, and make a DMG installer for it using electron-installer-dmg. Everything is working perfectly now.

My entitlements.mac.plist file looks like:

<?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-jit</key>
    <true/>
    <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
    <true/>
    <key>com.apple.security.cs.allow-dyld-environment-variables</key>
    <true/>
  </dict>
</plist>

I'm left with a few questions:

package.json

Why weren't entitlements and entitlements-inherit picked up from my package.json file? It appears that electron-osx-sign doesn't look for these settings:

  "mac": {
    "icon": "./assets/icons/mac/my-app.icns",
    "hardenedRuntime": true,
    "entitlements": "./build/entitlements.mac.plist",
    "entitlementsInherit": "./build/entitlements.mac.plist",
    "target": [
      "dmg",
      "zip"
    ]
  }

entitlements and entitlements-inherit

What should be in my entitlements file and what should be in my entitlements-inherit file? Should they both be the same? If so, why do we have two different settings? I am unable to find clear and concise documentation on this. When I reviewed Visual Studio Code's signing, they appear to use the same file for both entitlements and entitlements-inherit.

entitlements-loginhelper

For a darwin build vs. mas, do I even need this? Should it be empty? I didn't like seeing the warning in the electron-osx-sign debug output, so I added the --entitlements-loginhelper pointing to my entitlements file, which is what electron-osx-sign does anyway, to remove the warning.

Best,

Brian

@bddckr
Copy link

@bddckr bddckr commented Sep 20, 2020

The Apple logs eventually had the error "Embedded entitlements are invalid: syntax error near line 1". Their docs claim this means the entitlements file is in a binary format. In order to help the support engineer by providing the binary to which the entitlements had been applied, we had to create a new stand alone Azure (macOS) pipeline since you can't export artefacts from their releases pipelines. And this new pipeline worked like a charm! Notarising passed, and the software opened correctly on the Mac.

It seems as though passing the code over from the main Azure (Windows) pipeline to the releases (macOS) pipeline somehow damaged the entitlements.plist file? There is a nagging suspicion that in 6 months time, Apple will suddenly say that there is no problem.
Blightysoft on Apr 18

For anyone coming across this mentioned issue (Embedded entitlements are invalid: syntax error near line 1) and did also build on Windows, but then tried to sign+notarize on macOS:

I just got the same issue after I made my GitLab pipeline take the entitlements file as an artifact from a Windows runner, to then download it to the macOS runner. Somehow that breaks the file, but it's not the encoding (I confirmed that it stayed the same). Downloading the entitlements file as a fresh copy from my git repo works without issues, but that doesn't work for my pipeline details.

The quoted comment helped me to figure this one out, though! To fix it you want to use plutil to convert the entitlements file (after downloading it as an artifact from a Windows runner in my case):

Ensure Properly Formatted Entitlements

Command line tools and apps use entitlements to gain access to system resources and capabilities. The file that declares an app’s entitlements must be ASCII-encoded and must not include Unicode Byte Order Marks (BOMs). When using Xcode to code sign, Xcode ensures that the entitlements file is a well-formed XML property list with no extra characters. It also automatically converts entitlement files stored as binary property lists (bplist) into properly-formed XML properly lists.

When using a custom workflow, use the plutil utility to ensure proper formatting of your entitlements file. This is especially true if you manually edit the file. Validate the formatting before passing your entitlements file as an argument to the codesign utility. The convert option converts the entitlements to an XML property list, and the lint option verifies proper formatting:

% plutil -convert xml1 <Project_Name.entitlements>
% plutil -lint <Project_Name.entitlements>

https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution/resolving_common_notarization_issues

Running the command to convert did the trick.

@andrew-mclachlan
Copy link

@andrew-mclachlan andrew-mclachlan commented Oct 17, 2020

This was an exceptionally helpful post ! Thank you all for the in-depth comments.

In the end, keeping my entitlements as per instructed here: https://medium.com/@TwitterArchiveEraser/notarize-electron-apps-7a5f988406db .. and adding one extra com.apple.security.cs.allow-dyld-environment-variables did the trick!

<plist version="1.0">
  <dict>
    <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.allow-dyld-environment-variables</key>
    <true/>
    <key>com.apple.security.cs.disable-library-validation</key>
    <true/>
  </dict>
</plist>

@spooksmus
Copy link

@spooksmus spooksmus commented Oct 18, 2020

In my case, removing

    <key>com.apple.security.app-sandbox</key>
    <true/>

from my mac plist did the trick. FWIW my target platform was not mas but only mac.

@stale
Copy link

@stale stale bot commented Dec 18, 2020

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.

@stale stale bot added backlog and removed backlog labels Dec 18, 2020
@PaulKeefe
Copy link

@PaulKeefe PaulKeefe commented Jan 3, 2021

In my case, removing

    <key>com.apple.security.app-sandbox</key>
    <true/>

from my mac plist did the trick. FWIW my target platform was not mas but only mac.

I think that is what did it for me as well. I thought I needed the sandbox, but that is a MAS only entitlement.

@mmaietta mmaietta closed this as completed Mar 9, 2021
@rudyrichter
Copy link

@rudyrichter rudyrichter commented Jul 26, 2021

@mmaietta curious why this was closed on march 8, as far as i can tell its still not possible to create a sandboxed app that also has the hardened runtime enabled. they aren't mutually exclusive security features.

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

No branches or pull requests