<XgF>
Federated apps tend to have their own "complicated" authorization models
<kentonv>
XgF: How do people add other people to follow? Presumably they need to specify a URL?
<XgF>
kentonv: You can specify specify a username@domain address or an URL. In the former case, it does a .well-known lookup
<XgF>
Even in the URL case, you're not going to teach every feed reader in the world to authorize to poll a feed or send a pubsubhubub subscription
<XgF>
And theres also the issue of interop with Friendica, old StatusNet versions, rstatus, etc
<kentonv>
we can potentially support shoving the authorization token into the URL, as long as there is an adequate way for us to block the URL from being rendered in a real browser context.
<kentonv>
and then you get private feeds, which are potentially useful
<kentonv>
without updating any clients
<XgF>
As was noted above, given the number of apps written in HTML these days, "App" vs "Web browser" is an impossibel distinction to make
<dwrensha>
can we "just" make a conservative approximation based on the User-Agent header?
<XgF>
dwrensha: Great, you broke my feed reader :-)
<dwrensha>
how so?
<dwrensha>
it uses XMLHttpRequest to hit APIs?
<XgF>
If my feed reader is a Chrome extension, guess what user agent it uses?
<XgF>
And I believe extensions don't normally set the XMLHttpRequest header
<kentonv>
no no
<kentonv>
what we care about here is that the resource isn't being fed directly into a _browser context_, i.e. one that will render it as HTML and run scripts
<kentonv>
XMLHttpRequest is fine
<kentonv>
though I suppose it might not be possible to distinguish XHRs from otherwise, if the client doesn't know it needs to set a header to do that
<dwrensha>
XgF: do you mean the X-Requested-With header?
<XgF>
Yeah, but IIRC that's just a thing which jQuery adds isn't it?
<dwrensha>
we currently totally ignore it, but maybe using it somehow would help us here?
<dwrensha>
possibly User-Agent + X-Request-With give use sufficient information to filter incoming API requests?
<dwrensha>
*X-Requested-With
<paulproteus>
I semi-like the idea of requiring it. Django (and other frameworks) often dispatch on that header; see also @ajax_required in Django-land.
<XgF>
That doesn't work if the requester doesn't set it
<paulproteus>
It doesn't necessarily help with the problem of existing, deployed code aka existing protocols.
<dwrensha>
Maybe we need a new kind of session. InsecurePublicApiSession or something.
<dwrensha>
Apps would need to explicitly opt in to allowing it
<XgF>
I think in general "Public API" is an important export
<kentonv>
dwrensha: it's not the app we're trying to protect
<paulproteus>
i,i Content-Disposition: attachment
<kentonv>
yeah, I just worry whether content-disposition: attachment as CSP are really good enough for all cases, but maybe they are.
<XgF>
I think in this case the easier solution might actually be getting the browsers to support some form of "Never execute" header
<kentonv>
XgF: CSP does that, but not all browsers implement it. (Almost all do at this point, though.)
<paulproteus>
It's kind of awesome that you're right, XgF.
<paulproteus>
It's crazy awesome that we can actually expect new versions of browsers to actually reach people.
<kentonv>
not enterprise people, unfortunately
* XgF
stares at IE8 icon on work laptop
<XgF>
Not that anyone actually uses IE8 for anything other than dealing with Microsoft crap
<paulproteus>
We could blacklist some user-agents though.
<paulproteus>
Your IE8-based feed reader is just not gonna cut it.
<dwrensha>
kentonv: my understanding is that we're trying to prevent the browser's ambient authority from being abused.
<XgF>
paulproteus: I wonder if that would blacklist any feed reader which used the WinInet API though
<dwrensha>
and the kinds of things we're talking about here don't care if they are publicly accessible to the world
<kentonv>
dwrensha: we're trying to prevent a number of things. One is apps being able to talk to communicate/interfere with each other via script hosted in the shared API origin.
<dwrensha>
sorry, can you make that more concrete for me?
<kentonv>
dwrensha: a grain could host, via its API, an HTML page that uses javascript to set a cookie that is visible to all other apps serving from the API host. (In fact, that cookie can be scoped to the whole domain, unless the API host is actually a separate domain from the main server, which it usually isn't currently.)
<dwrensha>
that sounds silly but I don't yet understand why it's scary
<kentonv>
well, most obviously, apps could use it to leak data to each other without having received proper permissions
<kentonv>
but there is other lesser-known web tech that is scarier
<XgF>
The whole HTML security model is just freaking impossible unless you own infinity domains
<kentonv>
so here's one
<kentonv>
service workers
<kentonv>
install a service worker, now you can intercept all HTTP calls to the origin
<kentonv>
use that to _discover_ other apps' API tokens
<kentonv>
then attack them
<kentonv>
we built / are building a whole sandbox (based on per-session hostnames, among other things) to defend against these attacks for UIs, but we would have to weaken that sandbox considerably to support APIs, which want long-lived URLs
<XgF>
Hmm, I believe service workers only apply to a single subdomain?
<XgF>
(Otherwise why has nobody pwned the entirety of github.io yet?)
<kentonv>
XgF: yes, of course. But a Sandstorm server serves all its APIs off one hostname.
<XgF>
Perhaps for persistent APIs it would be worthwhile to reconsider that?
<kentonv>
dwrensha: token should not be in hostname; DNS is cleartext
<kentonv>
I suppose it could be hash-of-token, though
<XgF>
I'm not sure it matters ofr a public API :P
<XgF>
But I guess for stuff like your feed reader...
<kentonv>
XgF: I have yet to see a kind of API that wouldn't benefit from being able to use privately. I think people are just too lazy to secure them, so they say "eh, it's public".
<kentonv>
so I'd rather not distinguish. If you want to publish your token publicly, fine, but Sandstorm will treat public and private the same.
<kentonv>
I feel like I had a really good reason for not wanting one-off hostnames for APIs, but I am not recalling at the moment.
<paulproteus>
kentonv: "quick question": Sandstorm "only" needs to use user namespaces when creating a grain, right?
<paulproteus>
So in theory, we could permit Sandstorm to install on old kernels and Debian without unprivileged_userns_clone, and "just" have an info box in the shell being like "FYI THIS SANDSTORM CANNOT WORK YET, CLICK HERE"?
<paulproteus>
Now I will grep to evaluate my theory.
<paulproteus>
supervisor.c++ calls unshare() with CLONE_NEWUSER, so that's grain starting.
<paulproteus>
Alas, no, we seemingly run the shell with CLONE_NEWUSER, too.
<paulproteus>
Which is understandable.
<paulproteus>
(Looking at src/sandstorm/run-bundle.c++)
<kentonv>
paulproteus: we only run the shell that way if you chose not to start Sandstorm as root
<paulproteus>
Interesting, okay.I see that now in dropPrivs()
<paulproteus>
Er wait mumble it must be elsewhere but OK.
<paulproteus>
OK, so that does mean for the normal path ("install as root"), we could arguably skip the C compiling.
<paulproteus>
(And then indicate to the user in the Sandstorm shell that "You really have to fix this kernel thing.")
<kentonv>
I suppose.
<kentonv>
User might not like having installed the whole thing only to find it won't work on their system.
<kentonv>
not everyone is in a position to update kernels
<kentonv>
I mean, the check was placed there primarily for arch users
<kentonv>
where they really have no way to fix the problem except install a different distro or hand-compile a kernel
<kentonv>
which honestly I don't expect people would do
<paulproteus>
Yeah.
<kentonv>
hmm maybe we could use unshare(1) instead of compiling?
<kentonv>
i.e. unshare(1) rater than unshare(2)
<paulproteus>
Right, I see what you mean. re: unshare(1)
<paulproteus>
It's part of util-linux, so that's a plus.
<kentonv>
although that might trip people up if they have an old userspace but a new kernel
paroneayea has quit [Read error: Connection reset by peer]
<paulproteus>
Oh my.
<kentonv>
OTOH, compiling the binary might also be hard if userspace is old
<paulproteus>
The thing I'm after, fwiw, is having a confident way to proceed with the install even if the user doesn't have a C compiler.
<paulproteus>
Which I think it's pretty common not to have a C compiler.
<XgF>
I wasn't expecting to need a C compiler to install your binaries
<XgF>
Is there any reason the check binary can't be in the package?
<paulproteus>
On Debian, util-linux is Essential, so that's a plus.
<paulproteus>
XgF: Mostly it looks ridiculous, I think.
<kentonv>
well we could download a checker binary I suppose
<paulproteus>
I like the idea of using unshare(1); let me look into that.
<kentonv>
XgF: it should gracefully skip the test if there's no compiler.
<kentonv>
paulproteus: doesn't work on wheezy, even with backports
<paulproteus>
Aw.
<kentonv>
unshare: invalid option -- 'U'
paroneayea has joined #sandstorm
<paulproteus>
OK, but at least we can do that as an option first, before trying the compiler.
<XgF>
kentonv: To be fair, Wheezy's nginx is too old too :P
<paulproteus>
kentonv: What I'm clearly really after here is making install.sh be larger than 1 page of RAM.
<paulproteus>
: P
<kentonv>
maybe we should just download a binary. I just worry that security dunning-krugers who think they're going to go review the script to see if it does anything evil will find that line before they get bored and then complain.
<XgF>
It's downloading an archive of sodding binaries >_<
<kentonv>
XgF: I know, right?
<kentonv>
and yet...
<paulproteus>
I think it's not a huge deal to call unshare(1), and that'll work well enough for new installs on e.g. Ubuntu 14.04 (testing that theory now) that we won't commonly call the compiler.
<zarvox>
We could. Or we could embed the hex for the test program, which is like 3.3KB
<kentonv>
XgF: like, people complain about the curl|sh part because it's so insecure to let some web site run commands on your shell, but then _it's downloading a binary package_
<zarvox>
Or base64 or what have you.
<kentonv>
paulproteus: How will you distinguish between "unshare failed because it's too old" and "unshare failed because the kernel doesn't support it"?
<paulproteus>
if $(unshare -U id -u) doesn't print 65534 then I will continue to test w/ the C compiler.
<kentonv>
paulproteus: and if there's no C compiler?
<paulproteus>
The current "print a warning" behavior, is my plan.
<paulproteus>
i,i we could log analytics about which branch it is taking
<paulproteus>
Oh, I guess for Arch...
<paulproteus>
On current Arch probably there's a way to ask unshare(1) if -U works.
<paulproteus>
That is, it probably accepts -U and then breaks in half in some detectable way.
<paulproteus>
My main goals are:
<paulproteus>
1. For Ubuntu 14.04 users on Digital Ocean, let them have a happy time without needing a C compiler and without printing a warning.
<paulproteus>
2. For Arch users, at least reasonably-current ones, tell them they deserve to be sad.
<paulproteus>
The fact that people running less-up-to-date things might need a compiler doesn't bother me much, since the older distro you're running, the more likely you know what you're doing.
<XgF>
Whats the sadness-inducing Arch thing?
<XgF>
More sadness inducing than Arch usually is, that is :)
<paulproteus>
CONFIG_USERNS=n in Arch kernel
<XgF>
Heh
<paulproteus>
3. For users in Docker, tell them what to do, since we can't do it for them [presumably].
<paulproteus>
I think those are my goals.
<XgF>
My recent arch sadness discovery is that if you, for whatever reason, install egd, it's configured to extract entropy from /dev/urandom and stuff it into /dev/random...
<zarvox>
is the Arch failure detectable by any means other than calling unshare(CLONE_NEWUSER) and watching it fail?
<kentonv>
paulproteus: if failure of the unshare(1) check only leads to trying unshare(2), and lack of a compiler means we only print a warning in that case, then the only thing the unshare(1) check accomplishes is not printing a warning in some cases when we otherwise would have.
<XgF>
...you could read /proc/config.gz I guess?
<paulproteus>
re: kentonv's "security dunning-krugers" people, I offer you this lyric clip: https://www.youtube.com/watch?v=FDocJto-aVw "Black and white, it's become so black and white / So insecure, you're so insecure / That's what you are / That's what you are / That's what you are / That's what you are."
<paulproteus>
We could grep /proc/config.gz if it's there.
<XgF>
kentonv: Right. But feeding it its' own output is the worst possible thing you can do to it
<paulproteus>
AFK dinner.
<paulproteus>
If Arch has /proc/config.gz I'll be excited. Good question, zarvox.
<kentonv>
XgF: Only in the sense that it's effectively like directly incrementing the entropy bit count, and that bit count is a farce anyway. :)
<XgF>
kentonv: To a degree, but lots of things generate long term keys on boot which need actual entropy, and running EGD like that means you basically pull non-random garbage from an uninitialized RNG
<kentonv>
XgF: Ah, it does this on boot before baseline entropy has ever been gathered? I agree that's bad.
<XgF>
Of course EGD is itself sad, but shipping it default configured in a wrecks your system security state is something only Arch would do and EWONTFIX :P
kentonv has quit [Ping timeout: 256 seconds]
kentonv has joined #sandstorm
bb010g has joined #sandstorm
paroneayea has quit [Read error: Connection reset by peer]
paroneayea has joined #sandstorm
jadewang has quit [Remote host closed the connection]
jadewang has joined #sandstorm
fonfon has joined #sandstorm
jadewang has quit [Ping timeout: 264 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 240 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 244 seconds]
erikoeurch has joined #sandstorm
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 256 seconds]
erikoeurch has quit [Ping timeout: 272 seconds]
fonfon has quit [Ping timeout: 272 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 256 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 245 seconds]
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 245 seconds]
<dwrensha>
ugh, I feel like I always have to think too hard about how this works:
<dwrensha>
"Your app ID is actually its public key."
<dwrensha>
then in my pkgdef the appID is alphanumeric
<dwrensha>
an in my .sandstorm-keyring all of the public IDs look binary
<dwrensha>
looks like I should just just "spk getkey <appid>" and not worry about it, but still...
jadewang has joined #sandstorm
jadewang has quit [Ping timeout: 246 seconds]
paroneayea has quit [Read error: Connection reset by peer]