Subject: [Doh] DOH and Induced DNS

From: dagon <[email-masked]>
Date: Mon, 6 Nov 2017 17:07:50 +0000

I might have missed something in the draft, but I worry about a misuse
of the DOH protocol.  To my knowledge, there exists no practical means
(outside of Flash, java applets, and special, limited DNS prefetch
circumstances) for web sites to provoke third-party clients into
performing mass (million+) DNS queries.  Indeed, for this reason,
projects such as the ICSI Netalyzr resort to signed applets, which
users must inspect and intentionally approve.  Outside of these
limited and off-by-default cases, HTML visits can't generate arbitrary
volumes of DNS queries. A handful, yes, but not DoS-levels.

But depending on how the DOH stubs are implemented, DNS traffic could
be induced through trivially crafted javascript.  For example, if
GET/POST primitives are all that's needed, javascript and 'document
write' calls can generate random child label queries towards a target
zone, e.g. repeated GETs for the encoding of "${UNIX_EPOCH}.\
victimzone.example.com". Instead of doing a handful of DNS lookups
(mostly prefetch), a web visitor could perform thousands or millions
of queries.

Consider these scenarios: could one purchase ads which induce DOH
queries non-stop?  Likewise, could one insert such content on popular
forums, troll links on popular sites, or otherwise attract enough
views to generate streams of repeated DOH queries from browsers?  A
few thousand web views would turn into millions of DNS queries.  At
present, misuse of HTML may trigger only a few dozen DNS prefetches,
if such resolution is not already turned off by the site (as it is
with https by default).

If these concerns are valid, and not a misreading of the draft, then I
offer these further comments and suggestions:

  a) UI proof-of-life?  Perhaps DOH resolution should be tied to
intentional user action, somehow known to the stubs, based on UIX
feedback, and perhaps presented as proof to the recursive and
authority through new EDNS fields.  I recognize this idea as bad and
unworkable, but offer it to suggest a larger goal: DOH queries should
reflect a browser user's express desires, and not the worst intentions
of the HTML/js author.

  b) Recursive BMPs?  I appreciate that the draft is only focused on
wire format issues.  But perhaps the DOH draft could address various
implementation choices, such as aggregate query limits, same-origin
limitations on DOH-based queries, and the like?  Some stub
implementation guidelines seem prudent.

  c) Header-only?  If we assume implementation mistakes will always
occur in DOH stubs and recursives, perhaps the wire encoding should
appear only in HTTP headers, since these are less easily manipulated
by crafted javascript and HTML.  At the same time, the headers are
presumably within reach of the stub.  Header fields seem more likely
to reflect browser user decisions, and not the HTML author's malicious
whims.  (At least the problem would only be as bad as DNS prefetch, in
terms of volume.)

  d) Recursion only?  I assume non-recursive queries would be rejected
by the DOH servers.  Should the protocol require this?  The same
question applies to invalid DNS messages.  Should DOH proxies/stubs
and recursives parse and validate the query, or may they naively put
the DNS message on the wire, "as is"?  Naive DOH recursive
implementations may do the latter, enabling a large range of proxied
DNS probes and protocol attacks.  (E.g., 0-day "query of death" packets
can be delivered via Tor, perhaps.  Maybe this is slightly more
convenient than spoofed UDP.)

  e) ECS opt-in?  I suspect all DOH enabled recursives will also be
ECS speakers.  A standard concerned with privacy might suggest that
DOH stubs be ECS-disabled (or scope 0) by default, since EDNS client
subnet payloads communicate information about the stub.

  At the least, DOH stubs must expose this switch to the user, even if
the vendor decides to use an opt-out approach.  A DOH stub without ECS
opt-outs effectively mandates subnet leaks to arbitrary websites,
unbalancing the privacy trade-off in RFC 7871.  Likewise, a malicious
website could discover the client IP, and deliver ALL the client
octets (and just not the network), to any DOH recursive, via crafted
GETs.

                           *    *    *

