Subject: Re: [Acme] Adam Roach's Discuss on draft-ietf-acme-acme-14: (with DISCUSS and COMMENT)

From: Richard Barnes <[email-masked]>
Date: Wed, 3 Oct 2018 00:43:49 +0200

In the spirit of giving credit where credit is due: I just noticed that
Sophie Herold had suggested making URLs non-guessable all the way back in
January [0].  Not sure why that got missed at the time (looks like we got
distracted by the reasoning), but retroactive thanks to Sophie!

[0] https://mailarchive.ietf.org/arch/msg/acme/usaOr4Bnyma4jX1fjfE4Lftai8E

On Thu, Aug 30, 2018 at 6:50 AM Adam Roach <[email-masked]> wrote:

> Adam Roach has entered the following ballot position for
> draft-ietf-acme-acme-14: Discuss
>
> When responding, please keep the subject line intact and reply to all
> email addresses included in the To and CC lines. (Feel free to cut this
> introductory paragraph, however.)
>
>
> Please refer to https://www.ietf.org/iesg/statement/discuss-criteria.html
> for more information about IESG DISCUSS and COMMENT positions.
>
>
> The document, along with other ballot positions, can be found here:
> https://datatracker.ietf.org/doc/draft-ietf-acme-acme/
>
>
>
> ----------------------------------------------------------------------
> DISCUSS:
> ----------------------------------------------------------------------
>
> Thanks for all the work that everyone has put into this protocol. I'm
> excited by
> what it's been able to do for the certificate issuance sector as a whole,
> and
> truly appreciate all of the early implementors who have put both clients
> and
> servers into active production. I'm definitely balloting YES once we get
> clarity
> on my DISCUSS, below.
>
> ---------------------------------------------------------------------------
>
> I've looked at this several different ways, and I must be missing something
> obvious -- which should make this easy to clear.
>
> §6.2:
>
> >  Note that authentication via signed JWS request bodies implies that
> >  GET requests are not authenticated.  Servers MUST NOT respond to GET
> >  requests for resources that might be considered sensitive.  Account
> >  resources are the only sensitive resources defined in this
> >  specification.
>
> This doesn't seem correct.
>
> For example, let's imagine that I, as a user, get the directory for an ACME
> server, the body of which is the example in §7.1.1. Then, I go through the
> new-account process, and receive the Account object in §7.1.2:
>
>    {
>      "status": "valid",
>      "contact": [
>        "mailto:[email-masked]",
>        "mailto:[email-masked]"
>      ],
>      "termsOfServiceAgreed": true,
>      "orders": "https://example.com/acme/acct/1/orders"
>    }
>
> Huh. Suddenly, I'm not so interested in *my* orders, because I've noticed
> that
> different users' orders are apparently at a predictable URL that varies
> only by
> a small integer. Curious, I change the "1" to a "2" and send:
>
>   GET /acme/acct/2/orders HTTP/1.1
>   Host: example.com
>
> And get back not *my* orders, but someone *else's* orders.
>
>    HTTP/1.1 200 OK
>    Content-Type: application/json
>
>    {
>      "orders": [
>        "https://example.com/acme/acct/2/order/1",
>        "https://example.com/acme/acct/2/order/2",
>        "https://example.com/acme/acct/2/order/3",
>        "https://example.com/acme/acct/2/order/4"
>      ]
>    }
>
> Interesting. So now I can do four more unauthenticated GETs and grab those
> order
> objects.
>
>    HTTP/1.1 200 OK
>    Content-Type: application/json
>
>    {
>      "status": "valid",
>      ...
>      "identifiers": [
>        { "type": "dns", "value": "smithforcongress.example" }
>      ],
>      ...
>      "certificate": "https://example.com/acme/cert/1234"
>    }
> ----------
>    HTTP/1.1 200 OK
>    Content-Type: application/json
>
>    {
>      "status": "valid",
>      ...
>      "identifiers": [
>        { "type": "dns", "value":
> "something-embarassing-with-goats.example" }
>      ],
>      ...
>      "certificate": "https://example.com/acme/cert/5678"
>    }
> ----------
>    HTTP/1.1 200 OK
>    Content-Type: application/json
>
>    {
>      "status": "valid",
>      ...
>      "identifiers": [
>        { "type": "email", "value": "[email-masked]"
> }
>      ],
>      ...
>      "certificate": "https://example.com/acme/cert/9abc"
>    }
> ----------
>    HTTP/1.1 200 OK
>    Content-Type: application/json
>
>    {
>      "status": "valid",
>      ...
>      "identifiers": [
>        { "type": "tn", "value": "+12025550172" }
>      ],
>      ...
>      "certificate": "https://example.com/acme/cert/defg"
>    }
>
> So now I've learned that the same account has pulled certs for both
> "smithforcongress.example" and "something-embarassing-with-goats.example";
> that
> they have control over the email address
> "[email-masked]," and that their phone number is
> +1 202
> 555 0172. There's a pretty good chance that... someone didn't want all of
> that
> to be generally known.
>
> And... huh... that's interesting.
>
>      GET /acme/cert/9abc HTTP/1.1
>      Host: example.com
>
>      HTTP/1.1 200 OK
>      Content-Type: application/pem-certificate-chain
>      Link: <https://example.com/acme/some-directory>;rel="index"
>
>      -----BEGIN CERTIFICATE-----
>      [X.509 Cert for [email-masked]]
>      -----END CERTIFICATE-----
>      -----BEGIN CERTIFICATE-----
>      [Issuer certificate contents]
>      -----END CERTIFICATE-----
>      -----BEGIN CERTIFICATE-----
>      [Other certificate contents]
>      -----END CERTIFICATE-----
>
> Whoa. That's cool. The next thing I'm doing is configuring Thunderbird to
> forge
> mail from [email-masked] and going on an email
> spree
> admitting to owning a rather embarrassing domain name, in which I ask
> concerned
> constituents to call me on my unlisted phone number to discuss the issue.
>
> Clearly I've missed something, because this just seems way too obvious.
> What
> prevents this attack (or a similar one from observing that the order URLs
> are
> predictable?)
>
> If I *haven't* missed something, then there appears to have been an
> assumption
> here, never written into the document, that the URLs generated for the
> orders
> list and for the order objects are unguessable. If that's the case, I
> would:
>
> (1) Expect this to be stated in section 7.1.2.1 and 7.1.3
>
> (2) Expect a specification of a reasonable number of bits of entropy to
> use in
>     orders list and order object URLs.
>
> (3) Expect the examples to show appropriately random URLs (e.g.
>
> https://example.com/acme/acct/9258fac3-7866-4922-90e6-bbd0c89e751a/orders)
>
>
> (4) Expect a treatment in section 10 of the risks that might arise from
> third
>     parties gaining access to orders, as doing so provides free-and-clear
> access
>     to private certificates (which, for dns, can be trivially used to
>     revoke certs; and for other types, can be used for impersonation as
> well)
>
> Again, I'm still expecting that I've simply missed something obvious -- I
> just
> can't for the life of me figure out what it is.
>
>
> ----------------------------------------------------------------------
> COMMENT:
> ----------------------------------------------------------------------
>
> I have a small handful of substantive comments, and several editorial nits.
>
> ---------------------------------------------------------------------------
>
> General:
>
> This protocol specifies the use of RFC 3339 time formats in several
> places. Most
> modern protocols that reference RFC 3339 choose to place further
> restrictions on
> the format; commonly, the time-secfrac portion is required to be omitted,
> and
> the time-offset portion is required to be "Z". In addition to making
> parsing
> easier, these restrictions have the property of any given time having only
> one
> possible string representation.
>
> My suggestion would be for ACME to include similar restrictions.
> Alternately, if
> the full range of optionality allowed by RFC 3339 is actually intended,
> please
> adjust the examples so that at least a few of them include fractional
> seconds
> and non-UTC timezones.
>
> ---------------------------------------------------------------------------
>
> §5:
>
> For avoidance of doubt, this section should probably indicate that values
> that
> will appear in certificates will be used and conveyed in the form present
> in
> certificates, possibly with a reference to RFC 5280 section 7.
>
> ---------------------------------------------------------------------------
>
> §6.4.1:
>
> >  The server MUST generate the value provided in
> >  Replay-Nonce in such a way that they are unique to each message, with
> >  high probability.  For instance, it is acceptable to generate Replay-
> >  Nonces randomly.
>
> It's not clear whether the values need to also be unpredictable; e.g.,
> would it
> be okay if the value of the nonce for operation n+1 could be easily
> derived or
> guessed from the nonce for operation n?
>
> ---------------------------------------------------------------------------
>
> §7.4.2:
>
> >  GET /acme/cert/asdf HTTP/1.1
> >  Host: example.com
> >  Accept: application/pkix-cert
> >
> >  HTTP/1.1 200 OK
> >  Content-Type: application/pem-certificate-chain
>
> This pairing of "Accept: application/pkix-cert" with "Content-Type:
> application/pem-certificate-chain" seems to be at odds with the
> description in
> RFC 7231 §5.3.2. I know that proactive negotiation is optional in HTTP,
> but it
> seems that it would be much better to show this as something like:
>
>    GET /acme/cert/asdf HTTP/1.1
>    Host: example.com
>    Accept: application/pkix-cert, application/pem-certificate-chain;q=0.5
>
> ===========================================================================
>
> All of my remaining comments are editorial in nature, and most of those are
> minor editorial nits.
>
>
> i-d nits reports:
>
>   ** There are 3 instances of too long lines in the document, the longest
> one
>      being 15 characters in excess of 72.
>
> I'm not sure it's reasonable to expect the RFC editor to have enough
> knowledge
> to know how to best split the key authorization across lines (or to elide
> portions of it, whichever makes more sense).
>
> ---------------------------------------------------------------------------
>
> i-d nits also reports:
>
>   -- The exact meaning of the all-uppercase expression 'NOT REQUIRED' is
> not
>      defined in RFC 2119.  If it is intended as a requirements expression,
> it
>      should be rewritten using one of the combinations defined in RFC 2119;
>      otherwise it should not be all-uppercase.
>
> ---------------------------------------------------------------------------
>
> §1:
>
> >  Existing Web PKI certificate authorities tend to use a set of ad hoc
> >  protocols for certificate issuance and identity verification.  In the
> >  case of DV certificates, a typical user experience is something like:
>
> I expect this text won't age gracefully. Even at the time of publication of
> this document, over 64% of all certificates issued on the web have been
> issued
> using the ACME protocol, arguably making it the "typical user experience."
> (see
>
> https://censys.io/certificates/report?q=tags%3Atrusted&field=parsed.issuer.organization.raw&max_buckets=50
> )
>
> I suggest caveating this paragraph with text along the lines of "prior to
> the
> advent of the protocol described by this document, the typical user
> experience
> was..."
>
> ---------------------------------------------------------------------------
>
> §1:
>
> >  For example, as of this writing, there is
> >  ongoing work to use ACME for issuance of Web PKI certificates
> >  attesting to IP addresses [I-D.ietf-acme-ip] and STIR certificates
> >  attesting to telephone numbers [I-D.ietf-acme-telephone].
>
> Suggestion: consider including [draft-ietf-acme-email-smime] in this list.
>
> ---------------------------------------------------------------------------
>
> §6.2:
>
> >  These intermediaries can also change values in the request that are
> >  not signed in the HTTPS request, e.g., the request URL and headers.
>
> Nit: "...header fields."
>
> ---------------------------------------------------------------------------
>
> §6.4:
>
> >  An error response with the
> >  "badNonce" error type MUST include a Replay-Nonce header with a fresh
> >  nonce.
>
> Nit: "...header field..."
>
> ---------------------------------------------------------------------------
>
> §6.5:
>
> >  "urn:ietf:params:acme:error:rateLimited".  Additionally, the server
> >  SHOULD send a "Retry-After" header [RFC7231] indicating when the
> >  current request may succeed again.
>
> Nit: "...header field..."
>
> >  In addition to the human-readable "detail" field of the error
> >  response, the server MAY send one or multiple link relations in the
> >  "Link" header  [RFC8288] pointing to documentation about the specific
> >  rate limit that was hit, using the "help" link relation type.
>
> Nit: "...header field..."
>
> ---------------------------------------------------------------------------
>
> §7.1:
>
> >  The "->" is a mnemonic for a Location
> >  header pointing to a created resource.
>
> Nit: "...header field..."
>
> ---------------------------------------------------------------------------
>
> §7.1.2.1:
>
> >  The server MAY
> >  return an incomplete list, along with a Link header with a "next"
> >  link relation indicating where further entries can be acquired.
>
> Nit: "...header field..."
>
> ---------------------------------------------------------------------------
>
> §7.3.4:
>
> >  This response MUST
> >  include a Link header with link relation "terms-of-service" and the
> >  latest terms-of-service URL.
>
> Nit: "...header field..."
>
> ---------------------------------------------------------------------------
>
> §7.4.2:
>
> >  Because certificate resources are immutable once issuance is
> >  complete, the server MAY enable the caching of the resource by adding
> >  Expires and Cache-Control headers specifying a point in time in the
> >  distant future.  These headers have no relation to the certificate's
> >  period of validity.
>
> Nit: "...header fields..." (twice)
>
> >  The ACME client MAY request other formats by including an Accept
> >  header [RFC7231] in its request.
>
> Nit: "...header field..."
>
> >  provide one or more "Link: rel="up"" headers pointing to an issuer or
>
> Nit: "...header fields..."
>
> ---------------------------------------------------------------------------
>
> §7.5:
>
> >  When a client receives an order from the server it downloads the
> >  authorization resources by sending GET requests to the indicated
> >  URLs.
>
> Nit: "...from the server, it downloads..."
>
>
>