7 ms·
Great article! We've updated the OpenAI API to 403 on HTTP requests instead of redirecting. $ curl http://api.openai.com/v1/chat/completions \ -H "Content-
by athyuttamre 2y ago
Great article! We've updated the OpenAI API to 403 on HTTP requests instead of redirecting.
$ curl http://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer 123" \
-d '{}'
{
"error": {
"type": "invalid_request_error",
"code": "http_unsupported",
"message": "The OpenAI API is only accessible over HTTPS. Ensure the URL starts with 'https://' and not 'http://'.",
"param": null
}
}
- alberth 2y agoDoesn’t returning a 403 on HTTP break HSTS? https://security.stackexchange.com/questions/122441/should-hsts-header-be-sent-on-an-error-response https://security.stackexchange.com/questions/122441/should-h... Doesn’t HSTS require only responding to a user via HTTPS (even for error codes).
- gerdesj 2y agoHSTS is a note to the browser to insist on TLS when hitting a website. It is sent as a header, with a timescale, regardless of http/https.
- kji 2y agoHSTS is intended for browsers. For API clients the correct behavior (following curl's lead) is probably to never follow/make any redirects by default.
- josephcsible 2y agoWhat about this then? When the request is made over insecure HTTP, revoke the API key used, but then send the usual redirect response for HSTS. Then, when/if the request gets repeated over HTTPS, notice the key is revoked and so respond to that one with 403.
- freedomben 2y agoIf your goal is to waste people's time, cause them to question their sanity, and guarantee that they're way too pissed off when they finally figure out what happened that instead of teaching others about how important it is too use HTTPS from the start, they talk about how awful your API is and how much they hate your company for a terrible design, then yes this sounds like a good plan.
- josephcsible 2y agoIf it were a generic 403, sure. But if the 403 message said something to the effect of "this API key is no longer valid because it has previously been observed over insecure HTTP", then wouldn't that be fine?
- freedomben 2y agoYes agreed, I think that would improve it, although depending on the situation it may still cause substantial pain. Also apologies, after re-reading my previous comment it seemed unnecessarily harsh toward you, though that wasn't my intention! On the subject though, an example of how it could cause a lot of pain, many bigger corps don't allow developers to have "real" API keys, and they certainly can't generate new ones themselves, so this might mean one slip-up with curl results in at best a ticket with another team. It also might end up bringing down production in a horrible way, for example if the dev or an ops person is debugging and curls the endpoint from a pod in prod and forgets to explicitly put the https, curl will default to http which would then immediately cause the prod key to be revoked with no second chances. That could even happen on a GET request, which normally GETs are supposed to be safe/side-effect free! If you're operating at a big scale, that could be utterly disastrous, causing a widespread production outage immediately. If it's a dev that is just testing a key locally that isn't used anywhere else, then it's obviously less of an issue, but taking that into account starts to balloon the complexity around your token revocation code.
- LinAGKar 2y agoThe HSTS header is only effective when it's received over HTTPS. And if it has taken effect, the client won't try to access HTTP anymore, so it won't even know what response it would have gotten from HTTP.
- from-nibly 2y agoThis is better as it allow you to immediately notice that there's an issue. However it still facilitates api key exposing on the initial request.
- NotYourLawyer 2y agoHow would the endpoint prevent that?
- TheDong 2y agoNot listening on port 80, such that the user gets a connection refused, would result in the client not sending the api key over the wire at all. I personally think listening, accepting that user mistakes can expose API keys to MITMs, and returning the user-facing error is better than a "connection refused" error, but it is a tradeoff.
- marcosdumay 2y agoIf anybody is looking to copy in a public API, please return 400 and don't misuse a standard code.
- ants_everywhere 2y ago400 is usually for a malformed request. It seems like in this case the request is well formed, it's just not allowed. 403 seems reasonable if the user isn't authorized to make a request to the URL, which they aren't. Some APIs return redirects which also seems pretty reasonable.
- endofreach 2y agoWell in that case really anything is a 403.
- kijin 2y ago404 would also work, since the resource does not exist at the http: address.
- bruce511 2y agoTrue, but 404 has trained us to look hard at the URL part, not the protocol part. Whereas 403 or 400 are less likely to have so automated built-in handling on the client side.
- mbreese 2y agoBut that also implies that some user would be authorized to make a request to the HTTP port (or that the resource does exist, which in this case it doesn’t). IMO, 400 is more accurate, but really either could be acceptable, so long as the client is notified of the error. But, I wouldn’t automatically redirect the client. That’s what we are trying to avoid.
- ants_everywhere 2y agoGood point. I guess this might depend a little on the implementation. In some cases the http endpoint may exist but may only be accessible to a sidecar container via localhost. For example, if the sidecar terminates https.
- Hizonner 2y agoWhy not just stop listening on port 80, period?
- Pesthuf 2y agoIt’s a good option, but you can’t give users a reason for the failure. They might even assume your service is broken.
- booi 2y agoI stopped listening on port 80 for everything… nobody’s complained yet! Maybe because they can’t find the service though.
- inopinatus 2y agoI think it's fair to assume j. random user isn't typing "http://api.example.net http://api.example.net" into their web browser. leading www perhaps, leading api no.
- tracker1 2y agoYou'd be surprised... generally if there's a dedicated hostname for the API, I would expect / to either display or redirect to API docs. Also, doesn't help when you're reverse proxying /api to $API/api
- inopinatus 2y agoPosting on this forum means you are probably not J. Random User. I mean specifically anyone who will not grasp the difference between http:// http:// and https://api.example.com https://api.example.com.
- ikiris 2y agoBecause the whole point is a mitm can compromise it, and the mitm can listen on 80 regardless if you turn yours off.
- 2y ago
- bhawks 2y agoYou may want to disable path resolution as well. http://api.openai.com/v1/chat/completions/../bar http://api.openai.com/v1/chat/completions/../bar responds with error messages about http://api.openai.com/v1/chat/bar http://api.openai.com/v1/chat/bar which might suggest some path traversal vulnerability that could be exploited. Generally an API client is not going to need .. to be resolved in a path. It should return 400 - Bad Request (deceptive routing).
- freedomben 2y agoThank you for sharing! I think this sort of thing is what makes HN great. Have you rolled this out to prod yet? Did you check how many users this might effect? I can imagine some (probably amateur) apps are going to break when this hits, so some notice might be nice. I'm not asking those questions critically, mainly wanting to facilitate a full discussion around the pros and cons (I think the pros are are much stronger personally).