Read-only API is accessible on public gateway but has CORS disabled.
This makes it impossible to use it from JS in browser which was a point of it.
IMHO CORS handling in general should be as follows:
There were opinions that read-only API isn't that read-only as it can make user download some content. It shouldn't be taken as issue as it is already possible with just gateway.
(API might want to introduce change that GET uses data only available locally and specifies non-standard request method (i.e. FETCH) that downloads data from the network, this way GET does not have any side-effects).
Example of missing CORS on read-only API response:
卤 curl -v http://ipfs.io/api/v0/object/get?arg=/ipfs/QmbfChZw78fWH6ckgAb6mWLqm7k8gJJUVKgSYvFw2XiKiq
* Trying 178.62.61.185...
* Connected to ipfs.io (178.62.61.185) port 80 (#0)
> GET /api/v0/object/get?arg=/ipfs/QmbfChZw78fWH6ckgAb6mWLqm7k8gJJUVKgSYvFw2XiKiq HTTP/1.1
> Host: ipfs.io
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.9.3
< Date: Sun, 24 Jan 2016 10:30:22 GMT
< Content-Type: application/json
< Transfer-Encoding: chunked
< Connection: keep-alive
< Access-Control-Allow-Headers: X-Stream-Output, X-Chunked-Output
< Access-Control-Expose-Headers: X-Stream-Output, X-Chunked-Output
< Trailer: X-Stream-Error
< Strict-Transport-Security: max-age=15768000
<
{"Links":[],"Data":"\u0008\u0002\u0012\ufffd\u0001#!/usr/bin/env bash\n# adds files to IPFS and creates symlink to FUSE\n# probably will break in some cases and remove your files.\nHASH=$(ipfs add -r -q $1 | tail -1)\nrm -rf $1\nln -s \"/ipfs/$HASH\" \"$1\"\n\u0018\ufffd\u0001"}
* Connection #0 to host ipfs.io left intact
Seems that the current state was a quick security workaround from the time when entire API was writeable (https://github.com/ipfs/go-ipfs/issues/934#issuecomment-174227611) and these days we should simply remove skipAPIheader and allow CORS headers everywhere.
Gateway and API use separate settings trees now which gives us a good framework for writing specific security rules:
ipfs config --json Gateway.HTTPHeadersipfs config --json API.HTTPHeadersFor the writable API it is possible to give CORS access only to a specific host:
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://my.site.com"]'
Generally it should be possible to set up CORS if user choose to do so.
PS. We should make sure CORS test suite gets updated to reflect those changes:
https://github.com/ipfs/go-ipfs/blob/master/test/sharness/t0112-gateway-cors.sh
PS2. INB4 CORS is not enough to prevent CSRF attacks (Token API is needed to fix it): until we have Token API app developers can simply blacklist destructive API methods at the reverse-proxy level.
For me important and one that can be solved without API Tokens is lack of CORS on read-only API. It stops development of in browser applications that want to only read from the API.
Config should include following as defaults for CORS to be supported on gateways:
ipfs config --json Gateway.HTTPHeaders.Access-Control-Allow-Origin '["*"]'
ipfs config --json Gateway.HTTPHeaders.Access-Control-Allow-Methods '["GET"]'
ipfs config --json Gateway.HTTPHeaders.Access-Control-Allow-Headers '["X-Requested-With"]'
Preferably before 0.4.0 is released.
Solution above really doesn't solve much as:
@Kubuxu any plans of enabling this sometime soon-ish? :)
I think this is closable? @Kubuxu @lidel ?
Yeah, this can be closed as CORS looks fine in 2019 (go-ipfs v0.4.18):
$ curl -Is 'https://ipfs.io/api/v0/dns/ipfs.io?r=true' | grep Access-Control
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Range, Content-Range, X-Chunked-Output, X-Stream-Output
Access-Control-Expose-Headers: Content-Range, X-Chunked-Output, X-Stream-Output
ps. Cleanup of -Allow-Headers and -Expose-Headers is tracked in https://github.com/ipfs/go-ipfs/pull/5893#pullrequestreview-189648530