nips icon indicating copy to clipboard operation
nips copied to clipboard

NIP-46 secret

Open alexgleason opened this issue 11 months ago • 19 comments

We can skip the whole initial handshake of "connect" -> "ack" in NIP-46 by including a private key in the bunker:// URL instead of a secret.

The client has to sign events using that private key. It skips an entire layer of complexity between the client and the signer.

alexgleason avatar Mar 06 '24 20:03 alexgleason

This is a good idea. @pablof7z @nostrband

fiatjaf avatar Mar 07 '24 10:03 fiatjaf

Not sure much complexity is removed. No need to call connect for this particular flow? But connect is needed for other flows (i.e. oauth-like, nostrconnect). For users UX is the same be it secret or private key.

nostrband avatar Mar 07 '24 10:03 nostrband

I don't understand why you would need to call connect in those flows. If you can negotiate a secret you can negotiate a secret key. The complexity removed is that the signer can open a filter to only the key(s) it has authorized and does not have to store state with the connection.

alexgleason avatar Mar 07 '24 14:03 alexgleason

The main benefit is not that you can skip connect. I think we shouldn't skip that. The main benefit is that you get a single string credential that you can store and reuse.

fiatjaf avatar Mar 07 '24 21:03 fiatjaf

I don't understand why you would need to call connect in those flows

Oauth start from client - it knows nip05 and does 'connect', it must generate the local key for that. Nostrconnect: - I agree, it doesn't seem to require 'connect' (at least not from the app?), although I didn't try to implement it yet.

The main benefit is that you get a single string credential that you can store and reuse.

Who would store the bunker url w/ app key (more than they do without the app key)? When and where would they reuse it (more than they do now)?

brugeman avatar Mar 08 '24 12:03 brugeman

A client that uses a bunker to connect would presumably store that URL locally somehow, say, in localStorage. And today they would have to generate a secret key and then store it separately. with this they would just either generate and store the two things together, or they would just use the secret key from user input, not generate.

Am I thinking wrongly about this?

fiatjaf avatar Mar 08 '24 14:03 fiatjaf

I agree @fiatjaf

In the current flow you generate a random keypair and then use the "secret" provided by the bunker to authenticate with it. Now the bunker can trust your keypair.

But if the bunker just gives you the keypair to begin with, it already trusts it.

I don't get what's not to get.

alexgleason avatar Mar 08 '24 15:03 alexgleason

Whether one stores one or two strings to me is a triviality not worth the ink. I get what you're proposing Alex, I don't get the benefit.

I do get the reduced security though - today if bunker url with a single-use token leaks (which it will, bcs bunker urls are there to be copy-pasted), at least hopefully token has already been redeemed or expired, so it's not a big deal. If bunker url with private key leaks then much more damage can happen - that's the reason Pablo came up w/ a redeemable token afaik.

Oh btw the old spec had nothing about this 'secret' token, and the new one just mentions it without explaining why it's there. It's a single-use token, redeemed on the first connect - the connection perms are assigned to the npub that connected and token is no longer valid. Pablo came up with this token and that's how nsecbunker handles it.

Everything you can do with passing a private key you can also do with a token, but token is also more secure. Or is there a use case I'm not considering? Or does the current spec imply a different meaning for the secret token which I'm not aware of?

brugeman avatar Mar 08 '24 15:03 brugeman

I private key IS a token. You can revoke it just like a token.

alexgleason avatar Mar 08 '24 16:03 alexgleason

Ok I revoked the token - I no longer accept 'connect' call with this private key as a token. But what you're proposing is that client keeps using that private key and signer keep allowing this private key to sign. Which means if this bunker url with that token leaked, anyone else can use it and signer will allow them access to sign too. No?

brugeman avatar Mar 08 '24 16:03 brugeman

The bunker gives me a private key instead of a secret. As long as that key is not revoked, it can be used. The bunker can revoke the key to stop it from signing at any time. How is that any different from the current security?

In the current system leaking either the secret or the ephemeral keypair has the exact same problem depending on the bunker implementation. The important thing is that you can revoke it, though. That doesn't change with this.

alexgleason avatar Mar 08 '24 16:03 alexgleason

'secret' passed to 'connect' is single-use short-lived token, which only works on first connect (if it hasn't expired yet), so leaking it is okey-ish. If it leaks, it's very unlikely to be usable.

You're proposing to copy-paste long-term connection key. If it leaks - it's usable. Yes I can revoke it, if I ever detect anything 'suspicious', but this is less secure than a single-use token.

brugeman avatar Mar 08 '24 16:03 brugeman

@brugeman The secret authorizes your local keypair. If that local keypair leaks you have the same problem. You have a long-term secret keypair either way.

alexgleason avatar Mar 08 '24 16:03 alexgleason

The gain in "security" is complexity for complexity's sake.

alexgleason avatar Mar 08 '24 16:03 alexgleason

Local keypair is less likely to leak bcs it's not copy-pasted - it's generated in the app and kept in localstore.

brugeman avatar Mar 08 '24 16:03 brugeman

Then why use Nostr Connect at all if the local keypair is safe in localstorage?

alexgleason avatar Mar 08 '24 16:03 alexgleason

Local keypair in clipboard is 100x less safe than in localstorage. I will stop here.

brugeman avatar Mar 08 '24 16:03 brugeman

Revocable keypair in clipboard is fine in 99.99% of cases. Fine, one-time secret in clipboard is fine in 99.9999% of cases. I do not see the increased software complexity as a win, especially when complex software is more often the cause of security issues.

alexgleason avatar Mar 08 '24 16:03 alexgleason

'secret' passed to 'connect' is single-use short-lived token, which only works on first connect (if it hasn't expired yet), so leaking it is okey-ish. If it leaks, it's very unlikely to be usable.

Say it like this: In the case the secret or private key leaks BEFORE the connect request, it is indeed the same. But if the secret leaks AFTER the legitimate client has connected, it is useless to the attacker because it was already used up. BUT if the private key leaks AFTER the legitimate client has connected, the attacker can get still service from the bunker.

mikedilger avatar Mar 08 '24 19:03 mikedilger