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

Expire QR Codes #5126

Open
Hocuri opened this issue Dec 22, 2023 · 20 comments
Open

Expire QR Codes #5126

Hocuri opened this issue Dec 22, 2023 · 20 comments

Comments

@Hocuri
Copy link
Collaborator

Hocuri commented Dec 22, 2023

Context

https://securejoin.readthedocs.io/en/latest/ explains the current protocol and the considerations that led to it. Delta Chat doesn't actually implement expiry yet, which this issue is about.

Motivation

  • prevent-online-leak

    The first attempt at prevent-online-leak [POSTPONED] Sketch (just TODO comments) for prevent-online-leak #4932 turned out to be quite hard to get right usability-wise, esp. concerning groups:

    This rises an UI question in case of someone trying to join the group using expired QR code. In Zoom users who are invited but not yet approved end up in some sort of lobby. If we open a new contact request when someone tries to join old group and ask to approve, user has no context to decide why they should approve the contact. Implementing approvals for joining the group is better, but would require UI changes on all platforms.

  • Usable-security-wise, it will give green checkmarks a clear meaning without any exceptions (like, it's guaranteed that there is no MitM EXCEPT if you published your QR code on your website, or you shared a greencheckmarked-group-invite in a large group, or any of the people that are in greencheckmarked groups with you did one of these things)

  • Finally, this would bring us closer to the securejoin spec.

Details

  • Bob should still get a one-directional verification if he already knows Alice's key.
  • In order to warn Bob that the QR code is expired, we need to add a new parameter to the QR code. This is possible in a backwards-compatible way.
  • We need to pick a date when all the existing QR codes without an expiry expire.
  • QR codes for bots should not expire (if that's hard to do technically, set the expiry date to something very far in the future for them).
  • QR codes contain 2 tokens today: INVITENUMBER and AUTH. When Alice receives the INVITENUMBER, she automatically replies with her public key. When Alice receives the AUTH (in an encrypted subsequent message), she marks Bob's public key as verified.
    We can select separate expiration intervals for them, e.g. 10 minutes or until for AUTH

Problems

  1. Group invites: An invite link to a g-e2ee group chat can not add the joiner device if the link expired.
  • Solution 1: simply not show the green checkmark as soon as someone's public key is not verified. I.e. to downgrade the group for some/many members in this case (@missytake), but not for the members who have everyone verified
  • Solution 2: Show a helpful error message:
    • Maybe "This QR code is expired. You can let Alice scan your QR code and then ask her her to add you to the group." with a button "Show my QR code" and "Other possibilities" where "Other possibilities" shows how Alice can clone the group to an opportunistic one
    • Or simply "This QR code is expired."
  1. You can't encrypt after scanning a QR code with expired INVITENUMBER, which poses a problem with Chatmail -> INVITENUBMER needs to be valid for a rather long time (≥ a day).
  2. We will have more cases where people accidentally have a verified group and now want to add someone they have not verified.
  3. Technical challenges:
  • The QR code only contains the fingerprint, no key, so we can't directly mark the key as 1-way verified, but instead have to remember the fingerprint and then mark the key as verified as soon as we receive it.
  • If Bob scans a QR code with his phone and then doesn't open DC on his PC for a while, the QR codes might have already expired by the time he opens DC on his PC -> We need to make sure that the contact is verified on the PC too, in this case.

Open Questions

  • Should we show a green checkmark for contacts with a verified public key who don't have us verified? (i.e. forward verified but not backwards verified)
  • Should we allow "opportunistic" key changes for contacts with a verified public key who don't have us verified?

Alternatives

  • Fix problem 2 (see "Problems" above) by including a key in the QR code so that Bob can encrypt to Alice without having to wait for her answer.
    • Discussed at SecureJoin: encrypt {vc,vg}-request message #5182
    • This brings us away from the SecureJoin protocol (OTOH, noone except us implements it, anyway).
    • Upsides: It makes the protocol run faster (2 instead of 4 messages), and all SecureJoin messages will be encrypted
    • Including the whole OpenPGP key will not work for v6/crypto-refresh, because we will eventually need to transmit two keys
    • Possibility 1: Create a ED25519 PGP key for each invite. The public key replaces the INVITENUMBER. Bob can use it to send AUTH encrypted in the first message already, and to encrypt messages before Alice answers with her actual PGP key.
      • Downside: Complexity.
    • Possibility 2: Put a passphrase for symmetric encryption into the QR code, which replaces AUTH.
      • Upside: Will not need adaptions for PQC.
      • We should still include the public key fingerprint in the QR code, so that the scanner can do a one-sided verification if AUTH is expired

More possible improvements:

Both these improvements would help with the usability problem brought up by @dkg that a verified-checkmark implies something about identity:

  • After securejoin completes, show a dialog asking the user to set a name for the contact.
    This way, the green checkmarks will mean something about identity because the user confirmed that this display name goes with the contact who just scanned the QR code.
    • This will require that we either let AUTH tokens expire as soon as the app is not in the foreground anymore, or that we show a notification receiving a vc-request-with-auth message if DC is in the background already.
    • Also, we need to figure out what to do for transitively verified contacts. WhatsApp shows all display names with a "~" until the user manually sets a name for this contact, and they show a prominent prompt to add a contact in the 1:1 chat)
  • Don't show green "verified" checkmarks, instead show a warning when messages are not guaranteed-end-to-end-encrypted, possibly in the message composition field, on the send button, and/or where the green checkmarks are today
@link2xt
Copy link
Collaborator

link2xt commented Dec 22, 2023

Bob should still show a one-directional verification if he already knows Alice's key.

We do not show one-directional verification anywhere. Contact.is_verified() still returns false if there is no backward verification. With #5116 we will however mark 1:1 chat as verified very early on.

@Hocuri
Copy link
Collaborator Author

Hocuri commented Dec 22, 2023

Yes, I meant "get", I edited my original comment

@link2xt
Copy link
Collaborator

link2xt commented Jan 14, 2024

We need to pick an expiry time, we talked about something like 2 days. Thinking about it, I'd actually argue for something like 10 minutes, since that's enough to send a QR code via Signal if need be, but often not enough for Eve. If you want offline-verification, just scan the QR code in both ways.

This might be a problem if you want to setup contact via a friend using Signal or other messenger who you trust to resend QR code but nobody is online at the same time and Signal cannot be used as you don't want to share phone numbers directly. With chatmail this is a problem because you cannot even have forward verification and send a message. Scenario is constructed as chatmail is new, but I have seen this pattern of relaying Discord and similar messenger invitation links, SMS codes and so on.

Maybe "backward verification" (AUTH token) should expire in 10 minutes as it is important for verification security, but "forward verification" (INVITENUMBER token used to request the key) can take longer as it is just used to request the key and worst case leaks online presence. In any case we better talk about expiring these tokens rather than "expiring QR codes" which contain multiple tokens.

@link2xt
Copy link
Collaborator

link2xt commented Oct 1, 2024

Add context to securejoin invites

Currently if Alice shows "setup contact" QR code to two different Bobs while being offline, she will later get two chats from Bob 1 and Bob 2 without the ability to tell who is who.

One workaround is to create a group for each contact and use secure join protocol instead of setup contact. Then each Bob gets into his own group chat.

We can however change the core to show a new QR code each time QR code screen is displayed and associate some context such as the date and time to it (or allow to select custom name like "Cryptoparty" or "Onboarding Bob 4", but that would require UI changes). Then we can add this context as an info message to the chat (either 1:1 chat in case of setup contact or the group chat and 1:1 chat in case of securejoin). So unless Alice shows exactly the same QR code to multiple contacts, it is then possible to tell which Bob is the first one and which one is the second and add more context by actually writing messages into the chat. (based on short discussion with @r10s)

@Hocuri
Copy link
Collaborator Author

Hocuri commented Oct 2, 2024

Is this meant to be for usability (preventing confusion amongst friends) or for security (preventing attacks)?

Is this meant as an alternative to expiring QR codes? Or as a future improvement we might do afterwards? Or something we should do independently of expiring them?

@link2xt
Copy link
Collaborator

link2xt commented Oct 2, 2024

I think adding a context is an alternative to "After securejoin completes, show a dialog asking the user to set a name for the contact." that can be implemented entirely in the core and without UI changes like a new dialog. We can also make it possible to set a context while showing a QR code, then user can see the context in the info message later and rename the contact accordingly.

@Hocuri
Copy link
Collaborator Author

Hocuri commented Oct 3, 2024

Are there any user reports of users who onboard two friends with the same name at the same time and then can't tell them apart?

It seems unlikely to me that just the date and time is very helpful for most users.

And if we make it possible to set a context while showing a QR code, then it seems unlikely that many users will a) find this option and b) be so concerned that they won't be able to tell apart the two people they onboard next that they add some context. Plus, we will need to add some UI for this, too.

