Firebase security for things like indexes - firebase

I'm looking at using firebase for a small project, but one stumbling block I can't find an answer to is that of security as it relates to things like indexes for a purely client side application.
For example, if I need an index for articles -- that is, not using priority -- for alternate sorting, how would I secure this?
The client would need access to the list that contains the article ids sorted appropriately, which as far as I can tell also means the client can then be malicious and completely reorder or delete that index, not just the article it posted.
For that matter, the same goes for setting priority, or really any kind of auxiliary data that is automatic and not user entered - a change date for example.
Am I missing something? Or are you forced to have a server component to accomplish that level of data security/integrity?
Edit: The simplest case of this I can think of, is something like a date created field on an article - What prevents the client from just setting that maliciously?

Related

Risks to database and front-end coupling

I could not come up with any better title, after reading the question you can suggest a better one. Also you can suggest some better tags, I could not find web-development.
I am a student so I don't know the standard way to achieve the following issue.
I usually set the IDs of elements (div,span,tr,etc) according to the database primary key to reference it later easily.
For example on page having some rows of entries having their id set to the sno in the DB which is primary key and on click on any row checking the id and display the result from database using that id.
But I think its a bad idea as anyone can use Inspect Element or Dev Tools and change the ID.
What is the standard way to achieve this?
EDIT 1
I know that web browser wont enforce the security policy for me that's why I am asking for the standard way, or standard practices to use for this matter.
Anyway, you must assume that any request that comes to the back end may be forged, any any data sent to browser (visible or hidden) is public.
If you considere the the id are private (rather uncommon requirement), you could instead simply use a row order and keep on server session a table row_order <-> id.
If you simply want to ensure that the id are correct, just control them (server side) before updating the database, or at the time of the database write if you cannot control them before.
If you want to enforce any other policy (users have roles and depending on roles are allowed or not to update some values) all those controls have to be done server side.

Firebase - order items according to server time

I want to maintains user comments as an ordered list, based on the server write-time. A couple of questions regarding that:
Can I create (set / push) a locations based on ServerValue.TIMESTAMP?
Can I validate (1) with rules?
Can I safely assume that no two posts will be written at the exact "same moment", overriding eachother?
If I decide to use setWithPriority, and not order by the location-name, can I use ServerValue.TIMESTAMP for the priority (and validate it by rules....)
"Bonus" question - Is there still no way to create a COUNT query in firebase?
=== EDIT ===
I'm trying to achieve a chat-like feature. Messages must be ordered chronologically (by a server-side timestamp) in order to maintain a logical order for "discussion" (if I'll use a client-generated order than one local's machine clock offset could ruin the entire discussion). I can use rules to validate that a ServerValue.TIMESTAMP field is persisted to any new message, however, I can't seem to find a way to make sure that clients actually use setWithPriority() in order to persist data. I can't figure out any way to do this - am i missing something?
you can either .push() which generates auto ID as key or you can .setWithPriority() where your key can be anything and the priority can be pretty much anything as well. As far as I'm aware there is no option to have serverValue.TIMESTAMP as a key. The only way is to retrieve it and explicitly set it as the key with .child(retrievedTime).set(someData)
see 1)
Not sure what you mean exactly since there is no option to set servervalue as a key, but IMHO this is one of the reasons why is it so.
You can use some field on database and set ServerValue.TIMESTAMP and listen for the change - in the callback you will get the most current server time pretty much ASAP as the placeholder is replaced with TIMESTAMP. However there is no guarantee that it is going to be unique. It is perfectly legitimate to have to records with the same priority.
It is promised, but not yet available. You you can do it manually with transactions on every write/delete see docs

Is there a way to update Priorities without PUT erasing all your data?

Two questions: first, is it true that the only way to update '.priority' via REST is by using PUT, which forces you to rewrite all the other values? And I'm afraid to ask, but does that also apply to the Javascript SDK?
Second, is there maybe some other way other than using Priorities to order your collection 'server-side'?
Sorting things on the client doesn't work for me because I'm using a masonry-type plugin for layout which goes bonkers whenever the order changes client-side, but it seems to work fine server side. I'm using PHP to degrade the '.priority' value over time, lowering the item's position in the collection, but I'm forced to rewrite every other field at cron run. It works, but it would be better to just be able to update '.priority' or some other value that controls the position.
Question 1: .priority via REST API
You can set the priority without modify the record by calling PUT on the .priority directly. These examples are found in the REST API doc:
So, to reiterate, add .priority into the URL.
Question 2: Hacking masonry sorting in Angular using the data store?
If you haven't explored your options here, there are several libs dedicated to integrating masonry and angular which you may want to check out (e.g. angular-masonry). You may also have luck address sorting data in masonry directly, in its own SO question, rather than trying to solve it with your data store, which seems like an XY Problem.
The records in Firebase are sorted lexicographically, so you have three options:
name your items so they sort in the desired order
use push ids, which are ordered chronologically
use priorities to enforce a sort order other than the record id's natural sorting
Keep in mind that numeric keys, when mixed with lexicographic strings, cause behave strangely--err, by design--in Chrome. And, tangentially related, such a debate has waged that the ECMAScript standard will actually be changed to force them to correct it

