Subject: [Acme] POST-as-GET payload contents

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Tue, 4 Sep 2018 10:26:38 -0700

New day, new thread for a specific issue I'd like to nail down quickly.

> ISSUE 2: How should we signal that POST-as-GET request is different 
> from other POST requests?
>
> The current PR signals this by sending a JWS with an empty 
> (zero-octet) payload, instead of a JSON object.  Jacob and Daniel 
> suggested that we should instead use the payload being an empty JSON 
> object as the signal.  An earlier draft PR used a field in the 
> protected header.

In short, this question is about whether POST-as-GETs should have:

"payload": ""

or

"payload": "{}"

When implementing the first one (empty payload), Daniel and I each 
separately implemented a different bug that would have also accepted:

"payload": null

This may be quirk of Go's handling of byte arrays, but it may turn out 
to be a common pattern in JSON libraries. The downside, if a server 
implementer landed a bug like that, would be that clients might get away 
with generating the invalid "null" form, leading to interoperability 
problems.

There's also potential for client bugs that produce an empty payload 
simply due to an uninitialized field, rather than due to a POST-as-GET. 
This would produce confusing errors relating to GETs rather than a 
clearer "malformed input" error.

Lastly, many clients already implement the "{}" form as a way to GET an 
account, so expanding the use of "{}" minimizes disruption.

My preference is still for "{}" over "", but I am also willing to be 
convinced in the interests of landing this change speedily and keeping 
forward momentum.

---

From: Logan Widick <[email-masked]>
Date: Tue, 4 Sep 2018 14:17:11 -0500

I like using {} for the POST-as-GET payload as well.

Sincerely,

Logan Widick

On Tue, Sep 4, 2018, 12:26 Jacob Hoffman-Andrews <[email-masked]> wrote:

> _______________________________________________
> Acme mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/acme
>

---

From: Richard Barnes <[email-masked]>
Date: Wed, 5 Sep 2018 11:33:23 -0400

I'm tempted to say that the "" / null ambiguity is an interop problem for
JOSE, not for us.  But nonetheless, it's a problem.

I'm still uncomfortable with {}, though, because it risks colliding with
other POST uses.  What would you guys think about one of these explicit
markers:

1. A field in the protected header ("urn:ietf:params:acme:get": true) with
a requirement that the payload be "{}"
2. A field in the payload ({"get": true}) a requirement that if that field
be there, then there are no other fields present

Personally, I find (1) a little more explicit.  It's a little more bloat
because of the URN cruft, but (1) it doesn't make sense to register a
generic, unprefixed parameter, and (2) checking for "{}" is easier than
checking for "no other fields".

--Richard

---

From: Daniel McCarney <[email-masked]>
Date: Wed, 5 Sep 2018 12:23:36 -0400

#1 sounds OK to me

---

From: "Salz, Rich" <[email-masked]>
Date: Wed, 5 Sep 2018 16:44:28 +0000

I like the header, but rather than say the payload MUST be {} (which brings up all sorts of whitespace issues at least), maybe we should say the server MUST ignore the request body?

---

From: Richard Barnes <[email-masked]>
Date: Wed, 5 Sep 2018 12:46:47 -0400

Because being generous in what you receive is harmful.
https://tools.ietf.org/html/draft-iab-protocol-maintenance-00

In case anyone want to try to interop, I updated my lego patch to implement
(1):
https://github.com/bifurcation/lego/pull/1/commits/750383d7ad272a0894d6ff86d4d85d38f965c14f

On Wed, Sep 5, 2018 at 12:44 PM Salz, Rich <[email-masked]> wrote:

> I like the header, but rather than say the payload MUST be {} (which
> brings up all sorts of whitespace issues at least), maybe we should say the
> server MUST ignore the request body?
>

---

From: "Salz, Rich" <[email-masked]>
Date: Wed, 5 Sep 2018 16:53:31 +0000

*   Because being generous in what you receive is harmful.
https://tools.ietf.org/html/draft-iab-protocol-maintenance-00<https://urldefense.proofpoint.com/v2/url?u=https-3A__tools.ietf.org_html_draft-2Diab-2Dprotocol-2Dmaintenance-2D00&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=4LM0GbR0h9Fvx86FtsKI-w&m=lYcerr09XhdsUaFXXMZLv4sAfq3r-Nc2uKhaYjnBdpc&s=h1H5m5ejvoDCu-6t_gPl7-6njuU6OH8bsBhq-cGF6Zo&e=>

Sorry, I disagree with King Martin in this case. :)

I think mandating a specific requrest body is hard to get right.

---

From: Richard Barnes <[email-masked]>
Date: Wed, 5 Sep 2018 12:57:37 -0400

On Wed, Sep 5, 2018 at 12:53 PM Salz, Rich <[email-masked]> wrote:

>
>    - Because being generous in what you receive is harmful.
>
> <https://urldefense.proofpoint.com/v2/url?u=https-3A__tools.ietf.org_html_draft-2Diab-2Dprotocol-2Dmaintenance-2D00&d=DwMFaQ&c=96ZbZZcaMF4w0F4jpN6LZg&r=4LM0GbR0h9Fvx86FtsKI-w&m=lYcerr09XhdsUaFXXMZLv4sAfq3r-Nc2uKhaYjnBdpc&s=h1H5m5ejvoDCu-6t_gPl7-6njuU6OH8bsBhq-cGF6Zo&e=>
>
>
>

Can you point to an implementation framework where this would be
difficult?  AFAIK, every JSON library out there marshalls {} as "{}", with
no whitespace, and every JOSE library signs whatever string you give it.

---

From: Daniel McCarney <[email-masked]>
Date: Wed, 5 Sep 2018 13:00:21 -0400

>
> AFAIK, every JSON library out there marshalls {} as "{}", with no
> whitespace, and every JOSE library signs whatever string you give it.

I agree, I don't think the {} body will be an implementation challenge. We
can say that with some confidence because the existing draft already
includes a feature using this indicator:
https://tools.ietf.org/html/draft-ietf-acme-acme-14#section-7.3.3

I haven't seen anyone raising problems with this and there are definitely
implementations in the wild.

---

From: "Salz, Rich" <[email-masked]>
Date: Wed, 5 Sep 2018 17:01:10 +0000

*   Can you point to an implementation framework where this would be difficult?  AFAIK, every JSON library out there marshalls {} as "{}", with no whitespace, and every JOSE library signs whatever string you give it.

You know more than I do.  If it’s not an issue, okay.

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Wed, 5 Sep 2018 10:17:30 -0700

On 09/05/2018 08:33 AM, Richard Barnes wrote:
> 1. A field in the protected header ("urn:ietf:params:acme:get": true) 
> with a requirement that the payload be "{}"
> 2. A field in the payload ({"get": true}) a requirement that if that 
> field be there, then there are no other fields present

I dislike both of these options as adding complexity. My preference 
order is:

1) "{}"
2) ""
99) "urn:ietf:params:acme:get"

 > I'm still uncomfortable with {}, though, because it risks colliding 
with other POST uses.

The only current use it conflicts with is POSTing to challenges to 
trigger their validation. We can fix that two ways:

  - Define challenges as non-pollable: Poll authorizations instead, 
since they contain the challenges. This was something I'd proposed 
previously, in the spirit of "there should just be one way to do 
things." Right now, some clients poll authorizations and some poll 
challenges. There's no benefit to one way or the other, it's just a 
random implementer choice that sometimes exposes different code paths.

  - Define multiple POSTs to challenges as idempotent. That is, the 
first time you POST a "{}" body to a challenge it triggers validation, 
and subsequently it acts as a GET.

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 5 Sep 2018 12:22:52 -0700

> Sorry, I disagree with King Martin in this case. :)

I think he's still Prince Martin :)

-Ekr

---

From: Richard Barnes <[email-masked]>
Date: Wed, 5 Sep 2018 15:39:20 -0400

Using the same notation, I'm:

1) ""
2) "urn:ietf:params:acme:get"
99) "{}"

The problem with "{}" is not just what it conflicts with in the current
doc, it's that it constrains everything one might do in the future.  Same
with any other payload-only option (including {"get": true}) with valid
JSON payload.  So your options are (1) do something in the protected header
or (2) have the payload be something non-JSON.

If you want something payload-only that is not empty, that seems doable as
well.  We could require the payload to be the two-octet string 0x1844,
which conveniently base64url-encodes to "GET" :)

---

From: Jacob Hoffman-Andrews <[email-masked]>
Date: Wed, 5 Sep 2018 12:43:31 -0700

> 2) "urn:ietf:params:acme:get"

Given that, I'm willing to compromise on "". I think the experience we 
had of almost implementing bugs with that approach was informative, but 
isn't decisive.

---

From: Richard Barnes <[email-masked]>
Date: Wed, 5 Sep 2018 16:10:46 -0400

> had of almost implementing bugs with that approach was informative, but

Thanks for compromising.  I agree that the interop stuff will cause some
hiccups, but hopeful that rather than being a blocker for folks, it will
create some pressure for JOSE libraries to interop better in this case.  In
any case, I'll update the PR to make extra clear that {payload: ""} is
what's required.

Anyone else have opinions before we consider this closed?

--Richard

---

From: Tim Hollebeek <[email-masked]>
Date: Thu, 6 Sep 2018 12:16:56 +0000

I agree “” is better than “{}”.

-Tim

From: Acme <[email-masked]> On Behalf Of Richard Barnes
Sent: Wednesday, September 5, 2018 4:11 PM
To: Jacob Hoffman-Andrews <[email-masked]>
Cc: Logan Widick <[email-masked]>; IETF ACME <[email-masked]>
Subject: Re: [Acme] POST-as-GET payload contents

On Wed, Sep 5, 2018 at 3:43 PM Jacob Hoffman-Andrews <[email-masked] <mailto:[email-masked]> > wrote:

Thanks for compromising.  I agree that the interop stuff will cause some hiccups, but hopeful that rather than being a blocker for folks, it will create some pressure for JOSE libraries to interop better in this case.  In any case, I'll update the PR to make extra clear that {payload: ""} is what's required.

--Richard