BTW, for "After securejoin completes, show a dialog asking the user to set a name for the contact." we can just reuse the edit-contact dialog, and we won't need any new API, which will make the UI implementation simpler.

@iequidoo
Copy link
Collaborator

iequidoo commented Oct 3, 2024

One workaround is to create a group for each contact and use secure join protocol instead of setup contact. Then each Bob gets into his own group chat.

This can work, but Alice should take care to look at the original group name because Bob can rename it. So i think this workaround is too complicated for users.

EDIT: Maybe don't complicate the default QR code screen, but add "New Named Contact" next to "New Contact"?

@dkg
Copy link
Contributor

dkg commented Oct 7, 2024

Are there any user reports of users who onboard two friends with the same name at the same time and then can't tell them apart?

This is asked as a bit of an overstatement, but i have certainly onboarded more than one person while i was offline, and then received "green checkmark" contacts once i got back online where i couldn't tell who was who. People don't necessarily choose obvious names for themselves.

@dkg
Copy link
Contributor

dkg commented Oct 7, 2024

I think the usability concerns are real here, and i also think that mere expiration dates and visible date/time info are insufficient for real-world defenses against endpoint confusion/misattribution. So real usability work needs to be done here to think through a sensible workflow. The fact that my device has continued to show the exact same QR code for months means that if any one of my contacts decided that they wanted me to receive an ungovernable amount of spam, they could simply re-transmit my invite QR code to an arbitrary number of spamming lists.

