So, as with most things built with Firebase, I have to ask how the security works. Last I talked to the Firebase team, they were building expression-only rules for managing server-side validation. This allows you to express some reasonable subset of permissions, but not all possible ones.<p>In this case, the OT history for the document (required to synchronize clients) is stored in Firebase (with each op being a separate object with a massive ID, I imagine this will become awkward with large numbers of old documents, but I digress). Additionally, snapshots are occasionally stored.<p>Rather better than previous offerings I've seen using Firebase, this demonstration has been put together to solve the first few obvious problems: I am not allowed to dump the set of documents[1], nor am I allowed to arbitrarily corrupt the database by deleting random objects[2]. So far, so good.<p>[1]: <a href="https://news.ycombinator.com/item?id=4780495" rel="nofollow">https://news.ycombinator.com/item?id=4780495</a><p>[2]: <a href="https://news.ycombinator.com/item?id=3824775" rel="nofollow">https://news.ycombinator.com/item?id=3824775</a><p>A set of example security rules for Firepad is actually provided as part of the GitHub project, so we can do some analysis of the kinds of checks we will need to bypass in order to break this particular demo ;P. (Of course, this just makes us faster, it isn't what makes this possible.)<p><a href="https://github.com/firebase/firepad/blob/master/examples/security/secret-url.json" rel="nofollow">https://github.com/firebase/firepad/blob/master/examples/sec...</a><p><a href="https://github.com/firebase/firepad/blob/master/examples/security/validate-auth.json" rel="nofollow">https://github.com/firebase/firepad/blob/master/examples/sec...</a><p>Reading these, it turns out that the only verification that is being done on the snapshots is that 1) they look reasonably valid (have the correct set of fields) and 2) they have the correct author field associated with them (as in, the same one that is used on the history revision item).<p><i>However, it doesn't do any consistency checks on the data itself.</i> It doesn't even verify that the snapshot we are uploading is different than the one currently on the server, so the problem of corrupting the state is really easy: we just need to pull the current snapshot and modify its data.<p>The only pain we could run into is that it could also verify that the author of the snapshot is the current user; but that doesn't help: all we need to do is to make a quick edit to the document and then use our new revision (which we legitimately own) to build our new corrupted snapshot.<p>That said, while that check is present in the example rules on GitHub, that check isn't actually used in the deployed copy of Firepad on this server as this server is entirely anonymous and thereby none of the users have any auth information at all... we can just pretend to be other users.<p>For users who wish to follow along at home, you just need to have node.js installed, and then do "npm install firebase". You can then use the following script to destroy any document you want: you just need to set the "room" variable to the ID # of the document you want to modify.<p><pre><code> #!/usr/bin/nodejs
var Firebase = require('firebase');
// parseInt(window.location.hash.substring(1))
var room = 44;
var shard = room % 15;
var db = new Firebase('https://firebase-firepad' +
shard + '.firebaseio.com/' + room);
var check = db.child('checkpoint');
check.once('value', function (value) {
value = value.val();
check.set({
a: value.a,
id: value.id,
o: [''], // random data would be better
// but I'm both lazy and busy today ;P
});
});
</code></pre>
When the client then restores this snapshot and attempts to play back the resulting history to "catch up" it will instead end up outputting tons of errors to the console, as the operations stored in the history will be referring to document positions that no longer exist or are different.<p><pre><code> Firepad: Invalid operation. https://firebase-firepad14.firebaseio.com/44 C2GK
</code></pre>
The client then has two options: it can either skip the history entry or it can decide the entire document is corrupt. In this case, it seems that Firebase believed the better of the two options was to simply skip these operations: new clients then manage to resync their state.<p>But, existing clients now have desynchronized state, so all operations that are being synchronized live between the various clients on either side of this split (ones that started from this snapshot, and ones that pre-existed it) are going to result in this error; that didn't really help.<p>To be very explicit for a second: this is a different scenario than just "well, its an anonymous system, so anyone can delete the data": we didn't just go in and delete the data in the document, we actually corrupted the state of the document, rendering further attempts to edit it useless.<p>It is currently my belief that Firebase's security rules system is simply not powerful enough to secure an OT-based text editor, whether or not it uses snapshots (at least assuming it supports offline; there might be tricks you can play if all users are required to be online at all times).<p>(edit: I am finding it interesting that my previous security analyses of Firebase projects, combined with example code, had been voted up quite high, and this one has now been downvoted to 0. I wonder if people just don't care as much about security anymore? Is it because it is open source? Is the Firebase team themselves going around voting down? ;P)