Code Monkey home page Code Monkey logo

Comments (34)

jmattheis avatar jmattheis commented on May 22, 2024 4

Okay, implementing this feature may require some effort and changes how clients view messages. So let's wait till more users want this feature to decide whether to implement it or not.

from server.

Leopere avatar Leopere commented on May 22, 2024 3

Realistically at this point, if you don't trust your own TLS certificates and your own push notify hosts you should really rethink your security strategy. TLS already implements forward secrecy and GoLang is a really efficient language that cross compiles relatively easily so if you want you could run a Gotify server on a Raspberry PI you plug in at home if you don't trust anyone else with your server.

Most of the tools are available having End to End encryption would be nice but at that point, you might as well bake your own Signal Protocol equipped messaging app and just remove anything that allows the individuals to send messages in and just have one sender being the server itself or even have sender specific clients that can't receive.

Don't get me wrong I'm very much interested in this feature but as @jmattheis mentioned in their latest post its probably just too time consuming to add to this and might make sense for an entirely different app to be born.

from server.

mwild1 avatar mwild1 commented on May 22, 2024 1

I'm going to put in a contrary opinion... I don't think E2E is within the scope of a simple application like this. I already have an XMPP client with E2E, you mentioned Matrix too. Just send your notifications over these instead if your data is sensitive and you are so worried about interception by the server. Otherwise gotify would be essentially just recreating them.

from server.

jmattheis avatar jmattheis commented on May 22, 2024 1

Currently nothing. I'd say that the development costs for this feature outrange the current need for it.

from server.

jmattheis avatar jmattheis commented on May 22, 2024

Hey @iamtpage
what do you exactly mean with end2end encryption, with SSL the communication should already be secure. Do you mean, that the messages shouldn't be stored in plain text in the database on server side?

from server.

fbartels avatar fbartels commented on May 22, 2024

Yes, that is was e2e usually refers to. In addition only the user should be able to decrypt the message.

from server.

flamechair avatar flamechair commented on May 22, 2024

I'd like to see D@RE on server and client, so if server/client is compromised (phone is lost/stolen, malware on server, etc) then the contents of the notifications are not.

Implementation wise this would be a PSK that encrypts data on server, transmits message to client(s), clients decrypt message locally via the PSK

from server.

jmattheis avatar jmattheis commented on May 22, 2024

So the client still sends plain-text notifications but the server encrypts the messages before storing them. Yeah that could work.

from server.

flamechair avatar flamechair commented on May 22, 2024

Technically to be true E2E the client would have to encrypt messages locally before sending them to the server. I'd settle for encrypted at rest messages on the server, otherwise I'd have to build encryption into the notification scripts I build and that can get hairy. I'm open to other possibilities if anyone has a better idea.

from server.

Leopere avatar Leopere commented on May 22, 2024

End to End encryption generally requires some degree of sender client. Not the worst idea but its definitely something that would be required unless you just wanted to tell people to use GPG or something weird.

from server.

 avatar commented on May 22, 2024

Suggest looking into
tweetNACL
NATS nkeys uses it
Secret is stored on each device.
Provisioning key has to happen out of bound. Typically a QR code displayed and user scans it with camera. Like whats app a bit.

from server.

 avatar commented on May 22, 2024

I'd use this feature.

+1 for @gedw99's suggestion.

from server.

geeseven avatar geeseven commented on May 22, 2024

Android's notification log seems to be problematic for end to end encryption. I know that Signal's Android application offers a few different options to limit what information gets logged. The only way to ensure that no information is logged is to completely disable notifications. This might be acceptable for a secure messaging application where notifications could be seen as an optional feature.

Personally, I view gotify as a notification application so completely disabling notifications is useless. Limiting the information in a notification and have a user check an application and/or website seems like a reasonable compromise for some.

I am curious on what others think about end to end encryption being an option or should it enforced if we go that route. Also curious if end to end encryption should be used within a browser.

Note, I do not know all that much about the inner workings of Android's notification log, so please feel free to educate me. Now that I think about it, I am not sure how all the different browsers log notifications.

