core-wg / attacks-on-coap

Other
2 stars 1 forks source link

Comments received during WG adoption call - Jon Shallow #3

Open emanjon opened 2 years ago

emanjon commented 2 years ago

Jon Swallow https://mailarchive.ietf.org/arch/msg/core/GNnRO4-iE_jRb5X2HfRtV3c8Sew/

Med is actually referring to 2.4, but this made me realize there was a trap of seeing Block and hence thinking RFC7959 for 2.1 - "The Block Attack" which actually has no reference to CoAP blocks. A better section title could be "The Blocking Attack" and s/Block Attack/Blocking Attack/ elsewhere.

For 2.4, "Fragment" in terms of CoAP blocks is not defined, and is not used in RFC7959 (RFC7959 refers to fragmentation issues outside of the CoAP layer), so is unclear that "fragment" is meant to be referring to a CoAP RFC7959 (or draft-ietf-core-new-block to-be-RFC9177) block.

Thus, "2.4. The Request CoAP Block Rearrangement Attack" is a step in the right direction for me. Then most of the usage of the word fragment needs to be replaced with block.

As a note for mitigating 2.4.1, to-be-RFC9177 requires the use of Request-Tag (https://datatracker.ietf.org/doc/html/draft-ietf-core-new-block#section-4.3) and good use of tokens (https://datatracker.ietf.org/doc/html/draft-ietf-core-new-block#section-6).

The lost blocks recovery mechanisms in to-be-RFC9177 mitigate the risk of the wrong block being processed in a request by the server.

Again using Block-Wise transfers, there has not been consideration for a delay attack causing the server to send back the wrong data in a BLOCK2 response. See https://github.com/core-wg/echo-request-tag/issues/77 . If the attacker delays the first request (which triggers a BLOCK2 response), and then sends it just before/after the second request (also triggering a BLOCK2 response), the request for the next block for, say the second request, from the client may get back the block from either the first or second request. This can only be mitigated using the Request-Tag on each request, even though BLOCK1 is not being used for the request. I think this attack also needs to be included.

emanjon commented 2 years ago

https://mailarchive.ietf.org/arch/msg/core/dvPyvSLnQKpeaRUR3AW5h2tn6yQ/

Hi Jon,

I'm not sure about:

Again using Block-Wise transfers, there has not been consideration for a delay attack causing the server to send back the wrong data in a BLOCK2 response. See https://github.com/core-wg/echo-request-tag/issues/77 . If the attacker delays the first request (which triggers a BLOCK2 response), and then sends it just before/after the second request (also triggering a BLOCK2 response), the request for the next block for, say the second request, from the client may get back the block from either the first or second request. This can only be mitigated using the Request-Tag on each request, even though BLOCK1 is not being used for the request. I think this attack also needs to be included.

Does this refer to RFC7959?

may get back the block from either the first or second request.

But the response will contain a token, which is used for request-response matching. So, do you assume, that both request are using the same token (maybe then more a unintended violation of the token uniqness)?

best regards Achim

emanjon commented 2 years ago

https://mailarchive.ietf.org/arch/msg/core/tuI9NNtx5t3NDsK0zfhdvNGCmEg/

Hi Achim,

draft-mattsson-core-coap-attacks has a focus on using Request-Tag to mitigate attacks. Usage of ETag is not mandated in RFC7252 or RFC7959 as far as I can tell (but is in to-be-RFC9177), but using ETag with Block2 mitigates potential attack confusion. See attack below.

Otherwise, please see inline.

Regards

Jon

-----Original Message----- From: Achim Kraus [mailto: achimkraus@gmx.net] Sent: 25 February 2022 16:22 To: jon@jpshallow.com Cc: mohamed.boucadair@orange.com; 'Marco Tiloca'; core@ietf.org Subject: Re: [core] WG Adoption Call for draft-mattsson-core-coap-attacks

Hi Jon,

I'm not sure about:

Again using Block-Wise transfers, there has not been consideration for a delay attack causing the server to send back the wrong data in a BLOCK2 response. See https://github.com/core-wg/echo-request-tag/issues/77 . If the attacker delays the first request (which triggers a BLOCK2 response), and then sends it just before/after the second request (also triggering a BLOCK2 response), the request for the next block for, say the second request, from the client may get back the block from either the first or second request. This can only be mitigated using the Request-Tag on each request, even though BLOCK1 is not being used for the request. I think this attack also needs to be included.

Does this refer to RFC7959?

Jon> Yes, as Block2s are being used as well as RFC9175

may get back the block from either the first or second request.

But the response will contain a token, which is used for request-response matching. So, do you assume, that both request are using the same token (maybe then more a unintended violation of the token uniqness)?

Jon> No. I would be expecting the Token to be different in each request that asks for the next payload of the body. Use of the same Token is not recommended as per RFC9175, but people do not realize that an empty token should not be used across multiple requests (another attack if "Foe" was removing tokens as the CoAP packets passed through...).

Jon> Client gets earlier value (ETag not used) against what it thought was the second request.

   Client   Foe   Server
      |      |      |
      +------X      |    POST "request" T:1 { "offset":0, "length":2000}
      |      |      |
      +------------->    POST "request" T:2 { "offset":4000, "length":2000}
      |      |      |
      |      @------>    POST "request" T:1 { "offset":0, "length":2000}
      |      |      |
      <-------------+    2.04 T:2 Block2:0/1/1024 { data containing 4000:1024 }
      |      |      |
      <-------------+    2.04 T:1 Block2:0/1/1024 { data containing 0:1024 }
      |      |      |
      +------------->    POST "request" T:3 Block2:0/_/1024
                         server - is this continuation of request using T:1 or T:2 ?
      |      |      |
      <-------------+    2.04 T:3 Block2:1/_/1024 { data containing 1024:2000 }
                         Was this the expected data ?
      |      |      |

This is fixed if Request differentiating ETag is used in the response. The client may not be able to get the missing secondary block from the alternative request, unless Request-Tag is used in the initial request (hence issue 77).

~Jon>

emanjon commented 1 year ago

I changed "block attack" to "blocking attack", thanks for the suggestion.

Right or wrong, the term "fragment" is used heavily in RFC 9175 which this is an companion document to. RFC 9175 cannot be changes now. Even if the term is not perfect it might be better for draft-ietf-core-attacks-on-coap to align with RFC 9175.

@chrysn ?

emanjon commented 1 year ago

@chrysn has the comments above been handled?

chrysn commented 1 year ago

I think all was addressed, except what I'd address like this:

A point not discussed in this thread yet was talking about https://github.com/core-wg/echo-request-tag/issues/77 here. I think this would only be an attack if the requests pulling out the remaining body parts after a single-payload request did not carry the request payload -- but they do, so there's no attack per se. If a client chooses to try (and the server supports) different concurrent distinct requests on the same resource with the same body, yes there would be confusion, but that is only enabled by Request-Tag being there in the first place, and thus not using a Request-Tag is not an avenue for an attacker, but plainly does not work.

[edit / added:] Looking at the flow diagram in https://github.com/core-wg/attacks-on-coap/issues/3#issuecomment-1123631550 (originally in mail) once more, I think that flow diagram was based on the idea that the request body was not POSTed again in subsequent requests. AIU that is not how block-wise works, so I think my resolution above stands.

mrdeep1 commented 1 year ago

With the flow diagram https://github.com/core-wg/attacks-on-coap/issues/3#issuecomment-1123631550 , with concurrent requests being issued and both ETag and Request-Tag not being used, then the server randomly chooses which block to send back and the client associates the (potentially incorrect data) response with the request that it thought it was using for the second block.

Use of ETag makes sure that the client associates the response with the correct request, but this may be a response to a request for the next block which has not yet been issued. Use of Request-Tag (but not ETag) means server sends correct next block response, but client might associate it with the wrong request if both next block requests are sent concurrently. Use of both ETag and Request-Tag means everything correctly matches up, even if attacker re-orders the request sequences.

So, for me, without mitigating using both ETag and Request-Tag, it is a valid attack vector if concurrent requests are in use.

chrysn commented 1 year ago

I was about to tell that the flow diagram is broken because it doesn't retransmit the request payload=body when obtaining the responses, but turns out that is what 7959 says ("by sending further requests with the samej options as the initial request and a Block2 Option giving the block number and block size desired"). I'll have to revisit a lot based on that, including this discussion, and whether the provisions of 9175 are sufficient.

(The weird part with as things are is that the client has no way of knowing whether or not Block2 will happen, so can't take any measures beforehand -- would it need to apply Request-Tag logic to all requests?)

mrdeep1 commented 1 year ago

Because of this concurrent request issue, I think we need to always send the request with a Request-Tag (unless it is a DELETE) (sensibly limited in size) unless there is absolute knowledge that that the server will never respond with a Block2.

If the client is forbidden to do concurrent requests (all previous requests split over multiple blocks are responsed to before a new base request is allowed), then there is no need for Request-Tag.

I think this is true for TCP as well, even though T:1 and T:2 arrive in the correct order, the server still does not know which request T:3 refers to (could be searching as lifo or fifo).

chrysn commented 1 year ago

It's not that bad, fortunately (for it'd mean that every single request that carries a request payload needs to have a Request-Tag, adding about 3 bytes to every single message).

From my current understanding, at least in the mode with OSCORE, the regular recycling rules can apply: The only messages where the absent request tag can not be recycled (i.e. the only messages that need something set) are those that are sent while there are unfinished requests to the same server with the same options set. Unfinished here means that no (final, in case of non-traditional responses) response has been received, and requests can also be regarded as finished when the request has moved out of the replay window (which I'm once more glad is mutually agreed on in OSCORE).

For DTLS, yikes. As soon as a request gets retransmitted, that request tag is burned.

... I should probably take this to the mailing list.

mrdeep1 commented 1 year ago

For DTLS, yikes. As soon as a request gets retransmitted, that request tag is burned.

I don't follow you here with respect to the DTLS case.

If DTLS layer is re-transmitting a request packet, then (encrypted) then Request-Tag is unchanged. Potential issue is when DTLS gives up retrying, but CoAP layer should be told about this.

If CoAP is re-transmitting a request packet (triggered as CON) then Request-Tag is unchanged - whether over DTLS or not. CoAP will then detect transmission failure and recycle Request-Tag if needed.

Things may get interesting when NON is used and the server elects to not respond (or request/response is dropped somewhere). Does there need to be a timeout time, or do we following an incrementing method as per Tokens?

With CON, if a server elects to not send a response (but sends just an ACK) then there is no formal response that can be interpreted that Request-Tag is finished with.

chrysn commented 1 year ago

If DTLS layer is re-transmitting a request packet, then (encrypted) then Request-Tag is unchanged.

Yes, but you do need to set one. The beauty of Request-Tag is that in the vast majority of cases, you don't really need to set one. (Otherwise, all CoAP messages grow by 3 or more bytes compared to pre-2022, which may be acceptable for DOTS cases but not for 6lo cases, where things like EDHOC are fitting very snug).

DTLS already needs to set long tokens because they have cryptographic relevance, so the tokens are growing, and so are the request tags -- but non-DTLS applications can still get away with 0 or 1 byte tokens, and need to keep their Request-Tag usage at a minimum. (I don't know off my head if it made it into the text, but one way to avoid needing a Request-Tag when one would be due in OSCORE is to just bump the sequence number by 32, so we see it on the wire even more rarely).

mrdeep1 commented 1 year ago

Ah - had missed needing bigger tokens/Request-Tags for use with DTLS for better cryptographic security.

I know Request-Tags are not allowed in responses, but if a server has to respond with a Block2 andthe server knows that the request did not contain a Request-Tag, then it could indicate a pseudo-Request-Tag somehow to use for the ongoing client next-block requests (a Block2-including-Request-Tag-to-use option, or allow Request-Tag to be a response).