DOH is a tectonic shift in how users produce DNS queries.  It
potentially lets any normal html author wield a "Great Cannon"
capability, https://citizenlab.ca/2015/04/chinas-great-cannon/
assuming crafted HTML/js can appear on enough browsers.  It further
raises interesting questions about user intention, DNS privacy, and
authority DDoS query flooding.  It greatly expands the attack surface
that malicious site operators can use, to either expose more user
information or exfiltrate data.  Absent firm DOH stub guidelines, and
DOH recursive best practices, it seems to expand the surveillance and
measurement capabilities of DNS researchers.

If I have not misunderstood the draft protocol, then hopefully my
suggestions point to practical solutions.

-- 
David Dagon
[email-masked]
D970 6D9E E500 E877 B1E3  D3F8 5937 48DC 0FDC E717

---

From: Adam Roach <[email-masked]>
Date: Mon, 6 Nov 2017 12:21:33 -0600

> (mostly prefetch), a web visitor could perform thousands or millions

So you mean something equivalent to:

var date = new Date();
while (1) {
   var img = document.createElement('image');
   img.src = date.getTime() + date.getMilliseconds() + 
".victimzone.example.com";
   document.body.appendChild(img);
}

It's not clear that you're describing something new.

(It's also worth noting that, in the scenario you're describing, the 
victim DOH server would have to opt-in to allowing the attacking site to 
query it, unlike the script above. See [1] and [2] for background)

/a

____
[1] https://en.wikipedia.org/wiki/Same-origin_policy
[2] https://en.wikipedia.org/wiki/Cross-origin_resource_sharing

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 7 Nov 2017 10:32:52 +1100

> On 7 Nov 2017, at 4:07 am, dagon <[email-masked]> wrote:
> 

It's trivial for scripts to modify headers, EXCEPT those starting with Sec-:
  https://fetch.spec.whatwg.org/#forbidden-header-name

If this is a concern, it might be workable to define a header that looks something like:

Sec-Doh: 1

to indicate that the request was generated by the browser / client internals, not script.

Cheers,

--
Mark Nottingham   https://www.mnot.net/

---

From: Adam Roach <[email-masked]>
Date: Mon, 6 Nov 2017 17:39:42 -0600

> to indicate that the request was generated by the browser / client internals, not script.

If the notion here is to prevent JS-initiated queries, I'll point out 
that this is explicitly prohibited by the working group charter: "While 
access to DNS-over-HTTPS servers from JavaScript running in a typical 
web browser is not the primary use case for this work, precluding the 
ability to do so would require additional preventative design. The 
working group will not engage in such preventative design."

/a

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 7 Nov 2017 10:42:48 +1100

> On 7 Nov 2017, at 10:39 am, Adam Roach <[email-masked]> wrote:
> 
> If the notion here is to prevent JS-initiated queries, I'll point out that this is explicitly prohibited by the working group charter: "While access to DNS-over-HTTPS servers from JavaScript running in a typical web browser is not the primary use case for this work, precluding the ability to do so would require additional preventative design. The working group will not engage in such preventative design."

No, the intent is to allow a DOH server to distinguish between JS-initiated requests and "native" ones, making up its own mind what to do with that information.

---

From: Adam Roach <[email-masked]>
Date: Mon, 6 Nov 2017 17:47:05 -0600

> No, the intent is to allow a DOH server to distinguish between JS-initiated requests and "native" ones, making up its own mind what to do with that information.

It seems that the information in the "Referrer" header field would 
already provide this ability, and with far better granularity than a 
simple "yes/no".

/a

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 7 Nov 2017 10:50:18 +1100

> On 7 Nov 2017, at 10:47 am, Adam Roach <[email-masked]> wrote:
> 
> It seems that the information in the "Referrer" header field would already provide this ability, and with far better granularity than a simple "yes/no".

It could -- or Origin.