View Sidebar

Post Tagged with: Security

EphChat: An Ephemeral Chat Program Written in PHP, JS + Firebase

EphChat: An Ephemeral Chat Program Written in PHP, JS + Firebase

I took a break from ReservationHop today to build a new chat program.

Screen Shot 2014-07-17 at 9.08.30 PM

EphChat, which stands for, you guessed it, “Ephemeral Chat,” is a chat program with a twist. No data is stored server side, and messages are only visible to participants for 60 seconds before they fade away into nothingness.

Anyone can create a new chatroom with a random URL hash, or can create their own chatroom.  Users are anonymous but you can edit your name if you wish. Messages are encrypted all the way to the server, where they are relayed to the chatroom participants and then immediately deleted. User sessions are stored until a user disconnects, then they are deleted, too.

Why did I build this?  Well, partly as an experiment with Firebase, but also because I like the idea of people being able to communicate in an encrypted, anonymous way without governments snooping on them.  Reporters can use this to do sensitive interviews; protesters under despotic regimes can use it to organize resistance.

The code is up on GitHub, which I felt was necessary to provide transparency into the app’s inner workings and security.  I don’t usually make my repositories public, for fear of being ripped apart by the hackersphere, but if anyone is going to use this app they’re going to want to know how it works.

I had a lot of trouble with Firebase’s security rules, but I think I figured it out.  Here’s the current security schema:

    "rules": {
      "rooms": {
        "$RoomId": {
          "connections": {
              ".read": true,
              ".write": "auth.username == newData.child('FBUserId').val()"
          "messages": {
            "$any": {
            ".write": "!newData.exists() || root.child('rooms').child(newData.child('RoomId').val()).child('connections').hasChild(newData.child('FBUserId').val())",
            ".validate": "newData.hasChildren(['RoomId','FBUserId','userName','userId','message']) && newData.child('message').val().length >= 1",
            ".read": "root.child('rooms').child(data.child('RoomId').val()).child('connections').hasChild(data.child('FBUserId').val())"
          "poll": {
            ".write": "auth.username == newData.child('FBUserId').val()",
            ".read": true

I welcome any and all feedback on the app, especially security.

Go ahead and start a new chatroom at!

July 17, 2014Comments are DisabledRead More
What Google Knows About Me

What Google Knows About Me

I started keeping a list of what Google knows about me. Even knowing full well that I gave this information to Google freely, it’s pretty awe inspiring.

  • Google knows every website I’ve ever visited (Chrome)
  • Google knows who all my friends are (Gmail)
  • Google knows who my closest friends are (Gchat, Gmail)
  • Google knows what products I’ve purchased and how much I’ve spent (Gmail receipts)
  • Google knows what mailing lists I’m subscribed to, and to which clubs I belong (Google Groups, Gmail)
  • Google knows what stocks I own (Google Finance)
  • Google knows how popular my websites are, and, by proxy, how well my startup is going (Google Analytics)
  • Google knows where I travel and when I am traveling (Google Maps, Google Maps on iPhone)
  • Google knows what I look like and what my friends look like (Picasa)
  • Google knows where I am during the day, and who I’m with, and for what purpose (Google Calendar)
  • Google knows intimate details about my work and personal projects (Google Docs)

Obviously it’s an algorithm, and there isn’t a dude sitting at a computer in Palo Alto learning everything about me. But if someone wanted to, they would have a pretty easy time of invading my privacy to an insane degree.

We put a lot of trust in Google to handle our information on a day to day basis. There’s no grander point here, just something to think about. And I’m glad at least I can always walk away from Google if I wanted to.

September 20, 2013Comments are DisabledRead More