Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Enhancement] Encrypt signaling and the possibility to mark devices as verified #180

Open
schlagmichdoch opened this issue Oct 18, 2023 · 6 comments
Labels
enhancement New feature or request security

Comments

@schlagmichdoch
Copy link
Owner

schlagmichdoch commented Oct 18, 2023

What problem is solved by the new feature
MITM. Make PairDrop zero trust if code integrity can be insured (dedicated clients, Browser extensions or local running PairDrop in client mode).

Describe the feature

The security number should be more present when sending files by adding it to the receive dialog to increase its usage. (We could use a two to three word phrase instead to make it easier. Would this be confusing?).

First idea

To make sure this is only needed once for paired devices, part of the pairing should be a verification of the security number.

  1. For each new peer a private public key pair should be generated
  2. The public keys are exchanged via signaling server
  3. The security number is built by these public keys instead of the webrtc fingerprints
  4. For paired peers, these keys are saved alongside the pair secret in the indexeddb.
  5. All signaled/relayed messages e.g. localDescription/remoteDescription with a paired peer will be encrypted with its public key

This will ensure connections with paired devices are always secure.

Verifications can always be done via a dialog and the security number or a QR code consisting of the current peer id and its public key.
Verified clients could get a mark next to the security number.

Another possibility:

There is only one key pair per device so the public key sent to peers never changes. (This makes the device identifiable by peers and server though)
Public keys of clients get saved to DB as trusted keys whenever a verification is done. When a peer connects and its public key is signaled we can check whether it is a trusted key and show checkmark. So the verification would be independent of the pairing.

This makes only sense when the client files are not fetched but stationary aka client to be developed and client files downloaded via Releases on GitHub, on App Store or a solution with self hosted client.

Additional context
See https://github.com/saljam/webwormhole as reference

@schlagmichdoch schlagmichdoch added the enhancement New feature or request label Oct 18, 2023
@schlagmichdoch
Copy link
Owner Author

This makes only sense when the client files are not fetched but stationary aka client to be developed and client files downloaded via Releases on GitHub, on App Store or a solution with self hosted client.

  • You can host your own files via the soon to be released version v1.10.0
  • Additionally, we could provide a version via browser extensions

Verifications can always be done via a dialog and the security number or a QR code consisting of the current peer id and its public key.

This could also be automatically triggered after a device is paired. Then, the security number could also be shown as PGP phrases apron-cedar-baton. Numbers are much more international though as not everyone understands English.

@schlagmichdoch
Copy link
Owner Author

This private-public key pair should also be used to encrypt the traffic relayed via the websocket fallback

@schlagmichdoch
Copy link
Owner Author

Maybe it would also be okay to show the verification screen whenever a transfer request / message is sent for the first time between two devices. After the approval on both devices that they are seeing the same security number, the transfer request / message is sent as expected and the devices are never bothered with the verification screen again.

When using the QR-codes, the verification could be done automatically by adding an additional secret to the QR code that ensures the connection is safe.

Idea:

  • Pair Host (H) adds the public key (key_H) base64 encoded to the QR code URL hash
  • Pair Client (C) scans the QR-Code which opens the URL (URL hashes are not sent to the server)
  • C decodes hash and saves the decoded key_H
  • Key exchange
    • there is a flag to indicate that the payload is encrypted
    • H sends key_H unencrypted to C over the signaling server
    • C compares key_H with the key_H it scanned
    • C encrypts it’s own public key (key_C) with key_H
    • C sends the encrypted key_C to H over the server
  • other possibility:
    • C encrypts it’s own public key (key_C) with key_H
    • C sends the encrypted key_C to H over the server (encrypted payload flag set to true)
    • H can decrypt key_C so it knows that the connection is secure
    • H encrypts key_H with key_C and sends it to C

Idea2:

  • much easier
  • Hash is simply a strong key that now both devices know
  • The key exchange is encrypted by using this key to symmetrically encrypt payloads

@schlagmichdoch
Copy link
Owner Author

Verification should not be enforced but possible via simple UI. I guess it would be enough if you could verify the security number at any time.

Currently, I’d prefer an implementation similar to Signal:
IMG_6354

By using the QR code for pairing, the devices could directly be marked as verified by using Idea2 explained above.

@schlagmichdoch
Copy link
Owner Author

schlagmichdoch commented Feb 15, 2024

Summary of the ideas above

Each user creates a public/private key pair which is permanent.

Before exchanging their display names, peers exchange their public keys and fulfill a handshake by encrypting the signaling communication with these public keys.

When using the websocket fallback, all communication is encrypted with the public key.

New peers get a small button verify bellow them.
The verify button opens a verification dialog similar to Signal.
The security number shown is created by combining the public keys of both peers sorted and creating a 60 byte/character hash.

A button Mark as verified saves the currently used public key of the peer to a list of trusted public keys.

Whenever a peer connects with a public key in the trusted keys list, bellow the peer we add a label like verified ✅ (similar to Twitter accounts maybe).
Clicking this label opens the verification dialog again with the possibility to remove the public key from the trusted keys.

Comparing security numbers can also be done via a QR code. For this, clicking the QR code might show a built-in QR code scanner (#265). This shows a success dialog: marking it as verified must be always be done manually! Hence, there should be no mechanism to automatically verify devices when paired via QR code, as this might be confusing to users. If the comparison fails, the key should be marked as unverified.

The security number should not be part of any link. Copying it should only copy the number itself.

Afterwords, detection of peers on the same browser is as simple as detecting if a both peers of a connection have the same public key.

Also, the peer secret should be saved additionally alongside the public key as well. If the peer secret does not match the public key -> Do not connect / update roomIds

@schlagmichdoch schlagmichdoch changed the title [Enhancement] Encrypt sdp exchange for paired devices to add zero trust once verified [Enhancement] Encrypt signaling and the possibility to mark devices as verified (makes PairDrop zero trust) Feb 15, 2024
@schlagmichdoch schlagmichdoch changed the title [Enhancement] Encrypt signaling and the possibility to mark devices as verified (makes PairDrop zero trust) [Enhancement] Encrypt signaling and the possibility to mark devices as verified Feb 22, 2024
@schlagmichdoch
Copy link
Owner Author

schlagmichdoch commented Jun 6, 2024

Implementing this only adds zero trust to the signaling server if the client code can be trusted.
It does not add zero trust to the web version of PairDrop as we need to trust the server that the code it serves is not malicious.

Note

Add a note on page or on FAQ: „You need to trust this URL/server. To increase security use the official native apps or browser extensions.“

No trust of web version

Verifying a peer using the mobile version would falsely indicate that it can be trusted completely.

As we do not know anything about the code our peer uses, we should not trust it. Probably, this verification feature should only be available on the native apps.

Clients that use the web version of PairDrop should have a web client label in place of the verification button / label:
web client ( i )

Then all peers would have one of these three labels:

  • web client ( i )(grayish) - click explains: „It is not possible to verify web clients as you need to always trust the server. Use the official native apps or browser extensions to increase security.“
  • verify (grayish)
  • verified ✔️ (greenish)

On the verify screen there should be a note:
„Always ensure that official native apps or browser extensions are used only.“

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request security
Projects
None yet
Development

No branches or pull requests

1 participant