Is there (or has there been considered) anything like 'merge' or 'batch' setting in Firebase?

In doing a bit more programming with Firebase today, I found myself wishing for a couple of features:
1) Merge set:
Say I have a firebase ref that has the value {a:1,b:2,c:3}.
If I do something like ref.set({a:-1,b:-2}) the new value will (unsurprisingly) be {a:-1,b:-2}.
Instead, imagine ref.mergeSet({a:-1,b:-2}) which would have a result in the value of the ref being {a:-1,b:-2,c:3}.
Now, I realize that I could do something like ref.child("a").set(-1) and ref.child("b").set(-2) to achieve this result, but in at least some cases, I'd prefer to get only a single call to my .on() handler.
This segues into my second idea.
2) Batch set:
In my application I'd like a way to force an arbitrary number of calls to .set to only result in one call to .on in other clients. Something like:
ref.startBatch()
ref.child("a").set(1)
ref.child("b").set(2)
....
ref.endBatch()
In batch mode, .set wouldn't result in a call to .on, instead, the minimal number of calls to .on would all result from calling .endBatch.
I readily admit that these ideas are pretty nascent, and I wouldn't be surprised if they conflict with existing architectural features of Firebase, but I thought I'd share them anyway. I find that I'm having to spend more time ensuring consistency across clients when using Firebase than I expected to.
Thanks again, and keep up the great work.
UPDATE: We've added a new update() method to the Firebase web client and PATCH support to the REST API, which allow you to atomically modify multiple siblings at a particular location, while leaving the other siblings unmodified. This is what you described as "mergeSet" and can be used as follows:
ref.update({a: -1, b: -2});
which will update 'a' and 'b', but leave 'c' unmodified.
OLD ANSWER
Thanks for the detailed feature request! We'd love to hear more about your use case and how these primitives would help you. If you're willing to share more details, email support#firebase.com and we can dig into your scenario.
To answer your question though, the primary reason we don't have these features is related our architecture and the performance / consistency guarantees that we're trying to maintain. Not to go too deep, but if you imagine that your Firebase data is spread across many servers, it's easier for us to have stronger guarantees (atomicity, ordering, etc.) when modifying data that's close in the tree than when modifying data that's far away. So by limiting these guarantees to data that you can replace with a single set() call, we push you in a direction that will perform well with the Firebase architecture.
In some cases, you may be able to get roughly what you want by just reorganizing your tree. For instance, if you know you always want to set 'a' and 'b' together, you could put them under a common 'ab' parent and do ref.child('ab').set({a:-1, b:-2});, which won't affect the 'c' child.
Like I said, we'd love to hear more about your scenario. We're in beta so that we can learn from developers about how they're using the API and where it's falling short! support#firebase.com :-)

Encrypt IDs in URL variables

I am developing an HTTP server application (in PHP, it so happens). I am concerned about table IDs appearing in URLs. Is it possible to encrypt URL variables and values to protect my application?
oh ok, so for sensitive information best to use sessions then, are table Ids etc safe to throw in the GET var?
Yes, sensitive information must not leave your server in the first place. Use sessions.
As for "are table ids safe in the URL": I don't know, is there anything bad a user could do knowing a table id? If so, you need to fix that. Usually you need to pass some kind of id around though, whether that's the "native table id" or some other random id you dream up usually doesn't matter. There's nothing inherently insecure about showing the id of a record in the URL, that by itself means absolutely nothing. It's how your app uses this id that may or may not open up security holes.
Additionally think about whether a user can easily guess other ids he's not supposed to know and whether that means anything bad for your security.
Security isn't a one-off thing, you need to think about it in every single line of code you write.
Sounds like you want to pass sensitive information as a GET param.
Don't do that - use $_SESSION if you can.
However, if you want your params encoded (i.e. => +) use urlencode().
$a = 'how are you?';
echo urlencode($a); // how+are+you%3F
You can encrypt what you pass before you transmit, or you can run the entire communication over an encrypted channel (https or ssh for instance).
Your GET variables are called whatever you choose to call them, and assigned whatever values you choose to give them. So, yes: they can certainly be encrypted or, if you'd rather, simply obscured. If you're planning to encrypt variables, then PHP has quite a few options available.
For the above, I'd recommend using something like urlencode.
In general I'd suggest using POST instead of GET, assuming you're getting your variables from a form element. On the other hand it might be even wiser to use session variables.
Maybe this article can give you more ideas...
http://www.stumbleupon.com/su/1nZ6bS/:1PcFQMI0:6oJD.Hd1/www.ibm.com/developerworks/library/os-php-encrypt/index.html/

Resources