from server.

flamechair avatar flamechair commented on May 22, 2024

@geeseven The E2E would be more to ensure the security of the message/notification in transit from server to client, not for the security of the message once it's delivered. Once it's delivered the responsibility would be on the user to have only trusted apps installed.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

I think when we are talking about E2E we are talking about:

  • Keeping the plaintext unaccessible by the server(gotify) and other adversaries, but only accessible to the sender(applications) and receiver(clients)
  • Verification of the authenticity of the message source(applications)

These are not related to E2E:

  • How client applications could keep the received and decrypted message in a secure place
  • How the server(gotify) stores information

Routine description

An implementation of E2E in gotify with forward secrecy might look like this(with Ed25519 for identity key, ECDHE for key exchange, AES in GCM cipher for symmetric encryption):

  1. The first client need to share a secret(referred to as pre-shared secret token) with the application in a secure channel(SSH, etc.), or manually verifiy the signature of the received identity key at the last of the initialization sequence.
  2. The first client generates its own ed25519 identity key pair, HMAC the public part with the pre-shared secret token and publishes both the public part and the HMAC on the gotify server.
  3. The application generates its own ed25519 identity key pair, HMAC the public part with the pre-shared secret token and publishes both the public part and the HMAC on the gotify server.
  4. Both the client and application downloads each other's identity key, verifies the HMAC with the pre-shared secret token and the initial identity key exchange is complete.

And when sending messages:

On the sending routine:

  1. Prior to the message is sent, the receiver(client) generates a X25519 key pair(referred to as receiver ephermal key), signs the public part with its identity key and publishes both the public part and the signature on gotify server for ECDHE. (This process is known as pre-keying).
  2. One the message is generated, the sender(application) generates a X25519 key pair(referred to as sender ephemeral key), signs the public part with its identity key. Then, the sender randomly generates a symmetric key(referred to as message key) to encrypt the message body with an AEAD cipher(eg. AES in GCM mode). Then, the sender claims an ephemeral key on each trusted client from gotify server, verifies the signature on the ephemeral key to make sure that it is generated by the holder of the receiver identity key, calculates a ECDHE shared secret with the public part of the receiver ephemeral key and the private part of the sender ephemeral key. The sender encrypts the message key with the hash of each of the ECDHE shared secret. Eventually, the sender sends: (I) The message ciphertext (II) The public part of the sender ephemeral key and the signature (III) Each of the client's ephemeral key the message key is encrypted against, together with the encrypted message key. eg the final message object might look like this:
{
    "encrypted_message":"<base64_encoded_message_ciphertext>",
    "sender_ephemeral":{
        "key":"<base64_encoded_sender_ephemeral_key>",
        "signaure":"<base64_encoded_signature_of_the_sender_ephemeral_key>"
    },
    "message_key":[
        {
            "receiver_ephemeral":"<base64_encoded_receiver_ephemeral_key>",
            "key":"<base64_encoded_message_key_encrypted_with_ecdhe_secret>"
        },
        {
            "receiver_ephemeral":"<base64_encoded_receiver_ephemeral_key>",
            "key":"<base64_encoded_message_key_encrypted_with_ecdhe_secret>"
        },
        {
            "receiver_ephemeral":"<base64_encoded_receiver_ephemeral_key>",
            "key":"<base64_encoded_message_key_encrypted_with_ecdhe_secret>"
        }
    ]
}

On the receiving routine:

Since I think we need to keep the body size sent to the client as small as possible, gotify server looks up its database on which client owns the corresponding ephemeral key, and sends just enough information for it to decrypt and verify the message, eg the message sent to the client over WebSocket might look like this:

{
    "encrypted_message":"<base64_encoded_message_ciphertext>",
    "sender_ephemeral":{
        "key":"<base64_encoded_sender_ephemeral_key>",
        "signature":"<base64_encoded_signature_of_the_sender_ephemeral_key>"
    },
    "receiver_ephemeral":"<base64_encoded_receiver_ephemeral_key>",
    "message_key":"<message_key_encrypted_with_ecdhe_secret>"
}

