Constrained Application Protocol

From Embedded Lab Vienna for IoT & Security
Jump to navigation Jump to search

The Constrained Application Protocol (CoAP) is a specialized web transfer protocol, as defined in RFC 7252, for use with constrained nodes and constrained networks in the Internet of Things. The protocol is designed for machine-to-machine (M2M) applications such as smart energy and building automation.


The work on Constrained Environments aims at realizing the REST architecture in a suitable form for the most constrained nodes and networks. The nodes usually consist of 8-bit microcontrollers with limited amounts of RAM and ROM.

CoAP has the following main features:

  • Web protocol fulfilling M2M requirements in constrained environments
  • UDP [RFC0768] binding with optional reliability supporting unicast and multicast requests
  • Asynchronous message exchanges
  • Low header overhead and parsing complexity
  • URI and Content-type support
  • Simple proxy and caching capabilities
  • Stateless HTTP mapping
  • Security binding to Datagram Transport Layer Security (DTLS)

The Protocol

CoAP is similar to the client/server model of HTTP. M2M interactions typically result in a CoAP implementation acting in both client and server roles. A request is sent by a client to request an action on a resource (identified by a URI) on a server. The server then sends a response with a response code (equivalent to that of HTTP). Therefore, efficiency is very important, so CoAP uses UDP, a datagram-oriented transport.

CoAP is however a single protocol, with messaging and request/response as just features of the CoAP header

|      Application     |
+----------------------+  \
|  Requests/Responses  |  |
|----------------------|  | CoAP
|       Messages       |  |
+----------------------+  /
|          UDP         |

Message Format

By default, the messages are encoded in a simple binary format and transported over UDP. The message format starts with a fixed-size 4-byte header, followed by a variable-length Token value, which can be between 0 and 8 bytes long. Following the Token value comes a sequence of zero or more CoAP Options in Type-Length-Value (TLV) format, optionally followed by a payload that takes up the rest of the datagram.

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  |Ver| T |  TKL  |      Code     |          Message ID           |
  |   Token (if any, TKL bytes) ...
  |   Options (if any) ...
  |1 1 1 1 1 1 1 1|    Payload (if any) ...
Version (Ver) (2 bits)
Indicates the CoAP Version number. This must set this field to 1 (binary 01). Other values are reserved for future versions.
Type (T) (2 bits)
Indicates if this message is of type Confirmable (0), Non-confirmable (1), Acknowledgement (2), or Reset (3).
Token Length (TKL) (4 bits)
Indicates the length of the variable-length Token field, which may be 0-8 bytes in length.
CoAP Request/Response Code (8 bits)
Splits into a 3-bit class and 5-bit detail.
Message ID (16 bits)
Used to detect message duplication and to match messages of type Acknowledgement/Reset to messages of type Confirmable/Non-confirmable.

Security Considerations

This section gives an overview of possible threats to the protocol as listed in section 11 of RFC 7252. As CoAP realizes a subset of the features of HTTP/1.1, the security considerations in section 15 of RFC2616 are also pertinent to CoAP.

Note:"NoSec" mode means that the system simply sends packets over normal UDP over IP and is indicated by the "coap" scheme and the CoAP default port. The system is secured only by keeping attackers from being able to send or receive packets from the network with the CoAP nodes. There is no protocol-level security (DTLS is disabled). The other available modes for securing CoAP are listed in section 9 of RFC7252.

Parsing the Protocol and Processing URI's

The URI processing code in CoAP is likely to be a large source of vulnerabilities and should be implemented very carefully. Vulnerabilities include remotely crashing a node and remotely executing arbitrary code. CoAP aims to reduce the risk of these vulnerabilities by reducing parser complexity and moving much of the URI processing to the clients.

Proxying and Caching

Proxies are man-in-the-middle by their nature. They can break any IPsec or DTLS protection that would otherwise happen between direct CoAP message exchange. Risks include the loss of confidentiality and availability. If the proxies also cache the threat to confidentiality and integrity of request/response data is amplified as CoAP does not implement cache-suppressing Cache-control as in HTTP/1.1. For caching implementations any access control considerations also need to be applied to the value in the cache. A caching proxy must not make cache values available to requests that have lesser transport-security properties.

Risk of Amplification

