-
Notifications
You must be signed in to change notification settings - Fork 71
Description
For APIs that require HTTPS (the default), we return a 400 error response indicating that HTTPS is required (see #34 for additional context on why we use this approach for APIs, rather than redirects). However, the order in which we display this error message (in relation to other error messages), isn't ideal. The main issue is that we perform API key checks before the HTTPS checks, so API key error messages are printed before the HTTPS error message. The ordering of these error messages may lead users to submitting their API key over HTTP, which we should try to avoid.
An example might better demonstrate the issue:
-
If I make a simple HTTP request to an API endpoint, but without an API key, I get back an error message telling me I need to supply an API key.
$ curl -i 'http://api.code.gov/' HTTP/1.1 403 Forbidden Server: openresty Date: Fri, 10 Aug 2018 16:09:45 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding Access-Control-Allow-Origin: * X-Cache: MISS Strict-Transport-Security: max-age=31536000; preload { "error": { "code": "API_KEY_MISSING", "message": "No api_key was supplied. Get one at https://developers.code.gov" } } -
Only after supplying my API key do I then get the message about HTTPS being required:
$ curl -i 'http://api.code.gov/?api_key=DEMO_KEY' HTTP/1.1 400 Bad Request Server: openresty Date: Fri, 10 Aug 2018 16:10:31 GMT Content-Type: application/json Transfer-Encoding: chunked Connection: keep-alive Access-Control-Allow-Origin: * X-Cache: MISS Strict-Transport-Security: max-age=31536000; preload { "error": { "code": "HTTPS_REQUIRED", "message": "Requests must be made over HTTPS. Try accessing the API at: https://api.code.gov/?api_key=DEMO_KEY" } }
So while the user eventually gets the HTTPS requirement message (and hopefully won't send any more insecure HTTP requests), they only receive it after supplying an API key over an insecure HTTP connection. I think the ordering of these error messages need to be flipped, so that we first tell the user to use HTTPS, and then deal with the API key verification afterwards.
The reason for the current error message ordering is to deal with our HTTPS "transition" mode, where existing API keys can continue using HTTP (so we didn't break API clients). So for APIs still using that "transition" mode, the order may still not be ideal in all cases (since we need to fetch the API key information before determining the specific key's HTTPS requirements), but I think we can still improve this to encourage better security in most cases.