diff --git a/DesignRules.md b/DesignRules.md index cb08fc1..b51ae78 100644 --- a/DesignRules.md +++ b/DesignRules.md @@ -142,7 +142,7 @@ A resource describing a single thing is called a [=singular resource=]. Resource ## HTTP methods -Although the REST architectural style does not impose a specific protocol, REST APIs are typically implemented using HTTP [[rfc7231]]. +Although the REST architectural style does not impose a specific protocol, REST APIs are typically implemented using HTTP [[rfc9110]].
The HTTP specification [[rfc7231]] and the later introduced PATCH
method specification [[rfc5789]] offer a set of standard methods, where every method is designed with explicit semantics. HTTP also defines other methods, e.g. HEAD
, OPTIONS
, TRACE
, and CONNECT
.
+
The HTTP specification [[rfc9110]] offers a set of standard methods, where every method is designed with explicit semantics. HTTP also defines other methods, e.g. HEAD
, OPTIONS
, TRACE
, and CONNECT
.
The OpenAPI Specification 3.0 Path Item Object also supports these methods, except for CONNECT
.
- According to RFC 7231 4.1 the GET
and HEAD
HTTP methods MUST be supported by the server, all other methods are optional.
+ According to RFC 9110 9.1 the GET
and HEAD
HTTP methods MUST be supported by the server, all other methods are optional.
In addition to the standard HTTP methods, a server may support other optional methods as well, e.g. PROPFIND
, COPY
, PURGE
, VIEW
, LINK
, UNLINK
, LOCK
, UNLOCK
, etc.
- If an optional HTTP request method is sent to a server and the server does not support that HTTP method for the target resource, an HTTP status code 405 Method Not Allowed
shall be returned and a list of allowed methods for the target resource shall be provided in the Allow
header in the response as stated in RFC 7231 6.5.5.
405 Method Not Allowed
shall be returned and a list of allowed methods for the target resource shall be provided in the Allow
header in the response as stated in RFC 9110 15.5.6.
Adhere to HTTP status codes to convey appropriate errors
+The server SHOULD NOT only use `200` for success and `404` for error states. Use the semantically appropriate status code for success or failure. +
In case of an error, the server SHOULD NOT pass technical details (e.g. call stacks or other internal hints) to the client. The error message SHOULD be generic to avoid revealing additional details and expose internal information which can be used with malicious intent. +
Apply the transport security module
+ +Secure connections using TLS
One should secure all APIs assuming they can be accessed from any location on the internet. Information MUST be exchanged over TLS-based secured connections. No exceptions, so everywhere and always. This is required by law. +
One MUST follow the latest NCSC guidelines [[NCSC 2021]].
Since the connection is always secured, the access method can be straightforward. This allows the application of basic access tokens instead of encrypted access tokens.
The usage of TLS is machine testable. Follow the latest NCSC guidelines on what is required to test. The serverside is what will be tested, only control over the server is assumed for testing. A testing client will be employed to test adherence of the server. Supporting any protocols, algorithms, key sizes, options or ciphers that are deemed insufficient or phased out by NCSC will lead to failure on the automated test. Both positive and negative scenarios are part of the test: testing that a subset of *Good* and *Sufficient* configurations are supported and configurations deemed *Insufficient* or marked for *Phase out*. A manual exception to the automated test results can be made when configurations designated for *Phase out* are supported; The API provider will have to provide clear documentation regarding the phase out schedule. +
No sensitive information in URIs
+Even when using TLS connections, information in URIs is not secured. URIs can be cached and logged outside of the servers controlled by clients and servers. Any information contained in them should therefore be considered readable by anyone with access to the network (in the case of the internet, the whole world) and MUST NOT contain any sensitive information. This includes client secrets used for authentication, privacy sensitive information suchs as BSNs or any other information which should not be shared. +
Be aware that queries (anything after the '?' in a URI) are also part of an URI. +
Use mandatory security headers in API all responses
+There are a number of security related headers that can be returned in the HTTP responses to instruct browsers to act in specific ways. However, some of these headers are intended to be used with HTML responses, and as such may provide little or no security benefits on an API that does not return HTML. The following headers SHOULD be included in all API responses: +
Header | +Rationale | +
---|---|
Header | +Rationale | +
`Cache-Control: no-store` | +Prevent sensitive information from being cached. | +
`Content-Security-Policy: frame-ancestors 'none'` | +To protect against drag-and-drop style clickjacking attacks. | +
`Content-Type` | +To specify the content type of the response. This SHOULD be `application/json` for JSON responses. | +
`Strict-Transport-Security` | +To require connections over HTTPS and to protect against spoofed certificates. | +
`X-Content-Type-Options: nosniff` | +To prevent browsers from performing MIME sniffing, and inappropriately interpreting responses as HTML. | +
`X-Frame-Options: DENY` | +To protect against drag-and-drop style clickjacking attacks. | +
`Access-Control-Allow-Origin` | +To relax the 'same origin' policy and allow cross-origin access. See CORS-policy below | +
The headers below are only intended to provide additional security when responses are rendered as HTML. As such, if the API will never return HTML in responses, then these headers may not be necessary. You SHOULD include the headers as part of a defense-in-depth approach if there is any uncertainty about the function of the headers, the types of information that the API returns or information it may return in the future. +
Header | +Rationale | +
---|---|
`Content-Security-Policy: default-src 'none'` | +The majority of CSP functionality only affects pages rendered as HTML. | +
`Feature-Policy: 'none'` | +Feature policies only affect pages rendered as HTML. | +
`Referrer-Policy: no-referrer` | +Non-HTML responses SHOULD not trigger additional requests. | +
In addition to the above listed HTTP security headers, web- and browser-based applications SHOULD apply [[[SRI]]]. When using third-party hosted contents, e.g. using a Content Delivery Network, this is even more relevant. While this is primarily a client implementation concern, it may affect the API when it is not strictly segregated or for example when shared supporting libraries are offered. +
The precense of the mandatory security headers can be tested in an automated way. A test client makes a call to the API root. The response is tested for the precense of mandatory headers. +
Use CORS to control access
+Modern web browsers use Cross-Origin Resource Sharing (CORS) to minimize the risk associated with cross-site HTTP-requests. By default browsers only allow 'same origin' access to resources. This means that responses on requests to another `[scheme]://[hostname]:[port]` than the `Origin` request header of the initial request will not be processed by the browser. To enable cross-site requests API's can return a `Access-Control-Allow-Origin` response header. An allowlist SHOULD be used to determine the validity of different cross-site request. To do this check the `Origin` header of the incoming request and check if the domain in this header is on the whitelist. If this is the case, set the incoming `Origin` header in the `Access-Control-Allow-Origin` response header. +
Using a wildcard `*` in the `Access-Control-Allow-Origin` response header is NOT RECOMMENDED, because it disables CORS-security measures. Only for an open API which has to be accessed by numerous other websites this is appropriate. +
Tests of this design rule can only be performed when the intended client is known to the tester. A test can be performed when this information is provided by the API provider. Otherwise no conclusive test result can be reached. +