

Can Firebase/Meteor ever be secure? - tg3
http://tgriff3.tumblr.com/post/21025342161/how-can-client-side-databases-be-secure

======
mayop100
(Founder of Firebase here) - The answer here is an emphatic, unequivocal yes.
What BaaS providers like us do is create generic apis to allow developers to
do the common operations that already can do with their own server code.
Everything that can be done with your own server code can be done with our
server code. So if it's possible for you to write your own secure server, then
it's possible for a BaaS to do the same.

The trick here is designing an API that is simple and easy to use that still
works for a large set of use cases, and this is a very difficult task.
Security is complicated, so making a generic, simple API tends to lead to APIs
that apply to a reduced set of problems. Any particular BaaS system will
likely not solve every security scenario available, but that doesn't mean ones
can't be built that solve the vast majority of the scenarios that matter.

Firebase is working hard on building this API, and we're doing it with a lot
of careful diligence and input from our users. We're nowhere near done with
it, but we're confident that when we are, we'll have a simple, powerful
security model that works well and is secure for most apps without needing any
server code, and for those apps with more complicated needs, we make it easy
to hook up your own servers too.|

Also, I'm very excited you got your app working in 5 minutes : )

~~~
Animus7
> The trick here is designing an API that is simple and easy to use that still
> works for a large set of use cases, and this is a very difficult task.
> Security is complicated, so making a generic, simple API tends to lead to
> APIs that apply to a reduced set of problems.

I completely agree, and I think you understand the issue.

I'm just not convinced that any meaningful definition of app-specific
"security" can be achieved concurrently with the kind of simplicity that
underpins your value prop.

If I have to go and cook up logic validation, ACLs, and who knows what just to
make sure my app isn't trivially broken by anyone with a JS console, aren't I
basically doing the server-side programming that your pitch says you're trying
to eliminate? Except in a less familiar fashion?

I'm not saying this is unfixable; I hope you have novel insights, and I want
to be wrong. But I've always been sceptical of the free lunch.

~~~
mayop100
We're working hard to make this possible! Hopefully you'll be impressed with
what we're cooking up when it's ready.

~~~
buu700
Out of curiosity, how complete is your security system right now? As in, if
the code were frozen and documented as-is, would it be generally acceptable to
use in production as far as you've tested (ignoring the occasional non-
critical hiccup here and there)?

I noticed that your FAQ offers beta testers the option of trying out what you
have. Does this mean that it's at least functional for simple/common use
cases?

------
eaurouge
Am I missing something here? Just because you can request data and
functionality from the client doesn't mean you'll get said data or
functionality. On Meteor the database API is the same on client and server,
but that's just an API. A Mongo command on the client doesn't go directly to
MongoDB on the server. You could have an access layer (or controller) on the
server thru which all client requests are passed. And this access layer
determines which client requests are relayed to the database.

It seems to me the question isn't whether Meteor/Firebase can be made secure,
but which implementation would be best for client responsiveness, developer
effort etc.

~~~
bonaldi
You're missing that the pitch with Fireball at least is there is no server
code as such.

To which everyone is pointing out "what about the business logic and
validation?". The answers so far seem to be "we'll come up with, er, something
in future" and "Microsoft Office is all client-side".

EDIT: To clarify I'm not talking about Meteor here.

~~~
geoffschmidt
That's not part of the pitch for Meteor. Take a look at point 6 on the Meteor
homepage:

Sensitive code runs in a privileged environment: Write all of your code in
JavaScript (if you want.) The user interface runs in your browser. The
sensitive functions run in a privileged server environment.

------
shykes
I think it's perfectly doable - but it will require custom validation to run
on the server. I like that Meteor embraces that reality, although their
implementation is not complete nor documented.

The Firebase/Parse/Stackmob approach of API-driven ACLs and "zero code in the
backend" adequately covers certain common use cases, but completely breaks
down when you need something more custom - and, inevitably, you will. Sooner
or later these guys will need to run your code on their servers (or their API
will expose a dsl for querying/transformation/acl complex enough to be called
"code").

I do like that mayop100 mentions they'll "make it easy to hook up your own
servers too", although I'm not sure what that means in practice?

~~~
jamroom
Check out Trestle:

<https://www.trestleapp.com/services/custom>

we're already running custom NodeJS code for our customers - along with the 14
other API services we have (including our Chain server) you can do a ton. It
all is tied in to our ACL's too, so your custom service works the same as any
other API service.

We're also super happy to run it on DotCloud too ;)

~~~
shykes
Nice! I'll check it out.

------
saurik
Look at how Parse does ACL and user authentication (which might be difficult
as their documentation isn't well-organized). General idea: you add the
concept of "accounts" to the database API, have the server support the
password reset emails (as you can't trust the client app code), and thn use
session tokens for validation. So yes: trivially obviously possible, but with
irritating data structuring issues (to make the ACL grnular in the places you
need).

------
Void_
The issue is bigger:

All of the business logic is on the client side.

You will, eventually, have to move some of the logic to the server side.

I'm sure that it is/will be possible with Meteor/Firebase, but it's not as
easy as writing a Rails app.

~~~
mayop100
Actually, no, you won't. Before SaaS apps, all applications were client side.
Microsoft Office, for instance, is a fully client-side application.

~~~
bonaldi
... And, setting aside that Office is compiled, Office stores its files
locally. When then those files move to shared space like servers, those
servers get their own authentication and controls.

Unless you're really saying the Firebase can only be used securely for client
apps that live entirely on the client and don't need a server at all? I hope
not.

I was very interested to see what the answer is here, but the answers from the
team didn't give me confidence that there is one, or that they were treating
the problem with enough gravity.

Then I see answers like this one, which give me the fear. Business logic that
clients can access and change isn't a security hole, it's a security
catastrophe. Until it can be protected, you can't build anything more than
toys with this.

~~~
mayop100
Security for the data in Firebase is one issue - and as I've mentioned above
we're taking that very seriously, and we're working on it.

The business implications of having client-side software are a different
issue, and I think its been demonstrated many times that businesses can do
very well even with most or all of their code running client-side. Any desktop
/ mobile software works like this, as I mentioned.

Relying on a compiler for security is a bad idea, just as you shouldn't rely
on people not messing with your javascript. Clients today can access and
change MS Office if they know what they are doing.

~~~
bonaldi
Yes, but virtually the only business logic in traditional Office is in the
licensing, which has been repeatedly cracked.

You're not really comparing like with like here, unless you're saying that
Firebase will solely be used for making non-networked "tool" apps.

If you're talking about networked apps, then, no, they _havent_ always been
client side. They started as tty/3270-esque apps and grew from there, with the
business logic staying on the server and the clients growing in capability and
power.

Boil it down: there are rules that say only managers can change vacation days,
or that govern where and when discounts are applied, or who can upvote a
comment, or what the power up bonus is, or whether even to check for any of
these things. If these things live in the client, how are they secured from
interference?

~~~
buu700
_If these things live in the client, how are they secured from interference?_

It doesn't sound like he's implied that this could be manipulated by the
client at all; in fact, he's explicitly implied the opposite. Why would ACL
definitions have to live in code (as opposed to, say, a simple Web interface)?

I'd think something as simple as a graphical UI to define database schemata
with read/create/modify permissions for owner/world on each field would be
enough to cover 82% of use cases effectively. Beyond that (e.g. complex group
management), I can't think of a secure client-side solution off the top of my
head, but I suppose that would be what the Node.js plugin could be used for.

Edit: Actually, for a lot of use cases group management could be handled by
the client as well. For example, if a group is defined by a table, then the
creator/owner is de facto the first member and administrator. If any
administrative actions require an admin auth key and adding new members or
admins is an administrative action, then there really isn't any way to hack
the system. (I assume a user's auth key could just be something like a client-
side hash of their username and password.)

~~~
bonaldi
Security needs less implications and more explicit answers.

Besides, there is more to business logic than simple (or complex) access
control. More than one Facebook game has discovered to their cost the problems
of trusting the score the client is sending to you. Or take discounts: if I
want to give 10% off for orders over £20, where does that rule _live_?

If it's on the client, well, what stops the client changing that to 90% off?

Perhaps you ACL the order table and only allow access to a non-client facing
instance. The client sends an order to that, which verifies it and sends it on
if approved?

Well, fine, but that's a server, and one of the main pitches here is "No
servers! No server code."

~~~
buu700
Sure, those are fine examples of use cases that fall outside the general
category of applications which don't require server-side data validation.

You're using "security" to mean something totally different now (protection of
your data from other users v. prevention of you modifying your own data in
unexpected ways). My point before was that most applications just don't have
that concern of limiting what users can do to their own data, at least for the
MVP, because in most applications that will only affect the user herself.

~~~
bonaldi
It all amounts to the same thing: no server means putting your trust in the
client. Which you should never do. You don't trust who the client says they
are (authentication), you don't trust what the client says they can do
(authorisation), you don't trust what they're giving you (validation),

It's not something you bolt on later. You have to bake this in from the start,
because even the simplest operations depend on it. Posting a comment? Great:
are you allowed to post? Who are you posting as? Is there HTML in your post?

~~~
buu700
_You don't trust who the client says they are_

I shouldn't trust a hashed username and password? How are server-based systems
more secure?

 _you don't trust what the client says they can do_

That's a non-issue if it's handled by ACLs on the server.

 _you don't trust what they're giving you_

Like I mentioned before, though, for most applications you _can_ trust what
they're giving you. Sure, Amazon isn't going to ask the client how much an
iPad costs and WoW isn't going to ask the client for the player's stats, but
why should an application like Facebook care to verify whether you want to
modify your own settings or send a friend request / wall post / whatever? If
you attempt to perform an unexpected action (say, post to the wall of someone
who's blocked you), the _other_ user's client application logic (which is
beyond your control) can still handle the junk data gracefully and simply.

Also, later on (when you have more developer time to spare), if you want to
for whatever reason, you can easily just deploy a server-side "garbage
collector" of sorts to regularly clean up the database without disrupting
client-side flow.

 _It's not something you bolt on later._

It can be, provided that it's only in the form of new features rather than
fixing something which was insecurely implemented to start with. (For example,
maybe the MVP is free but the next iteration is freemium and requires server-
side price validation.)

~~~
bonaldi
_I shouldn't trust a hashed username and password? How are server-based
systems more secure?_

How are you going to verify the password without a server? Passwords _are_ a
server-based system.

 _That's a non-issue if it's handled by ACLs on the server._

ACLs fine-grained enough to handle modern security scenarios are going to be
just as complex as doing traditional validation. Any non-trivial sites are
quickly going to get _way_ more complex than just doing it the old-fashioned
way. So why bother?

 _why should an application like Facebook care to verify whether you want to
modify your own settings or send a friend request?_

Because privacy is mission-critical for Facebook, and an exploit that allows
me to send a friend request to myself as you is an unmitigated disaster for
them. And trivial to do in a mostly-client world. Beyond trivial if I have
access to the other client, which I am one browser bug or open wifi access
point away from having.

 _It can be, provided that it's only in the form of new features_

And those new features are going to be written in what? Since your MVP's
framework doesn't support server-side logic, you're now splitting your code in
three. Now you're either in maintenance or rewrite hell, just as you're taking
off.

That's not one of the good problems to have, it's one of the stupid problems
you should have avoided by laying the right foundations at the start.

~~~
buu700
_How are you going to verify the password without a server?_

Only a dreadfully insecure system would choose to compare plain text passwords
over the standard practice of hashing. It makes no difference if the hash is
done client-side or server-side; if anything, even with SSL it's more secure
to keep the plain text password removed from the network.

 _ACLs fine-grained enough to handle modern security scenarios are going to be
just as complex as doing traditional validation._

How so? If I can manage my Facebook privacy settings graphically, any
developer can manage ACLs in a DB schema graphically. No reason to
unnecessarily clutter up code and deal with pointless architectural issues.

 _Because privacy is mission-critical for Facebook, and an exploit that allows
me to send a friend request to myself as you is an unmitigated disaster for
them. And trivial to do in a mostly-client world. Beyond trivial if I have
access to the other client, which I am one browser bug or open wifi access
point away from having._

Uh, what? If you have access to someone else's account then the game is
already lost; no backend can solve that.

 _Since your MVP's framework doesn't support server-side logic, you're now
splitting your code in three. Now you're either in maintenance or rewrite
hell, just as you're taking off._

...What? Who says whatever framework I use won't support server-side logic?
Even vanilla JavaScript or jQuery is fine for AJAX calls. Not sure where
you're getting "rewrite hell" from, but you must _really_ hate the client APIs
provided by Google, Yahoo, Facebook, and Microsoft.

~~~
bonaldi
_over the standard practice of hashing_

A hash (like a plain password) is just a meaningless string unless you have
_something to compare it to_. That means you have to store a trusted version
elsewhere. Eg: a server.

 _any developer can manage ACLs in a DB schema graphically_

And the client?. When I as user make you admin of my facebook event, how do I
do it? Can my client side code change the access for other users? That might
be, y'know, bad. Exploitable.

 _Uh, what? If you have access to someone else's account then the game is
already lost; no backend can solve that._

Not access to someone else's account, just access to the other _client_ via
the network, browser bugs, bad proxies etc. It's a whole flock of blacksheep.
There is a world of XSS that is only stopped by having wary, untrusting
servers.

 _Who says whatever framework I use won't support server-side logic_

Hi. This is a thread about _Fireball_ , which is a new BaaS, one that promises
no server-side logic. You appear to be defending this idea. Now I wonder if
you understand it. We are _not_ just talking about "some code running in the
client".

If you want to say client side code is fine so long as you have server-side
logic for sanity checking, well, yes. Yes, it is. That's my point.

~~~
buu700
Okay, I think I was unclear in my proposal. None of what you've said is
related in any meaningful way to my idea, but I think that was my fault for
just pointing out the "important" parts and assuming the rest would fall into
place naturally for everyone else.

\---

This is the system I'm suggesting Firebase implement:

* User registers client-side with a username and password; username and password are salted/hashed to an auth key, which is then sent to the server and put into a server-side key-value store with the username.

* User logs in to the client; auth key is reconstructed and stored to a cookie to be sent with each Firebase access.

* Whenever a field in Firebase is created, an associated "owner" property is set to the username of the user who created the field, and an associated "group" property is set based on an optional API parameter with a default value of null.

* Each field has pseudo-chmod-style permissions settings of the form read/modify/create for owner/group/world; everything is "777" by default, but a simple administrative Web UI allows the developer to define database schemata and assign permissions settings.

* Groups are implemented as server-side lists of usernames.

* When a client attempts to perform an operation through Firebase's API, first the "world" permissions are checked; if the operation is allowed, it completes normally.

If the operation in question is a "create" operation, only the "world"
permissions can be reasonably utilised, so if the operation is not allowed and
the operation is a "create" operation, then no change is made to the data and
an error code is returned (or printed to logs or something).

If the operation is not allowed and not a "create" operation, then the owner's
auth key is retrieved from the earlier key-value store and compared with the
auth key from the client; if the keys match, the "owner" permissions are
checked to determine whether the operation is allowed; if the operation is
allowed, it completes normally.

If the keys don't match or the operation isn't allowed, a search is performed
to determine whether the username associated with the client auth key is in
the appropriate group; if so, the "group" permissions are checked to determine
whether the operation is allowed; if the operation is allowed, it completes
normally.

If the group is null, the user isn't in the group, or the operation isn't
allowed, no change is made to the data and an error code is returned.

\---

 _A hash (like a plain password) is just a meaningless string unless you have
something to compare it to_

This should be clear now.

 _Can my client side code change the access for other users?_

No. As mentioned above, permissions are set by the developer.

 _Not access to someone else's account, just access to the other client via
the network, browser bugs, bad proxies etc._

I haven't seen any XSS vulnerabilities inherent to the Firebase JS library.
Everything else can be reasonably addressed with SSL and a secure browser.

 _This is a thread about Fireball, which is a new BaaS, one that promises no
server-side logic._

Don't be a condescending prick, especially when you're the one who's wrong. We
were specifically on the topic of adding price validation to a freemium
Firebase application; you still have yet to explain what's stopping me from
leaving the bulk of my code as-is and using AJAX off my server only for the
price validation.

~~~
bonaldi
_Don't be a condescending prick, especially when you're the one who's wrong._

Stop, just stop. This isn't right/wrong, because we don't even seem to be
having the same conversation. _Everything_ you talk about assumes and depends
on having a server and server-side logic. Your arguments all amount to "I can
totally do client-side-only, I just have to do X on my server". Like:

 _Which is then sent to the _server_ and put into a server-side key-value
store with the username._

Right, so your solution for Firebase is that they should have more server-side
stuff? Good, we agree. Wait:

 _We were specifically on the topic of adding price validation to a freemium
Firebase application; you still have yet to explain what's stopping me from
leaving the bulk of my code as-is and using AJAX off my _server_ only for the
price validation._

What's stopping you is that in this scenario you don't _have_ a server! So if
you want to add this, you have to now add a server. Now you've got your MVP
running on Firebase, _and_ a new server-side setup, just to add a feature?
Seems like a disaster.

(To be fair, Firebase are talking like they'll make some private quasi-
sessions that could act as servers, but setting up conversation between them
and the clients sounds like a recipe for callback spaghetti, at the _very_
least.)

The point the OP, some other posters here and I am trying to make is that
client-side sounds great -- it's way simpler, for sure -- until you start to
think about security. Because, frankly, security depends on things not being
in the client's control, and that means servers.

If you disagree with that, please email me, because this conversation is now
adding no value to HN.

~~~
buu700
Er...... I don't think you understand what Firebase is... Obviously they're
still running servers; the entire service is basically hosted MongoDB with a
clever Scala API and a JS library that further abstracts Socket.IO.

~~~
buu700
Jeez, HN needs a better system for nested replies. Anyway.

 _You seem to think it can be patched up by turning it into something else.
Great, we agree that it doesn't work as is, then._

Well, yeah, of course. The whole discussion started off as a debate about
whether and how _they_ could go about implementing security after the beta
launch.

It's pretty well understood by all parties (and admitted by the founders
themselves) that security isn't something Firebase is currently equipped to
handle...

\---

 _Sorry, I have no idea what you are shadow-boxing at, any more._

I've gone above and beyond in terms of explicit clarity to un-derail this
conversation. Which part of my solution are you confused about? (I don't think
I was too technical, but I can explain in more detail if necessary.)

 _I suspect that whatever the final solution is, it is going to be just as
complicated as what we have now._

Do you mean that my system would be too complicated for developers? (The
operation seems pretty straightforward to me.) Or are you just implying that
you think they'll go in a different direction which involves a lot more
developer labour?

 _You have been saying it should be mostly possible. I am sceptical._

In that case, do you see a specific hole in my design, or are you just unclear
in general about how it would be used?

~~~
bonaldi
Yes. The discussion was over whether proper security is something it could
_ever_ be equipped to handle in an all or mostly-client world. The founders
have been saying it is (and pointing to Office as an example). You have been
saying it should be mostly possible. I am sceptical.

------
qznc
Restricting database access is one aspect of security with Firebase.

Much more interesting is the cross-site scripting problem. For example,
firebase.com pulls in Javascript from Twitter and Google. Is Firebase safe
from the other code on the same page?

------
voidfiles
You could use third party auth, like facebooks. you could use an iFrame on
another domain to setup all the secure stuff, and then use something like
easyXDM to communicate with that iFrame.

------
willvarfar
The moment some twit goes and writes a script to systematically wipe these
servers, and there'll be a whole new flood of articles on HN/reddit ;)

------
minimaxir
What about nonces? Have the Meteor server create a unique nonce per user per
instance of DB action, then verify it serverside.

