channel_db: skip non-ASCII DNS hostnames in node announcements - #10823
channel_db: skip non-ASCII DNS hostnames in node announcements#10823ekzyis wants to merge 1 commit into
Conversation
| elif atype == 5: # dns hostname | ||
| len_hostname = int.from_bytes(read(1), 'big') | ||
| host = read(len_hostname).decode('ascii') | ||
| host_bytes = read(len_hostname) | ||
| port = int.from_bytes(read(2), 'big') | ||
| try: | ||
| host = host_bytes.decode('ascii') | ||
| except UnicodeDecodeError: | ||
| continue |
There was a problem hiding this comment.
receivers need to check that the bytes are indeed decodable as ASCII
are we allowed to forward the node announcement message if it fails this check?
There was a problem hiding this comment.
I have only found this in the spec regarding not forwarding node announcements:
- if more than one `type 5` address is announced:
- SHOULD ignore the additional data.
- MUST not forward the `node_announcement`.
Fwiw, LND does not forward node_announcements if they contain an invalid DNS hostname, see here.
Before, we also did not forward it. With this PR, we do, like the other test cases that fail to parse. Maybe it's better to actually throw like LND?
|
To be totally conformant, we should 'punydecode' the hostname, but since at least LND does not seem to do that, it's likely node operators avoid unicode domain names anyway. |
I only see the spec mentioning that the sender must encode DNS hostname bytes as ASCII, and Punycode for non-ASCII characters. I don't see where it mentions the receiver needs to decode Punycode back into Unicode. For connection purposes, the Punycode ASCII characters should be enough. Did you mean for display purposes?
Yes, I agree, I think Unicode domains are rare. |
Indeed, it is actually what DNS resolvers do when resolving a unicode domain name; convert to punycode :) |
BOLT-07 mentions here that senders of
node_announcementneed to encode DNS hostname bytes with ASCII:(Punycode maps non-ASCII characters to ASCII characters.)
However, receivers need to check that the bytes are indeed decodable as ASCII. Currently, the code to parse address descriptors would throw
UnicodeDecodeErroron the first DNS hostname with non-ASCII characters and drop the remaining descriptors.1 With this PR, such invalid address descriptors are skipped.FYI, LND additionally checks that the characters are within
[a-zA-Z0-9_.]but this is not part of the specification.Footnotes
I haven't tested this against running code, only using the existing tests, so I don't know if Electrum would crash during runtime or not. ↩