As CoAP server reply to request packets with response packets that may be significantly larger an attacker can use CoAP nodes to generate more traffic and use them in a denial-of-service(DoS) attack. Turning a small attack packet into a larger one is called amplification. The attacker wants to overload a victim but is limited in the amount of traffic can use amplification to generate larger amounts. If a node that enables NoSec access becomes available to an attacker it can access victims on the general internet. UDP provides no way to verify the source address given in the request packet and an attacker can place the IP of the victim in the source address of a request packet to generate a larger packet directed at the victim. The risk is reduced however as constrained networks are only able to generate small amounts of traffic. In contrast the network itself with its limited capacity is a viable victim of an amplification attack. Large amplification factors should not be provided if the request is not authenticated. Also the slicing/blocking modes of CoAP [BLOCK] should be used for large resources. Because CoAP supports the use of multicast IP addresses in requests, CoAP servers should not accept multicast requests that can not be authenticated. Servers should limit the use of multicast requests as they can be a source of an accidental or deliberate DoS attack.

IP Address Spoofing

As there is no handshake in UDP a rogue endpoint that can read and write messages can attack a single endpoint, a group of endpoints or the whole network.

  1. Spoofing a Reset message in response to a message making an endpoint "deaf"
  2. Spoofing an ACK in response to a CON, preventing the sender of the CON from retransmitting to drown out the actual response
  3. Spoofing the entire response with forged payload/options, attacking a single endpoint or the supporting infrastructure
  4. Spoofing a multicast request for a target node resulting in network congestion or collapse due to a DoS attack on the victim, or forced wake-up from sleeping
  5. Spoofing observe messages

Response spoofing can be mitigated by choosing a nontrivial, randomized token in the request. Other kinds of spoofing can only be detected by CoAP if Confirmable message semantics are used and if one keeps track of Message ID's. A client can also attempt to overload a server by sending complex requests as the cost of a CON request is small. This can be used in a battery depletion attack or to make the server run out of resources for processing legitimate traffic. All these attacks can be prevented if a security mode other than NoSec is used.

Cross-Protocol Attacks

In general, for any pair of protocols, one could have been designed in a way, that enables an attacker to cause the generation of replies that look like messages of the other protocol. Because a CoAP endpoint can be manipulated to send packets to a fake source address it can be used to attack a victim listening to UDP packets at a given IP address and port.

  1. The attacker sends a message to a CoAP endpoint with the given address as the fake source address.
  2. The endpoint replies with a message to the source address.
  3. The victim receives a UDP packet that it interprets according to the rules of a different protocol.

This can be used to circumvent firewall rules that prevent direct communication but allow communication from the CoAP endpoint. This scenario can work the other way too. A CoAP endpoint could be attacked from another UDP-based protocol. Attacks are possible if the endpoints rely only on checking IP addresses. To prevent these kinds of attacks strict checking of syntax of packets received should be implemented. Furthermore endpoints should not authorize actions based on trusting the source IP address of a packet.

Constrained Node Considerations

Keys should be generated externally and added to the device during manufacturing or commissioning. Due to low processing power constrained nodes are susceptible to timing attacks. Cryptographic principles should be implemented with special care as many nodes are installed in exposed environments and have little resistance to tampering. The scope of credentials assigned to them should be considered carefully. A shared key assigned to a group of nodes may make any single node a target for subverting the entire group.


Generic implementations are becoming available for a variety of platforms. Implementations for constrained devices are typically written in C. CoAP is also used between them and more powerful systems such as cloud servers, home centrals, smartphones:

Name Programming Language Client/Server License Link
Erbium for Contiki C Client + Server 3-clause BSD
libcoap C Client + Server BSD/GPL
Eclipse tinydtls C Client + Server EPL+EDL
LibNyoci C Client + Server MIT
microcoap C Client + Server MIT
cantcoap C++/C Client + Server BSD
Lobaro CoAP C Client + Server MIT
Wakaama C Client + Server EPL+EDL
coap-node Javascript Client MIT
coap-shepherd Javascript Server MIT
Californium Java Client + Server EPL+EDL
nCoap Java Client + Server BSD
leshan Java Client + Server EPL+EDL
CoAP.NET C# Client + Server 3-clause BSD
CoAPSharp C#, .NET Client + Server LGPL
Waher.Networking.CoAP C# Server
gen_coap Erlang Client + Server MPL v1.1
go-coap Go Client + Server MIT
node-coap Javascript Client + Server MIT
coap-cli Javascript MIT
txThings Python (Twisted) Client + Server MIT
aiocoap Python 3 Client + Server MIT
CoAPthon Python Client + Server MIT
Ruby coap Ruby Client MIT
Ruby david Ruby Server MIT
coap-rs Rust Client + Server MIT
Copper JavaScript (Browser Plugin) Client BSD
iCoAP Objective-C Client MIT
SwiftCoAP Swift Client + Server MIT
nCoap Java Client + Server BSD
txThings Python (Twisted) Client + Server MIT