Are Firebase dynamic links short url info exposable? - firebase-security

Can an attacker view the query parameters of a shortened firebase dynamic link?
If yes, is it secure enough to use let’s say invite links that contain a group ID to access that certain group.
In that case wouldn’t there technically be the security issue of someone having a program attempt all ids till they get a correct ID?

After some research, the url parameters are indeed exposed and viewable.
Secondly, firebase document ID's consist of 20 characters, each character could be 26 * 2 (Alphabet Capital and small) + 10 number possibilities. Meaning that an ID has 62^20 combinations, Good luck to anyone trying that amount out.
Thirdly, i believe App attest would block a user if he's abusing resources.

Related

Does it make sense to define a GET /users/{id}/photos route or should I just send multiple GET /photos/{id} requests to return a user's photos?

This is a dilemma I find myself facing very often when dealing with nested resources.
So suppose the target user has n photos. Does it make sense to define a GET /users/{id}/photos route or should I just send n GET /photos/{id} requests by first requesting the User object and then looping through that User's photo_ids attribute?
From a best practices perspective, I would not send several request for such similar resources. In that scenario, you end up creating more work for yourself by having to rate limit on the backend, in order to keep your users with a lot of pictures from blowing up your server. That would be impactful to your UX as well.
I recommend you format your route as such:
GET /users/photos?id={{id}}
And return all associated photos with that user ID all at once. You can always limit that to X number of photos per call too, and paginate:
GET /users/photos?id=658&page={{1,2,3, etc.}}
My personal preference is always to try to keep variable data in the URL parameters. Having spent the afternoon with several unrelated APIs, I can tell you a whole slew of developers agree.

Translations API Usage by API Key

Here is what I have:
Project in Google API (Translate API)
Billing Enabled
Upgraded Quota limit up to 10 000 000 chars per day
One server key
Many sites, which use this key to translate text
And here is the problem: it seems our sites request more texts for translations than we expect and we can't find which of the sites sends so many texts. We have looked at our sites and found nothing. We want to determine translations requests volume by each site or module.
I can see overall usage and quota usage in API Manager. But there is no information about IP / domain name input to the overall usage. Is it possible to see translations usage by site / API usage / other parameter.
I have some ideas and questions. First, I can create a unique API key for each site/module so each site will use its own key. But it seems it is not possible to see translations usage by keys within one project.
The second idea was about adding parameter in URL like user_id. That method was mentioned in API docs but, again, I can't see how to generate translations usage by a certain parameter.
Could you please advise?

Why randomize your file names for cloud storage/CDN?

When you look at a profile picture on a social networking site like Twitter, they store image files like:
http://a1.twimg.com/profile_images/1082228637/a-smile_twitter_100.jpg
or even with a date somewhere in the path like 20110912. The only immediate benefit I can think of is preventing a bot from going through and downloading all files in your storage in a linear fashion. Am I missing any other benefits? What is the best way to go about randomizing it?
I am using Amazon S3 so I will have one subdomain serving all my static content. My plan was to store an integer ID in my database and then just concat the URL with the id to form the location.
One reason I cryptographically scramble identifiers in public URLs is so that the business' rate of growth is not always public.
If the current ids can be deduced simply by creating a new user account or uploading an image, then an outside person can calculate the growth rate (or an upper limit) by doing this on a regular basis and seeing how many ids were used during the elapsed time.
Whether it's stagnating or whether it's exploding exponentially, I want to be able to control the release of this information instead of letting competitors or business analysts be able to deduce it for themselves.
Offline examples of this are invoice and check numbers. If you get billed by or paid by a company on a regular basis, then you can see how many invoices or checks they write in that time period.
Here's a CPAN (Perl) module I maintain that scrambles 32-bit ids using two way encryption based on SkipJack:
http://metacpan.org/pod/Crypt::Skip32
It's a direct translation of the Skip32 algorithm written in C by Greg Rose:
http://www.qualcomm.com.au/PublicationsDocs/skip32.c
Use of this approach maps each 32-bit id into an (effectively random) corresponding 32-bit number which can be reversed back into the original id. You don't have to save anything extra in your database.
I convert the scrambled id into 8 hex digits for displaying in URLs.
Once your ids approach 4.29 billion (32-bits) you'll need to plan for extending the URL structure to support more, but I like having shorter URLs for as long as possible.
Changing URLs is a safe way to invalidate outdated assets.
It is also a necessity if you want to allow users storing private images. Using a path deductible from the users account name/id/path would render privacy settings useless as soon as you store assets on a CDN.
Mainly, it prevents name collisions. More than one person might upload "IMG_0001.JPG", for example. You also avoid limits on the number of files in one directory, and you can shard images across multiple servers - there's no way a huge site like Twitter or Facebook could store all photos on one server, no matter how large.

VB - hashing registration data for offline authorization

I have a vb application where I was using an online mysql database for user access. The online database had username, password, then a bunch of single digit (basically yes/no) fields for determining which items that user was allowed to access. When a user would log in, the database retrieved all the 'yes' answers and enabled those buttons, and retrieved all the 'no' answers and disabled those buttons.
My issue is there is a very good possibility that any given user will not be online. So I thought of copying the online database to a local device (this program is going to be running on windows tablets that may or may not have internet - possibly never having internet connection). This would suffice except a user may use a different tablet and that device wouldn't know what the user is allowed to access (based on a lack of internet connection).
So my new approach is when a user registers, having them provide first name, last name, phone number, and email address. At this point in time I would also select which buttons they are authorized to use. I want to put all that info into a code (probably a hash) so the next time the user would login (online or offline), they would use their first name, last name, and the generated code. The user could even go to a different device and still get the same result. I hope this makes sense.
So basically I am looking for a way (I am pretty sure hashing is involved) that would allow a user to register with some info, receive a code that ties it together, then log on to any windows tablet that is running my program without the device ever having to go online to download a new list of authorized users.
Thanks in advance.
A hash is part of what you're thinking of, but not the whole thing. A key part of a hash is that it's not reversible, and so you can't use a hash on it's own to communicate information like which buttons to enable/disable. It does sound like you also need to implement hashing elsewhere in your system (NEVER store unhashed passwords!). The rest of what you need for this question are secure check digits.
The idea is that you generate a number with a few holes/empty spaces, where different parts of the number have different meaning. It might look something like:
4325_-23R3_-F257_-D982_-__
A few of those characters are a hash of the user information, with the bits from other characters corresponding to your Yes/No database fields. Once you have this much, you have an algorithm (using a secure key) that computes what characters belong in the missing spaces, and then you can issue the final number to your user. Your software will take the number entered by the user, and check to the make sure the check digits it comes up with match the check digits entered.
There is a downside to this approach. Allowing offline activation means including including the key used to compute the check digits with your product, and as with any digital security once you put that kind of thing out in the wild crackers will be able to find a way to get at it.
Now let's move on to the big gaping security hole in your current code. You state that your database stores a username and password. I'm hoping that you're just simplifying things, but this is a huge problem, to that point that I can't in conscience leave it unchallenged. Instead of storing the actual password, you should hash the password and store only the hash. When someone wants to log in, you hash the attempted password they try to use and compare the hashes. This is a big deal, and if you're not doing that, you're doing it wrong.
That also over-simplifies it a bit. You also want to salt your passwords before hashing them, to help thwart dictionary attacks on common hash results. Additionally, choice of hashing algorithm matters. md5 does not cut it here. Your best option is bcrypt or scrypt, but you can use sha1 for now if you really have to.
The biggest thing to know here is that you should never try to build your own authentication system. It's easy to get it close enough that it passes all your tests, but is still wrong in some subtle way that won't know about until a year later when you find out you were hacked six months ago. Instead, look for a pre-written component or product for your existing platform to handle this. Rely as much as possible on code from projects (and programmers) that specialize in this area.

What validation must a form include? Best practices

I am trying to put together a checklist things I need to keep in mind when creating forms. I know I need to filter input content. I already am filtering for errant html and scripts, escaping mysql, and limiting to data types(phone numbers are 10+ digits with training extension digits, email has to be email, strings cannot contain html or code, etc.), and word or character limits (names max out at 4 words separated by whitespace, etc.). But what else should I be doing and what are good ways of doing them?
This validation will be taking place on the server, but I am looking for best practices across platforms. The data will be coming in using POST, so I don;t have to worry too much about mucking about with the url. Also the form presentation, with hinting, js input masking is handled, and pretty much all the client side stuff is in place.
Validation down to its simplest term: only accepting what you want.
For example, if your telephone field should only include numbers (in no particular phone number format) and no longer than 20 numbers, you can check it against regular expression to make sure that it is what you want to accept, i.e. ([0-9]{7,20})
Another example, Twitter. It only accepts username up to 15 characters, alphanumeric and consisting of underscores. So the validation regex might something be: ([a-zA-Z0-9]{1})([a-zA-Z0-9\_]{0,14})
Form validation can also be in the form of security check. One could be honey potting, form validity and so on.
Form Honey potting: Preventing automated/spamming of your form submissions
Form Validity: Check between the time the form has loaded and the time of form submission. If it is too short, the form might be submitted by a bot. If it took too long, the data might be old and expired.
CAPTCHA: another level of bot prevention / human only form validation.
The always great smashing magazine has some great tips:
http://www.smashingmagazine.com/2009/07/07/web-form-validation-best-practices-and-tutorials/
But if I could offer my own:
Make it secure but usable.
Use client side validation along
with server side validation
If you post back with errors, make
sure the users' information is still
populated in the form
Limit the field size in HTML forms.
Of course, all this is assuming you're using web forms.
Commenter S. Lott is correct: Escaping should be taken care of automatically by the framework. If you're not working with an explicit framework, then at the very least, the utility functions you use to access the database and display data on the page should escape for SQL and HTML, respectively. If you have to worry about escaping in your validation code, sooner or later you'll make a mistake, and some twelve-year-old script kiddy will replace the contents of your web site with horse porn.
Stuff that makes sense in the context is good, stuff that doesn't make sense is bad.
If this site filtered for HTML, then we couldn't give HTML examples. Instead it processes the HTML so that they are output escaped, rather than as HTML.
Beware of over-validating. < is not necessarily bad, there are all sorts of reasons people will use <, > and especially &.
Likewise, while Robert '); DROP TABLE Students;-- isn't someone you want signing up at your school, if your preventing that means that O'Brien, O'Tierney, O'Donovan and O'Flanagan can't sign up, by the time O'Donnell is refused he's going to think it's anti-Irish racism and sue you! (More realistically, I do know people here in Ireland who go off to find a competitor when a SQL-injection prevention script blocks or mangles their surname - though more often they've just found yet another site that isn't preventing injection, as either will fail on their name in some way).
Validation, as opposed to security-checking is about making sure something plausibly reflects reality. In reality personal names have ' in them and company and town names have & in them all the time, and "validation" that blocks that has turned valid data into invalid. In reality, credit card numbers are 16digits long (some debit cards 19digits) and pass a luhn check, email addresses have a user info part, an # and a host name with an MX record. People's names are never zero-characters long. That's validation. Only reject (rather than escape) if it genuinely is invalid.
You may want to check out OWASP http://www.owasp.org/index.php/OWASP:About. Especially if you're planning on handling credit cards.