Protect Yourself Against Firebase Database Refs!
My worst nightmare is to lose production data, thank God for backups. But my nightmare came to life on a project's Firebase database. This is a noSQL JSON-like document database offered as a service from Google Cloud Platform. You use it like this:
firebase.database.ref('/customers/1')
This is how you get the data at that path. Like a file system.
And when you want to make it dynamic:
firebase.database.ref(`/customers/${customerID}`)
Cool.
But, what if customerID
is blank?
cue Nightmare Before Christmas soundtrack
funtion handleDelete(customerID) {
firebase.database.ref(`/customers/${customerID}`)
// ...delete()
}
If I ran that function in production with a blank customer ID, well then I just deleted all the customers.
Fear Not!
import protectedRef from './protectedRef.js'
const customerID = ''
protectedRef('customers', customerID)
// => [ERROR] Bad ref! 1: ""
Use protection kids.
// protectedRef.js
import { sanitize } from './sanitize.js'
function protectedRefReducer(pathSoFar, pathPart, index) {
const sanitizedPathPart = sanitize(pathPart)
if (!sanitizedPathPart) {
throw new Error(`Bad ref! ${index}: "${pathPart}"`)
}
return pathSoFar + '/' + sanitizedPathPart
}
export default function protectedRef(...parts) {
if (!parts.length) {
throw new Error('noop')
}
return firebase.database().ref(parts.reduce(protectedRefReducer, ''))
}
Tweet