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 : )
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.
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?
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.
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.)
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.
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?
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.
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.
This thread isn't a good place for it, but we'll get something out soon.
Does this mean the entire dataset is sent to the client?
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.
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.
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.
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?
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.
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 ;)
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.
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"
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.
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.
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?
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.)
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."
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'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?
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.)
How are you going to verify the password without a server? Passwords are a server-based system.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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?
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.
As soon as more than one user is involved, there must be some logic on the server side.