You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We considered using Ionic Live Updates or Capgo for our app, but both are lacking a fundamental feature which makes us uncomfortable going ahead.
Said feature would be code signing1: we must ensure that whatever package is delivered to our users is authentic, and generated by us. Our app handles some pretty sensitive user data, and risking any kind of code injection would be reckless.
Arguably, Ionic Live Updates does offer this feature2, but only under the Enterprise plan and with self-hosting, but:
we're a startup, we can't afford "Contact us" pricing tiers; 🥲
we don't care about self-hosting, we just care about security. 🧐
We really liked Capgo in general, and it was pleasant and quick to integrate with it! However...
I saw something in the docs that made me do a double take. There's a mention of end-to-end encryption3, but after reading carefully docs and code, I'm not quite convinced this is the implementation we need.
This is what I understood:
the native app has access to a private key (either a default one, or one provided by the developer)4;
at build time, the ZIP archive is AES-encrypted and the symmetric key is encrypted with said RSA key;
the encrypted ZIP and key are shared with the apps along with the package;
the app downloads the encrypted ZIP and decrypts the key with the hardcoded RSA private key, with it it decrypts the zip, then installs it.
With said approach, I identified 2 flaws:
The package is encrypted with a private key that is publicly known: if it's the default one, it is here on GitHub4, and in any case, anyone who downloads the app may easily decompile it and obtain the key.
It follows that this encryption scheme does not provide origin authentication: anyone who has the RSA private key can recompute the public key, and therefore produce packages indistinguishable from genuine ones.
I may be missing something, but I can't quite understand the threat model for such an implementation. Assuming the requirement was to deliver some secrets to the target apps (which in my opinion should not be in the application code anyway, but I digress...), this still would provide no guarantee because of point 1. This would require device attestation or some other form of client authentication, to ensure deliver only to trusted clients...
Going back to our primary concern: whatever updates the app receive, they must originate from the developer.
Attackers may take control of the delivery server (or even just the domain name) and replace packages, and still the plugin must reject them in absence of a valid signature.
Our proposal would be to implement some form of asymmetric signatures in Capgo CLI, and verification in the plugin. Apps would have at least 1 public key to verify said signatures. Ideally, there should be a key revocation procedure, so that the plugin won't accept new updates from keys marked as compromised.
Key rotation may be considered superfluous in this scenario, since developers could always release a new native build through the app stores to distribute new public keys.
Most OTA update systems and package managers use some variation of code signing256 (including the app stores themselves78), I think it'd be wise to have something similar.
One should discuss carefully different key management options and tradeoffs. In the end, PKI is always the weak link in these implementations. But I think this could provide much more safety to developers and end-users.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi!
We considered using Ionic Live Updates or Capgo for our app, but both are lacking a fundamental feature which makes us uncomfortable going ahead.
Said feature would be code signing1: we must ensure that whatever package is delivered to our users is authentic, and generated by us. Our app handles some pretty sensitive user data, and risking any kind of code injection would be reckless.
Arguably, Ionic Live Updates does offer this feature2, but only under the Enterprise plan and with self-hosting, but:
We really liked Capgo in general, and it was pleasant and quick to integrate with it! However...
I saw something in the docs that made me do a double take. There's a mention of end-to-end encryption3, but after reading carefully docs and code, I'm not quite convinced this is the implementation we need.
This is what I understood:
With said approach, I identified 2 flaws:
I may be missing something, but I can't quite understand the threat model for such an implementation. Assuming the requirement was to deliver some secrets to the target apps (which in my opinion should not be in the application code anyway, but I digress...), this still would provide no guarantee because of point 1. This would require device attestation or some other form of client authentication, to ensure deliver only to trusted clients...
Going back to our primary concern: whatever updates the app receive, they must originate from the developer.
Attackers may take control of the delivery server (or even just the domain name) and replace packages, and still the plugin must reject them in absence of a valid signature.
Our proposal would be to implement some form of asymmetric signatures in Capgo CLI, and verification in the plugin. Apps would have at least 1 public key to verify said signatures. Ideally, there should be a key revocation procedure, so that the plugin won't accept new updates from keys marked as compromised.
Key rotation may be considered superfluous in this scenario, since developers could always release a new native build through the app stores to distribute new public keys.
Most OTA update systems and package managers use some variation of code signing2 5 6 (including the app stores themselves7 8), I think it'd be wise to have something similar.
One should discuss carefully different key management options and tradeoffs. In the end, PKI is always the weak link in these implementations. But I think this could provide much more safety to developers and end-users.
What do you think?
Cheers
Giorgio
Footnotes
https://en.wikipedia.org/wiki/Code_signing ↩
https://ionic.io/docs/appflow/deploy/setup/self-hosted#code-signing-generate-live-update-signing-keys ↩ ↩2
https://capgo.app/docs/tooling/cli/#end-to-end-encryption-trustless ↩
https://github.com/Cap-go/capacitor-updater/blob/fc722890806a667b25ffce1c3e053145181afbf0/android/src/main/java/ee/forgr/capacitor_updater/CapacitorUpdaterPlugin.java#L170 ↩ ↩2
https://docs.mender.io/artifact-creation/sign-and-verify ↩
https://wiki.debian.org/SecureApt ↩
https://developer.apple.com/support/code-signing ↩
https://developer.android.com/studio/publish/app-signing ↩
Beta Was this translation helpful? Give feedback.
All reactions