Skip to content
This repository has been archived by the owner on Mar 10, 2020. It is now read-only.

version forbidden ? #855

Closed
mitra42 opened this issue Sep 11, 2018 · 10 comments
Closed

version forbidden ? #855

mitra42 opened this issue Sep 11, 2018 · 10 comments

Comments

@mitra42
Copy link

mitra42 commented Sep 11, 2018

I'm seeing an issue with the js-ipfs-api where "version" is forbidden.

Its unclear to me if this is a JS-IPFS-API issue or a GoLang daemon issue?

I call ipfs.version and see in the console.log :

request.js:150 POST http://localhost:5001/api/v0/version?stream-channels=true 403 (Forbidden)
archive.html:1 Failed to load http://localhost:5001/api/v0/version?stream-channels=true: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access. The response had HTTP status code 403. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Request headers are:

Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 0
DNT: 1
Host: localhost:5001
Origin: http://localhost:8081
Pragma: no-cache
Referer: http://localhost:8081/archive.html
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36

and Response is:

HTTP/1.1 403 Forbidden
Vary: Origin
Date: Tue, 11 Sep 2018 06:35:05 GMT
Content-Length: 15
Content-Type: text/plain; charset=utf-8

Running ipfs -D daemon generates the following debugging:

16:46:32.041 DEBUG  cmds/http: incoming API request: /version?stream-channels=true handler.go:88
16:46:32.041 WARNI  cmds/http: API blocked request to /version?stream-channels=true. (possible CSRF) handler.go:107
@parkan
Copy link

parkan commented Sep 11, 2018

the check for "local" access here is only looking for empty referrer/origin, so you may need to configure CORS like

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://localhost"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'

but... the other requests in this context work?

@mitra42
Copy link
Author

mitra42 commented Sep 11, 2018

I don't know if other requests work - when it fails the "version" test, it assumes there is no usable local ipfs instance, falls back and loads js-ipfs instead of js-ipfs-api. I'm assuming any other request from the browser is also going to fail if it calls the same "allowOrigin()" function.

I can't follow the Go code enough to understand where cfg.AllowedOrigins is coming form, but
It sounds to me like that configuration check is wrong, this request is coming from an unmodified browser to an unmodified go server, and you'd think that a local browser would be included by default in what can use the API ?

I may be able to figure out how to get this to work with the Docker-based IPFS instance we'll use for dweb-mirror, but that is far from the only case where I'd expect an ideal browser app (or an extension) to check for a local ipfs instance before starting up a JS-IPFS client so that we get the cross-page and cross-visit to the site caching.

@parkan
Copy link

parkan commented Sep 11, 2018

ok, that makes a lot more sense (re: other calls not working), otherwise this would have been a mystery :)

in that case you just need to configure CORS as indicated here: https://github.com/ipfs/js-ipfs-api#cors

localhost should arguably be included in default CORS (just like the hardcoded check for local curl), I'll open an issue for that

@alanshaw
Copy link
Contributor

I think @parkan has answered this, CORS prevents localhost:8081 from making requests to localhost:5001 unless the server has CORS headers setup correctly. You'll need to add localhost:8081 to the list of origins allowed to make requests to localhost:5001.

Shout if that didn't fix it for you @mitra42.

@mitra42
Copy link
Author

mitra42 commented Sep 14, 2018

I haven't been able to test this yet, if it works it will fix one (of three) cases we are interested in, where we have installed the local ipfs daemon ourselves.

In dweb-mirror we plan on distributing a docker with an http image and either an integrated, or a separate docker with IPFS. It doesn't currently fix that case because I can't figure out how to set config variables on a docker-based IPFS, since the "ipfs config" line only works AFTER start_ipfs is run (i.e. after the container is operating), so-far I haven't been able to figure out how to set them in the downloadable docker image before IPFS is running.

This also doesn't handle the case of a browser app (such as dweb.archive.org) optimising for the case where another instance of IPFS is running locally. This is what we'd like to do with dweb.archive.org so that if you run a local daemon we take advantage of the speed improvement from a local IPFS caching across runs of the browser. This might make up for some of the speed hits we take by including IPFS. Unfortunately that isn't going to work since its unlikely the user will have done the workaround @parkan suggests.

Anyway, as @parkan says, allowing any localhost port should probably be the default, its unclear to me why CORS (which blocks where a webpage is loaded from) is being used to block api requests, rather than basing it on the IP where the request is coming from.

@parkan
Copy link

parkan commented Sep 17, 2018

I haven't been able to test this yet, if it works it will fix one (of three) cases we are interested in, where we have installed the local ipfs daemon ourselves.

In dweb-mirror we plan on distributing a docker with an http image and either an integrated, or a separate docker with IPFS. It doesn't currently fix that case because I can't figure out how to set config variables on a docker-based IPFS, since the "ipfs config" line only works AFTER start_ipfs is run (i.e. after the container is operating), so-far I haven't been able to figure out how to set them in the downloadable docker image before IPFS is running.
You can configure this in a Dockerfile, like

FROM ipfs/go-ipfs
RUN ipfs config ...

can discuss that offline

This also doesn't handle the case of a browser app (such as dweb.archive.org) optimising for the case where another instance of IPFS is running locally. This is what we'd like to do with dweb.archive.org so that if you run a local daemon we take advantage of the speed improvement from a local IPFS caching across runs of the browser. This might make up for some of the speed hits we take by including IPFS. Unfortunately that isn't going to work since its unlikely the user will have done the workaround @parkan suggests.

this is a reasonable security policy and applies to any kind of local HTTP API, not just IPFS: imagine arbitrary websites being able to run commands against your local servers, potentially leaking private data

IPFS companion has per-site access policies that are presented in a friendly UI and will probably be the best way to allow web<>local IPFS access for the immediate future

@mitra42
Copy link
Author

mitra42 commented Sep 17, 2018

OK - understood re security issue, so looks like local config is going to be needed before can use js-ipfs-api. But note @parkan see https://github.com/protocol/collab-internet-archive/issues/55#issuecomment-422075488 ,for why that docker suggestion doesn't actually work.

@mitra42
Copy link
Author

mitra42 commented Sep 20, 2018

I can confirm that adding the two line @parkan suggested works to allow the API to work.

It looks like the docker issue above, will stop it working in docker for now, though that presumably is fixable.

Of course, the more general issue is the bizareness of using the location from which content was loaded as the security test in a content-addressed file system ! Which means that an application downloaded via a HTTP server, or even fetched through IPFS won't be able to use a local IPFS server to ensure persistence, but I guess that is a topic for elsewhere since @alanshaw has closed this issue :-(

@mitra42
Copy link
Author

mitra42 commented Sep 27, 2018

For anyone reading this later ... the solution for the docker case is to run

ipfs init
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://localhost"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'

@prayaglehana
Copy link

prayaglehana commented Oct 2, 2019

i dont know why but these config setting commands
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'
are not working .
Another way is to directly go to ipfs config file (mine was at "C:\Users\praya.ipfs" ) then open it ,
and paste where API is the key

  "API": {
    "HTTPHeaders": {
      "Access-Control-Allow-Origin": [
        "*"
      ],
        "Access-Control-Allow-Methods": [
        "PUT", "GET", "POST"
      ]
    }
  },

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

No branches or pull requests

4 participants