Bug 6338 - Use of Bit 0x20 in DNS Labels to Improve Transaction Identity
Summary: Use of Bit 0x20 in DNS Labels to Improve Transaction Identity
Status: RESOLVED FIXED
Alias: None
Product: Spamassassin
Classification: Unclassified
Component: Libraries (show other bugs)
Version: 3.3.0
Hardware: All All
: P5 enhancement
Target Milestone: 3.4.0
Assignee: SpamAssassin Developer Mailing List
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-02-17 19:42 UTC by Mark Martinec
Modified: 2011-09-24 01:23 UTC (History)
3 users (show)



Attachment Type Modified Status Actions Submitter/CLA Status
patch implementing the dns0x20 feature application/octet-stream None Mark Martinec [HasCLA]

Note You need to log in before you can comment on or make changes to this bug.
Description Mark Martinec 2010-02-17 19:42:21 UTC
Created attachment 4671 [details]
patch implementing the dns0x20 feature

draft-vixie-dnsext-dns0x20

( http://tools.ietf.org/html/draft-vixie-dnsext-dns0x20-00 )

                               Abstract

The small (16-bit) size of the DNS transaction ID has made it a
frequent target for forgery, with the unhappy result of many cache
pollution vulnerabilities demonstrated throughout Internet history.
Even with perfectly and unpredictably random transaction ID's, random
and birthday attacks are still theoretically feasible.  This document
describes a method by which an initiator can improve transaction
identity using the 0x20 bit in DNS labels.


The attached patch implements the draft-vixie-dnsext-dns0x20
when enabled by:
  dns_options dns0x20


Documented as:

 =item dns_options opts   (default: empty)                                     
                                                                               
 Provides a whitespace-separated list of options applying to DNS resolver.     
 Available options are 'rotate' and 'dns0x20'.                                 

 Option 'dns0x20' enables randomization of letters in a DNS query label
 according to draft-vixie-dnsext-dns0x20-00, decreasing a chance of
 collisions of responses (by chance or by a malicious intent) by increasing
 spread as provided by a 16-bit query ID and up to 16 bits of a port number,
 with additional bits as encoded by flipping case (upper/lower) of letters
 in a query. Should work reliably with modern resolvers - do not turn on
 if you see frequent info messages "dns: no callback for id:" in the log.
Comment 1 Mark Martinec 2010-02-18 00:30:37 UTC
Updated to:

=item dns_options opts   (default: empty)                                     

Provides a (whitespace or comma -separated) list of options applying to       
DNS resolving. Available options are 'rotate' and 'dns0x20' (without quotes). 
Option name may be negated by prepending a 'no' (e.g. 'norotate') to          
counteract previously enabled option. The last setting in configuration       
files prevails. By default options 'rotate' and 'dns0x20' are disabled.       
                                    
Option 'rotate' [...]
           
Option 'dns0x20' enables randomization of letters in a DNS query label        
according to draft-vixie-dnsext-dns0x20, decreasing a chance of collisions    
of responses (by chance or by a malicious intent) by increasing spread        
as provided by a 16-bit query ID and up to 16 bits of a port number,          
with additional bits as encoded by flipping case (upper/lower) of letters     
in a query. The number of additional random bits corresponds to the number    
of letters in a query label. Should work reliably with all mainstream         
DNS servers - do not turn on if you see frequent info messages                
"dns: no callback for id:" in the log, or if RBL or URIDNS lookups            
do not work for no apparent reason.                                           


trunk:

Bug 6338: Use of Bit 0x20 in DNS Labels to Improve Transaction Identity
(adds 'dns_options dns0x20', allows negation of dns options, off by default)
Sending        lib/Mail/SpamAssassin/Conf.pm
Sending        lib/Mail/SpamAssassin/Dns.pm
Sending        lib/Mail/SpamAssassin/DnsResolver.pm
Transmitting file data ...
Committed revision 911235.
Comment 2 Mark Martinec 2010-02-18 14:18:27 UTC
preserve entropy across Razor call,
reveal less of a random accumulator at a time
Sending        lib/Mail/SpamAssassin/DnsResolver.pm
Sending        lib/Mail/SpamAssassin/Plugin/Razor2.pm
Transmitting file data ..
Committed revision 911411.
Comment 3 Matt Sergeant 2010-02-18 16:46:51 UTC
Doesn't this just change the query and not check it is valid on return? Or is the return check already done elsewhere?
Comment 4 Mark Martinec 2010-02-18 17:09:04 UTC
> Doesn't this just change the query and not check it is valid on return?
> Or is the return check already done elsewhere?

It is checked by existing code in poll_responses: it tries to associate
a 'signature' (i.e. $self->_packet_id($packet) ) of a received reply
with a 'signature' of a transmitted query, they must match exactly.
If they do not, we end up with a "dns: no callback for id:" message.

This 'signature' is constructed in _packet_id() by concatenating the:
id, query-string, type, and class. (The port number matching is done
by the Net::DNS and a network layer). The 'signature' of a query section
in a reply packet must match exactly (no case-insensitivity) to the
query section of the transmitted request. The query-string (e.g. a
case-permuted host name) is thus an integral part of the matching,
any changes in case of its letters would break the match.
Comment 5 Matt Sergeant 2010-02-18 17:12:07 UTC
Awesome. Thanks.
Comment 6 Mark Martinec 2010-03-01 19:50:02 UTC
Now that I think of it, even the current (3.2, 3.3) code relies on a query
section of a reply packet matching exactly the query packet. This happens
to work on all mainstream DNS servers, but there is no guarantee for this
in a form of a RFC requirement.  In essence, we are already depending on
poor-man's form of a dns0x20, just without any additional entropy.

The 'dns_options dns0x20' could just as well default to true, without
breaking anything that isn't already broken.

Does anybody feel we need to lift the requirement for an exact (case-for-case)
match when dns0x20 option is NOT enabled? Some poor soul on a cheap home
router/firewall/dns-server may be affected by this without knowing why
his SA DNS queries sometimes fail.
Comment 7 Kevin A. McGrail 2010-03-01 20:00:46 UTC
(In reply to comment #6)
> Now that I think of it, even the current (3.2, 3.3) code relies on a query
> section of a reply packet matching exactly the query packet. This happens
> to work on all mainstream DNS servers, but there is no guarantee for this
> in a form of a RFC requirement.  In essence, we are already depending on
> poor-man's form of a dns0x20, just without any additional entropy.
> 
> The 'dns_options dns0x20' could just as well default to true, without
> breaking anything that isn't already broken.
> 
> Does anybody feel we need to lift the requirement for an exact (case-for-case)
> match when dns0x20 option is NOT enabled? Some poor soul on a cheap home
> router/firewall/dns-server may be affected by this without knowing why
> his SA DNS queries sometimes fail.

If I understand you correctly, currently we require an exact match and that could be causing some cheap-home DNS proxies, etc. to be having problems?

I'd say let's add a dbg that outputs the non-match if we can and if that generates a lot of user questions, we open a different bug and address.

KAM
Comment 8 Justin Mason 2010-03-01 22:55:33 UTC
I'd like to let this "bake" in trunk for a little bit more, btw, before putting it in 3.3.x, if that's ok.
Comment 9 Karsten Bräckelmann 2010-03-02 00:42:30 UTC
(In reply to comment #6)
> Does anybody feel we need to lift the requirement for an exact (case-for-case)
> match when dns0x20 option is NOT enabled? Some poor soul on a cheap home
> router/firewall/dns-server may be affected by this without knowing why
> his SA DNS queries sometimes fail.

Are you talking about a DNS server responding with a canonicalized, all lower case version?

Anyway, the "cheap home router" scenario is exactly what's most likely to fail ALWAYS for large DNS BLs, as apposed to "sometimes" due to response mis-match -- the DHCP assigned forwarder ISP's DNS is most likely to be blacklisted by major DNS BLs, and that user won't get any hits for them.
Comment 10 Mark Martinec 2010-03-02 01:13:56 UTC
> I'd like to let this "bake" in trunk for a little bit more, btw,
> before putting it in 3.3.x, if that's ok.

Sure, I haven't touched the target milestone.

> If I understand you correctly, currently we require an exact match and that
> could be causing some cheap-home DNS proxies, etc. to be having problems?

Exactly. Or maybe with some proprietary/vendor DNS server used by
some ISP or a company.

> I'd say let's add a dbg that outputs the non-match if we can and if that
> generates a lot of user questions, we open a different bug and address.

Issuing a dbg() or info() on a mismatch would probably be a good idea.
Unfortunately it is not trivial to implement - I guess that all queries
would need to be stored twice, once with exact keys, and once with
lowercased keys - as we depend or a perl hash for reverse mapping of a
reply packet back to our query. I'll think about it.

> Are you talking about a DNS server responding with a canonicalized,
> all lower case version?

Yes, likely, or all-caps, or maybe passing back whatever comes from
the authority server.

The quoted draft states:

 6.1. Several popular authoritative DNS implemenations including ISC BIND
 (versions 4, 8, and 9), Nominum ANS, Akamai AKADNS, Neustar UltraDNS,
 Verisign Atlas, NLNetLabs NSD, PowerDNS, and DJBDNS were tested.  All
 copied the question name exactly, bit for bit, from the request into the
 response.

 6.2. Operational testing has revealed a small set of rare and/or private
 label authoritative DNS implementations who modify the 0x20 bits in
 question names while copying the question section from the request to
 the response.  Usually this modification is to set the 0x20 bit, thus
 converting a domain name to be all-lower-case (0x61..0x7A, e.g., a-z).


> Anyway, the "cheap home router" scenario is exactly what's most likely to
> fail ALWAYS for large DNS BLs, as apposed to "sometimes" due to response
> mis-match -- the DHCP assigned forwarder ISP's DNS is most likely to be
> blacklisted by major DNS BLs, and that user won't get any hits for them.

Not sure I follow. What I meant by 'sometimes' is that if a queried label
happens to be e.g. all-lowercase, a query may succeed, but may fail with a
mixed-case query. In our case, a queried label may come from a mail header
section (like From, To, ...), or from a rule specifying a RBL/URIBL.
Comment 11 Mark Martinec 2010-03-30 01:21:15 UTC
(In reply to comment #6)
> Now that I think of it, even the current (3.2, 3.3) code relies on a query
> section of a reply packet matching exactly the query packet. This happens
> to work on all mainstream DNS servers, but there is no guarantee for this
> in a form of a RFC requirement.  In essence, we are already depending on
> poor-man's form of a dns0x20, just without any additional entropy.
> 
> The 'dns_options dns0x20' could just as well default to true, without
> breaking anything that isn't already broken.
> 
> Does anybody feel we need to lift the requirement for an exact (case-for-case)
> match when dns0x20 option is NOT enabled? Some poor soul on a cheap home
> router/firewall/dns-server may be affected by this without knowing why
> his SA DNS queries sometimes fail.


trunk (3.4.0):

Bug 4260: rewrite DNS code to use a single socket, event-based model;
Bug 6338: Use of Bit 0x20 in DNS Labels to Improve Transaction Identity;

Remove case sensitivity on DNS label in a query section
when 'dns_options dns0x20' is NOT used - RFC 1035 does NOT require
DNS server to preserve case in a query section of a reply, even
though in practice all mainstream DNS servers do preserve it.
In effect, code before this patch was half-way between dns0x20
and nodns0x20 setting.

Sending lib/Mail/SpamAssassin/DnsResolver.pm
Committed revision 928955.
Comment 12 Karsten Bräckelmann 2010-04-01 12:46:07 UTC
(In reply to comment #10)
> > Anyway, the "cheap home router" scenario is exactly what's most likely to
> > fail ALWAYS for large DNS BLs, as apposed to "sometimes" due to response
> > mis-match -- the DHCP assigned forwarder ISP's DNS is most likely to be
> > blacklisted by major DNS BLs, and that user won't get any hits for them.
> 
> Not sure I follow. What I meant by 'sometimes' is that if a queried label
> happens to be e.g. all-lowercase, a query may succeed, but may fail with a
> mixed-case query. In our case, a queried label may come from a mail header
> section (like From, To, ...), or from a rule specifying a RBL/URIBL.

I was referring to your concern in comment 6 about the exact case match with respect to "some poor soul on a cheap home router", who might be affected.

My point being, that the cheap hardware usually just forwards DNS to the ISP's DNS. Which is likely to be blocked by major DNS BLs. Thus, unless the poor soul runs his own caching nameserver locally, he won't be affected by case mismatches due to the cheap hardware, but actually not get any blacklisted response off of the major DNS BLs.
Comment 13 Mark Martinec 2011-09-24 01:23:03 UTC
closing, implemented and in use in 3.4.0 for a year now