etternagame / etterna

Advanced cross-platform rhythm game focused on keyboard play
https://etternaonline.com/
MIT License
474 stars 132 forks source link

[META] Fix Problems Relating to macOS Notarization/Signing #1292

Open bluebandit21 opened 4 months ago

bluebandit21 commented 4 months ago

Introduction

Etterna is currently distributed as an unsigned app on all platforms, including macOS. Windows throws some mildly-scary looking warnings up to users (which most people are conditioned to bypassing anyway), but macOS takes many active measures to severely limit the functionality of unsigned apps for security reasons.

At this point, many bugs exist and have been encountered by users stemming indirectly from this problem, and they will only become greater and harder/impossible to work around in the future.

App Translocation:

By default, macOS prevents apps from accessing resources relative to the app's location. This is to prevent a class of attacks known as "dylib hijacking", wherein an attacker maliciously replaces external resources used by an app, which can potentially cause even signed intact apps to exhibit unintended malicious behavior. [1]

To fix this, recent versions of macOS do not always launch apps with a current working directory equal to where the app actually lives on disk. Instead, apps are sometimes launched from a read-only dynamically created volume under /private/var/ containing the app and any internal resources. This process is known as "App Translocation", and occurs when certain conditions are met, including the launching of an unsigned app with the com.apple.quarantine xattr set (which occurs automatically when apps are downloaded through Safari) [2] [3] This breaks Etterna because we intentionally store the Songs and Saves directories relative to Etterna.app itself, instead of within ~/Library/Application\ Support like Apple intends us to.

We currently work around this in an incredibly hacky way, by explicitly checking if we are undergoing app translocation, locating the real location of Etterna.app if so, and directly removing the com.apple.quarantine xattr from our own app ourselves before then killing and relaunching Etterna. See:

https://github.com/etternagame/etterna/blob/9a0b9fb94ea0c1f4d24b707bd00fad24d94d22ec/src/Core/Platform/PlatformMac.mm#L24-L69

This workaround is bad for a number of reasons: 1) It is fragile, in that it relies upon the internal function SecTranslocateCreateOriginalPathForURL in the Security framework [4] This is certainly something Apple doesn't want us doing and relies upon an internal function that could change or disappear in the future. 2) The roundaboutness of the way we try to do this has caused problems

Input Handling

Currently, we use a horribly outdated API for handling low-level input on macOS, as described by https://github.com/etternagame/etterna/issues/1260 and other issues/discussions.

This API requires elevated permissions to be allowed for use by an app, namely the Input Monitoring permission, without which certain API calls fail with a lack-of-permissions error. (TODO: Expand, link to relevant detailed sources)

Unfortunately, the system for handling per-app permissions seems to somehow interact with whether the app is signed or not; sometimes the com.apple.quarantine xattr seems to have to be removed before it's even possible to grant Etterna permissions to Input Monitoring in the first place! (TODO: This is possibly also related to us not having a valid CFBundleID; investigate further...) See: https://gist.github.com/bluebandit21/d34d7b0b4f9137c34c167e607db63c03

Native M-Series (Apple Silicon) Builds

To ease the transition when Apple switched from Intel's x86_64 chips to their own in-house ARM (aarch64) chips, Apple created the library Rosetta v2 which transparently and efficiently lets Apps compiled for the x86_64 architecture run on aarch64, via a JIT compilation layer. [6] This fortunately means that existing Etterna apps built for x86_64 do not encounter any more problems than we already do when trying to run on M-series machines.

However, we definitely want to get native ARM macOS builds working at some point for two main reasons:

Why is this of potential concern w.r.t. notarization/signing? Because modern versions of macOS require any apps running natively on M-series to be signed and notarized to run!

Beginning in macOS 10.14.5, software signed with a new Developer ID certificate and all new or updated kernel extensions must be notarized to run. Beginning in macOS 10.15, all software built after June 1, 2019, and distributed with Developer ID must be notarized. However, you aren’t required to notarize software that you distribute through the Mac App Store because the App Store submission process already includes equivalent security checks. [8]

Conclusion:

We should probably actually figure out how to notarize ourselves on Etterna!! The most straightforward route would probably be to have a single individual developer for Etterna (most likely @jameskr97 or @bluebandit21 ) pay for a personal Apple Developer license at the cost of $99/year and sign all releases intended for public distribution. [9] This would likely have to be a manual process, or we'd have to very carefully modify the CI to make it possible for this signing to occur without leaking the personal signing information of the said developer...

Another possible way would be establishing an Organization Apple Developer account for Etterna, also at the cost of $99/year. This obviously has the relative downside that we'd have to somehow generate this money specifically for Etterna, while the "Individual random developer" route might be "free" in the sense that we might just have access a developer that already pays this cost and lets us use their signing identity at no additional cost to either us or them. However, it is theoretically possible we could get this fee completely waived for us by applying for a non-profit fee waiver.[10] This would require Etterna to have a legal Non-Profit status, which might be much more work than the potential benefit it provides.

bluebandit21 commented 4 months ago

@jameskr97 Could I ask you to quickly double-check this hecking essay of an issue post for correctness? I believe everything I'm saying is correct and should be well-supported by the many citations I've included inline, but always good to have a second set of eyes :)

bluebandit21 commented 4 months ago

Note: I snapshotted all of the resources I link to on archive.org, so they should be available there if Apple takes down/moves random documentation pages as they like to do :)