Subject: [jose] Text about applications and "alg":"none"

From: Mike Jones <[email-masked]>
Date: Tue, 3 Sep 2013 18:02:35 +0000

I took an action item during the last call to write text along the lines suggested by ekr about applications and "alg":"none".  I propose that the following text be included:

It is RECOMMENDED that libraries provide applications a means of specifying the list of acceptable algorithms used in a JWS object in a way that causes inputs using algorithms outside the specified set to be rejected.  In particular, it is intended for applications to use this mechanism to exclude accepting inputs using "alg":"none" in security contexts where non-integrity protected inputs are not acceptable.

Feedback/proposed wording refinements welcomed.

                                                                -- Mike

---

From: Richard Barnes <[email-masked]>
Date: Tue, 3 Sep 2013 16:33:22 -0400

This text is still far too weak, and does not reflect what I remember EKR
saying (in particular, there is no MUST).  It does not address the attack
where an application may, in general, be willing to accept both signed and
unsigned content, but each in specific contexts.  Proposed text:

"""
JWS implementations MUST provide an interface for applications to specify a
list of "alg" values that are acceptable for the validation of a given JWS
object.  JWS implementations MUST NOT indicate that a JWS object is valid
if the "alg" value for the object is "none", unless the application has
specifically indicated that the value "none" is acceptable for the
particular JWS object being validated.  Applications using "none" MUST
indicate support on a per-object basis, in order to avoid downgrade attacks
that arise if more broadly-applicable preferences are specified.
"""

I continue to believe that this is far too subtle, and that applications
are very likely to get it wrong.  It is far simpler and safer to require
that a JWS implementation MUST reject an object with "alg":"none", and have
another content type for unsigned content.

Also, if "none" is going to remain, then it needs to be OPTIONAL.  Given
all the above limitations, I don't see how you could justify it being
mandatory.

--Richard

On Tue, Sep 3, 2013 at 2:02 PM, Mike Jones <[email-masked]>wrote:

>  I took an action item during the last call to write text along the lines
> suggested by ekr about applications and "alg":"none".  I propose that the
> following text be included:****
>
> ** **
>
> It is RECOMMENDED that libraries provide applications a means of
> specifying the list of acceptable algorithms used in a JWS object in a way
> that causes inputs using algorithms outside the specified set to be
> rejected.  In particular, it is intended for applications to use this
> mechanism to exclude accepting inputs using "alg":"none" in security
> contexts where non-integrity protected inputs are not acceptable.****
>
> ** **
>
> Feedback/proposed wording refinements welcomed.****
>
> ** **
>
>                                                                 -- Mike***
> *
>
> ** **
>
> _______________________________________________
> jose mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/jose
>
>

---

From: Mike Jones <[email-masked]>
Date: Tue, 3 Sep 2013 22:47:21 +0000

Your proposed text seems overly verbose.  In particular, I believe you'll find that the text I proposed already means the same thing / modulo the difference between RECOMMENDED and MUST.  If the WG wants a MUST we could do that instead of RECOMMENDED.  We can discuss that on tomorrow's call.

