Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

w3id.org should not redirect on OPTIONS #4185

Open
pchampin opened this issue Jun 13, 2024 · 4 comments
Open

w3id.org should not redirect on OPTIONS #4185

pchampin opened this issue Jun 13, 2024 · 4 comments

Comments

@pchampin
Copy link
Contributor

When w3id.org gets an OPTIONS request, it returns a 302 Found redirect (as it does for a GET).
The problem is that, in a CORS context, this leads to a 'CORS request external redirect not allowed' error.

The problem would be solved if w3id.org returned a 200 Ok on OPTIONS.

@pchampin
Copy link
Contributor Author

Steps to reproduce:

  • go to https://www.w3.org/ (or any other page not blocking CORS requests -- Github does block them)
  • open the dev console
  • run
    await fetch(
      "https://w3id.org/SpOTy/ontology",
      {headers: {"user-agent": "to-force-preflight-query"}}
    )
    
  • the presence of the user-agent headers triggers a preflight request
  • that preflight requests (with method OPTIONS) fails, because it got a 302 response

Example of working configuration

  • go to https://www.w3.org/ (or any other page not blocking CORS requests -- Github does block them)
  • open the dev console
  • run
    await fetch(
     "https://champin.net/2023/SpOTy/ontology",
     {headers: {"user-agent": "to-force-preflight-query"}}
    )
    
  • the requests succeeds; notice that the first preflight requests got a 200 Ok response
  • notice also that, after the redirect, another preflight request is sent, so the destination server still has an opportunity to stop undesired behaviour. It is then safe for w3id.org to allow any preflight request blindly.

@davidlehn
Copy link
Collaborator

There are a few things going on here. Summary is that I'm not sure how to solve this in a generic global way.

  • I had some trouble with your examples in a recent Chromium. It wasn't allowing "user-agent" to be updated and would send requests with default user-agent header with no preflight.
  • Doing something to trigger a preflight request means making something that isn't a "simple request" (https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests).
  • When forcing the preflight request, you then almost immediately get CORS errors. Need to go to an endpoint that is setup to handle extra non-simple headers or methods for it to succeed.
  • I tried some experiments to always handle OPTIONS requests with a 204. That does make that part of the preflight bit work, but I'm not sure that is universally desired behavior? Though we do always set Header always set Access-Control-Allow-Origin "*".
  • If you do have global 200/204 for OPTIONS, you can still fail in new ways. For instance, github pages returns an error for OPTIONS. So if you did a non simple request to a w3id resource that redirected to github pages, you would still get a preflight error. In your case, you are going to a server that does know how to handle OPTIONS.
  • I'm not entirely sure how best to even do the global OPTIONS idea. It's a bit tricky and, due to the redirect fixes in the root .htaccess, I think it needs to be set in the apache Directory config directly. I was trying the rather blunt hammer method that would be difficult to override, and I'm not sure how efficient global inherited rules are.
RewriteOptions InheritDownBefore
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^ - [R=204,L]
  • Anyone can add that Cond+Rule at the top of their own .htaccess and handle the issue locally. But that's a bit of magic people might not know to use.
  • I suspect people are only using simple requests so no one is even seeing the preflight issue.

I'm not sure what to do here. Since people haven't been complaining about this, and even I didn't realize this was an issue, perhaps it can be better documented and handled on a per-id basis when needed? It's a few lines and I think the special local use cases can be handled better. Like using other CORS headers to set allowed headers, methods, etc.

Thoughts?

@pchampin
Copy link
Contributor Author

Disclaimer: I don't claim to be the ultimate expert on CORS, but I think I have a fair understanding of how it works.

My thinking is that w3id.org is meant to be as transparent as possible. It sets Access-Control-Allow-Origin to *, and leave it to the destination server to apply its own policy.
Similarly, it should accept all preflight requests, and leave it to the destination server to handle them with more scrutiny. You are right, "accepting" them requires more than just returning 204, you need to fill all the "allow" headers with whatever was requested in the preflight.

Yes, if the destination server is not configured for handling preflight requests, there will be an error down the line. This is not your concern, just like it is not your concern if the URL you redirect to returns a 404, or if it does not include the allow-origin header to allow CORS queries. Anyway, CORS is "reject by default", so if the destination server is not configured, the query will be rejected. Being permissive on w3id's side is not putting the destination server at risk.

That being said, you are right, I might just as well try to configure it locally, and when I have a working configuration, we can discuss if it is worth making it global.

@pchampin
Copy link
Contributor Author

#4196 did the trick (in the SpOTy folder).

Note that, for testing in Chrome, you can force the preflight request by replacing user-agent with a custom header x-foo:

await fetch(
  "https://w3id.org/SpOTy/ontology",
  {headers: {"x-foo": "to-force-preflight-query"}}
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants