appstream icon indicating copy to clipboard operation
appstream copied to clipboard

[Feature Request] Support ownership verification for domains in <url> Tags

Open elsiehupp opened this issue 3 years ago • 9 comments

Presently the AppStream specification does not provide any means for protecting against malicious domain transfers of URLs specified in AppStream metadata.

For example, with the tag:

<url type="homepage">https://foo.bar</url>

There is no way for the recipient of the AppStream file to verify if the domain https://foo.bar is legitimately the website that the AppStream’s author intended to point to.

I’m not an expert on DNS, by any means, but my understanding from setting up a personal email server is that there is a standard—DNSSEC—for cryptographically signing DNS records.

If the AppStream specification were to designate syntax along the lines of the following:

<url type=“homepage" pubkey="PUBLIC_KEY_STRING">https://foo.bar</url>

Then the recipient of a given AppStream file would have the means to verify the legitimacy of a given <url/> tag and act accordingly.

The specific XML syntax is an open question, as is the means of validating that syntax, but what I’m requesting here is the end goal, not the specific implementation.

elsiehupp avatar May 19 '21 21:05 elsiehupp

Uhm, what exactly should the public key string contain?

SISheogorath avatar May 19 '21 21:05 SISheogorath

Again, I’m not hugely familiar with how DNSSEC works, but essentially the attribute could (optionally) specify a string that, e.g., corresponds to the public key for the domain at the time that they write the AppStream.

Like, you can try the following with my email domain:

$ whois elsiehupp.com | grep DNSSEC

My guess is that the string would be what’s listed under DNSSEC DS Data:? But again, this is somewhat beyond my expertise. I tried $ whois github.com | grep DNSSEC, and they don’t have DNSSEC enabled, but also they might not feel they need it, idk.

The main case I’m suggesting trying to protect against is a defunct domain being taken over by a phishing site, in which case a downstream distributor parsing the AppStream could simply choose to hide that given URL (or even contact the <update_contact/> to ask them to fix the issue). This would be particularly important if the downstream distribution were otherwise validating URLs, so as for example not to show a blue checkmark next to a link to a phishing site.

elsiehupp avatar May 19 '21 21:05 elsiehupp

I probably should have included a link to the Wikipedia page on DNSSEC.

elsiehupp avatar May 19 '21 21:05 elsiehupp

I'm sorry, but that doesn't make a lot of sense. DNSSEC keys are stored in DNS and already trusted as their trust is delegated down the DNS tree. So there is no need to match fingerprints here unless we really talk about very long term attacks.

Then again, if the goal is to verify domain ownership, then there are already existing standards. the mentioned rel=me mechanism that e.g. Mastodon but also other indie.web application use, works by having pages link to each other, proving that one has access to metadata on both ends and this way mutually linking with a rel="me" -attribute proves the relationship.

However for the app metadata standard, this wouldn't work, here the mechanism you proposed in the linked issue of the flathub storefront would work, where the page metadata contains a <meta>-tag which provides the app-id. However, since the app ID is supposed to be a reverse of a domain the app developer controls, one could just use that to verify the app ownership. e.g. if my app-id is com.example.app we could consider to validate the ownership by requesting https://app.example.com or https://example.com and contain some sort of validation string.

Either way, there is little value in adding a DNSSEC public key to the homepage url entry, since a) the attack is so rare, that it's ridiculous, b) simply opening the URL using https proves almost as well the page ownership and is way more adopted than DNSSEC, and c) no one will ever remember to update all their app metadata just because they rotate DNSSEC keys. Think of GNOME, they would need to update all their apps, when changing something on their DNS server which might not even be operated by them.

And finally, finally, all this would proof is that someone with access to the metadata of an app, can discover the DNSSEC keys of a domain, which are public information and therefore the proof is no proof, but rather duplicated information.

SISheogorath avatar May 19 '21 21:05 SISheogorath

You’re referring to a conversation that’s in an entirely separate thread. It might be better for you to post your comments there.

What I’m requesting is the ability to determine that the DNS at a given point in time has been signed by the same entity as the DNS at a specific previous point in time. DNSSEC isn’t the same as simply hashing the domains.

This request isn’t specific to Flatpak. Basically, if you have an AppStream file, allowing for the <url/> tag to specify a DNS signing key would allow the author of the AppStream file to protect against that URL’s presence in the AppStream file from being used for phishing at some point down the line. (It would also provide the convenience of not linking to unrelated content if a domain is legitimately resold.)

There are a lot of dead links out there, especially in the open source community. Developers go MIA and companies go out of business all the time. Sure, a client application or downstream distributor can ignore a dead link. Adding optional support for DNSSEC would simply provide the means for a client application or downstream distributor to choose to ignore a spoofed or transferred domain, as well.

Regarding the inconvenience of having to replace the public key in an AppStream file when the private key is rotated… AppStream files are already usually updated with each new version release of a given package, so if the public key stops working, the same validation script that gets run every time the AppStream file gets updated could nag the address listed in <update_contact/> or otherwise contact the maintainer of the AppStream file (e.g. on GitHub) to ask them to verify that the new public key is legitimate.

Again, this would entirely be optional: whether to include a public key in the first place and what to do in the case of a key mismatch would be entirely up to downstream implementors to decide.

elsiehupp avatar May 19 '21 22:05 elsiehupp

What I’m requesting is the ability to determine that the DNS at a given point in time has been signed by the same entity as the DNS at a specific previous point in time. DNSSEC isn’t the same as simply hashing the domains.

But that's not what DNSSEC does. DNSSEC signs resource records with keys that are assigned to a domain. So providing a key here is basically pinning DNSSEC keys to a domain, which is unnecessary if you trust the root keys and the delegation of trust originating from them. So if at all, you could go ahead, put your app-id in a some kind of resource record and e.g. a TXT and validate that this is the same as the app-id in the app metadata file. And to make is DNS spoofing proof, you would require a DNS resolver that valides DNSSEC for this record and fails if no DNSSEC validation is provided.

Your current proposal of providing a key there is nonsense as you just copy public information from place A to place B, ignores how delegation works and does not proof anything about domain ownership.

If you want to insist of using the same private key to proof the app ownership, then you would need to provide a signed text block in this place, not the DNSSEC public key. As you could validate this signed text against the DNSSEC key. However you have to keep in mind, that many people don't manage their own DNS and might don't even have access to their DNSSEC key material.

But if you think I got this completely wrong, feel free to provide me with a concrete example and I'll try to show you what problem I see with that.

SISheogorath avatar May 19 '21 22:05 SISheogorath

Kindly reread what I originally wrote:

what I’m requesting here is the end goal, not the specific implementation.

You seem to be hung up on the fact that the specific means of achieving a particular goal may not be ideal.

In other words, your criticism is not constructive, and you are engaging in bad faith.

elsiehupp avatar May 19 '21 22:05 elsiehupp

Uhm, what exactly should the public key string contain?

It sounds like you know the answer to your own question, in which case, why are you asking it?

elsiehupp avatar May 19 '21 22:05 elsiehupp

VS Code just implemented a process for verifying publisher URLs that might be an interesting precedent. The linked help section doesn't go into a lot of detail, but they're apparently using DNS TXT records.

elsiehupp avatar Nov 10 '21 14:11 elsiehupp