The client does the following:

  1. Verifies the sender ephermal key against the signature to make sure that the sender ephermal key is held by the application itself
  2. Recalls the private part of the receiver ephermal key from a trustable source(eg: memory, local database, etc.)
  3. Calculates the ECDHE secret with the private part of the receiver ephermal key and the public part of the sender ephermal key
  4. Calculates the message decryption key with hash of the ECDHE secret
  5. Decrypts the encrypted message

Special Occasions

This routine would be smooth in a normal operating condition. However, we need to deal with special ones:

Client offline

To guarantee message delivery when the client is offline, the client should always pre-key a certain amount of ephemeral keys on the gotify server. Moreover, To guarantee forward secrecy, the ephemeral key should only be used once(eg. Clients might not accept more than one messages encrypted with the same ephemeral key; However in this case if the ephemeral key pool is empty, there will be no way for applications to send more messages with forward secrecy. If we want to balance deliverability and security, we might allow gotify server to send used ephemeral keys if the ephemeral key pool is starving. However, the client would issue a warning to these messages which used obsolete ephemeral keys, which does not provide forward secrecy, and also might be the result of a replay attack)

Dynamically adding and removing client devices

The application need to keep a list of known trusted clients by syncing a list of known public identity keys of clients with the gotify server. Maybe we can take the implementation by Matrix as a reference

The trust of additional clients could be obtained by either of:

  • Manually sharing the secret and running the initialization sequence again
  • Have a trusted device sign the new device's identity key and send it to the server identity key storage with the signature

What needs implementing

In short, the gotify server would need to implement:

  • An identify key storage, capable of storing identity keys corresponding to each application/client and signatures on them. Authenticated endpoints can query identity keys by client/application ID.
  • An ephemeral key pool, capable of storing and rotating ephemeral keys from clients. Applications can claim ephemeral keys by client ID.
  • Device key update notification. The server should notify applications on newly added keys(eg: rejecting a message by asking the application to query and verify on new identity keys before sending the message again)
  • Compression(optional), to minimize the body size sent to the client, the server should discard other receiver's ephemeral keys when sending messages to the client.
  • Filtering(optional), on the occasion of an active DDOS attack, the gotify server could choose to stand in front of clients by verifying the ephemeral key signature before forwarding them to the client.

The application/client would need to implement:

  • Identity key generation, publishing, and verification
  • Verifying signed ephemeral keys and signing ephemeral keys
  • Ephemeral key storage. The storage would need to persist between sessions and restarts, otherwise, there would be no way for clients to decrypt messages that were sent with the ephemeral keys whose private part have been lost.

Others

As for whether to enforce E2E by @geeseven my opinion is no. E2E is mainly designed to keep your message secure from an untrusted central server(e.g. a gotify server hosted on a VPS, etc.) Maintaining trust of device keys and application keys is really exhausting, plus newly added device would be unable to decrypt previous messages due to forward secrecy. Moreover, in some cases where the client is less safe than the gotify server itself, E2E can't provide you much security ( I think a gotify server running on a raspberry Pi that is safely locked in my home is much more secure than my phone which is carried to all kinds of places and running a lot of unknown softwares). TLS is enough in this case. Of course, you could choose to let clients only accept E2E encrypted messages, but I don't think it should be enforced by the gotify communication protocol.

As for encrypted database storage, I cannot think of something the messages could be encrypted against. As long as you could obtain a copy of the configuration and the database, there is nothing to prevent an adversary from running a copy of the same gotify instance, authenticate itself and inspect on the message in plain text. So I don't think this would provide extra security.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

The identity key storage API might look like this:

Add a new key or update existing key

POST /identities/:userName/:clientOrAppID?token=<access_token_corresponding_to_this_user>
{"key": "<base64_encoded_public_identity_key>"}

returns:
{"holder": "<client_or_app_ID>", "key": "<base64_encoded_public_identity_key>", "certifications":[]}

Delete keys

