How does the appsecret_proof provide better security? - facebook

The Graph API offers something called an appsecret_proof but how is it any less compromisable than the access token? It's the HMAC of the access token and the secret, so it's going to be the same for each API call anyway. Since both the appsecret_proof and the access code are needed for each API call, they could be sniffed together. So how does it make things more secure? What is the rationale?

Let´s say someone hacks your App and gets an Access Token of another User. Without appsecret_proof, he would be able to use the Access Token for something malicious. With appsecret_proof, the Access Token alone is useless for anyone who gets it. You can only use the Access Token with the generated appsecret_proof, so you would need the App Secret too - and the App Secret should only be used on the server anyway. It´s called "Secret" for a reason :)
More information: https://developers.facebook.com/docs/graph-api/securing-requests
Example: Extended Page Tokens are valid forever, so they usually get stored in a database. If some user gets access to one of those, he may be able to publish stuff to the Page wall (if the Token includes publish_actions). appsecret_proof makes sure you can only use the Page Token on your server with the App Secret. So the hacker would have to get the Page Token AND he would need to somehow get your App Secret too.

Related

How can I get a permanent access token to post to a Facebook page that I own?

I am the administrator of a Facebook Page. I am building a web app which, under certain circumstances, will post on Facebook as that Page.
With most APIs, I would just get an API key, and supply that when connecting to the API from my app. But Facebook expects an access token instead of an API key. (Specifically, in this case, it needs a "page access token".)
I am trying to figure out how to get a page access token that will be as permanent as possible.
After jumping through a bunch of esoteric, undocumented hoops (see here and here) in order to get a token that wouldn't expire, I had this working. When I ran the token through Facebook's Access Token Debugger, the "Expires" field read "Never". All was good in the world.
But, the next day, my token became invalid anyway. The Access Token Debugger, and my app's calls to Facebook's PHP SDK, both started returning this error:
Error validating access token: Session does not match current stored session. This may be because the user changed the password since the time the session was created or Facebook has changed the session for security reasons.
It seems that a token can become invalid for a variety of reasons (but this article is five years old, so who knows – Facebook changes things every two weeks). I had not changed my password. (I might have logged out of Facebook, though.) Facebook offers no specifics about why this particular token might have become invalid.
I've also seen a few references to a permission called offline_access, but Facebook seems to have removed this.
I suppose my question is twofold:
In general, I've found Facebook token authentication to be incredibly brittle when calling the Facebook API from the server. The token system seems to be designed mainly to allow other users to grant (or revoke) various kinds of account access to my apps. But that's not what I'm doing – I'm trying to get a token that will let me post to a page that I own. And for that scenario, Facebook's aggressive invalidation of tokens becomes a serious liability. I can't launch my app if my access token (and therefore my Facebook integration) could randomly stop working at any moment, requiring me to generate a new token and update the app. This seems absurd. Is there an alternative method of authenticating to Facebook for my purposes?
If a page access token is, in fact, the best way to authenticate my app to Facebook in order to post as my Page: how can I ensure that my token doesn't spontaneously become invalid?
I hate developing for Facebook :/ Thanks for any insight you can offer.
Extended Page Tokens are valid forever. They only get invalidated if you change your password or if you change the App Secret of your App. There´s really no magic in it, checking if the Token is still valid is obviously not a bad idea but that´s up to you. For example, you can send yourself an automated Email when there is an error using the Token, so you can refresh it. But it will really just happen if you change your password.
Links:
https://developers.facebook.com/docs/facebook-login/access-tokens
http://www.devils-heaven.com/facebook-access-tokens/

Where to request extended access token in Facebook App using PHP SDK

I need to get access to my user's information when they are offline and I understand that I need to use an extended access token which lasts 60 days. I have been looking at this SO post How to extend access token validity since offline_access deprecation and this says that I need to include the stated method in my base_facebook.php file and make a call to the method.
However, looking through my code there is no explicit request or use of access tokens anywhere so I'm unsure how to request an extended access token. This post Do I need to use access token in Facebook API? explains that using the PHP SDK the access token is automatically appended to the api requests, which would explain why I have never encountered access tokens so far.
So my question is how do I get the user to give an extended access token when they sign in using the PHP SDK method getExtendedAccessToken()?
EDIT: A key point here is that you can't seem to get an extended access token for your own app! I tried this with one of my test users and it worked fine! Another point to note is that the access token tool will only show by default the access tokens for the person who actually developed the app. To see the specifics of the access token for other users you need to go to the debugger part and input the access token there. Hope this helps.
If you haven't seen any references to access tokens, they are most likely being stored in session variables. You could try adding echo "<pre>";print_r($_SESSION);exit(0); to your code to see what is stored in the session. You would add it somewhere after you have already been logged in.
If you are calling getExtendedAccessToken() from the PHP SDK, then the access token returned will automatically be long lived. To retrieve it after they are directed back to your site, you can use the getAccessToken() method. You would then store the returned value, and use it when you want to make calls later with setAccessToken($stored_token) .
Hope that helps.

How do you generate an expired Facebook Access Token for testing?

We are trying to update our app and server to handle the upcoming Facebook offline_access deprecation. However, we're having trouble testing it since we can't find an easy way to generated an expired access token.
We've tried using the Graph API Tool to create an access token but change a character in it. However this just results in an invalid token instead of a valid expired token.
I'm shocked Facebook hasn't provided a way to do this to facilitate testing. So I'm just assuming I've missed some straightforward way to do this, so would appreciate a pointer from someone.
If you generate an access_token and then change your password, it will auto-expire the token.

Does a Facebook application's access token expire?

This is the access token associated with my Facebook application -- the thing that comes back from https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id=APP_ID&client_secret=APP_SECRET. Can I get this once from FB and save it away somewhere for future use, or do I need to refresh it on a regular basis?
Access Token Tool - Facebook Developers
App tokens do not expire and should be kept secret as they are related to your app secret.
I don't know for sure, but since the documentation does not state that you get back an expiration time for the access token, I guess that it's an educated guess that it does not expire.
But why does it matter? the application authentication process is much simpler than the one with users, so just save the token somewhere (db, memory) and then try an api call, if it fails just issue one call to obtain a new token, save that, and continue as usual.
If you want a token to manage a page, never-expiring token can be obtained by
Get user token
Exchange user token to long-living token (Valid for 30days)
Obtain a page token with this user token (This page token is not going to expire)
When you check the token you've got, check it on Debugger. You will now see 'Expires Never'.
Documentation is on Facebook Developers ,Scenario 5: Page Access Tokens
My app access token does not seem to have changed for just under a month. I do not know if it changes. For fun I just changed my app secret...
My app access token then immediately changed and when I try to use the old one I get a
HTTP 400 error with a message body...
{"error":{"message":"Invalid OAuth access token signature.","type":"OAuthException","code":190}}
My advice is save the access token and use it. Unless you get the message above in which case obtain a new one and use that. One thing that I have not checked yet is if you get the same result if the user access token (that you may be querying) has expired instead.
For each and every user token (which is what you're getting from your link), there is an expiration date. Take one of those tokens to https://developers.facebook.com/tools/debug and debug it. You will see that generally they expire within 60 minutes or so.
To extend that user token, call the exchange command (https://developers.facebook.com/docs/offline-access-deprecation/) to get it to become a 60 day token. That user token has to be still valid (not expired) to do this.

Decrypt OAuth 2.0 access token

Is it possible to decrypt Facebook's new OAuth 2.0 access_token ?
I need to somehow get user_id and app_id from the access_token.
PS:
I need to get the user_id and app_id ONLY from the access_token as Facebook Linter used to do.
As others have already pointed out, the access_token is a unique random string, so it cannot be decrypted as such. Also, we all know that the user_id and app_id are prerequesites to generate the token in the first place.
However, let's assume you stored your token(s) in a database and lost the associated user_id and app_id. In that case, it is a valid question on how to retrieve them having only the token at hand. If your token is still valid, this is possible. If it is expired, you're out of luck.
To retrieve the user_id, make a call to:
https://graph.facebook.com/me?fields=id&access_token=xxx
To retrieve the app_id, make a call to:
https://graph.facebook.com/app?fields=id&access_token=xxx
In both cases, the associated id's will be part of the JSON response, regardless of the access_token being an encrypted or unencrypted one.
Let's illustrate this with an example. Let's assume Mark Zuckerberg uses the Graph API Explorer to generate an access_token. Calling the /me endpoint gives you:
{
"id": "68310606562"
}
and calling the /app endpoint gives you:
{
"id": "145634995501895"
}
The ids you were looking for are part of the response.
Please note that this does not work with the access_token shown on https://developers.facebook.com/apps (not sure if this is a Facebook mistake or intentional). Please use the access_token that your app receives via OAuth.
If the access token is in the encrypted format, there's no programmatic way to determine the User ID and App ID.
I struggle to think of a legitimate way you could have come across an access token without already having those two pieces of information since presumably you know your own App ID and the User ID you stored the access token against.
Nevertheless, assuming there's a legitimate use-case for this:
a call to /me?fields=id will return the user ID and/or you can use the debug tool at https://developers.facebook.com/tools/debug to debug the other properties of the access token
Generally you use the access_token to access other data from your application. So for example, your application would authenticate the user then use the access token to access other functions in FB's API, such as the graph:
https://graph.facebook.com/me?access_token=<access_token>
There is no public way of decrypting an access token to get the user id and app id. This is also very likely a massive breach of Facebook policy.
To get an access token in the first place you have to have access to the user and the app id anyway so you shouldn't need to do this. If you don't actually have access to the user or the app id then my guess would be you probably shouldn't even have their access token and have probably obtained it 'illegally'...
This is actually a very simple task, if you look closely at the access token itself. It consists of 3 segments, separated by a pipe character, |:
APP_ID|SOME_STUFF.NUMBER-USERID|SOME_MORE_STUFF
I'm not sure what SOME_STUFF, NUMBER, and SOME_MORE_STUFF are; presumably timestamps, signatures, or other encoded data that facebook uses to keep track of the access_token's validity and so on.
Unless you've obtained the acces_token in question by fowl means, I don't see a problem with being able to access the APP_ID and USER_ID from them (and neither does Facebook, apparently). So all I'll say on that is be responsible :)
The other thing to keep in mind is that this isn't a standard or anything, and is subject to change. So, watch out for that, too.
you don't have to decrypt accesstoken
As far as AppID is concerned,you should get it from facebook whn you make an app there,its your id to connect to facebook.
facebook sends the userId along with accesstoken..
just check your cookies in browser or in oauth case check entire string returned when request for acess token.
Are you sure you're talking about the Access Token here and not the signed request?
When you're Facebook Application is loaded you have a signed request object, which has the information I believe you are looking for (however if the user has not authorized your application their user ID will not be in the signed request, Facebook security)
The only way currently available is to use to Facebook Access Token Lint Tool.
You can consider to automate the process.