sandstorm-io / sandstorm

Sandstorm is a self-hostable web productivity suite. It's implemented as a security-hardened web app package manager.
https://sandstorm.io
Other
6.75k stars 706 forks source link

Apps can load images from arbitrary websites (!) #2906

Open zenhack opened 7 years ago

zenhack commented 7 years ago

The short version: apps can link to images (and possibly other resources that will get loaded when the page is rendered) from abitrary third party sites. This came up on the mailing list:

https://groups.google.com/forum/#!topic/sandstorm-dev/sxAZHpHfcDE

(See my reply in that thread).

This is pretty serious -- it means sandstorm's promise of keeping apps from "phoning home" is completely broken; arbitrary information can be transmitted to a remote server via a URL (e.g. Github uses this kind of thing to mark notifications as read when you open them via email).

Perhaps this a known issue/TODO, but I couldn't find any direct reference to it.

I don't actually know how you'd go about fixing this -- even with sandbox="" an iframe can still inject remote images.

//cc @kentonv, @dwrensha

ocdtrekkie commented 7 years ago

This is definitely known and something that I believe they have a plan to handle.

But one highlight point I wanted to make, is that client side activity like this is more manageable than if Sandstorm apps could communicate outside via the server, because your browser extensions can handle it. If there was server-side communication, I wouldn't know and couldn't do anything about it. But if you have say, a Google Analytics code embedded in your app, a browser extension like Privacy Badger will catch it and block it.

zenhack commented 7 years ago

Is said plan doucumented anywhere?

I'm not sure the available suite of extensions does all that much to assuage my concerns. That said, it occurs to me that an extension could be written that is sandstorm aware that can plug this hole more thoroughly.

It would be better to have this not work "by default" though; otherwise you have apps breaking because of the privacy extensions.

kentonv commented 7 years ago

I thought we'd been very clear that confinement doesn't exist yet. See the "beta notice" under: https://docs.sandstorm.io/en/latest/using/security-practices/#true-confinement

I try to bring up this disclaimer every time I talk about it. But not enough, I guess... :/

Now that the powerbox is implemented perhaps we can find a way by which apps can legitimately request client-side access to third-party sites so that we can close this hole.

(FWIW the way to block third-party resources is with the Content-Security-Policy header.)

zenhack commented 7 years ago

I do vaguely recall having come across that at some point, though I'd misremembered exactly what the issues were. It is probably worth having a bit less buried; I did look before opening this.

zenhack commented 7 years ago

This came up on IRC again. I'm lead to understand that TinyTinyRSS uses HackSessionContext, rather than simply linking to external resources. Is anything actually using this legitimately, besides that app in the mailing list post I linked?

@ocdtrekkie seems to think the answer is no. It's probably better to close this sooner rather than later.

zenhack commented 7 years ago

Do we have any sort of timeframe in which we plan to close this hole? It would be good to at least compile a list of TODOs; do we still need to add anything to replace the functionality this provided? Other than that I think it's just a matter of how to manage the transition for the few apps it will break. Probably better to do that sooner rather than later.

I was just reminded of this when privacy browser told me permanote was pulling in stuff from google (fonts & api stuff).

zenhack commented 5 years ago

I'd like to get the ball rolling on closing this hole. Despite the fact that sandstorm is for the most part not receiving feature updates, it is still mostly usable, but having this not closed indefinitely is a bit distressing.

@kentonv, what needs to happen before we can set that header and turn this off? Is it merely a matter of testing apps, are are there other things that need to happen first?

xet7 commented 5 years ago

@zenhack

Wekan can have markdown that included some image from elsewhere, like stats image etc. There should be option to enable/disable loading images, otherwise a lot of Wekan boards will be broken.

In general, remote contect can be blocked with browser policy. Wekan currently uses browser policy to only allow iframing from one website, not to block any content. See: https://github.com/wekan/wekan/blob/devel/server/policy.js https://atmospherejs.com/meteor/session?q=browser-policy

xet7 commented 5 years ago

Here is related old issue how disabling framing did break functionality https://github.com/wekan/wekan/issues/1676

kpreid commented 5 years ago

Cases like the images you mention could be handled by having an opt-in mechanism (user grants the grain network access). But the default policy must be to block all, otherwise Sandstorm won't offer the guarantee it's supposed to:

A Sandstorm app, by default, is totally isolated from the network. It cannot connect to anyone; it can only receive proxied HTTP requests from the user. Thus, by default, an app cannot "phone home" to its developers' servers, and cannot build an advertising profile on you, unless you give it permission to do so. — https://docs.sandstorm.io/en/latest/using/security-practices/#true-confinement

xet7 commented 5 years ago

@kpreid

Yes, I agree.

zenhack commented 5 years ago

I don't know enough about the wekan codebase to know how difficult a change this would be to implement, but it seems like the optimal thing would be for wekan to request the resource via the powerbox, when it sees an image URL:

https://docs.sandstorm.io/en/latest/developing/powerbox/#using-sandstorm-http-bridge

Quoting Kevin Reid (2019-03-17 15:51:07)

Cases like the images you mention could be handled by having an opt-in mechanism (user grants the grain network access). But the default policy must be to block all, otherwise Sandstorm won't offer the guarantee it's supposed to:

 A Sandstorm app, by default, is totally isolated from the network.
 It cannot connect to anyone; it can only receive proxied HTTP
 requests from the user. Thus, by default, an app cannot "phone home"
 to its developers' servers, and cannot build an advertising profile
 on you, unless you give it permission to do so. �
 [1]https://docs.sandstorm.io/en/latest/using/security-practices/#tru
 e-confinement

-- You are receiving this because you were mentioned. Reply to this email directly, [2]view it on GitHub, or [3]mute the thread.

Verweise

  1. https://docs.sandstorm.io/en/latest/using/security-practices/#true-confinement
  2. https://github.com/sandstorm-io/sandstorm/issues/2906#issuecomment-473708408
  3. https://github.com/notifications/unsubscribe-auth/AA18PsoeOKglQ7Ef72SaSxM43fjHyq0yks5vXpyrgaJpZM4Mw31D
xet7 commented 5 years ago

@zenhack

Would this mean, that every Sandstorm user would get Internet access popup for every Sandtorm Wekan grain and other grains?

xet7 commented 5 years ago

@zenhack

Also, would this be setting that: a) Requires changes to all Sandstorm apps code b) Be Sandstorm grain setting that is grain allowed to access some other grains or Internet.

xet7 commented 5 years ago

Related to Content Policy is, that I would like to have Sandstorm inside iframe of some other platform like Friend, and have Friend login do login to Sandstorm too.

zenhack commented 5 years ago

I think you could do something where on first access you download the image and save it locally; then you'd only need to prompt the user when they first add the image. That said, this may be a fairly invasive change to the app.

Re: putting sandstorm itself in an iframe, it looks like there's an open issue (#3068).

Now I'm worried, since this is sounding really non-trivial. I fear if we don't do this soon sandstorm will basically never be able to live up to its promise of isolating apps from the internet.

Perhaps we could just allow the app to specifically request that the content-security-policy be reverted to the old behavior, at least as an intermediate step. Having to prompt the user "can we have internet access?" might put a bit of pressure on app developers to find another way, while not actually putting us in a position where apps are broken.

xet7 commented 5 years ago

@zenhack

Which of the following would work on Sandstorm?

All of those above would be Sandstorm settings, because not all Sandstorm app repos have been moved to https://github.com/Sandstormports yet.

zenhack commented 5 years ago

My intuition is that any of those should be realistic to implement, but I'm not familiar enough with the codebase to know exactly what needs to change where.

@kentonv, opinions, and insights re: what various proposals would entail would be appreciated, when you have some time.

Quoting Lauri Ojansivu (2019-03-20 10:22:13)

[1]@zenhack

Which of the following would work on Sandstorm?

  • Admin Panel option to allow/deny all users all grains internet access, with Content Policy header to whole Sandstorm
  • Admin Panel Users option for each user, does grains have Internet access, with per grain iframe Content Policy
  • Per app settings, does grain type have Internet access, for example can Wekan grains have Internet access
  • For each user, have above grain slider or checkmark and some Internet font awersome icon, that can be used to switch grain's Internet access on or off

    All of those above would be Sandstorm settings, because not all Sandstorm app repos have been moved to [2]https://github.com/Sandstormports yet.

    -- You are receiving this because you were mentioned. Reply to this email directly, [3]view it on GitHub, or [4]mute the thread.

Verweise

  1. https://github.com/zenhack
  2. https://github.com/Sandstormports
  3. https://github.com/sandstorm-io/sandstorm/issues/2906#issuecomment-474851825
  4. https://github.com/notifications/unsubscribe-auth/AA18Podp3I1Ur3pg7-x8lkV6nR5K7z9uks5vYkQVgaJpZM4Mw31D
kpreid commented 5 years ago

Key elements of Sandstorm's security model are that:

This implies that network controls should not be admin-managed in the normal case. Rather — to analyze things in perhaps a bit too much depth —

But implementing all of the above options would be hairy UX-wise. We might decide that to avoid overcomplicating users' choices, the client-side network access and the server-side network access are both controlled by the same powerbox UI and resulting capability grant. This would mean that admins only have the choice "do/don't grant [some] users network access for them to grant to apps", and visiting a grain that already has network access gives it the use of that client machine's network access. This is probably okay for most users since it's not worse than visiting arbitrary web pages.

xet7 commented 4 years ago

Related to #2602 , currently in Wekan it is possible to:

Currently it's not possible to:

To block, or not to block, that is the question. So what to do? a) Add just more and more options b) Is there some single way that would work for everyone?

xet7 commented 4 years ago

Also, some have moved from Sandstorm Wekan to Standalone Wekan, because full Wekan API is not yet available for Sandstorm. AFAIK currently it's only possible to export board with API.

Is there some overview or big picture somewhere, what should in general be possible at Sandstorm, and what should not be possible?

ocdtrekkie commented 4 years ago

@xet7 Actually, you could look at https://github.com/zenhack/hello-sandstorm-oauth as an example of how to access an external API, so it should be possible to import direct from Trello via the Powerbox. Though unlike Google and GitHub, Sandstorm would not handle the OAuth credentials for you.

Accessing the Wekan API in Sandstorm is presumably very, very possible, but it is likely an issue with someone working on the Sandstorm-specific integration code in Wekan to manage permissions for it and such.

xet7 commented 4 years ago

@ocdtrekkie

If you mean Trello OAuth, that is not required at all. Import from Trello is implemented in a way that Trello JSON is copied to Wekan input form, and in that JSON is links to Trello attachments at https://trello-attachments.s3.amazonaws.com/.... that can be downloaded without any authentication. Sure it's a long complex URL. In Wekan only public board attachments can be seen without authentication, not private board images. In Wekan that same bug was fixed in 2017 https://github.com/wekan/wekan/issues/1105 .

xet7 commented 4 years ago

There seems to be reply about it at Atlassian community https://community.atlassian.com/t5/Trello-questions/Attachments-in-Trello-are-public-or-private/qaq-p/990831

ocdtrekkie commented 4 years ago

Ah, okay, so yeah, that should be fairly trivial to do then with the Powerbox. Basically, when you did the import, your Wekan grain would open up a Powerbox asking the user to allow Wekan to access https://trello-attachments.s3.amazonaws.com/ and if they allowed it, the import would work.

xet7 commented 4 years ago

It seems here is a complete list about what to allow: https://help.trello.com/article/1072-configuring-your-firewall-for-trello

ocdtrekkie commented 4 years ago

I am not sure how clean the user flow would be to request access to all of those. But I am doubtful all of them would be needed for an import. But this doesn't have much to do with issue #2906.

zenhack commented 4 years ago

Yeah, I suspect you wouldn't need access to everything in order to do the import. But this is indeed getting a bit off topic; I suggest moving further conversation elsewhere (@xet7, maybe see how far you get, and poke the mailing list if you hit any stumbling blocks?)

Quoting Jacob Weisz (2020-01-20 14:21:24)

I am not sure how clean the user flow would be to request access to all of those. But I am doubtful all of them would be needed for an import. But this doesn't have much to do with issue [1]#2906.

xet7 commented 4 years ago

@zenhack

Yes.