2

I'm testing an API, which allows an arbitrary origin on POST/GET requests, by responding with the CORS header Access-Control-Allow-Origin: *.

However, with OPTIONS requests and an arbitrary origin, the web service does not respond with Access-Control-Allow-Origin: *, it does not use the response header at all.

This means that any CORS preflight requests with an arbitrary Origin, would fail.

I don't see the point in having the CORS response header for GET/POST requests, but not the OPTIONS request. However, I also can't provide an example for a vulnerability or how this may be exploited.

Q: Is it safe to say that does not pose a vulnerability, but is just bad practice?

2 Answers2

1

Q: Is it safe to say that does not pose a vulnerability, but is just bad practice?

Since it's an API and assuming it requires Authorization header for all requests, it's safe to say that it doesn't pose a vulnerability. The behavior, however, limits communication to same-domain.

It's worth noting that not all requests are preflighted. Please refer to https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests for more details.

An API expects, if properly configured, a proper Content-type header and an authorization header which in most cases is Authorization. If a request sets a "forbidden header name" or an unsafe Content-type, it's always preflighted. And as such, no other domain would be able to send an authenticated request at all.

1lastBr3ath
  • 909
  • 6
  • 13
1

This is simply a way to allow browsers to make unauthenticated requests against the site, but not authenticated ones. Access-Control-Allow-Origin: * doesn't support authenticated CORS requests anyhow - it's a violation of the spec to specify that and also specify Access-Control-Allow-Credentials: True and conforming browsers would ignore that - but simple (GET/POST/HEAD, no custom headers, only content types supported by HTML forms) requests made without credentials will work fine and the requesting site will be able to see the response.

There's no security impact of configuring CORS this way EDIT: provided that the server doesn't have any non-credentials-based authorization (that is, it doesn't trust any clients based purely on things like being on the same LAN or loopback server, or the request coming from a specific IP); the server for the other origin (or any host controlled by a hypothetical attacker) could just send its own request to the target site, retrieve the resource that is available unauthenticated, and send it to the browser. The advantage to setting this header is that the server can say "hey, go ask some other site for this info yourself" and the client-side code will be allowed to do that (this reduces other-origin server activity and network load, and exposes where the requests are ultimately coming from to the target site).

Some web scanners still report Access-Control-Allow-Origin: * as inherently vulnerable; this is wrong and their developers should feel bad.

CBHacking
  • 40,303
  • 3
  • 74
  • 98
  • *a way to allow browsers to make unauthenticated requests against the site, but not authenticated ones*. The OP writes that the preflight response doesn't contain any `Access-Control-Allow-Origin`. In that case, if the resource is accessed via a CORS request, there's no way its preflight check would succeed. – jub0bs Sep 09 '21 at 13:43
  • True, but irrelevant to security (unless the API server is not publicly accessible). The point I was making about ACAO: * is that it's not security-relevant (and gave the reason why it exists at all). The fact that it won't work for non-simple CORS requests is still not going to impact security at all (though it might be inconvenient for third parties that want to use the API for something). – CBHacking Sep 09 '21 at 21:48
  • A `ACAO: *` CORS policy is relevant to security in some contexts; see, for example, https://security.stackexchange.com/questions/227779/concrete-example-of-how-can-access-control-allow-origin-cause-security-risks/254684#254684 – jub0bs Sep 10 '21 at 05:52
  • 1
    I specified the context, @jub0bs. "(unless the API server is not publicly accessible)". I suppose "publicly accessible" is too specific - the actual case is "unless the API server is reachable from the victim's browser but not from any host the attacker controls" - but it rounds off pretty well to "not publicly accessible". I'll edit it into the answer though. – CBHacking Sep 10 '21 at 07:40
  • No worries, I'm nitpicking :) – jub0bs Sep 10 '21 at 07:41