Validate Facebook JavaScript API response - javascript

Is there a way to validate the response from say:
FB.api(
{
method: 'fql.query',
query: 'SELECT name, pic FROM profile WHERE id= ' + FB.getSession().uid
},
function(response) {
//...
}
);
Validating the cookie for login is easy enough using a MD5 hash and the application secret key compared to the provided sig parameter. However in the case of the api calls, what would stop someone from using firebug to change the response? Obviously this can be done on the back end for sensitive information but i'd like to keep as much of the back and forth bandwidth to Facebook on the clients end as possible.
Any thoughts?

I can't think of anything harmful the user can do other than breaking his own experience in your application UNLESS you are getting these inputs (responses) and processing them/saving them to the DB for example:
Having an input field where the user can update his FB status through it, and you want to save that to your own DB too?
In this case you would/SHOULD do the usual input validations (mysql_real_escape ..etc) anyway.
Saving the user Email?
You already can get almost all the information about the user using server-side calls once the user is authenticated and grant your application access..for instance to save the user email you shouldn't wait for the user to send it to you when you can acquire it using the email permission

Any validation you might do in JavaScript(1) would be something the user could overcome with a little JS of their own.
If you need to ensure that communications to/from Facebook are secure and not interfered with... then do it on the server.
(1) e.g.
if you had a validateFacebookResponse(resp); function... an end user simply needs to re-declare the function...
function validateFacebookResponse(resp){
return true;//always return true!
}
and any "security" you had is out the window.

Related

Should Token created when the user registers or login?

I have an API created by one of my team :),
And he made an endpoints "Register/Login"
his thought
When user create a user we save his data and the endpoint response it " without generating a Token"
so i can't navigate him to other screens cuz I make a request based on his Token,
So he wants me to navigate user after register to the login screen then Login endpoint will response the Token
But I think it's not a nice way and not improve UX.
So what you think we do?
generate Token in the register or log in?
The way I see this:
Solution 1:
You have him change the register API so that returns a token for you and you keep doing whatever you do with it.
Solution 2:
By registering, I'm assuming they type in a username/email, some personal details and a password!? So you have all the data to log the user in after registration. Upon successful registration, use the same username/email and password from memory (do not store them in browser storage) and call the login api to get the token (you only redirect after you've gotten the token) - so UX doesn't suffer here.
P.S. Instead of "fighting" one another over who's solution is better, try to work together in a solution. This is clearly an "I told you so" attempt - hence why I gave you two solution where both sides can do the work. Both of you can implement a solution without affecting UX, it's a matter of who's more stubborn :P

Password protect a page with Firebase

I'm building a CMS with Firebase, but struggling to assess whether what I require is possible, or if I'm missing something.
What I require is the ability to password-protect a page only, and remember that browser as having access. A full user account (using the in built auth) is required to edit the content of the page, but only a password is required to view it.
I know I can use the auth flow with email, but am looking for the editor to be able to create a password for viewing only.
Is this possible, or should I look elsewhere?
The way I commonly do this is a bit like Jeremy's answer, but simpler.
You ask the user for a password when they enter the page, and store that password locally (for reloads).
Then you store data in your database under a path that includes the password. So say that your password is geheim, you could store the data under:
data: {
geheim: {
value: "This is the secret value"
}
}
Now you secure your database with rules like these:
{
"rules": {
".read": false,
"data": {
"geheim": {
".read": true
}
}
}
}
Now somebody can only read the data at /data/geheim if they know the entire path. So you'll enter the data part in your code, but require them to enter geheim as the password. Then you attach a listener with:
firebase.database().ref("data").child(password).once("value", function(snapshot) {
console.log(snapshot.val());
});
And if the user entered the correct value for password, this will read the value.
Firebase Authentication only deals with authenticated user accounts. It doesn't deal with simple password protection of content.
It's definitely possible, but as Doug's answer indicated, you'll have to do it outside normal means. Off the top of my head, the way I would accomplish this is...
When a user enters a password, it stores the password in their local storage.
On page load, or on password entry... pull the password from local storage
Make a request to a Firebase cloud function, makes sure to include the password it just retrieved from local storage, and which page it is requesting content for
Firebase cloud function validates password
Firebase cloud function retrieves data for specific page
Firebase cloud function returns said data
Load data on front-end like normal
As you already identified, you should stick with the built-in Firebase auth for content editing.
I definitely suggest Frank's answer because it's simple and it works. Btw the moral of the story is that you use the firebase Database to store you view-only password but, if you want to complicate your life because you need a strong view-only password system, the Authentication product provides the custom authentication method that you can integrate with your existing auth system (for example fb login). It obviously needs a server-side implementation that is a code that takes the password, check if it's valid and sends the token back to the Auth system.
Here more details: https://firebase.google.com/docs/auth/web/custom-auth

Protect PHP endpoints called by AJAX

My app consists of several PHP endpoints which are accessible via AJAX. The problem is they are also accessible via anyone who makes an HTTP request to the same endpoint. I can add checks for HTTP_X_REQUESTED_WITH and HTTP_REFERER as specified in this answer, but these can be spoofed. I could add a secret key that needs to be posted with the request, but anyone viewing the javascript and/or the console would be able to see this key. What is the solution here?
People often think that because they're using Ajax requests regular sessions don't work. They do.
If you have an endpoint to delete something from the database that's visible in the source code, such as:
example.com/user/1/delete
You can protect this request from non authenticated users the same way you would when using a non Ajax HTTP request in the browser. Using sessions. If the user has the privileges to remove users, this route will work, otherwise return an error (or do nothing).
You can also protect an API using OAuth. There's a great document here that explains how it works: http://tatiyants.com/using-oauth-to-protect-internal-rest-api/
Most of the answers are not helpful if you have your app and your api on separate domains for example app.example.com and api.example.com - in that case sessions won't work and you would have to turn to OAuth which is quite a big hammer for such a simple problem.
Here is what I would do:
I assume you have users in a database and a unique identifier like user_id=12345. I also assume that you have your Jobs in a Database and they also have unique ID's like job_id=6789.
First on app.example.com you encrypt both IDs with something fast and easy like Blowfish:
$secret_uid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($user_id));
$secret_jid = mcrypt_encrypt(MCRYPT_BLOWFISH, "your_secret", strval($job_id));
I assume your endpoint would work somewhat like this:
api.example.com/jobs/delete/<job_id>/<user_id>
so now from Ajax you call that endpoint, but instead of calling with plain IDs
api.example.com/jobs/delete/6789/12345
you call it with the encrypted IDs:
api.example.com/jobs/delete/6A73D5B557C622B3/57F064C07F83644F
On the API side of your software you decrypt the parameters:
$jid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_1>);
$uid = mcrypt_decrypt(MCRYPT_BLOWFISH, "your_secret", <param_2>);
Now you can search your db for uid and jid and perform whichever task you were planning to do. Make sure that a user can only delete his own jobs of course.
I admit this is not a 100% solution, but it leaves an attacker with a lot of guess work - he would have to guess the user_id and a matching job_id, the encryption algo and your secret. It does not protect against running millions of brute force attempts to guess a matching pair, but it put's the odds in your favor (and you should have some sort of quota limitation protection of your endpoints anyway).
Good luck!
There isn't one. If you give someone some data, then they can process it in whatever way they like. You can't control what happens to it after it leaves your server.
Likewise, you can't control what data they send to the endpoint.
it is very important for a developer to put authentication for API or web services. dchacke and BugHunterUK has given perfect answers, I just want show you simple code I use to make very simple and easy to use authentication.
Adding Session for the authentication
you can add session, and session timeout for your APIs so, only your app can use this, you can start session when front page of your app is loaded, you can set timeouts and also restrict the different service for different users by sessions.
General Idea how to do that
<?php
if(!empty($_SESSION['api_session']) && $_SESSION['api_session'] == 'usertype'){
//usertype comprise of what access you want to give
//guest, registered user, stack holder, admin etc.
...
header('Content-Type:application/json;');
echo json_encode($output);
}

server request security with tokens

I have built a browser game and now I'm working on making it a bit more secure. Since all server requests are initiated from javascript even kids could tamper data on the server. I've been reading through questions on stackoverflow and implemented sending/receiving a token in my requests however I am regenerating this token on every request to the server and send the new one back to the client for the next call. Requests are made through https and are of type POST.
Here's the token flow on client side:
var token = 'abcd1234';
$.ajax({
url: "index.php",
type: "post",
data: {
method: "score",
value: 50
}
});
$(document).ajaxSend(function(e, xhr, o){
o.data += '&token=' + token;
});
$(document).ajaxComplete(function(e, xhr, o){
var data = JSON.parse(xhr.responseText);
token = data.token;
});
And on server side:
if (!isset($_POST['token']) || ($_POST['token'] != $_SESSION['token']))
{
die();
}
else
{
// generate new token and send it back along with the response
}
So my question would be if this token increases the security of my server requests or not and what can be done to further increase the security?
EDIT This is a facebook game, all code is javascript and the server side simply handles updating the database.
I dont really think tokens do alot when using Ajax.
You should just validate all your forms and data server sided with the users session because the login itself is the most realiable way to identify a user.
A token an merely help to make session stealing/riding harder but if you code your session handle to logout the user on changed IP adress this should be fair secure enough.
I have an online game aswell and I dont do more but validate all forms and values against injection, valid data and check the login/session every time correctly and never had any bad experience with that.
One more thing I do is security issue is that you should flag your admin accounts with a special attribute that it requires a special IP range to login, then I fetch the ip range with a whois lookup on ripe.net and enter it into the database and look if the users actual IP is inside the min and max ip, this way maybe 1 of 1000 attackers would have the correct IP adress to login with the admin account even if they achive the login data.
Remember that the generated token will be received and send with every normal ajax request and someone who want to harm you and your page will analyse your form and request data and then simply copy that process.
It will make it harder for script kiddies, but not for professional intruders.
Its all just a matter about how paranoid you are about security issues and how skilled your possible attackers are.
As Steini already stated the ONLY reliable login system is done with session. The client side solution has got infinity security issues.
You can for example make the system using session and than use Javascript to ask php if the user is logged, and which privilege it has.
This said you can use PDO to increment the security, you can also fetch all the data from all the form and all variables that are passed through browser alone to exclude some issues.
Without a secure login system your game will be a security bomb and will create you trouble soon or later.

Persisting a security token between calls

We are creating a prototype application as follows:
We have a html web site using knockoutjs
Using qQuery/Ajax it communicates with Web Api services
We only want the services to be accessed by authorised users. So we have written in security that can validate the user based on username/password
So next I guess we need to pass back some type of token to the client which it uses in further communications with the API services.
What I would like to know is how this is stored on the client so it can be passed back to the server again for the next call?
I assume the client makes an initial call passing in the user name and password over HTTPS and gets back a token. You question is to how to store the token? I assume your application is an SPA. If so, why not just store it in a JavaScript variable? If you do not use a cookie, you avoid XSRF. Of course, you must ensure the user name and password are never stored in the client side and that the life time token of your token is finite and preferably as small as possible.
EDIT:
If you can regenerate the token with every page (since it is not SPA), it is even better and you make the life time of token very small. You can use code like this. I use Authorization header and bearer scheme but you can use your own scheme as well, if no standardization is needed.
var accessToken = ''; // Write out the token into this variable in the server side (view)
$.ajax({
type: 'GET',
url: 'http://whatever',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
headers: { 'Authorization=': ='Bearer ' + accessToken },
success: function (data) {
}
});
So we have written in security that can validate the user based on username/password
This sentence basically means that you need to store the username and password in your javascript file in order to be able to call the service, unless of course you want to ask the user to enter his credentials on every single action he performs. I hope this is not something you are wiling to do at the moment. If it is then you can stop reading my answer and store the username and password in your javascript file.
At this stage it is more than clear that your security should be handled differently. Your Web API should not be protected by a username and password but by a token. Here's how this could work in practice. You will have an action that will take the username and password, validate them and if successful it will return a token. This token could contain the encrypted username. So your javascript will ask the user for his username and password, call the Login method and it could store the token. Then it will use this token on subsequent calls. The API will in turn decrypt it in order to extract the username.
What I would like to know is how this is stored on the client so it can be passed back to the server again for the next call?
Cookies. You will send token as a cookie, and it will be sent automatically when user requests your page.
create a server side session, for the once authorised md5(username) md5(password).
generate an uuid per request, and return it in the response.
basic model is called token exchange and it is reliable (no m.i.t.m) even w/o SSL.

Categories

Resources