-
Notifications
You must be signed in to change notification settings - Fork 143
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
payRequest multi-step overcomplicated #133
Comments
I don't think this is overcomplicated at all and the server doesn't have to store any state. Look at this pseudocode for a request handler at
|
This isn't an explanation for why it works the way it does, only one possible way to implement it (assuming the local invoice-generation API supports description_hash). |
It's a response to your claims that the server must store state between requests. The hash checking is required so the user doesn't see a description that says they are buying a car and then on the next step their wallet blindly pays a signed invoice from the service with a description that says "a bicicle". |
The choice of Since lnurl-pay was the perfect match for that because it defined the transport already, we decided to use it. But if you think that was a ridiculously stupid idea then I would just forward that criticism to the BOLT11 authors. Why has it defined such a field? I don't know either. To me it just feels safer to use a hash on a place dedicated to hashes instead of what?, a hex-encoded hash in a place dedicated to human-readable descriptions? |
Fair, I suppose if you put the state back in the URL for the second request you get it back and the server can verify it and re-use it. Its still a level of indirection that isn't explained in the docs at all, and requires the server to verify whatever state came back from the client in the second request. I'm still confused as to why this multi-request design is required.
This doesn't track. The point of descriptions in BOLT 11 is because the payment request is authenticated by the node signature. In LNURL there isn't (really) an authenticated payment request at all There is no requirement in LNURL that the invoice be signed by any given node, and an LNURL endpoint can return an invoice signed by a random one-off pubkey (i.e. an attacker can provide an invoice from their node) and services today generate invoices against many different nodes. The standard BOLT 11 proof-of-payment design no longer applies, making the description somewhat redundant. |
I agree the proof-of-payment scheme is not working as designed, but I don't know if we have all collectively agreed to throw it into the trash already. In many cases it's still possible with some manual work it's still possible to prove after the fact that a specific service was responsible for signing a given bolt11 invoice. And there are ways for making that process more seamless and automatic without having to change anything in the architecture of current services, although these improvements would be independent from LNURL. In the case of an attacker they would have to be in control of the domain of the service the user is interacting with and that already breaks the basic trust assumption of LNURL and they can probably do more harmful things. But the hash checking still prevents a service from sending the wrong invoice due to a bug, for example. And the preimage verification has worked in the real world many times to clarify misunderstandings between customer and service provider. I've seen it happen a dozen of times, so it's in the interest of service providers to issue valid invoices from stable pubkeys (although I realize this is not very relevant in the specific case of LNURL, or is it?). Is there any other alternative for payment proofs? |
Oh, don't get me wrong, I'm not claiming at all that proof-of-payment is something we should give up on, only that in an HTTPS-authenticated environment its not possible. That's fine, plenty of users will use HTTPS-authenticated environments, and invoice authentication isn't possible in that environment, there's just not anything we can do about that. We can chat about ways to make the node public key signing the invoice committed to by a URL (ie have the domain commit to one by putting it in a DNS TXT record authenticated by DNSSEC - a functioning client can get a full authenticity proof from the DNS), but today it doesn't exist.
Yes, my point is that the trust model of LNURL is HTTPS CAs (personally I'd prefer if DANE were required, but that ship may have sailed). There is nothing tying the BOLT11 invoice to HTTPS, and I don't think there's much hope of changing that. Relying on the BOLT11 invoice to contain authenticated data doesn't add anything given the trust model. In general, LNURL docs seem to be lacking on motivation sections - ie where is the specified trust model that implementors need to consider and that provides guarantees for users?
You could also avoid that by making it one request instead of two :p.
This seems unrelated to the invoice description? Payment preimage exchange indeed can be useful and service providers hopefully know the set of public keys from nodes they use, though some service providers (eg strike) use many nodes today already and seem to have no issues with it. All of this said, I'm not sure how any of this is connected to payment description in invoices in LNURL. If we move to requiring DNSSEC-authenticated node ids to sign the BOLT11 invoices we can still just put the description in the invoice and sign it - same amount of data as the current first response, just avoids the second response (and JSON in between). There's no particular size limits to BOLT11 invoices - the only restrictions come from putting them in QR codes. |
Ok, I agree with you on everything. My only remaining points are:
|
That's fair, though given how early things are, I wonder how much effort (on the sending side) it would really be to have a lnaddress-minified option at least for lightning-address. Simple request, gets an invoice, user can pay or not. Adding support on the sending side is significantly more trivial than any other existing implementation, and it would avoid new receivers having to be as complicated (given the relatively weak support for lnaddress-receive, providing authenticated invoices instead of HTTPS-secure-connections may enable better uptake, though that may be better off putting the node id in the QR code than relying on DNSSEC or similar systems). |
@TheBlueMatt Are we talking about LNURL-pay or Lightning Address? Lightning Address is not a payment protocol, it 100% reliant on LNURL-pay (LUD-06), which is the actual payment method. However, breaking out Lightning Address to be able to support multiple payment methods (raw bolt11, bolt12/bolt12address, amp invoice, whatever) is something I've been positive about in the past and could be a good idea to continue pursuing. |
I went to implement LNURL-16 figuring it would be quite simple (ie request-invoice - get-invoice) but instead it requires a few hoops without any motivation for why. Specifically, the multiple requests to get an invoice may be fine, but multiple steps with server-side state required is a bunch of complication (not to mention DoS risk). Worse, using description_hash instead of description makes LNURL-payRequest/LNURL-16 harder to integrate with some standard tooling, and there doesn't seem to be any motivation listed for why the description_hash needs to match the first request (there doesn't appear to be any security motivation for it?) and without the metadata being passed back to the server.
Can we define an LNURL-21 that is just GET /.well-known/lnurlq/ that just returns an invoice. No JSON, no complexity, no server-side state, just an invoice? Or maybe remove the description_hash-matching requirement from the LNURL-payRequest requirements?
The text was updated successfully, but these errors were encountered: