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

What can be done to prevent XSS attacks against IPFS sites? #32

Closed
Mithgol opened this Issue Sep 15, 2015 · 13 comments

Comments

Projects
None yet
9 participants
@Mithgol

Mithgol commented Sep 15, 2015

According to the Open Web Application Security Project, XSS (cross-site scripting) was the third most common Web app vulnerability in 2013.

The current security measures against XSS (such as same-origin policy or content security policy) rely on the centralized nature of the Web, e.g. different domain names mean different ownership of hostnames and thus some types of access are restricted (unless some CSP or CORS settings explicitly say otherwise).

They won't be effective in IPFS where all data seems to have the same hostname (of its Web gate such as ipfs.io) or becomes a part of the local filesystem.

Then what can be done to prevent XSS attacks against IPFS sites?

@whyrusleeping

This comment has been minimized.

Show comment
Hide comment
@whyrusleeping

whyrusleeping Sep 15, 2015

Member

we set CORS headers and restrict origins, see https://github.com/ipfs/go-ipfs/blob/master/core/corehttp/commands.go#L33 and similar.

Member

whyrusleeping commented Sep 15, 2015

we set CORS headers and restrict origins, see https://github.com/ipfs/go-ipfs/blob/master/core/corehttp/commands.go#L33 and similar.

@jbenet

This comment has been minimized.

Show comment
Hide comment
@jbenet

jbenet Sep 15, 2015

Member

We've discussed this a few other places, but we need to pull the information into here.

things worth mentioning/discussing:

Member

jbenet commented Sep 15, 2015

We've discussed this a few other places, but we need to pull the information into here.

things worth mentioning/discussing:

@lgierth

This comment has been minimized.

Show comment
Hide comment
@lgierth

lgierth Sep 15, 2015

Member

Something that can be done by anyone, without any work on our part, is using a custom domain, as described in ipfs/notes#39

Member

lgierth commented Sep 15, 2015

Something that can be done by anyone, without any work on our part, is using a custom domain, as described in ipfs/notes#39

@Mithgol

This comment has been minimized.

Show comment
Hide comment
@Mithgol

Mithgol Sep 16, 2015

@whyrusleeping CORS is not effective if an IPFS site is attacked by a malicious script that does also reside in IPFS (i.e. an attacker does ipfs add beforehand and then uses the IPFS path of the script) and thus has the same hostname (IP address).

Mithgol commented Sep 16, 2015

@whyrusleeping CORS is not effective if an IPFS site is attacked by a malicious script that does also reside in IPFS (i.e. an attacker does ipfs add beforehand and then uses the IPFS path of the script) and thus has the same hostname (IP address).

@edrex

This comment has been minimized.

Show comment
Hide comment
@edrex

edrex Sep 16, 2015

Just to unwrap this

Cause

The root cause of the vulnerability is serving unsanitized resources from mutually-untrusted sources from a single origin.

Attack

  • The user accesses IPFS-deployed App A via the shared gateway.ipfs.io domain, and authorizes some privilege/stores data via that app.
  • Later the user accesses (malicious) App B also via the shared gateway domain. App B is able to use the privileges / access the stored data meant for App A, counter to the user's expectation of app-level isolation. Targets include:
    • Stored user data
    • Stored credentials for remote services
    • User-approved privileges for "HTML5" APIs such as media capture, storage quota exceptions

Potential resolutions

  • Enforce a separate origin per IPFS/IPNS per "root" node (root: an arbitrary node used as the base/starting point for DAG traversal). Each root represents a trust scope, since all linked objects are fixed at creation time
  • Another resolution, targeting a proposed standard, would be to continue using <gateway.ipfs.io>, but set a per-root suborigin header. See ipfs/go-ipfs#651.
  • The domains (or suborigins) could be <hash>.gateway.ipfs.io or similar, where <hash> is the root node hash encoded using @kyledrake's hshca.
  • As @lgierth points out, many app publishers will opt to use their own domain which will also close the vulnerability for their app.

References

TiddlyWiki is a venerable distributed publishing system. Various hosting systems for TiddlyWiki content including TiddlySpace use per-application subdomains to prevent XSS attacks.

edrex commented Sep 16, 2015

Just to unwrap this

Cause

The root cause of the vulnerability is serving unsanitized resources from mutually-untrusted sources from a single origin.

Attack

  • The user accesses IPFS-deployed App A via the shared gateway.ipfs.io domain, and authorizes some privilege/stores data via that app.
  • Later the user accesses (malicious) App B also via the shared gateway domain. App B is able to use the privileges / access the stored data meant for App A, counter to the user's expectation of app-level isolation. Targets include:
    • Stored user data
    • Stored credentials for remote services
    • User-approved privileges for "HTML5" APIs such as media capture, storage quota exceptions

Potential resolutions

  • Enforce a separate origin per IPFS/IPNS per "root" node (root: an arbitrary node used as the base/starting point for DAG traversal). Each root represents a trust scope, since all linked objects are fixed at creation time
  • Another resolution, targeting a proposed standard, would be to continue using <gateway.ipfs.io>, but set a per-root suborigin header. See ipfs/go-ipfs#651.
  • The domains (or suborigins) could be <hash>.gateway.ipfs.io or similar, where <hash> is the root node hash encoded using @kyledrake's hshca.
  • As @lgierth points out, many app publishers will opt to use their own domain which will also close the vulnerability for their app.

References

TiddlyWiki is a venerable distributed publishing system. Various hosting systems for TiddlyWiki content including TiddlySpace use per-application subdomains to prevent XSS attacks.

@jbenet

This comment has been minimized.

Show comment
Hide comment
@jbenet

jbenet Sep 16, 2015

Member

@edrex can you add:

  • implement per-page suborigins in all browsers

to the "resolution" part? TBL recently spoke about this, and it will get more traction. we may see it be standard as soon as next year or the following if we make a big push for it.

Member

jbenet commented Sep 16, 2015

@edrex can you add:

  • implement per-page suborigins in all browsers

to the "resolution" part? TBL recently spoke about this, and it will get more traction. we may see it be standard as soon as next year or the following if we make a big push for it.

@edrex

This comment has been minimized.

Show comment
Hide comment
@edrex

edrex Sep 16, 2015

@jbenet suborigins per page or per "root"? i could see wanting to share local resources between two pages within the same root, even though "Single Page Apps" are in fashion. Especially since the same page object might get reused under multiple roots, and I think the expectation would be that each usage of a page would be isolated from the others.

How would you ensure security for legacy browsers while serving all gateway content from the same origin with different suborigin header per page (or root)?

edrex commented Sep 16, 2015

@jbenet suborigins per page or per "root"? i could see wanting to share local resources between two pages within the same root, even though "Single Page Apps" are in fashion. Especially since the same page object might get reused under multiple roots, and I think the expectation would be that each usage of a page would be isolated from the others.

How would you ensure security for legacy browsers while serving all gateway content from the same origin with different suborigin header per page (or root)?

@jbenet

This comment has been minimized.

Show comment
Hide comment
@jbenet

jbenet Sep 16, 2015

Member

we would do it per-root.

Member

jbenet commented Sep 16, 2015

we would do it per-root.

@stevearm

This comment has been minimized.

Show comment
Hide comment
@stevearm

stevearm Dec 19, 2015

@edrex By "Enforce a separate origin per IPFS/IPNS per "root" node" did you mean having a dns subdomain (<hash>.gateway.ipfs.io)? If so, I think that solution provides:

  • isolation from other pages
  • transferability (the same hash can point to a new version of the page while preserving the same javascript permissions and client-side data)
  • persistence (if the original publisher shuts down all their servers, the page remains functional)

I've got a bit more rambling version of this in a blog post

stevearm commented Dec 19, 2015

@edrex By "Enforce a separate origin per IPFS/IPNS per "root" node" did you mean having a dns subdomain (<hash>.gateway.ipfs.io)? If so, I think that solution provides:

  • isolation from other pages
  • transferability (the same hash can point to a new version of the page while preserving the same javascript permissions and client-side data)
  • persistence (if the original publisher shuts down all their servers, the page remains functional)

I've got a bit more rambling version of this in a blog post

@kyledrake

This comment has been minimized.

Show comment
Hide comment
@kyledrake

kyledrake Dec 20, 2015

Member

@stevearm I've ran into this issue as well. Take a look at https://github.com/neocities/hshca and https://github.com/neocities/hshca-proxy

Per-page origins is coming, but is still a ways off. This is a decent workaround for now.

Member

kyledrake commented Dec 20, 2015

@stevearm I've ran into this issue as well. Take a look at https://github.com/neocities/hshca and https://github.com/neocities/hshca-proxy

Per-page origins is coming, but is still a ways off. This is a decent workaround for now.

@lgierth

This comment has been minimized.

Show comment
Hide comment
@lgierth

lgierth Dec 20, 2015

Member

I ordered ipns.name a few a days ago and will deploy HSHCA for IPNS hashes there.

Member

lgierth commented Dec 20, 2015

I ordered ipns.name a few a days ago and will deploy HSHCA for IPNS hashes there.

@edrex

This comment has been minimized.

Show comment
Hide comment
@edrex

edrex Dec 20, 2015

@stevearm, yes, with separate base domains for IPFS and IPNS.

Thanks @kyledrake for thinking through and proposing hshca, it seems reasonable.

Once sub origins are sufficiently baked, we can look at how to support them without compromising security for non-supporting clients.

I'll be watching ipfs/go-ipfs#651.

edrex commented Dec 20, 2015

@stevearm, yes, with separate base domains for IPFS and IPNS.

Thanks @kyledrake for thinking through and proposing hshca, it seems reasonable.

Once sub origins are sufficiently baked, we can look at how to support them without compromising security for non-supporting clients.

I'll be watching ipfs/go-ipfs#651.

@RichardLitt RichardLitt added the answered label May 2, 2016

@flyingzumwalt

This comment has been minimized.

Show comment
Hide comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment