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

[IPFS] Don’t redirect ipfs subresources away from public gateways to the local gateway when the local gateway will get blocked #20357

Closed
da2x opened this issue Jan 6, 2022 · 10 comments · Fixed by brave/brave-core#11799
Assignees

Comments

@da2x
Copy link

da2x commented Jan 6, 2022

Description

Steps to Reproduce

  1. Enable and switch to a local IPFS gateway from brave://settings/ipfs (like this, restart Brave to apply!).
  2. (Generic) Visit any HTTPS webpage that embeds an image (or other subresource) from a HTTPS-IPFS gateway
  3. OR (Simplified) Visit https://jsbin.com/suwosiyaba/edit?html,output – you should see the IPFS logo in the Output view

Actual result:

Brave redirects the subresource (e.g. https://gateway.ipfs.io/ipfs/<cid>) to the local gateway under localhost. The request is blocked as Brave doesn’t allow loading subresources from localhost on HTTPS pages (brave/brave-core/pull/7194 by @bbondy).

Expected result:

The image should load from the public HTTPS gateway. Brave should not redirect the subresource request away from a public HTTPS gateway when it intends to block the resulting address.

Preferred results:

The image should load from the local gateway as that’s how I’ve configured Brave. It’s an opt-in feature, and it’s super-annoying that Brave’s policies blocks mixed-mode uses.

Reproduces how often:

Every time.

Brave version (brave://version info)

1.33.106 Chromium: 96.0.4664.110 (Official Build) unknown (64-bit)

@da2x da2x added the OS/Desktop label Jan 6, 2022
@bbondy bbondy added feature/web3/ipfs priority/P3 The next thing for us to work on. It'll ride the trains. labels Jan 6, 2022
@stephendonner
Copy link

cc @spylogsster and @lidel

@spylogsster
Copy link

image
Seems working in Nightly, @da2x can you confirm? Thanks.

@da2x
Copy link
Author

da2x commented Jan 10, 2022

@spylogsster, no it doesn’t work in nightly (1.36.23 Chromium: 97.0.4692.71 (Official Build) nightly (64-bit), adefa7837d02a07a604c1e6eff0b3a09422ab88d-refs/branch-heads/4692@{#1247}) either. I’ve updated the steps to reproduce to clarify that you need to restart Brave after changing the settings for them to apply. I also included a screenshot of my settings (local node, redirect to configured node.)

@spylogsster spylogsster self-assigned this Jan 10, 2022
@bbondy
Copy link
Member

bbondy commented Jan 10, 2022

@spylogsster there is a security / privacy concern here when the top level page is HTTP(S) and it's loading IPFS resources. For example a website could host a page and add a file onto the user's cache. We require that the top level be an IPFS resource.
We could perhaps always use gateway in this case.
cc @lidel

@lidel
Copy link

lidel commented Jan 10, 2022

Redirecting subresources on https:// to local gateway is always tricky. In the past 5 years we had regressions around redirect handling in both Firefox and Chromium, and most recently realized IPFS Companion is unable to do it in Brave due to privacy shield rules (#13641). It is too brittle for people to rely on it working reliably.

The top level document requirement proposed by @bbondy is sensible here – at least it will make subresource redirect possible on DNSLink websites (loaded over ipns://) and immutable website snapshots (ipfs://).

@da2x
Copy link
Author

da2x commented Jan 11, 2022

there is a security / privacy concern here when the top level page is HTTP(S) and it's loading IPFS resources. For example a website could host a page and add a file onto the user's cache. We require that the top level be an IPFS resource.

Firefox and Chrome both assume http://localhost (and variations) to be secure origins. Safari doesn’t.

I don’t see why this is considered a bigger issue for subresources loaded over localhost/IPFS than third-party resources hosted on HTTP(S).

[…] the user's cache […]

Is cache-based fingerprinting the issue? Here are some possible privacy enhancements for the IPFS cache that could allow Brave to still use it (ordered by implementation complexity):

  • Introduce a random delay when loading from the IPFS cache to thwart timing based fingerprinting.
  • Randomly lie about the caching status and require reloading resources.
  • Use a Tor/Firefox style first-party cache isolation.

We could perhaps always use gateway in this case.

Just not redirecting to the local (or even the configured public) gateway is probably the best compromise here. Some gateways don’t serve videos, for example. Presumably, the fallback gateway specified on a page allows the resource it attempts to load. (E.g. DTube uses its own IPFS gateways that allow serving video.)

This leaves ipfs:// and ipns:// subresourcs loading unhandled and broken, though. An HTTPS page that tries to load with these schemes will presumably also handle loading error events themselves.

[…] at least it will make subresource redirect possible on DNSLink websites (loaded over ipns://) and immutable website snapshots (ipfs://).

That seems to work fine already, by the by. This is only an issue on HTTP(S) pages.

@diracdeltas
Copy link
Member

i'll have to dig up the original IPFS security review for more details, but IIRC the two main concerns were cache probing (being able to check what IPFS pages a user has in their cache) and cache polluting (where a site puts objectionable/incriminating IPFS content in a user's cache by making third party requests). originally i wanted to restrict third-party CID loading but was told this would break too many IPFS sites, so we just applied these restrictions to non-IPFS/IPNS origins.

@da2x
Copy link
Author

da2x commented Jan 12, 2022

[...] cache polluting (where a site puts objectionable/incriminating IPFS content in a user's cache by making third party requests).

The same threat exists with the HTTPS cache. Any site can put anything into your cache. Although, it's a bit different with the distributed nature of the IPFS cache. There's not really anyway to mitigate this completely, as it's fundamental to the technology.

I have two possible proposals:

  1. Introduce a JavaScript API for websites to request permission to loading assets over IPFS. Boolean site permission. If permission is granted, use a local (or configured gateway) node. If not then reject loading of ipfs: and ipns: schemes (verify that it issues an interceptible network error), and don't intercept or redirect the https: gateway specified by the page.
  2. For HTTPS origins, inject a js-ipfs service worker to handle IPFS. (Currently no support for IPNS. The local configured node can be used for name resolution, however.) This isolates the cache to the current https: origin and stops distributing the cached content when all the origins tab are closed. Users won't host content any longer than their visit to the site. It's not perfect, but potentially very useful for video sites wanting to offload some hosting costs. It's a nice compromise between P2P benefits and risks.

@diracdeltas
Copy link
Member

The same threat exists with the HTTPS cache. Any site can put anything into your cache.

Right, the difference is that with IPFS your cache contents are potentially visible to anyone (law enforcement, etc.).

For HTTPS origins, inject a js-ipfs service worker to handle IPFS. (Currently no support for IPNS. The local configured node can be used for name resolution, however.)

I think this would address the cache polluting issue nicely but sites could still see what is in your IPFS cache; and also as a side effect, this would mean that cache-probing attacks are non-destructive (the second time a user visits your site, you can query and get the same result as the first time, which makes it easier to fingerprint them).

@stephendonner
Copy link

stephendonner commented Jan 19, 2022

Verified PASSED using

Brave 1.36.46 Chromium: 97.0.4692.71 (Official Build) nightly (64-bit)
Revision adefa7837d02a07a604c1e6eff0b3a09422ab88d-refs/branch-heads/4692@{#1247}
OS Windows 10 Version 20H2 (Build 19042.1466)

Steps:

  1. new profile
  2. launched Brave
  3. loaded brave://settings/ipfs
  4. choose Brave Local IPFS Node from Method to resolve IPFS resources
  5. toggled Redirect IPFS resources to the configured IPFS gateway
  6. restarted Brave
  7. loaded https://jsbin.com/suwosiyaba/edit?html,output
  8. confirmed I saw the IPFS icon
  9. loaded brave://settings/ipfs
  10. chose Gateway from Method to resolve IPFS resources
  11. restarted Brave
  12. loaded https://jsbin.com/suwosiyaba/edit?html,output
  13. confirmed I saw the IPFS icon
steps 3-5 step 7-8 steps 9-10 steps 11-12
20357-1 20357-2 20357-3 20357-4

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

Successfully merging a pull request may close this issue.

6 participants