frejete You're right, that's a good point. The use of the memo is a clever way to handle sub-accounts. I can’t however shake the feeling that by taking this approach you end up depending on core, federation, and the app developer to apply logic in isolation. Bring the end user sending a payment into the equation and you now have 4 variables. That’s a lot of moving parts, and if a payment goes awry the ability to diagnose the issue and enforce accountability will be difficult.
DomainKeys Identified Federation (DKIF)
- Edited
rbates Couple additional thoughts I've been having since I wrote this.
There's really two things being addresses here. One is making sure that the mapping between the federation address and the wallet address can't be easily tampered with. The second is using federation + memo as a mechanism for managing sub accounts.
For the sake of the discussion I think it's worth considering that these could be solved in different ways. For example, if stellar core had the concept of an incremental id attached to each account people could still build their account management solutions off the ledger, but there would be a way to enforce uniqueness and prevent situations where the memo is critical but gets submitted as empty. You wouldn't need to store balances for sub-accounts in the ledger, just have core reject the transaction if it's not in range (ABC, ABC-01, ABC-02).
Circling back to federation, with a setup like this you could require that Stellar accounts and their user aliases were mapped one-to-one without passing around memos from federation to client to core.
Sorry if this is slightly off the original topic of DKIF, I just feel like the security, identity, and technical architecture discussions around all of these are intertwined.
We are live!
Finally, we went live with our Secure Open & Hosted Stellar Federation service.
The site is here: https://lumenbox.org
Please enjoy and provide your feedback. ?
- Edited
We wrote proposal pretty long time ago but did not get feedback from Stellar DEVs.
We created a site which explains the DKIF in a simple way and put it up to lumenbox: https://lumenbox.org/dkif-explained/
As you can see above, we went live with our service which is using DKIF (obviously, we would need wallets to support it but for this we need the SDF's support): https://lumenbox.org
- Edited
Hi keksper
In the current federation workflow if any of the web server or federation server gets compromised the attacker can redirect the payment to his own account. This is independent of who hosts these services.
In case your federation record is hosted by someone else obviously the problem mentioned above is also there but the owner would not even need to overtake the server as he manages it ?
With the DKIF extension, this risk is mitigated as the records are signed and the key for the validation is in the DNS. So in order to redirect the payment, an attacker would need to take over one of the servers AND forge the DNS query/response on the client side.
https://lumenbox.org (thanks to DKIF) allows you to upload your signed federation records for your own domain to our federation database. We will serve it to the world so you do not need to run and maintain a federation server. As the signing is done by you (only you know the secret key that you used for signing) and the DNS is also managed by you for your own domain (so you are the only one who can upload/change the validation key into it) your records cannot be tampered on the federation server side.
Obviously this only works when the clients/wallets are supporting the DKIF extension to verify the signature of the records. Let see if the Stellar DEVs will like the idea and ask everyone to support this.
As the DKIF extension is fully backwards compatible, until this happens, you can register a lumenbox.org Stellar address or use an address for your own domain on https://lumenbox.org. This will work perfectly for the current, standard federation.
Hi Cajga!
Finally I took the time to read and try to understand the technicals.
Congratulation for the good design job and the nice website. ?
There's only one part I don't get: how do you store the key in the DNS? Is it an option to serve text file directly from your DNS provider?
I'm willing to implement a securing protocol for address resolution into Stellar Authenticator & cosmic-lib. The library would allow other web developpers to use your enhanced resolution protocol without any pain. Cosmic link protocol support federated address by default and as you did explain we need it to be more secure than it actually is. We need it rock-solid! You can guess how happy I am that someone is willing to tackle this issue ?
I'm still wondering about your design. Is it correct than taking over the DNS an attacker could redirect payment? As I understand it, the public key is on the DNS, and the DNS is also the link between user and toml file, is that right?
- Edited
Hi @MisterTicot
Thanks for the congratulation for the site, the points are going the other two members of the team. They developed the site, the app and the underlying API.
The DKIF public key is stored as a TXT record in the DNS. As an example, here is the public key pair of the key that we use for signing at https://lumenbox.org:
$ dig +short -t txt federation._stellardomainkey.lumenbox.org
"GAI55SVFTWSRNRFQGPUD264OF6UDD2O3MGUBDZWFR2GRJ3WOCTFUUMLP"
Your question about DNS server mentions a very important point. Although, DKIF is a significant and very important step towards a secure Stellar Federation protocol (as signing the federation record reduces the attack surface with the federation and the web server), it is not an all-in-one solution which mitigates all the possible attack vectors alone. It is very important to understand that securing the underlying protocols and infrastructure are still required!
Taking over the DNS request/response is a very powerful attack and an attacker has many different possibilities/places to do so. It is extremely difficult to properly protect the name resolution against these.
In case an attacker is able to take over the DNS server which serves your records (or your account at the registrar who registered your domain ? ) then basically he owns your domain. He can simply resolve the records of the domain to his own IP and start to serve the federation responses from his own federation server (some ISP may cache the DNS records so it may take few hours until all the federation requests will be directed to his server) after he got a TLS cert to your domain from one of the automated cert providers which use Domain Validation.
There are some ways to try to prevent this (DNNSEC is probably the best and could delay the real problem a bit but unfortunately apart from other weaknesses, the client resolver must support it otherwise it is useless and it is often not the case!).
These are serious risks but it is more likely that the attacker take over the client itself (like has a software on your PC on which you use your wallet) and just simply get your Stellar Secure Seed when you log in to your wallet or sign a transaction ?
So, all in all, there is no bulletproof solution out there but we should try to improve the security posture with solutions which does not "cost too much".
- Edited
Cajga
Thank you for this complete answer, I think I got it all now.
Maybe some caching could secure the process further? Then check against new values. Like if public key and destination both changed since last time, raise an error and ask for explicit user confirmation?
The idea is that in most cases legitimate users would update one or the other at a time; while an attacker likely would change both.
Or did I missed a common usage scenario where you would update both publicKey and account ID?
Edit: hm... Nevermind there's some issues that looks difficult to tackle. Like what if I didn't connect since a month(ignore change?); Or what if my federated server host thousands of address and I want to change my publicKey?
There should be some simple way but I can't catch it.
MisterTicot Also the Stellar protocol explicitly says you should not cache Federation responses. https://www.stellar.org/developers/guides/concepts/federation.html#caching
frejete
Thank you for bringing this to my attention.
It would be nice having thoses federation servers adding a no-cache clause to their reply.
MisterTicot Good point, I will do that for StellarID.io
Your federation server returns an empty string as memo when no memo is set.
I don't know if it's legit or not. I would rather expect no memo field at all, like StellarId does.
@MisterTicot thanks for the report.
Let me have a look and get back to you.
- Edited
So, even if I kind of agree with you on this, please note that the official federation server behaves in this way. Here is how I tested it:
$ go get -u github.com/stellar/go/services/federation
$ cat federation.cfg
port = 8000
[database]
type = "postgres"
dsn = "postgres://localhost/federation_sample?sslmode=disable"
[queries]
federation = "SELECT id FROM people WHERE name = ? AND domain = ?"
reverse-federation = "SELECT name, domain FROM people WHERE id = ?"
[tls]
certificate-file = "/tmp/localhost.crt"
private-key-file = "/tmp/localhost.key"
$ ./federation --conf federation.cfg &
$ psql -U postgres federation_sample
psql (9.2.23)
Type "help" for help.
federation_sample=# \pset null '(null)'
Null display is "(null)".
federation_sample=#
federation_sample=# select * from "people" where name='szil2' or name='sig';
id | name | domain | signature | signature_rev | memo | memo_type
----------------------------------------------------------+-------+-------------+-------------+---------------+--------+-----------
GD2GJPL3UOK5LX7TWXOACK2ZPWPFSLBNKL3GTGH6BLBNISK4BGWMFBBC | szil2 | stellar.org | | | |
GA2GJPL3UOK5LX7TWXOACK2ZPWPFSLBNKL3GTGH6BLBNISK4BGWMFBBC | sig | stellar.org | test | | (null) | (null)
(2 rows)
federation_sample=# \q
$ curl -k 'https://localhost:8000/federation?q=szil2*stellar.org&type=name'
{"account_id":"GD2GJPL3UOK5LX7TWXOACK2ZPWPFSLBNKL3GTGH6BLBNISK4BGWMFBBC","memo":""}
We patched (and submitted a pull request to) the official federation server to support DKIF and we are using this version for our federation service.
We could open an issue (I had a look but could not find one) to the official federation server about this and see why did they decide to return an empty valued memo field in the json and I am happy to follow what they decide.
Hm I kind of expected this. Well, that would be nice to know.
Thank you for this complete answer.
Cajga
I still wonder. Do you know why in the DB in your example szil2
have an empty memo field while sig
have a (null)
memo field ? Wouldn't then be (null)
value the right one ?
I'm not sure if I get it right.
I'd like to integrate lumenbox into something I'm building. Would it be possible for you to enable CORS on the https://lumenbox.org/verify path?
@Cajga I'm running into a problem trying to implement DKIF support into cosmic-lib. Client-side JavaScript seems to have no way to get TXT records information. A solution could be using one of the API (third-party) available. I wonder if we can find a way to store the public key that would.allow for a direct fetch from client side application.
- Edited
@MisterTicot Yes, we thought about this limitation (problem with "pure client-based" application) and actually did a lot of research back when we designed the protocol but could not find a very good solution for it.
The thing is that DNS is the best place to store your public key as this reduces the possible attack vectors of the system (in case the attacker can modify your DNS records, you are done anyhow).
Some big players realized this issue long ago and started to offer DNS-over-HTTPS interface and as you said probably this is the best what you can do when you do not have any server side component (which could do the lookup for your client):
cloudflare
google
One more solution could be that this lookup gets integrated into horizon but how the things are moving currently (we've never received any comment on our PRs or SEP) I do not think this will ever happen.