Hacker News new | comments | show | ask | jobs | submit login
Can Firebase/Meteor ever be secure? (tgriff3.tumblr.com)
82 points by tg3 1696 days ago | hide | past | web | 58 comments | favorite



(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 : )


> 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.


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


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?


Agreed. If you can provide an generic implementation able to work across many applications, you save everyone from having to reinvent the wheel - at the cost of delegating a portion of your app to the service host.

The model I used in pageforest.com is to enable users to secure their documents as public, private, or shared access with other named users. Some apps don't fit in these neat categories, so a more complex system would be needed to support them.


What does BaaS stand for?


Backend as a Service, I'd guess.


I completely agree. It is entirely possible to secure with the appropriate API's.

Operations can be rejected by the server. If done correctly the client side can have an optimistic UI that is also secure. (Optimistic UI's don't need to wait for an ack from the server. They display local changes immediately and roll back if server denies.)


But that just adds to the complexity that the "BaaS" is aiming to remove?


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.


I guess the long form of the question I'm asking is, "Can Meteor/Firebase be secure without adding back in a lot of the server-side effort that they were built to avoid."

Avoiding the server-side seems to be a central part of Firebase's pitch, but as you say, you have to have a separate access layer through which your clients pass their requests. Who designs what the access layer looks like? Doesn't that require that you set up your users' accounts in a Firebase specific way so that they can have appropriate permissions in the access layer (which is server-side, by definition)?

And that's only considering actual authorization to change data on the server. One of the comments below mentions business logic that shouldn't be tampered with, like discounts. How can any business logic at all be entrusted to the client to perform?


I don't think it's right to lump Meteor and Firebase together as you've done here. They are similar and the sets of problems they aim to solve may overlap. But Firebase is a "scalable backend for your web app" and Meteor "is a set of technologies for building web apps". Firebase is more like a platform and Meteor is more like a framework, or SDK if you like.

If you want to get a web app up and running quickly without having to build a backend, Firebase would be an option.

With Meteor, one advantage is that you can write your client code as if you were building a desktop app, i.e. with minimal context switching. You can imagine the database is local and that any methods you call on the server are like calls to a local library with a well-defined API. Meteor would provide the glue between client and server that allows you to do this.

Regarding your question: "Can Meteor/Firebase be secure without adding back in a lot of the server-side effort that they were built to avoid?" I think the Firebase founder commented somewhere on this post on how they might do this. But for Meteor, (1) I don't think the goal is merely to reduce server-side effort (2), I expect Meteor would provide much of this out of the box and you wouldn't have to do more on the server than you would with say Express or Rails.


You're right, I probably shouldn't have lumped them together. My question is probably more applicable to Firebase since they explicitly state that a goal is to eliminate servers (or at least make them optional).


Yup, seems like the hype took peoples common sense with it out the window. I'd assume and hope that just because there's a mongo api on the client, surely doesn't mean it's the raw socket that's exposed?


The way it works in Meteor is, there is a data cache on the client with a Mongo-compatible API. When you type commands in the browser console, you're not hitting the real Mongo database at all, you're hitting that client-side cache. That's why it can be synchronous.

When you do a write, it also does a RPC to the server to ask the server to do the same write. The server can accept the request, reject it, or do something totally different. Whatever ends up happening, the client cache is patched to reflect the results.


Geoff, a bit off topic here but do you have any comment on the GPL licensing/linking conversation people have been getting their nickers in a twist about every time meteor comes up on HN?


We've been working very hard on this, and are scrambling to digest all of the (stunningly helpful and specific) feedback and to educate ourselves.

This thread isn't a good place for it, but we'll get something out soon.


Any idea if you can call a dropDatabase() from the client? That's my big fear.


Definitely not. It's not even in the wire protocol.


Geoff,

Does this mean the entire dataset is sent to the client?


You have a choice.

If the "autopublish" package is added to your project, which it is by default, then the entire dataset is sent to the client. That's good for learning and prototyping, but isn't any good for production use. The Leaderboard example uses autopublish.

Once you app works and you're ready to lock it down and scale it up -- and only then -- you remove the autopublish package. Now, it's up to you to define what's sent to the client. Use Meteor.publish() on the server to set up different datasets that clients are allowed to subscribe to, and use Meteor.subscribe() on the client to turn on/off a particular dataset. The Todos example demonstrates this -- it retrieves just the items for the todo list you're looking at, plus the list of lists. It's just a couple of lines of code, like 5 or 10, and not tricky ones either.


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.


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.


You're missing that the pitch with these things is there is no server code as such.

For Firebase, yes that is part of the pitch. Personally the use case for Firebase doesn't really appeal to me. For Meteor, it's the opposite. The fact that you can write some server-only code is a plus.


That's simply untrue, at least as far as Meteor goes. One of their big selling points is, in fact, that there IS server code.


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?


The basic idea for hooking up a server, is that the server will act like any other client, except it will authenticate with an API key and have full read / write access.

This server can perform data validation for you. All you need to do is have a "unvalidated" bucket where clients put their data, and then have your server have callbacks that validate that data and copy it over into the "validated" bucket (where clients do not have write access) when everything checks out.

This would need to be in concert with ACL's to prevent clients from writing in each other's buckets.

Note that you still get the major advantages of Firebase -- simpler code, easy scaling, data accessibility, and real-time, even though you're running a server.


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 ;)


Nice! I'll check it out.


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).


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.


Meteor apps have both a client side and a server side. That's why you use 'meteor bundle' to bundle up your app, instead of just ftp'ing the source to the server.

For the business logic that needs to be secure, you put it on the server using Meteor.methods() and Meteor.call(). You still get all the Meteor features like automatic distributed page updates and latency compensation.

EDIT: sorry, didn't catch the "is/will be"


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


... 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.


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.


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?


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.)


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."


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.


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?


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.)


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.


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.


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.


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.


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.


Until those questions are answered, explicitly explicitly, doubts hang over the whole idea.

.....

Did you read what you were responding to? I explicitly prefaced the idea with "This is the system I'm suggesting Firebase implement" (emphasis added).


Sorry, I have no idea what you are shadow-boxing at, any more. There are questions over security with Firebase. They say it will be fine when they're done. You say it will be fine in 80% of cases if they implement your idea.

I suspect that whatever the final solution is, it is going to be just as complicated as what we have now. Security isn't easy. Disabling it sure makes for great demos, though.


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.


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?


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.


Read their front page. "No servers, no server side code". Of course there are actually servers involved, but they're inaccessible by the developer.

That's the whole point of this post: how much access will devs have to the servers, and how? Until those questions are answered, explicitly explicitly, doubts hang over the whole idea.

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.


So you're saying that all server-side data that all apps using Firebase want to store should be stored centrally on Firebase owned servers. i.e since trusted user/pw hashes must be stored on a server to be matched against and the only server we have is the one that Firebase provides, all apps using Firebase will store these hashes on central servers owned by Firebase.. That sounds like a really bad idea.


It's the age of Google Docs, not Microsoft Office.

As soon as more than one user is involved, there must be some logic on the server side.


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?


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.


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 ;)


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




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: