Skip to content

Security

Flajt edited this page Mar 16, 2024 · 6 revisions

As security is paramount to this project I will explain my attempts to secure everything. All feedback from professionals is appreciated!

Note: While I'm trying my best to secure the project, no app/service can be 100% secure!

Device Integrity

Rooted or jailbroken devices prevent quite a challenge for app security. To prevent this from happening, the app uses AppCheck which is built on SafetyNet, AppAttest, and DeviceCeck (the first is for Android everything else for IOS).
The first time you use the app, the device attempts to get verified and use this verification to get an API key from the backend. If it fails, it won't get the key and in turn, wouldn't be able to sign things.

API access

Securing the API without accounts is quite challenging. This leads me to using API keys. The backend will generate API keys which are used to access the signature functionality of the app. Without it, you can't sign anything. To prevent hacking or leaking which would make the whole project useless, the key will be rotated every week. The checks for new keys happen at random (50% chance that the app will check for a new key). This is to prevent thousands of users from trying to get a new key at the same key and overwhelm the backend with requests. Due to the firebase appcheck limitation of 10.000 tokens a day, I thought that api keys scale better than sending a token for every request.

API Keys

The keys are stored on the device with the help of KeyChain and encrypted Shared preferences. For this, the flutter_secure_storage package is used. In the backend, the keys are stored via SCW Secret Manager

Firebase and Private Key

The firebase is stored in encrypted env variables. The private key is stored via the secret manager. Currently, I'm also considering rotating signature keys to prevent issues in case of a hack or leak.

E-Mail Encryption

If you add your E-Mail address to get the proof certificates, the app will "share" your E-Mail in the webhook URL, but encrypted.

This way I don't need to set up a DB, which keeps data collection and cost lower. To encrypt your E-Mail I've followed BSI recommendations (see section 2.1 and 2.2) Your E-Mail is encrypted via AES-GCM encryption. IVs change for every request and are randomized, as required.

Encryption happens server side, not client side, since that seems overkill as the data is sent securely via SSL and is additionally secured via SSL pinning, to prevent MITM attacks.

The email encryption keys are also stored in the secret manager and roate every week, one key is valid for two weeks (1 week for encrypting & decrypting, and 1 week for only decrypting).

Firebase Client Side

The firebase client is pinned to the app hashes to prevent unauthorized access, also the api access has been limited to appcheck only.

Threat Model

Decentproof Threat Model.pdf

Feedback appreciated

Note:

If you happen to know some nice resources that explain certain concepts mentioned here, please let me know! I want to make this section easy to understand for non-technical people as well.

Clone this wiki locally