Currently, it looks like Delta's semantics are "if i show you my QR code, i am allowing you to invite any arbitrary number of contacts to appear as verified contacts, with no way for me to distinguish between them." this is a surprising semantic.

@dkg
Copy link
Contributor

dkg commented Oct 7, 2024

I think what i would like for most individual introductions is a semantic more like a single-use invite:

  • give this scrap of paper to someone, and then they (and only they) can use it to establish a channel back to you.

I think this covers the use-case for single introductions, and it seems plausible that those introductions could be associated with arbitrary stored internal metadata, so that when the contact does eventually come in, the user's own contextual notes are already associated with it.

I recognize that this proposal doesn't necessarily cover the use case of "i'd like everyone in this group to be able to contact me securely". I'd be curious to hear proposals for how to achieve such a semantic in a meaningful way for the user without any input from the other participants' devices. What info should i learn? what sort of temporal/spatial bounds should i associate with such a broad group invite?

@iequidoo
Copy link
Collaborator

iequidoo commented Oct 8, 2024

I recognize that this proposal doesn't necessarily cover the use case of "i'd like everyone in this group to be able to contact me securely".

I think this is just what's implemented currently, but

  • Currently the QR code is never renewed.
  • Also it has no limit on the number of joiners.

I think it should be auto-renewed by default so that different codes are shown to different scanners. And the default limit should be 1, but the user should be able to change it, probably in the same place where they can add a context which is then added to the contact when the "setup contact" protocol completes. Also the user should be able to see all their active QRs and show them to scanners so that the user can onboard contacts to multiple chats/contexts at the same time. To sum up, probably both cases may be achieved by the same, customisable, approach.

@dkg
Copy link
Contributor

dkg commented Oct 8, 2024

@iequidoo that sounds like a complicated UX proposal, but maybe someone who is a better UX designer than me can streamline it to the point where it doesn't feel complicated ☺

The SecureJoin handshake in its present form reminds me of other cryptographic handshakes, which tend to have a common set of tradeoffs that are used to establish some sort of shared secret between the two parties involved. With advance planning, a relatively small/simple shared secret can subsequently be bootstrapped into a stronger set of secrets or channel properties.

