web-security

orestis 2022-10-18T06:35:56.446679Z

I saw an OPTIONS request in our logs recently, which is very confusing to me since we don't use cross-origin requests anywhere. We got alerted to it because Sentry caught the resulting error (an XHR status of 0)

seancorfield 2022-10-18T06:42:37.608499Z

I would expect OPTIONS requests for any API that might be accessible via XHR in a UI.

orestis 2022-10-18T06:43:11.595079Z

Even in the same origin? e.g. http://site.com/foo making an XHR/JSON request to http://site.com/api ?

seancorfield 2022-10-18T06:43:33.990849Z

It wouldn't surprise me. It's up to the browser, yes?

seancorfield 2022-10-18T06:43:49.878189Z

I don't associate that with cross-site requests.

seancorfield 2022-10-18T06:44:42.981609Z

I mean, you may be right, but it's just not something I'd ever assumed would be only for cross-site requests...

orestis 2022-10-18T06:45:33.766589Z

Getting hold of a spec of how this works is proving impossible, I’m getting drowned in a million tutorials.

seancorfield 2022-10-18T06:49:01.465109Z

Yeah... a brief search does suggest that OPTIONS should only be sent if the request is to a different domain. Interesting. Although folks say it's browser-dependent and hard to control so I guess it's possible an aggressive browser is sending OPTIONS even when it doesn't strictly need to? What does the REFERER say in the logs, or don't you log that?

seancorfield 2022-10-18T06:49:33.920299Z

(I had just assumed that XHR requests from JS would send OPTIONS even to the same domain but I'm less convinced now)

orestis 2022-10-18T06:57:57.386709Z

No referer in the logs for OPTION request, I see if for other requests though.

orestis 2022-10-18T06:59:50.273499Z

All the OPTIONS requests I see in our nginx access logs look to be bots/spam.

orestis 2022-10-19T07:21:30.640999Z

I expected I would see this much more often though. As it stands we're talking a single data point of an OPTIONS request to our /graphql endpoint for a single tenant - if it was hammered it would definitely show up in the logs. I don't believe same-domain requests (using XHR, not sure about the fancy new fetch api) get pre-flighted at any point.

orestis 2022-10-18T07:33:36.913739Z

Now I've gotten curious, I'll try to get to the bottom of this.

orestis 2022-10-18T08:14:49.874449Z

Installing an HTTP interceptor, under normal circumstances, I don't see OPTIONS requests coming out of Chrome (chrome doesn't show the OPTIONS requests in the Network tab, so you have to look from the outside).

orestis 2022-10-18T08:15:09.486269Z

In addition, that OPTIONS requested ended up in a "login required" redirect so I think someone was trying something fishy there.

seancorfield 2022-10-18T15:31:51.163199Z

I'm surprised Chrome doesn't show those. Edge does and it's based on Chromium.

Dave Russell 2022-10-18T21:09:56.163039Z

We’ve hit this before — I believe OPTION pre-flight requests are generally issued for “https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests” requests, even to the same domain. So many headers, HTTP methods, content-types, etc will cause the browser to issue a pre-flight.

Dave Russell 2022-10-18T21:17:09.210949Z

As for the redirect to the login form, OPTION requests are often not authenticated (I can’t recall whether the browser sends cookies with them, but the expectation in CORS is that they don’t require auth), so it might be being caught in your generic middleware’s

Dave Russell 2022-10-18T21:18:50.138749Z

Not saying someone isn’t doing something fishy, but if you don’t support CORS then an unauthenticated OPTION getting slammed with a 403 by the auth layer seems like a reasonable outcome 😛