The correspondence is as follows:
Your sentence 1 is covered in my sentence 1.
Your sentence 2 is covered in my sentence 1.
Your sentence 3 is covered in my sentences 1 & 2.  In particular, the "per-object basis" is already covered by "in a JWS object".  (If it were not on a per-object basis, it would have said something like "in all JWS objects".

                                                                Cheers,
                                                                -- Mike

From: Richard Barnes [mailto:[email-masked]]
Sent: Tuesday, September 03, 2013 1:33 PM
To: Mike Jones
Cc: [email-masked]
Subject: Re: [jose] Text about applications and "alg":"none"

This text is still far too weak, and does not reflect what I remember EKR saying (in particular, there is no MUST).  It does not address the attack where an application may, in general, be willing to accept both signed and unsigned content, but each in specific contexts.  Proposed text:

"""
JWS implementations MUST provide an interface for applications to specify a list of "alg" values that are acceptable for the validation of a given JWS object.  JWS implementations MUST NOT indicate that a JWS object is valid if the "alg" value for the object is "none", unless the application has specifically indicated that the value "none" is acceptable for the particular JWS object being validated.  Applications using "none" MUST indicate support on a per-object basis, in order to avoid downgrade attacks that arise if more broadly-applicable preferences are specified.
"""

I continue to believe that this is far too subtle, and that applications are very likely to get it wrong.  It is far simpler and safer to require that a JWS implementation MUST reject an object with "alg":"none", and have another content type for unsigned content.

Also, if "none" is going to remain, then it needs to be OPTIONAL.  Given all the above limitations, I don't see how you could justify it being mandatory.

--Richard

On Tue, Sep 3, 2013 at 2:02 PM, Mike Jones <[email-masked]<mailto:[email-masked]>> wrote:
I took an action item during the last call to write text along the lines suggested by ekr about applications and "alg":"none".  I propose that the following text be included:

                                                                -- Mike

_______________________________________________
jose mailing list
[email-masked]<mailto:[email-masked]>
https://www.ietf.org/mailman/listinfo/jose

---

From: Richard Barnes <[email-masked]>
Date: Wed, 4 Sep 2013 18:45:28 -0400

I think it's important to emphasize that an implementation MUST NOT allow a
global setting.  In fact, I would argue that if "none" is in the acceptable
algorithm list, it MUST be the only thing in the list.  Any other way, and
you end up with downgrade.

--Richard

On Tue, Sep 3, 2013 at 6:47 PM, Mike Jones <[email-masked]>wrote:

>  Your proposed text seems overly verbose.  In particular, I believe
> you’ll find that the text I proposed already means the same thing / modulo
> the difference between RECOMMENDED and MUST.  If the WG wants a MUST we
> could do that instead of RECOMMENDED.  We can discuss that on tomorrow’s
> call.****
>
> ** **
>
> The correspondence is as follows:****
>
> Your sentence 1 is covered in my sentence 1.****
>
> Your sentence 2 is covered in my sentence 1.****
>
> Your sentence 3 is covered in my sentences 1 & 2.  In particular, the
> “per-object basis” is already covered by “in a JWS object”.  (If it were
> not on a per-object basis, it would have said something like “in all JWS
> objects”.****
>
> ** **
>
>                                                                 Cheers,***
> *
>
>                                                                 -- Mike***
> *
>
> ** **
>
> *From:* Richard Barnes [mailto:[email-masked]]
> *Sent:* Tuesday, September 03, 2013 1:33 PM
> *To:* Mike Jones
> *Cc:* [email-masked]
> *Subject:* Re: [jose] Text about applications and "alg":"none"****
>
> ** **
>
> unsigned content, but each in specific contexts.  Proposed text:****
>
> ** **
>
> """****
>
> JWS implementations MUST provide an interface for applications to specify
> a list of "alg" values that are acceptable for the validation of a given
> JWS object.  JWS implementations MUST NOT indicate that a JWS object is
> valid if the "alg" value for the object is "none", unless the application
> has specifically indicated that the value "none" is acceptable for the
> that arise if more broadly-applicable preferences are specified.****
>
> """****
>
> ** **
>
> another content type for unsigned content.****
>
> ** **
>
> mandatory.****
> --Richard****
> On Tue, Sep 3, 2013 at 2:02 PM, Mike Jones <[email-masked]>
> wrote:****
>
>  ****
>  ****
>  ****
>  ****
> https://www.ietf.org/mailman/listinfo/jose****
>
> ** **
>

---

From: Richard Barnes <[email-masked]>
Date: Wed, 4 Sep 2013 18:49:15 -0400

Just so people have a point of comparison, my proposed "JSON Web Payload"
definition is in the patch attached to ISSUE-36:
<http://trac.tools.ietf.org/wg/jose/trac/attachment/ticket/36/ALG-NONE.patch

I agree with James and Vladimir that a separate object type is easier to
get right than all of the security checks that "none" requires.

--Richard

---

From: Richard Barnes <[email-masked]>
Date: Wed, 4 Sep 2013 18:50:59 -0400

Also, note this text needs to appear in JWS, not JWA, since it's a general
requirement on JWS implementations.  So in addition to requiring
implementations to be unnecessarily complex, it also breaks the clean
separation between those documents.

On Wed, Sep 4, 2013 at 6:45 PM, Richard Barnes <[email-masked]> wrote:

> I think it's important to emphasize that an implementation MUST NOT allow
> a global setting.  In fact, I would argue that if "none" is in the
> acceptable algorithm list, it MUST be the only thing in the list.  Any
> other way, and you end up with downgrade.
>
> --Richard
>
>
>>                                                                 Cheers,**
>> **
>>                                                                 -- Mike**
>> **
>>                                                                 -- Mike**
>> **

---

From: Richard Barnes <[email-masked]>
Date: Wed, 4 Sep 2013 18:51:20 -0400

BTW, I added support for JWP to PyJOSE.  It was easier than adding support
for "none".
<
https://github.com/bifurcation/pyjose/commit/5ad79d842beb6b680be6ba14263a9b85c29fde65

On Wed, Sep 4, 2013 at 6:49 PM, Richard Barnes <[email-masked]> wrote:

> <
> http://trac.tools.ietf.org/wg/jose/trac/attachment/ticket/36/ALG-NONE.patch
> >
>
>>  I took an action item during the last call to write text along the
>> lines suggested by ekr about applications and "alg":"none".  I propose that
>> the following text be included:****
>>
>> ** **
>>

---

From: Mike Jones <[email-masked]>
Date: Wed, 4 Sep 2013 22:55:07 +0000

Exactly the same security checks are required at the library level no matter what the protocol representation, assuming that the library supports all JOSE object types.  An object using your JWP is acceptable in exactly the same situations that an "alg":"none" JWS is, as there's no security difference between them - only a protocol syntax difference.

                                                                -- Mike

From: Richard Barnes [mailto:[email-masked]]
Sent: Wednesday, September 04, 2013 3:51 PM
To: Mike Jones
Cc: [email-masked]
Subject: Re: [jose] Text about applications and "alg":"none"

BTW, I added support for JWP to PyJOSE.  It was easier than adding support for "none".
<https://github.com/bifurcation/pyjose/commit/5ad79d842beb6b680be6ba14263a9b85c29fde65>

On Wed, Sep 4, 2013 at 6:49 PM, Richard Barnes <[email-masked]<mailto:[email-masked]>> wrote:
Just so people have a point of comparison, my proposed "JSON Web Payload" definition is in the patch attached to ISSUE-36:
<http://trac.tools.ietf.org/wg/jose/trac/attachment/ticket/36/ALG-NONE.patch>

I agree with James and Vladimir that a separate object type is easier to get right than all of the security checks that "none" requires.

--Richard

                                                                -- Mike

---

From: Richard Barnes <[email-masked]>
Date: Wed, 4 Sep 2013 19:04:43 -0400

No.  jose.verify(JWP) will always fail.  So there's no downgrade risk.

On Wed, Sep 4, 2013 at 6:55 PM, Mike Jones <[email-masked]>wrote:

>  Exactly the same security checks are required at the library level no
> matter what the protocol representation, assuming that the library supports
> all JOSE object types.  An object using your JWP is acceptable in exactly
> the same situations that an “alg”:”none” JWS is, as there’s no security
> difference between them – only a protocol syntax difference.****
>
> ** **
>
>                                                                 -- Mike***
> *
>
> ** **
>
> *Sent:* Wednesday, September 04, 2013 3:51 PM
>
> *To:* Mike Jones
> *Cc:* [email-masked]
> for "none".****
> On Wed, Sep 4, 2013 at 6:49 PM, Richard Barnes <[email-masked]> wrote:****
>
> definition is in the patch attached to ISSUE-36:****
>
> <
> get right than all of the security checks that "none" requires.****
>
> ** **
>
> --Richard****
>
> ** **
>

---

From: Richard Barnes <[email-masked]>
Date: Thu, 5 Sep 2013 11:10:27 -0400

Thinking on this a little more, it seems like it would be simpler to state
this just as an "allow unsigned" flag, rather than a more general
"acceptable algorithms" set.  That way we don't have to worry about all the
downgrade scenarios when you have "none" along with something else.

"""
Implementations that support unsigned JWS objects (i.e., the "alg" value
"none") MUST NOT accept such objects as valid unless the application
specifies that it is acceptable for a specific object to be unsigned.  For
example, the "verify" method of a JWS library might have a boolean
"acceptUnsigned" parameter that would indicate that "none" is an acceptable
"alg" value.

Applications MUST specify this flag on a per-object basis, since otherwise
they will be vulnerable to downgrade attacks.  For example, suppose an
application accepts JWS objects over two channels, (1) HTTP and (2) HTTPS
with client authentication. It requires a JWS signature on objects received
over HTTP, but accepts unsigned JWS objects over HTTPS.  If the application
sets a global setting that "none" is acceptable, then an attacker could
provide it with an unsigned object over HTTP and still have that object
considered valid.  Instead, the application needs to set the
"acceptUnsigned" flag to "false" for each object received over HTTP, and to
"true" for each object received over HTTPS.
"""

This makes the equivalence between the "separate object" and "constrained
verify" cases a lot clearer.  On the one hand, you would have
"jose.somethingNotVerify(JWP)", and on the other hand, you would have
"jose.verify(JWP, acceptUnsigned=True)".

--Richard

---

From: "Matt Miller (mamille2)" <[email-masked]>
Date: Thu, 5 Sep 2013 15:55:07 +0000

I agree with the intent, but I'm not very comfortable with the actual text.  It reads too much like software interface design, and I'd rather avoid telling people exactly how to write their software.

My suggested change (still makes me squeamish, but I can live with it):

"""
Implementations that support unsigned JWS objects (i.e., the "alg" value
"none") MUST NOT accept such objects as valid unless the application
specifies that it is acceptable for a specific object to be unsigned.
Implementations MUST NOT accept unsigned JWS objects by default.  For example,
the "verify" method of a hypothetical JWS software library might have a
boolean "acceptUnsigned" parameter (which defaults to "false") that indicates
"none" is an acceptable "alg" value.

In order to mitigate downgrade attacks, applications MUST NOT indicate
acceptance of unsigned JWS objects at a global level, and SHOULD specify
acceptance on a per-object basis.  For example, suppose an application accepts
JWS objects over two channels, (1) HTTP and (2) HTTPS with client
authentication.  It requires a JWS signature on objects received over HTTP,
but accepts unsigned JWS objects over HTTPS.  If the application globally
indicates that "none" is acceptable, then an attacker could provide it with an
unsigned object over HTTP and still have that object considered valid.
Instead, the application needs indicate acceptance of "none" for each object
received over HTTPS (e.g., by setting "acceptUnsigned" to "true" for the
hypothetical JWS software library above), but not for each object received over
HTTP.
"""

- m&m

Matt Miller < [email-masked] >
Cisco Systems, Inc.

---

From: Richard Barnes <[email-masked]>
Date: Thu, 5 Sep 2013 12:02:14 -0400

That text is fine with me.  I would prefer the SHOULD be a MUST, but I
could imagine some interface like RealJWSVerifier that takes things from
HTTP, vs. NotReallyAJWSVerifierDangerWillRobinson from HTTPS.

Though it does highlight the crazy contortions we're having to go through
to get "none" right, rather than just defining a separate syntax.

On Thu, Sep 5, 2013 at 11:55 AM, Matt Miller (mamille2)
<[email-masked]>wrote:

> I agree with the intent, but I'm not very comfortable with the actual
> text.  It reads too much like software interface design, and I'd rather
> avoid telling people exactly how to write their software.
>
>  For
> > On Tue, Sep 3, 2013 at 2:02 PM, Mike Jones <[email-masked]
> >wrote:
> >
> >>                                                                --
> Mike***

---

From: Mike Jones <[email-masked]>
Date: Thu, 5 Sep 2013 19:22:29 +0000

Thanks Matt, for suggesting the text.  The version below has slight edits to make it editorially consistent with the terminology used elsewhere in the specs and to give the acceptable algorithm list approach equal billing with the Boolean approach.

Implementations that support plaintext JWS objects (i.e., the "alg" value
"none") MUST NOT accept such objects as valid unless the application
specifies that it is acceptable for a specific object to be non-integrity-protected.
Implementations MUST NOT accept plaintext JWS objects by default.  For example,
the "verify" method of a hypothetical JWS software library might have a
boolean "acceptUnsigned" parameter (which defaults to "false") that indicates
"none" is an acceptable "alg" value.  As another example, the "verify" method
might take a list of algorithms that are acceptable to the application as a parameter
and would reject plaintext JWS values if "none" is not in that list.

In order to mitigate downgrade attacks, applications MUST NOT signal
acceptance of plaintext JWS objects at a global level, and SHOULD signal
acceptance on a per-object basis.  For example, suppose an application accepts
JWS objects over two channels, (1) HTTP and (2) HTTPS with client
authentication.  It requires a JWS signature on objects received over HTTP,
but accepts plaintext JWS objects over HTTPS.  If the application were to globally
indicate that "none" is acceptable, then an attacker could provide it with an
unsigned object over HTTP and still have that object successfully validate.
Instead, the application needs indicate acceptance of "none" for each object
received over HTTPS (e.g., by setting "acceptUnsigned" to "true" for the
first hypothetical JWS software library above), but not for each object received over
HTTP.

                                                            -- Mike

From: Richard Barnes [mailto:[email-masked]]
Sent: Thursday, September 05, 2013 9:02 AM
To: Matt Miller (mamille2)
Cc: Mike Jones; [email-masked]
Subject: Re: [jose] Text about applications and "alg":"none"

That text is fine with me.  I would prefer the SHOULD be a MUST, but I could imagine some interface like RealJWSVerifier that takes things from HTTP, vs. NotReallyAJWSVerifierDangerWillRobinson from HTTPS.

Though it does highlight the crazy contortions we're having to go through to get "none" right, rather than just defining a separate syntax.

On Thu, Sep 5, 2013 at 11:55 AM, Matt Miller (mamille2) <[email-masked]<mailto:[email-masked]>> wrote:
I agree with the intent, but I'm not very comfortable with the actual text.  It reads too much like software interface design, and I'd rather avoid telling people exactly how to write their software.

"""

- m&m

Matt Miller < [email-masked]<mailto:[email-masked]> >
Cisco Systems, Inc.

On Sep 5, 2013, at 9:10 AM, Richard Barnes <[email-masked]<mailto:[email-masked]>> wrote:

> On Tue, Sep 3, 2013 at 2:02 PM, Mike Jones <[email-masked]<mailto:[email-masked]>>wrote:
>

---

From: "Manger, James H" <[email-masked]>
Date: Fri, 6 Sep 2013 13:18:56 +1000

> "none") MUST NOT accept such objects as valid unless…
> For example, the "verify" method of a hypothetical JWS software library…

“unprotected JOSE message” would be better than “plaintext JWS object”. “plaintext” usually means the input to encryption; the major point is not to treat "alg": "none" like signed or MACed messages so don’t call it a JWS, even if it has the same syntax; “object” often means a set of name/value pairs.

I’m not sure a verify() method means the same to everyone. In Richard’s PyJOSE library I think verify() both parses and applies any necessary crypto checks. In the Nimbus-JOSE library, in contrast, parse() is quite separate from verify(). A verify() method doesn’t exist when parse() sees an "alg": "none" message. Consequently I don’t think talking about verify() is clear enough.

If an app is expecting a MACed message, it is crucial it doesn’t inadvertently accept an "alg": "none" message. It is also crucial that it doesn’t inadvertently accept an
"alg": "RS256" message. While only the 1 person you shared a symmetric key with can create MACed message that passes verify(), anyone certified by any commonly trusted CA can create a signed message that passes verify().

Suggested text:

  JOSE messages can involve a variety of cryptographic operations (or even no
 cryptography) providing a range of very different security properties. It is
 crucial that, on receiving a JOSE message, an application confirms that this
  specific message has the required security properties. To reduce the risk that
  applications inadvertently accept inadequately protected JOSE messages, JOSE
 library APIs ought to expose the security properties of a message in ways
 that applications cannot ignore. For example, a strongly typed language can
 use a distinct class for unprotected messages that is not a sub-class of the
  class used for MACed messages. As another example, distinct methods can be
 provided for verifying the authenticity of a JOSE message with a shared
 symmetric key (eg verifyMAC(secret)), and verifying an asymmetric signature
  against trusted root CAs (eg verifyPKI(roots)).
[The best way for JOSE specs to encourage safe API designs is to re-structure
the text so a JOSE message with different security properties is not specified
in a sub-section of another sort of message.]

--
James Manger

From: [email-masked] [mailto:[email-masked]] On Behalf Of Mike Jones
Sent: Friday, 6 September 2013 5:22 AM
To: Matt Miller (mamille2)
Cc: [email-masked]
Subject: Re: [jose] Text about applications and "alg":"none"

Implementations that support plaintext JWS objects (i.e., the "alg" value
"none") MUST NOT accept such objects as valid unless the application
specifies that it is acceptable for a specific object to be non-integrity-protected.
Implementations MUST NOT accept plaintext JWS objects by default.  For example,
the "verify" method of a hypothetical JWS software library might have a
boolean "acceptUnsigned" parameter (which defaults to "false") that indicates
"none" is an acceptable "alg" value.  As another example, the “verify” method
might take a list of algorithms that are acceptable to the application as a parameter
and would reject plaintext JWS values if “none” is not in that list.

Cc: Mike Jones; [email-masked]<mailto:[email-masked]>

"""

- m&m

---

From: Richard Barnes <[email-masked]>
Date: Mon, 9 Sep 2013 13:23:45 -0400

That text seems to accurately express the requirements.  I would prefer
"plaintext JWS" be something like "unprotected JWS", for the same reason as
James.

I continue to think, however, that the better course of action here is to
create a separate object type for unprotected content.  As James notes,
it's what NimbusDS already does internally.  It's simpler, so developers
are more likely to get it right.  And legacy plaintext JWSs can be
trivially back-ported, by removing a single character.  We should not
sacrifice future security in exchange for illusory backward compatibility.

--Richard

On Thu, Sep 5, 2013 at 3:22 PM, Mike Jones <[email-masked]>wrote:

>  Thanks Matt, for suggesting the text.  The version below has slight
> edits to make it editorially consistent with the terminology used elsewhere
> in the specs and to give the acceptable algorithm list approach equal
> billing with the Boolean approach.****
>
> ** **
>
> specifies that it is acceptable for a specific object to be
> non-integrity-protected.****
>
> boolean "acceptUnsigned" parameter (which defaults to "false") that
> indicates****
>
> "none" is an acceptable "alg" value.  As another example, the “verify”
> method****
>
> might take a list of algorithms that are acceptable to the application as
> a parameter****
>
> and would reject plaintext JWS values if “none” is not in that list.****
>
> ** **
>
> acceptance on a per-object basis.  For example, suppose an application
> accepts****
>
> indicate that "none" is acceptable, then an attacker could provide it with
> an****
>
> unsigned object over HTTP and still have that object successfully validate
> .****
>
>                                                             -- Mike****
> *Sent:* Thursday, September 05, 2013 9:02 AM
> *To:* Matt Miller (mamille2)
> *Cc:* Mike Jones; [email-masked]
> HTTP, vs. NotReallyAJWSVerifierDangerWillRobinson from HTTPS.****
>
> ** **
>
> to get "none" right, rather than just defining a separate syntax.****
>
> ** **
>
> On Thu, Sep 5, 2013 at 11:55 AM, Matt Miller (mamille2) <
> [email-masked]> wrote:****
>
> My suggested change (still makes me squeamish, but I can live with it):***
> *
>
>
> """
> specifies that it is acceptable for a specific object to be unsigned.****
>
> boolean "acceptUnsigned" parameter (which defaults to "false") that
> indicates****
>
> "none" is an acceptable "alg" value.****
>
> acceptance on a per-object basis.  For example, suppose an application
> accepts****
>
> indicates that "none" is acceptable, then an attacker could provide it
> with an****
>
> unsigned object over HTTP and still have that object considered valid.****
>
> Cisco Systems, Inc.****
> >> suggested by ekr about applications and "alg":"none".  I propose that
> the****
>
> >> ** ******
> >> mechanism to exclude accepting inputs using "alg":"none" in security***
> *
>
> >> ** ******