Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

One of the approaches mentioned in the article is to just not listen on port 80. Supposedly that’s equally good because the connection should get aborted before the client has the chance to actually send any API keys.

But is that actually true? With TCP Fast Open, a client can send initial TCP data before actually learning whether the port is open. It needs a cookie previously received from the server to do so, but the cookie is not port-specific, so – assuming the server supports Fast Open – the client could have obtained the cookie from a prior connection over HTTPS or any other valid port. That’s the impression I get from reading the RFC, anyway. The RFC does mention that clients should distinguish between different server ports when caching refusals by the server to support Fast Open, but by that point it’s too late; the data may have already been leaked.



If you're serving web traffic and API traffic on the same domain, which many services are, then not listening on port 80 may not be possible. Even if you do use a different domain, if you're behind a CDN then you probably can't avoid an open port 80. I do keep port 80 closed for those of my services I can do so for, but I don't have anything else that needs port 80 to be open on those IPs.

I think Stack Exchange's solution is probably the right one in that case -- and hopefully anyone who hits it will do so with dev keys rather than in production.


I always thought it was bad practice to use the same domain for API and non-API traffic. In the browser there'll be a ton of wasted context (cookies) attached to the API request that isn't needed.

So it's better to have "api.example.com" and "www.example.com" kept separate, rather than using "www.example.com/api/", where API requests will have inflated headers.


That very much depends on what's hitting your API and why. If it's browser clients, you might want to worry about headers and cookies -- but with http/2 and http/3 using hpack and qpack you should be able to avoid sending all the data each time. If the clients aren't browsers then the question is moot but there are other reasons to consider.

In any case, I'd recommend same-origin requests for browser access to APIs and a separate domain for non-browser access, purely for separation of concerns. That lets you tailor the access rules for your endpoints according to the type of caller you're expecting.


What matters is that there is nothing listening on port 80 on the same IP address. That may be hard to control if you are using an environment with shared ingress.


If someone is in your path they can just fake listen to 80 and intercept, then forward your call to 443.

Probably best to listen on 80 and trash the token right then as the majority of the time there won't be a MITM and breaking the application will force the developer to change to https


> If someone is in your path they can just fake listen to 80 and intercept, then forward your call to 443.

They can do that whether or not you are listening on port 80 though.


That was OPs point. Not listening on port 80 won't help against an active MitM.


But listening on port 80 and revoking the key also won’t help either as the active MitM would have been smart enough to internally proxy to port 443 or return some other fake response.

The real point is to break the application during development before the first MitM. Either approach does that equally well.


But not listening on port 80 will also usually break the application. Though I suppose the same API key may be used by multiple applications, or multiple copies of an application configured differently.

edit: and even if there's only one application, yet for whatever reason it doesn't get taken down despite being broken, revoking the key now still prevents against a MITM later.


The point in the article is that APIs are used by developers, not end users.

Returning an error (and/or blocking the port entirely) allows the developer to understand he is using the wrong protocol and fix it.

In this scenario, the end user never actually performs an http request, because the protocol was fixed by the service developer.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: