App Integrity
Learn how MōBrowser packages your application sources and verifies them at startup.
Packaging application sources
When you build the application, MōBrowser packs the compiled sources and assets of your application into a single app.bin file inside the application bundle. At runtime, the application reads its files from app.bin in memory.
app.bin is not encrypted. Any code shipped to the user’s machine can ultimately be read: the application has to turn it into plain JavaScript to run it, and a determined user can extract it from memory or reverse engineer the runtime. Encryption with a key shipped alongside the files wouldn’t prevent this, it would only look like it does.
Important: Don’t ship secrets such as API keys, credentials, or private keys with your application, and don’t rely on the packaging to hide proprietary logic. Keep sensitive data and logic on a server that your application calls.
What MōBrowser guarantees instead is integrity: a signed application refuses to start if app.bin has been modified after signing.
Integrity verification
Before loading any sources, the runtime verifies app.bin. The check depends on whether the application is code-signed and on the platform:
| Application | Verification |
|---|---|
| macOS, signed with a Developer ID Application certificate | The code signature of the bundle covers app.bin. |
| Windows, signed with an Authenticode certificate | A signed catalog covers app.bin. |
| macOS or Windows, not signed | A SHA-256 checksum detects corruption. |
| Linux | A SHA-256 checksum detects corruption. |
The runtime chooses the check from the executable it’s running, not from environment variables or files next to it. Nothing can switch a signed application to the weaker check.
macOSmacOS
When you sign the application with a Developer ID Application certificate, the signature seals every file in the bundle, including app.bin. No separate signature is needed.
At startup, the runtime validates the code signature of the bundle and checks the loaded app.bin against the seal. If app.bin or the signature has been modified, the application refuses to start.
An ad-hoc signature isn’t a production signature. The runtime treats an ad-hoc signed application as unsigned.
WindowsWindows
The app.bin file isn’t an executable, so it can’t carry an Authenticode signature itself. Instead, packaging creates the resources/app.bin.cat catalog with the SHA-256 hash of app.bin and signs it with the same signCommand as the application executable.
At startup, the runtime:
- Checks that the hash of the loaded
app.binmatches the catalog. - Verifies the Authenticode signatures of the catalog and the application executable, including certificate revocation.
- Checks that the catalog and the executable are signed with the same certificate.
If any check fails, or if a signed application has no catalog, the application refuses to start.
Revocation is checked against the certificate revocation data cached on the machine, so startup never waits for the network. When the machine has no cached data, the application starts, and only a certificate known to be revoked fails the check.
Linux and unsigned applicationsLinux
Linux has no platform code signing, and macOS and Windows applications may be built without signing. In these cases, app.bin ends with a SHA-256 checksum of its content, and the runtime verifies it at startup.
The checksum detects truncation, disk errors, and interrupted writes. It doesn’t protect against deliberate modification: anyone who edits app.bin can recompute the checksum.
What integrity verification protects against
To modify the sources of a signed application, an attacker has to remove its code signature. The modified application then no longer carries your Developer ID on macOS or your publisher identity on Windows, so the operating system and the user can tell that it’s not the application you released.
Integrity verification doesn’t:
- Prevent reading the application sources.
- Protect applications that aren’t signed.
- Protect against an attacker who controls the process at runtime, for example with a debugger.
Code signing is therefore what makes the integrity of your application verifiable. Sign every application you distribute on macOS and Windows.
Development builds
Applications run with npm run dev, or built without signing credentials, aren’t signed. They use the SHA-256 checksum, the same as on Linux, so you can build and run them locally without a certificate.
Unpacked resources
Some files must stay accessible on the file system at runtime. Put them in the resources directory of your project. Files in this directory:
- Are copied into the application bundle as-is and are not packed into
app.bin. - Remain accessible through the file system at runtime.
On macOS, the code signature of the bundle covers these files too. On Windows and Linux, the runtime doesn’t verify them.