One common desideratum for such a shared-secret establishment is so-called "contributory behavior", which ensures that neither party can unilaterally establish the shared secret. A handshake that lacks "contributory behavior" risks exposing users to confusion about keys, and may be vulnerable to replay or relay attacks.

I understand that the in-person/out-of-band/non-mediated part of the current SecureJoin UX probably can't offer contributory behavior: one party produces something that is effectively the shared secret (by emitting the QR code) and the other party consumes it (by scanning the QR code). There's nowhere for the second party to contribute to the shared secret, they can only confirm it later, over the mediated channel based on the split between the s and i parameters.

But this makes avoiding reuse of the QR code even more important if the goal is that the two parties can reliably recognize each other over mediated channels in the future.

@hpk42
Copy link
Contributor

hpk42 commented Oct 11, 2024 via email

@ell1e
Copy link

ell1e commented Oct 13, 2024

It was suggested to me to bring up here: I was invited via a link through an unencrypted mailing list. Delta Chat just assumed the invite link implied trust, and marked the user as verified, even though the link could have been forged from basically anybody. I don't think this makes sense neither for QR codes nor links, it feels like I should rather be able to pick whether I acquired the link or code through a secured transmission or in person, from a trusted source. If not, then I should be able to establish contact but without trusting anybody introduced via the link. If I just missed something about this concept that makes this work, then I apologize.

@link2xt
Copy link
Collaborator

link2xt commented Oct 13, 2024

Related forum discussion: https://support.delta.chat/t/trust-design-perhaps-an-invite-link-shouldnt-always-be-trusted-maybe-its-a-good-idea-to-ask-the-user/3279

@adbenitez
Copy link
Member

adbenitez commented Oct 17, 2024

  • Solution 2: Show a helpful error message:

this doesn't sound helpful, if I invite people with an invite link I don't want it to break arbitrarily, there is an option to reset/discard QR invitation already, otherwise DC would just get in the way of most users that just want to chat and get in contact and don't care about theoretical complex attach vectors and MITM by someone that is in the groups and control the server at the same time

if contact is not marked as verified it means that people can't add them to groups, if there is a real MITM attack what will happen is that people will just send the invite link again in the MITM-ed chat to just let the folk join the group, solving nothing while making things harder UX wise, or if you would be really serious about the problem you wouldn't allow people to join with a link that was shared in a non-protected chat, so then the user can't join the protected group until they meet in person or use another potentially insecure channel that is out of DC's control, you can't never be 100% the link was transmitted in a secure way

I think the focus here is chat encryption protection, so even if MITM-ed at least encryption can't change arbitrarily without user noticing, it was never about contact identity verification, it was and is a common misunderstanding because the green checkmark icon, that is IMHO the real problem here

@ell1e
Copy link

ell1e commented Oct 17, 2024

if contact is not marked as verified it means that people can't add them to groups

Without fully understanding every point in this discussion, this seems like it should be fixed. Maybe there should be a difference between "the two contacts on each end successfully established via some invite link that they probably know each other" and "this contact is verified since local user confirmed the link was obtained through a secure channel". Or maybe somebody has a better idea. This seems like an important part to get right, if in practice I'm just verifying people left and right that I didn't actually verify, I don't really get all the focus on autocrypt and DKIM and all that. (Or maybe it's just me finding encryption by itself not all that useful, if I'm not actually talking to who I think it is.) If I'm just misunderstanding the context then sorry about that.

@iequidoo
Copy link
Collaborator

if contact is not marked as verified it means that people can't add them to groups

Without fully understanding every point in this discussion, this seems like it should be fixed.

@adbenitez probably meant that you can't add unverified contacts to verified groups. Or if you verified the contact, but haven't received a confirmation message (vc-contact-confirm) from them so it's only "unidirectionally-verified". Otherwise, if you could add such a contact to a verified group, they may reject such an addition. It's supposed that you first should resolve the problem (maybe trying to rescan the QR code, fix connectivity etc.) and then add the contact to the group. Note that you can already use the 1:1 chat safely as you have the contact verified.

@ell1e
Copy link

ell1e commented Feb 11, 2025

So unless Alice shows exactly the same QR code to multiple contacts

For what it's worth, to avoid it being forwarded it might make sense to make QR codes single use and time limited by default.

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

No branches or pull requests

8 participants