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

API returns 403 when Origin header is set without CORS setup #6204

Open
MichaelMure opened this issue Apr 10, 2019 · 12 comments
Open

API returns 403 when Origin header is set without CORS setup #6204

MichaelMure opened this issue Apr 10, 2019 · 12 comments
Labels
topic/CORS Issues related to CORS on HTTP endpoints

Comments

@MichaelMure
Copy link
Contributor

Version information:

go-ipfs version: 0.4.19-
Repo version: 7
System version: amd64/linux
Golang version: go1.11.5

Type: bug

Description:

$ ipfs init
$ ipfs config show
{
  "API": {
    "HTTPHeaders": {}
  },
...

$ ipfs daemon &
...
$ curl http://localhost:5001/api/v0/version
{"Version":"0.4.19","Commit":"","Repo":"7","System":"amd64/linux","Golang":"go1.11.5"}
$ curl -H 'Origin: http://example.com' http://localhost:5001/api/v0/version
403 - Forbidden

$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'

<restart ipfs daemon>

$ curl http://localhost:5001/api/v0/version
{"Version":"0.4.19","Commit":"","Repo":"7","System":"amd64/linux","Golang":"go1.11.5"}
$ curl -H 'Origin: http://example.com' http://localhost:5001/api/v0/version
{"Version":"0.4.19","Commit":"","Repo":"7","System":"amd64/linux","Golang":"go1.11.5"}

As shown in the previous example, if no CORS setup is done, any request with a Origin header will be denied. This breaks a few usecases, including handling CORS in a proxy sitting in front of go-ipfs.

@Kubuxu
Copy link
Member

Kubuxu commented Apr 10, 2019

AFAIK this is done on purpose to secure the API endpoint from arbitrary scripts in a browser.

@MichaelMure
Copy link
Contributor Author

If the client side manage to do a non-CORS request when go-ipfs is setup for CORS, it will work no problem. This one make sense to me. My understanding is that CORS is a client side protection, so why not.

If the client side try to do a CORS-enabled request when go-ipfs is not configured for CORS, it will be denied. This one doesn't make sense to me. By not configuring go-ipfs for CORS, we explicitly say that we don't care about CORS, but go-ipfs will still deny the request.

I'm far from an expert on CORS, but I don't see how it protect anything. Could someone enlighten me ?

Maybe it's a matter of having CORS configured by default ?

@Kubuxu
Copy link
Member

Kubuxu commented Apr 11, 2019

If CORS is not configured then the default config is used which prohibits most CORS requests.

@MichaelMure
Copy link
Contributor Author

Sorry, my point was that if go-ipfs has CORS properly configured by default (with * origin allowed), not having a CORS configuration make it an explicit choice by the node administrator. There would be no point anymore of denying request by default if they have an Origin header.

@Kubuxu
Copy link
Member

Kubuxu commented Apr 11, 2019

The default is not * origin allowed. It would allow every website in a browser full access to go-ipfs API (access to pinning, running gc, reading config and so on) which isn't something we would like to allow.

@parkan
Copy link

parkan commented Apr 17, 2019

This is a bit tricky. @MichaelMure is correct in that CORS is as a client-side standard that works through a send/read permissions table. Simple GET/POST requests are permitted, only reading the response inside the browser is denied (this is how any normal web server works -- the browser won't know to deny reading the request until it gets the response back without CORS headers, or else the corresponding preflight). From that POV, CORS configuration should have no impact on server response codes.

On the other hand, we do want to secure the API! From that perspective, denying browser-originating requests from arbitrary Origins by default makes sense. The other option here would be to use an auth mechanism or token that the local client has access to, similar to how CSRF prevention works.

I feel like this is an API design/documentation issue above all: in reality the ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin X is actually saying "change the access control table on the server to allow requests from Origin X, and set corresponding CORS header so the browser allows the response to be read". I'm assuming this is what happens internally, but we should change the API to something more like ipfs config --json API.AllowedHTTPOrigins ... so it doesn't have the surprising server-side side effect.

@parkan
Copy link

parkan commented Apr 17, 2019

another option might be to add something similar to Chrome's --disable-web-security flag, which turns off origin checking without any CORS headers

@MichaelMure
Copy link
Contributor Author

I think that even though we a have a slightly different POV, we pretty much agree. This is more a UX problem than a technical one.

Yes, the API should be secure by default. My point is that there is situations where you want to drop that security, if only because it's handled somewhere else, but go-ipfs doesn't allow that at the moment.

Now the question is how ? My view is that removing the CORS config should be enough. It's the less surprising solution which IMHO is a very important property in UX design. But as we are desling with security, an extra explicit --disable-web-security-like flag might work as well.

@MichaelMure
Copy link
Contributor Author

In a similar fashing, there is #6213

@Stebalien
Copy link
Member

@Kubuxu not sure if we talked about this yet but would be up for taking API security/access control on as a KR this quarter?

@momack2 momack2 added this to Inbox in ipfs/go-ipfs May 9, 2019
@MichaelMure
Copy link
Contributor Author

So apparently, go-ipfs does the same thing for requests with a Referer header, even without any Origin or Access-Control-* header.

@subdavis
Copy link

subdavis commented Jan 2, 2021

How I fixed this

I got stuck on this issue using docker.

  1. You must start the container with volume mounts for /export and /data/ipfs
  2. After starting the container, docker exec -it containername and run the CORS whitelist commands
  3. You must now restart the container. docker restart containername

It would be great if the CLI mentioned that config changes don't take effect until after a restart. Also, it's pretty odd that an improper CORS configuration would result in 403 errors and not, you know, CORS errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic/CORS Issues related to CORS on HTTP endpoints
Projects
No open projects
Development

No branches or pull requests

6 participants