DELETE /identities/:userName/:clientOrAppID?token=<access_token_corresponding_to_this_user>

returns:
{"success": true}

Make a certification. The alg field denotes how the key can be verified. It can be verified by either with a shared secret as a root of trust, or signed by another already trusted ed25519 key. For example you can use a trusted device to scan a QR denoting the new identity on a new device. Then the trusted device could POST to this endpoint to add its signature on the new key.

POST /identities/:userName/:clientOrAppID/certify?token=<any_valid_access_token>
{
    "alg":"hmac_sha256_with_preshared_secret",
    "sign":"<hmac_sha256_digest>"
}

returns:
{
    "holder":"<client_or_app_ID>",
    "key":"<base64_encoded_public_identity_key>",
    "certifications":[
        {
            "alg":"hmac_sha256_with_preshared_secret",
            "sign":"<hmac_sha256_digest>"
        }
    ]
}

Query keys for a user, build trust chain by starting from root trust and verifying along the signature chain

GET /identities/:userName?token=<any_valid_access_token>&skipNoCertification=true

returns:
[
    {
        "holder":"app0",
        "key":"<base64_encoded_public_identity_key>",
        "certifications":[
            {
                "alg":"hmac_sha256_with_preshared_secret",
                "sign":"<hmac_sha256_digest>"
            }
        ]
    },
    {
        "holder":"client0",
        "key":"<base64_encoded_public_identity_key>",
        "certifications":[
            {
                "alg":"hmac_sha256_with_preshared_secret",
                "sign":"<hmac_sha256_digest>"
            }
        ]
    },
    {
        "holder":"client1",
        "key":"<base64_encoded_public_identity_key>",
        "certifications":[
            {
                "alg":"ed25519_signature",
                "sign":"<signer_public_identity_key_from_another_client_or_app>:<key_signature>"
            }
        ]
    }
]

And for the ephmeral key:

pre-keying:

POST /ephmeral/:clientID?token=<client_access_token>
[
    {
        "key":"<base64_encoded_ephmeral_key>",
        "sign":"signature_of_ephmeral_key"
    },
    {
        "key":"<base64_encoded_ephmeral_key>",
        "sign":"<signature_of_ephmeral_key>"
    }
]

returns:
{"success": true, "pool": <remaining_epheral_keys>}

clearing(when the client lost its local ephmeral key storage):

DELETE /ephmeral/:clientID/*ephmeralKeyHash?token=<client_access_token>

returns:
{"success": true, "pool": 0}

claiming:

GET /ephmeral/:clientID?token=<any_app_access_token>

return:
{
    "identity_key":"<base64_encoded_identity_key>",
    "key":"<base64_encoded_ephmeral_key>",
    "sign":"<signature_of_ephmeral_key>"
}

from server.

jmattheis avatar jmattheis commented on May 22, 2024

@eternal-flame-AD Thanks for that detailed proposal.

I intended Gotify to be as simple as possible, with e2e encryption like this, sending a messages without any cli would be nearly impossible. Sure e2e could be optional it would still greatly increase the code complexity of both gotify/server and all clients.

Here is a different implementation using PGP, remember: I'm an encryption noob.

Gotify could derive two distinct passwords from the original user password. One for authentication to Gotify and one for the private PGP key.

For easy usage gotify/server would distribute both public and private key. Clients/applications should request a confirmation from the user that the key is correct and then cache the key.

Clients use the public PGP key to encrypt the message and then send it to gotify/server. When clients send a plaintext message, gotify/server will encrypt the message.

New api's:

  • GET /current/user/pgp/public returns the public pgp key
  • GET /current/user/pgp/private returns the private pgp key (requires client authentication)
  • POST /message/encrypted sends a encrypted message to gotify/server

When an evil hacker has access to the server hosting gotify/server, he has access to the private key but not the passphrase and therefore cannot read the messages. (he can read not encrypted messages)

It would be possible to show a fake web-ui and obtain the original user password. I don't see any way to protect against that as gotify/server provides the web-ui.

I understand that this approach wouldn't be as security as @eternal-flame-AD solution but it would be a lot simpler to implement and use.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

First I need to clarify some words I used in the later text to prevent misunderstandings:

  • Gotify denotes the gotify server process
  • User denotes a user on gotify, which controls a group of applications and clients authenticated by access token.
  • User password denotes the username/password used to generate access tokens.
  • User authentication denotes the authentication with username/password
  • Application denotes notification sender
  • Client denotes notification receiver

First I might need to make an important point: What is the root difference between the current authentication scheme and an additional layer of E2E authentication? Sorry I am not very good at explaining things to others, if my words sound ambiguous maybe this Wikipedia article would be helpful. In short, messages are encrypted to so-called "end-points"(in the gotify context it means a particular application and a particular client, not a generalized one like user)

In the current scheme, both applications and clients possess an access token, with the access token obtained by authenticating with user passwd and being protected by transport layer security, denotes that those possesses access tokens are authentic endpoints from an user. In short, messages are protected against those who can not be authenticated as the user, if the user authentication method (currently user password) is compromised, the whole security collapses.

In a E2E scheme, in addition to the user authentication mentioned above, each application and client possesses their own signing key, which certificates that this message is sent by App0, who trusts Client0 and Client1, but not other clients even if they possesses access tokens. In short, messages are protected against those who can not be authenticated as a verified recipient(client in the gotify context), even if the user authentication method is compromised, the application would refuse to send messages to the newly added clients as long as they are not verified.

PGP proposal

As for the PGP one you proposed I have to point out some potential risks:

For easy usage gotify/server would distribute both public and private key. Clients/applications should request a confirmation from the user that the key is correct and then cache the key.

When we are talking about E2E we are generally talking about the central server is NEVER trusted. Also keep in mind that confirming the key signature only indicates that both the client and application possesses this key. It does not prevent the server from keeping a copy of the plain private key which can be used to eavesdrop communication. In your context, try replacing "public and private key" with "access token", both generated issued by the server, both with a trust anchor on user authentication. Then you would find out that it is only as secure as the current implementation(with an encryption on database storage of course).

Gotify could derive two distinct passwords from the original user password ... one for the private PGP key. ... GET /current/user/pgp/private returns the private pgp key (requires client authentication)

I guess you meant client/server authentication token here? User passwords are shared among clients.

This would definitely render the whole E2E encryption useless. In other words, who possesses the authentication token would be able to obtain the private key. If:

  • the authentication token is stored in plain(as is for now) on the gotify server, any adversary who has control over the server or the database would be able to decrypt the PGP private key
  • the authentication token is stored with bcrypt, etc. on the gotify server, the adversary would need to listen for an authenticated request from the server, obtain the token and decrypt the PGP private key.

In both occasions, for an active attacker all he needes to do is obtain the access token and all "end-to-end encrypted" messages would be able to be read, he could also fake new requests.

It would be possible to show a fake web-ui and obtain the original user password. I don't see any way to protect against that as gotify/server provides the web-ui.

This is indeed a problem, similar to the android notification thing, which is about how to prevent the client from telling secret to others. I think they could be talked about later after the main scheme on the E2E thing is settled. We are actually talking about a scnario similar to a compromised client here. However, with forward secrecy, as long as the ephemeral keys are safely destroyed after use, nobody would be able to decrypt past sessions again.

There are also some additional setbacks on the PGP one:

  • No forward secrecy, in short, in the event of the PGP private key is stolen, all past messages would be decryptable.
  • There is nothing to prevent App0 from sending a message as App1, as long as it can pass the user authentication.

Full E2E proposal

I agree that the proposal is a big task and it would take quite an amount of work to complete, but I think the task could be split into rather simpler tasks clearly(see What needs implementing) and implemented one by one. I wrote the whole process and wished to start from scratch because current E2E implementations are generally designed for two-way multi-peer communications(such as webchat), which are really reavy-duty and unncessasary to be brought in whole onto gotify. I know it sounded really complex but I think it does not require much extra user interaction as you thought it would be. I think the mandatory extra user interactions are:

  • On initialization, verify the key signature or share a secret between applications and clients(same as your PGP implementation)
  • On new client/application added, verify the signature or use another trusted device to cross-sign the new device's key(by scanning a QR on the new device with the trusted device, etc.)
    And that's all :) I don't think require much of some complex cli thing, etc.

If are interested in making it happen, I could provide a minimal example that demostrates how this works maybe next week.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

If you wish to explore on what E2E provides and looks like in action. I highly recommend trying out Matrix. They have an open API and clearly demonstrated the key verification process between endpoints.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

Actually I also partially agree with you that this is not a very important feature, but it seemed that this issue received a lot of support. If this is really wanted by a lot of users than we might add this feature. Generally speaking, we are choosing between the two:

  • Encrypt messages that is stored to the database on a user level, which is undecryptable only using the information available on the server. I did not think much about the details on how to implement this currently but I think it definitely added an extra layer of security and resolves a lot of security concerns on messages stored in plain text.
  • Implement a full E2E protocol

from server.

jmattheis avatar jmattheis commented on May 22, 2024

Also keep in mind that confirming the key signature only indicates that both the client and application possesses this key. It does not prevent the server from keeping a copy of the plain private key which can be used to eavesdrop communication.

The server should never obtain the plain private key. It only has access to the private key protected by the passphrase.
image

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

I think I got what you meant here. The required user interaction would be:

  • verify the recipient key signature from the application perspective each time a new application is added

And this would implement

  • a proper encryption on server storage
  • messages encrypted on a user level

This would NOT implement

  • forward secrecy
  • end-to-end encryption
  • authenticity verification of message source(since the message is not signed and the public key is public), to deal with this applications should have their PGP keys as well and it would users to verify it each time a new client is added.

In general if we settled on not implementing E2E then this is a good point where we could start from on server storage encryption.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

This is my evaluation on the three implementations we have talked about by now. I prefer the second or the third one.

Implementation Privacy Authentication Integrity Forward Secrecy User-Interaction Code Complexity Extra API
Client-Only PGP User-Level No Yes No + + +
PGP on both sides User-Level User-Level Yes No ++ ++ ++
Full E2E Device-Level Device-Level Yes Yes ++ +++ +++

User-Level denotes that the key is shared between applications AND/OR clients. Thus messages could be only verified as sent by a certain user and encrypted to a certain user.
Device-Level denotes that the key is not shared between different applications and different clients. Thus, messages could be signed as a certain application and encrypted to certain verified clients.

from server.

jmattheis avatar jmattheis commented on May 22, 2024

Could you clarify what you mean with client-only PGP and PGP on both sides?

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

In the client only mode, there is only one PGP key in the system(actually we can use symmetric cipher instead in this case), the public key is open and the private key is shared among clients. Application sends encrypted but not signed messages to clients. Thus, each time a new application is added, user need to make sure that it received the correct public key.
On the both sides mode, in addition to the key on the client side(referred to as client key), application also derives user password in another way and share their own pgp key(referred to as application key), applications send encrypted and signed message to clients. In this case, verification would be needed whenever a client or application is added.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

New thoughts: actually in your case I think a simpler solution is just to use the derived user password which is kept secret from the server as a symmetric key and I think that provides just as much security as your implementation.

Also I thought it would be complex to keep the key in consistent among endpoints by switching the encryption key smoothly while not losing old messages during a password change. I think this might add extra complexity to your solution. New clients would be unable to be added until old clients in possession of the private key upload the private key encrypted with the new password on the server. More dangerously, in a worst case scenario, due to user(either human or coding) error, the user password is changed but nobody in possession of the private key is notified of the password change(they have their own access tokens so they might not be aware of this, maybe they are all offline so server can't tell them that someone changed the password). If all devices in possession of the private key logged out before at least one device notices the password change and sends the newly encrypted private key to the server(server is not aware of this as it cannot be sure if the encrypted version of the pgp key is encrypted with the old key or the new key), next time they login they would have no way to use a single password to both authenticate with the server and decrypt the message key. This is not a non-recoverable error but is indeed annoying.

from server.

jmattheis avatar jmattheis commented on May 22, 2024

Alright, thanks for the clarification. I would say, we wait some time till we have feedback for the given proposals.

from server.

sik0vny avatar sik0vny commented on May 22, 2024

I'm voting for implementing E2E.
If a user will not host Gotify server himself ( for example his friend will host it for him, or he will run it on VPS) - E2E is the must. We don't want our precious data to by going unencrypted through some server we don't have control of.

from server.

buckket avatar buckket commented on May 22, 2024

Web Push seems like a technology that solves a very similar to problem to what Gotify is trying to do and has E2E encryption built in. Specifically I’m talking about RFC8291 and RFC8188. They describe the encryption process (ECDH, HKDF and aes128gcm) and how to transmit the encrypted payload via HTTP.

With slight adjustments this scheme could be mapped to Gotify’s needs while reusing a great deal of the underlying technology. There are quite few libraries out there already which handle encryption/decryption.

Bonus: One might even think about supporting Web Push altogether so that existing applications can use Gotify without additional middleware. For example Mastodon allows to set custom Web Push endpoints. Right now I had to write a small script which decrypts the messages before relaying them to my Gotify server in plaintext.

from server.

eternal-flame-AD avatar eternal-flame-AD commented on May 22, 2024

@buckket Thanks for the info, but we would need to make some fundamental changes to support the key exchange problem, and it is in some ways not conforming with the design goal of gotify: just a simple push messaging system. This feature is still in consideration.

from server.

hpmueller1971 avatar hpmueller1971 commented on May 22, 2024

@eternal-flame-AD Why not use the approach that irssinotifier uses, you (the sender) pre-encrypt all data (Title, Channel, Text) with a static key in openssl:

my $pid = open2 my $out, my $in, qw(openssl enc -aes-128-cbc -salt -base64 -md md5 -A -pass stdin);

then you send that encrypted string to the server (which in case of irssinotifier runs on google-appengine). On the android-client, you then have to manually enter the same key. You dont need a complicated software and keymanagement to send notifications, just openssl...

But considering, that gotify is intended to be self-hosted, i would rather suggest to add an option to do some sort of certificate- or CA-pinning in the android-client, an evil ssl-breaker with a govt-owned-ca-certificate would be the only real practical way to decrypt our very important messages ;)

Edit: Duh, now i feel stupid, CA-pinning is already supported ;)

from server.

sik0vny avatar sik0vny commented on May 22, 2024

So what is happening with this subject?

from server.

niwla23 avatar niwla23 commented on May 22, 2024

+1 for this feature

from server.

Leopere avatar Leopere commented on May 22, 2024

I am not against this, but devil's advocate. Would it even make sense to protect secrets from your servers? This is a self-hostable service. You don't have to trust others with the server, so isn't TLS already forward secret already, at least making any of this stuff kind of extra? It's a fantastic idea, but implementation isn't trivial, and poorly implemented crypto is typically worse than no crypto at all. If you imply there's E2E on something and need help understanding how it's working, you might make bad decisions and create new security holes. I argue that E2E granted it be something I would always prefer to have personally as I don't think that central servers ever really need the ability to be transparent to any onlookers is necessary.

tl;dr

Pro's of e2e:

  • increased privacy and fewer things to be subpoenaed for
  • increased security in sensitive scenarios, possibly enabling privacy compliance for projects

Con's of e2e:

  • Gotify would end up scope creeping from a relay/push system into the realm of signal security, where it gets harder to manage.
  • increased complexity/technical debt
  • typically more challenging to maintain correctly
  • challenging to conceptualize, let alone implement (can risk increasing the chances of leaking actually sensitive information through poor configuration)
  • if you imply there's increased privacy without actually knowing the implementation rigorously and having a focus on its upstream, you basically risk assuming responsibility for keeping people's secrets safe, and some secrets are better delivered "by the professionals."

from server.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.