Firebase Security Rules: Guard against reserved chars - firebase

Firebase has certain reserved characters:
., $, #, [, ], /
How do I block these characters from being added into my database in security rules?

Use .validate along with matches(). matches() accepts regular expressions. contains() checks if the string contains the specified value.
This would be if you were writing an object like this: {"post": "he.lo"}
".validate": "!(newData.child('post').val().matches(/[.$\/#]/) || newData.child('post').val().contains(']') || newData.child('post').val().contains('['))"
And if you were just writing a string: "he.lo"
".validate": "!(newData.val().matches(/[.$\/#]/) || newData.val().contains(']') || newData.val().contains('['))"
I tried for quite some time to include "[" and "]", but Firebase didn't like them which is why I added the contains() methods.
These rules would be used for checking against values and, as #Frank said, not keys.
Reference: Firebase 3.0 Security Rules

These characters cannot be used in database keys, but can be used in database values.
The Firebase Database will automatically rejects write operations where such characters appear in a key, you don't have to write any rules for that.

Related

Unable to access field that has hyphen in it

I am struggling to write a firebase rule that is checking the user id that is stored in a document. Hardcoding a given value as a string works
allow write: if request.auth.uid == 'user-id-hardcoded';
,however I am unable to find a way to dynamically address it. I am left with the impression it's due to the hyphen in the document field after checking this question - Firebase security rules : How can I use dashes or hyphen in paths?. I also tried to substitute user-id with userId to no avail.
allow write: if request.auth.uid == resource.data.user-id;
Any help will be appreciated.
If your field name in document contains a hyphen then use the brackets notation instead:
allow write: if request.auth.uid == resource.data["user-id"];
I checked this link, it looks like the hyphen will be detected start or end of a structural component.
FirebaseVisionDocumentText.RecognizedBreak

Firebase security hashing UID doesn't match client computed

Following firebase documentation here, I have implemented the following security rule:
match /docs/{hashID} {
allow read, write: if hashing.md5(request.auth.uid.toUtf8()).toBase64() == hashID;
}
On the client side, I am using node-md5 to compute user's hashID and write to a document
firebase.firestore().collection("docs").doc(md5(user.uid)).writeSomething()
It is failing the security rule because the hashes don't match.
For uid "crz6KyreRCM4A0Qvk9EfeXHBLF43", my client md5 gives me "eee1f958a8c0a273f138bdee0167693d", while Firebase Rules Playground gives me "fbOLeadWz7YxnsGgfESBNg==". I've verified the client md5 value is correct using https://www.md5hashgenerator.com/. What am I doing wrong in the security rule?
Solved! The node-md5 output was a hex string, so the following rule is appropriate:
match /docs/{hashID} {
allow read, write: if hashing.md5(request.auth.uid.toUtf8()).toHexString() == hashID;
}
Furthermore, Firebase's toHexString() returns a result in all caps, so I need to do this on the client side
firebase.firestore().collection("docs").doc(md5(user.uid).toUpperCase()).writeSomething()
You are calling toBase64() unnecessarily. That's for converting byte arrays into strings, which can then be hashed. Since you're dealing entirely with strings here, there is no need to base64 encode anything.

how to check if a filename contains uid in firebase storage security rules?

I want to make a rules in my firebase storage, and I want the filename of image stored in firebase storage contains uid of its uploader. usually in programming language I use .contains to check
service firebase.storage {
match /b/{bucket}/o {
match /eventThumbnail/{imageID} {
allow create: if request.resource.name.contains(request.auth.uid)
}
}
}
is this rules valid ? I can't find documentation about using contains in firebase storage security rules documentation. actually the rules is more complex, I still search what makes I fail to create an image, and I suspect that rules is not valid
You can use something like this:
match /{fileName} {
allow read: if fileName[0:6] == 'abcdef';
}
Documentation on string rules:
https://firebase.google.com/docs/reference/security/storage#string
The API documentation for security rules for Cloud Storage is here. The specific documentation for string type objects is here. You can see that in the documentation, there is no "contains" method for string. But there is a method for using a regular expression to verify the contents of a string using matches().
However, I think Frank is correct in his comment suggesting that it would be better to use a dedicated prefix for each user using their UID in the path of the file. For example "/eventThumbnail/{uid}/{file}" could be used to determine the permissions for any file organized under uid, where uid could simply be verified as equal to request.auth.uid (no substrings or regular expression required). This is also far more secure and reliable than checking file substrings.
Filename can now be used as UID and matched using Firebase storage split syntax found here.
I do also recommend rather using the path to prefix each UID instead, but if the files are already in a production environment the split syntax could prove useful.
Update:
Syntax on Firebase Documentation appears to be incorrect as indicated by this post

How to properly write Regex validation in Firestore Security Rules

I'm trying to validate submitted data against Regex expressions in Firestore Security Rules. I've read through the documentation, but I'm still unsure how to write them.
I read through the Regex documentation here https://firebase.google.com/docs/reference/security/database/regex , but it doesn't really show how to use it in Firestore. I tried using an 'allow validate' rule and copy/pasted a regex expression from the docs, but I'm getting all kinds of errors.
Here's what I tried:
Do I need to put it in a format like this? (From the docs) allow create: if !("ranking" in request.resource.data)? If so, how do I use a regex expression with it?
It looks like you're trying to start a regex with /. That's not going to work - it's not like perl. Slash starts a path object. Might want to check the API documentation on this. You should just be passing a plain string to matches() that contains the regex to match.
https://firebase.google.com/docs/reference/rules/rules.String#matches

JavaCC match token group

I ended up writing a parser for a small subset of SQL.
The grammar has a lot of regular tokens (SELECT, CREATE, ...) and a few more general (e.g. S_GEN_IDENTIFIER matches [A-Z_.\d]|\"(~[\n, \r, \"])*\").
The problem is, "SELECT col AS type ..." doesn't get parsed since instead of <S_GEN_IDENTIFIER> "type" column alias is matched as <T_TYPE>.
I had an idea to replace token with a rule with the same name and check is the token of interest lies within some token range (something like [<T_AS> - <T_KEEP_DUPLICATES>]. Unfortunately it turned out that the syntax for tokens and rules differs so I can't do it.
I could just copy-paste all tokens inside the new rule but I don't want to do it for obvious reasons.
Is there any way to check if token lies within the range of predefined tokens?
Perhaps you could treat "type" as an unreserved keyword. Then you can follow the advice of question 4.19 of the FAQ
http://www.engr.mun.ca/~theo/JavaCC-FAQ/javacc-faq-moz.htm#tth_sEc4.19

Resources