Subject: Re: [core] Benjamin Kaduk's Discuss on draft-ietf-core-stateless-06: (with DISCUSS and COMMENT)

From: Benjamin Kaduk <[email-masked]>
Date: Sun, 3 May 2020 15:46:25 -0700

Hi Klaus,

On Wed, Apr 29, 2020 at 01:11:04PM +0200, Klaus Hartke wrote:
> Hi Ben,
> 
> here's the next batch. Please see inline below.
> 
> Best regards,
> Klaus
> 
> 
> Benjamin Kaduk wrote:
> > Section 3.1
> >
> >    o  A client SHOULD integrity protect the state information serialized
> >       in a token, unless processing a response does not modify state or
> >       cause any other significant side effects.
> >
> > If the intent is that the "does not modify state" clause is the only case
> > when one would disregard the need for integrity protection, "MUST [...]
> > unless" seems more appropriate.  (I would prefer unconditional MUST and am
> > not sure I understand the cases where there is a need to skip integrity
> > protection.)
> 
> The intent here is that a client must do integrity protection, but
> there may exist valid reasons in particular circumstances to ignore
> this requirement. In this case, the full implications must be
> understood and carefully weighed.
> 
> All of the circumstances that come to my mind here are those where a
> modified token doesn't actually hurt. For example, if a client sends a
> request to some server at regular intervals, it might only be
> interested in whether the response has an error or success code and
> not even deserialise the token.
> 
> What's the best way to capture this?

Before I get into suggested text, I want to check that I understand the
situation properly -- in such a case where the client is not even
deserializing the token, why would the client not be able to use a regular
token and not look at that token's value?  It doesn't seem like the client
is gaining anything from having the serialized state available.

Your description makes it sound like we may have to just do "SHOULD
integrity protect" without the "unless [...]" clause.

> >    o  Even when the serialized state is integrity protected, an attacker
> >       may still replay a response, making the client believe it sent the
> >       same request twice.  For this reason, the client SHOULD implement
> >
> > (Basically the same comments about "SHOULD".)
> 
> See above.
> 
> This section is about protecting the serialized state, but of course
> the requests and responses need to be protected as a whole as well
> (e.g., using DTLS or OSCORE). In some circumstances, receiving a
> replayed token might not hurt if the client can verify that the
> response is coming from the right server.

Presumably the same cases where a replayed response from the right server
would be tolerable?  Such cases are ... rare, in my opinion.

> >       cause other any significant side effects.  For replay protection,
> >       integrity protection is REQUIRED.
> >
> > I'm not entirely sure if the normative keyword is needed for effect, here;
> > it's simply a fact that replay protection is impossible in the absence of
> > integrity protection, isn't it?
> 
> Right. The intention here was to turn the "SHOULD integrity protect
> the state information" from above into a "MUST". But I can lowercase
> the "REQUIRED" or remove the sentence.

I'd suggest rewording to say that "replay protection is impossible if
integrity protection is not in use" (or similar).

> >    o  If processing a response without keeping request state is
> >       sensitive to the time elapsed since sending the request, then the
> >       serialized state SHOULD include freshness information (e.g., a
> >       timestamp).
> >
> > Continuing the theme, this seems like a conditional MUST (not SHOULD).
> > Actually, all the rest of the SHOULDs in this section do.
> 
> See above.
> 
> > This particular one should also note that the response processing needs to
> > actually check the timestamp and reject ones that are insufficiently fresh.
> 
> I've made the following change (ignoring the SHOULD/MUST discussion):
> 
> OLD:
> 
>     If processing a response without keeping request state is
>     sensitive to the time elapsed since sending the request,
>     then the serialized state SHOULD include freshness
>     information (e.g., a timestamp).
> 
> NEW:
> 
>     If processing a response without keeping request state is
>     sensitive to the time elapsed since sending the request, then the
>     client SHOULD include freshness information (e.g., a timestamp) in
>     the serialized state and reject any response where the freshness
>     information is insufficiently fresh.

Sounds good (ignoring the SHOULD/MUST discussion), thanks.

> > Also, integrity protection is again required for this to work.
> 
> Right. I think I'll remove the sentence "For replay protection,
> integrity protection is REQUIRED." from above so that I don't have to
> repeat it for every item. I think it's quite obvious.

Ah, fair enough (my suggestion above notwithstanding).

> > Section 5.2
> >
> >    The use of encryption, integrity protection, and replay protection of
> >    serialized state is recommended, unless a careful analysis of any
> >    potential attacks to security and privacy is performed.  [...]
> >
> > I suggest an alternative wording:
> >
> > % It is generally expected that the use of encryption, integrity protection,
> > % and replay protection for serialized state is appropriate.  However, a
> > % careful analysis of any potential attacks to the security and privacy
> > % properties of the system might reveal that there are cases where such
> > % cryptographic protections do not add value in a specific case.
> 
> Sounds good. Thanks!

Thanks,

Ben

---

From: Klaus Hartke <[email-masked]>
Date: Mon, 4 May 2020 19:40:39 +0200

Benjamin Kaduk wrote:
> Klaus Hartke wrote:

Hmm... the top-level section is about clients that avoid keeping
per-request state, which a client can be regardless of whether it uses
<=8 byte tokens or >8 byte tokens; but this sub-section talks about
serialized state, from which indeed the client doesn't get anything if
it's never deserialized...

Maybe the best way forward is indeed to use SHOULD with the "unless
[...]" part... If we change to MUST, then I can already anticipate
people complaining that in their particular use case any integrity
protection is just wasting precious bytes. The SHOULD would take care
of that. And maybe we don't have to go into detail under which
circumstances it might be justified to ignore this SHOULD.

OLD:

NEW:

      in a token.

OLD:

   o  Even when the serialized state is integrity protected, an attacker
      may still replay a response, making the client believe it sent the
      same request twice.  For this reason, the client SHOULD implement
      replay protection (e.g., by using sequence numbers and a replay
      window), unless processing a response does not modify state or
      cause other any significant side effects.  For replay protection,
      integrity protection is REQUIRED.

NEW:

   o  Even when the serialized state is integrity protected, an attacker
      may still replay a response, making the client believe it sent the
      same request twice.  For this reason, the client SHOULD implement
      replay protection (e.g., by using sequence numbers and a replay
      window).

Does it look OK without the "unless [...]" parts?

Klaus

---

From: Benjamin Kaduk <[email-masked]>
Date: Fri, 8 May 2020 19:01:28 -0700

> Does it look OK without the "unless [...]" parts?

I think so (for both cases), though some note about it being impossible to
implement replay protection without integrity protection (while still
avoiding per-request state) would probably still be in order.

Thanks,

Ben