Skip to content

Encryption key derivable from stored password hash — server operator can decrypt all data #63

Description

@salmon-21

Summary

The current encryption scheme derives the Fernet key directly from the argon2 password hash stored in the database:

hashed_password = user['password']
key = base64.urlsafe_b64encode(hashed_password.encode("utf-8").ljust(32)[:32])
fernet = Fernet(key)

Since the password hash is stored server-side, anyone with database access (including the server operator of a public instance) can decrypt all user health data. The encryption effectively only protects against partial DB leaks where the users collection is not exposed.

Suggested approach

Move to client-side encryption (E2E) where the encryption key is derived on the device and never sent to the server. The server would only store and return opaque encrypted blobs.

This would require changes to both the API (/sync, /fetch) and the client app.

Impact

This primarily affects users of public instances who trust the server operator with their credentials but may not expect their health data to be readable by the operator.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions