I have a Facebook app with a page tab installed on many pages.
I know I can parse, server side, the signed_request and have all the data I need on the page, the current user etc.
However, I just need to know the page ID, or even the page URL, using client side JS (so, no access to signed_request which is sent via POST, no PHP or other server side language).
Is there a way to grab that information alone? Even if unsigned and insecure?
I'd really love to know whether it is possible at all before setting up a server side process, however even if the answer is "no, you can't do it" please give some motivation on why the only way to know the current page should be a server side script, what security violations could possibly arise if Facebook was offering a way to know the current page in an insecure way.
The signed_request (http://developers.facebook.com/docs/authentication/signed_request/) is part of the authResponse when calling FB.getLoginStatus() (https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus/)
{
status: 'connected',
authResponse: {
accessToken: '...',
expiresIn:'...',
signedRequest:'...',
userID:'...'
}
}
And inside the signed Request is the page id.
However, for this to work you will need to authenticate the user to your app. But at least you can do it all client side without any need for server-side scripting. And another really important item to remember is that you'll need your app secret to parse the signed request, and exposing that critically secret item in your client-side could will be extremely risky!
If your requirements say you can neither auth the user nor process the signed request server-side, then you won't be able to get the page id client side.
For security's sake, process the signed_request server-side. :)
Happy coding!
Using window.top.location you can get the complete URL of the page tab. You can then parse the ID from there!
Related
I'm currently playing around with a KnockoutJS SPA template in ASP.NET Core 2.1, and I managed to implement an authorization flow exactly as this one which was made in Angular:
https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login
As you can see in their User front-end service, basically the only check for whether the user is logged in on the client side is the check if the "auth_token" key exists in the client's local storage:
https://github.com/mmacneil/AngularASPNETCore2WebApiAuth/blob/master/src/src/app/shared/services/user.service.ts
this.loggedIn = !!localStorage.getItem('auth_token');
// ?? not sure if this the best way to broadcast the status but seems to resolve issue on page refresh where auth status is lost in
// header component resulting in authed user nav links disappearing despite the fact user is still logged in
Simply put, anyone can open up the browser local storage and insert a random string with the "auth_token" key and they'll be able to see everything admin-related in the UI (even though they will fail on API requests).
Can someone suggest a better flow for this? Or is the only option to send a "log in request" to the API, whenever an admin page is "opened"?
P.S. I am relatively new to the authentication schemes front, should JWT perhaps not be used for client-side content validation?
Considering JWT best practices, all your validations should be done in your back-end, since any validation coded in your web app could be read by any of your clients, resulting in a huge security flaw: anyone would know how to create a valid JWT for your application.
Is it a big problem to be possible to see your admin-related UI, even without any data? Considering that all of the routes which can return sensitive data are protected by JWT authorization, if a user access any pages or parts of your UI which require data, they would trigger a request to retrieve it, which would probably return a 401 (Unauthorized) HTTP status, or similar. A common front-end practice in these situations is to erase client user data, and redirect to a login page.
So, a typical flow would be:
User inserts a fake access token into their storage
User opens an admin page/ui which uses sensitive data in any way (showing, using for any internal logic, etc)
Web app does a request to the API requesting data
API returns a response which will be interpreted as an authorization error
Web app receive the API response, erase user access token and redirect them to its login page
In most cases, this entire flow will happen fast enough to block your user to further interact and explore your web app.
Would be better if you provide more information about your scenario, so anyone could understand if your worries are something that needs to be considered and truly solved. However, in most cases, the behavior above is accepted.
I have a web site with following functionality: An user comes to www.mysite.com/page.php. Javascript on that page makes ajax API call to www.mysite.com/api.php and shows results on the same page www.mysite.com/page.php
I'm afraid of situation where somebody starts to use my api.php on own software, because using www.mysite.com/api.php costs me a bit money. Therefore I want that only users that have visited the page www.mysite.com/page.php can get valid results from www.mysite.com/api.php . There won't be any way for users to log in to my web site.
What would be the right way to do this? I guess I could start a session when an user comes to page.php and then somehow maybe first check on api.php that a session with valid session id exists?
If you just want the user to visit page.php before using api.php, the session is the way to go.
Typically, if you want a "soft" protection you use the POST verb to get results from your site. Then, if the user goes the the URL in their browser and just types the api.php call they will not get a result. This doesn't protect your site but it keeps search engines away from that url reasonably well and accidental browsing to it.
Otherwise, there are lots of authentication plugins for php.
http://www.homeandlearn.co.uk/php/php14p1.html for example.
You can check the request in several ways such as Token validation, Session validation or even by Server 'HTTP_REFERER' variable
Check the referrer with $_SERVER['HTTP_REFERER'] if its outside the domain block it.
Beware that people can alter their REFERER so its not secure.
Another better solution might be a CAPTCHA like this one from google https://www.google.com/recaptcha/intro/index.html
Cookies, HTTP-Referer, additional POST-Data or some form data, that you send in an hidden input field aren't secure enough to be sure, that the user comes from your site.
Everything of it can be easily changed by user, by modifying the http-headerdata (or if you use cookies, by changing the cookie-file on the client machine).
I would prefer the PHP-Session combined with an good protection against bots (ex. a Honeypot), because it's not so easy to hi-jack, if you use them properly.
Please note: If there is a bot especially for your site, you lost anyway. So there isn't a 100% protection.
I want to send a request (or any response or notification) from the server side to the browser without a browser request to the server.
I use JSP and the Struts framework in my Java EE application. When some one is on my page, and when some processing in done in my action class/servlets, I want to send a notification or message or request to the browser to be appeared on the page. Here the relevant page cannot be refreshed or reloaded and it may be handled on the browser side with javascript or jquery. I use Http.
Is there a way to do this?
EDIT: Example: The application is an online inventory system. An Admin has logged in. If one of the items is out of stock, the admin should be notified saying that that particular item is out of stock without the admin searching the stores and do nothing (when he is on his account page, a pop up may be displayed to him).
I am not so sure what you meant but according to my understanding you can do this.I guess Comet is the thing you are looking for.Comet is the technique where in server pushes the data to the browser.
Try Pushlet concept which might address your requirement
http://www.javaworld.com/jw-03-2000/jw-03-pushlet.html
I have two web pages that I am trying to send information between. One is the login page that takes in the users information and calls a web-service to determine if the user is authenticated. Upon ensuring authentication I want to redirect to my other web page with some way of telling that the user has logged in and is authenticated.
I know that javascript has window.location = url but this does not forward the authentication header or anything else as far as I know. Is there a way to redirect with authentication headers or other way to tell the user is authenticated?
Thanks for any help.
There is not a standard method for doing that since javascript is a client side language but you have some alternative low-security solutions.Sessions are not necessary to function a client side language also for the better security you better stick to PHP or some other server side language.Because javascript can be easily skipped and it might put you in a trouble.
Just use your authenticated language for session and header functions also.
Hope this helped,
Regards.
According to the Facebook API documentation, most of the work is handled through javascript.
That means that all the processing is done, and then the front end checks if the user is connected to Facebook/authorized. right?
My question is:
Suppose a user goes to my site for the first time ever.
He clicks on "facebook connect". The javascript verifies him as authentic, and it "redirects" to another page on my server. From then on, how do I know that the user is actually authenticated to my website, since everything is done on frontend?
I think this is correct, but aren't there some security issues..:
-After user clicks Login, Facebook redirects to a page on my site. AND they also create a cookie with a specific "Facebook ID" that is retrieved only from this user. My backened will "read" the cookie and grab that ID...and then associate it to my userID.
If that is correct...then it doesn't make sense. What if people steal other people's "facebook ID" and then forge the cookie? And then my backend sees the cookie and thinks it's the real user...?
Am I confused? If I am confused, please help me re-organize and tell me how it's like.
Facebook Connect uses a clever (or insane, depending on your point of view) hack to achieve cross-site communication between your site and Facebook's authentication system from within the browser.
The way it works is as follows:
Your site includes a very simple static HTML file, known as the cross-domain communications channel. This file is called xd_receiver.htm in the FB docs, but it can be named anything you like.
Your site's login page includes a reference to the Javascript library hosted on Facebook's server.
When a user logs in via the "Connect" button, it calls a function in Facebook's JS API which pops up a login dialog. This login box has an invisible iframe in which the cross-domain communications file is loaded.
The user fills out the form and submits it, posting the form to Facebook.
Facebook checks the login. If it's successful, it communicates this to your site. Here's where that cross-domain stuff comes in:
Because of cross-domain security policies, Facebook's login window can not inspect the DOM tree for documents hosted on your server. But the login window can update the src element of any iframe within it, and this is used to communicate with the cross-domain communications file hosted on your page.
When the cross-domain communications file receives a communication indicating that the login was successful, it uses Javascript to set some cookies containing the user's ID and session. Since this file lives on your server, those cookies have your domain and your backend can receive them.
Any further communication in Facebook's direction can be accomplished by inserting another nested iframe in the other iframe -- this second-level iframe lives on Facebook's server instead of yours.
The cookies are secure (in theory) because the data is signed with the secret key that Facebook generated for you when you signed up for the developer program. The JS library uses your public key (the "API key") to validate the cookies.
Theoretically, Facebook's Javascript library handles this all automatically once you've set everything up. In practice, I've found it doesn't always work exactly smoothly.
For a more detailed explanation of the mechanics of cross-domain communication using iframes, see this article from MSDN.
Please someone correct me if I'm wrong - as I am also trying to figure all this stuff out myself. My understanding with the security of the cookies is that there is also a cookie which is a special signature cookie. This cookie is created by combining the data of the other cookies, adding your application secret that only you and FB know, and the result MD5-Hashed. You can then test this hash server-side, which could not easily be duplicated by a hacker, to make sure the data can be trusted as coming from FB.
A more charming explaination can be found here - scroll about halfway down the page.
Same issues here, and I think Scott is closer to the solution.
Also Im using "http://developers.facebook.com/docs/?u=facebook.jslib-alpha.FB.init" there open source js framework. So things are a little different.
For me, via the opensource js framework, facebook provides and sets a session on my site with a signature. So what I am thinking is to recreate that signature on my side. - if they both match then the user is who he says he is.
So basically if a user wanted to save something to my database, grab the session signature set up by facebook and recreate that signature with php and validate it against the one facebook gave me?
if($_SESSION['facebookSignature'] == reGeneratedSignature){
// save to database
}else{
// go away I don't trust you
}
But how do you regenerate that signature? preferably without making more calls to Facebook?