I am building an api for my first app, which consists of both a web based app grafted onto an existing website, and a mobile Cordova app. I am still something of a noob to concepts of authentication and security, so I am just trying to get an idea of the basics, and want to make sure I'm not missing something obvious. So far here's what I've got:
The server currently is non-ssl. I am registering users by making a POST request to the API with the plain text username and password appended as form data. An api key is then generated for the user which is returned to them, which they will then use for subsequent requests by including it in the header.
OK, so... given that this app isn't handling particularly sensitive data, and I only really care about basic-level security, is this acceptable? Is there any obvious and simple step I could take to improve the above setup?
Thanks.
Related
Actually I have an API called update user data, it is called when the user moves from one page to another page. If the user copy the API from console and post in postman, user should not able to update the user data. How to provide security or implement feature to not to update data through post man.
You really can't.
You can slightly make it harder using some CSRF protection, but that's just it - it will only make it a bit harder, but not stop anyone determined.
If your API is public, you should be ready for your users to have custom client apps.
I am a bit confused by your question. Because PostMan or other applications like Fiddler are created to make the job easier for developers during development. anyhow if you are concern about who makes call to your webpage, you can make your API private and just give access to the user that have the right credentials. You can also read about CSRF or XSS.
I have been asked to use ember for front end and java rest services as the backend. I am trying to figure out how to manage session for a particular user.
i know there are couple of options like storing in the local store, cookie but they are error prone as some users might disable those features. I want to know what is the preferred approach in normal enterprise apps.
Mine app is simple 15 page app. i need to capture user, and some profile details.
Session are usually more of server side part. You have to just make sure whether the provided session is available or not for every transformed route and request. There is a library which takes care of authentication and authorization in ember https://github.com/simplabs/ember-simple-auth.
We intend to develop rest based api. I explored the topic but it seems, you can secure api when your client is an app (So there are many ways, public key - private key etc). What about websites / mobile website, if we are accessing rest based api in website which do not use any login for accessing contents ( login would be optional ) then how could we restrict other people from accessing rest based api ?
Does it make sense using Oauth2.0 ? I don't have clear idea of that.
More clear question could be ,How can we secure get or post request exposed over web for the website which doesn't use any login ?
If it's simple get request or post request , which will return you json data on specific input, now i have mobile website , who will access those data using get request or post request to fetch data. Well, some else can also access it , problem is i am not using Login, user can access data directly. But how can we restrict other people from accessing that data.
What do you think is the difference between securing a website that is not using REST vs one that is using REST API?
OAuth provides authorisation capabilities for your site, in a REST architecture this means a user of the mobile application will have to provide their credentials before being allowed to access the resource. The application can then decide on if that user has access to the requested resource. However you've said your website doesn't need use authorisation.
You can use certificates however good luck managing the certificate for each client. My take on it is for your explanation you don't need to secure your website because you will never be able to manage a trust relationship between the client and the server. There are some options though:
You build your own client application that you ship out to people which can verify itself with the server using a packaged certificate with the client. E.g. iOS has this kind of feature if you build for that device.
You provide a capability to download a certificate that is 'installed' in the browser and used when communicating to your REST API
Use something like a handshaking protocol so when a client wants to make the first request it says; 'hi I'm a client can we chat?' And the server responds with 'yes for the next X minutes we can however make sure you send me this key everytime you tell me something YYYYYY' (you can use something like SecureUDID or equivalent for other devices than iOS).
There are probably others but you get the basic idea. Again in my opinion if your resource doesn't need authorisation then you don't need to secure that REST API. Can I ask what kind of data are you exposing via this REST API or functionality your providing? That might help provide a better answer.
You want authorization: only some agents (mobile clients) and/or users should be allowed to access those APIs.
To solve that problem, you need identification: a way for the server to tell who is who (or what), so the right decision can be made.
There are many different way to provide some form of identification, depending how much you care about security.
The simplest is a user agent string, specific to your mobile clients. But it can be faked easily. Slightly harder to fake are client based 'secrets' - embed some kind of secret or key in your mobile client code. You can make it really complicated and secret, but as ramsinb pointed out, you can't get security this way as it would require you to be able to guarantee that the secret you're shipping with the client (wether it's code, algorithm or any other fancy construct) can't be compromised or reverse engineered. Not happening when you don't control the client.
From there, 3 choices:
Security isn't really required, don't bother
Security isn't really required, but you still want to limit access to your API to either legit users/agents or people ready to invest some time hacking your protection - go with a specific user agent or a client embedded secret - don't invest much into it as it won't block people who really want access to get it anyway
Security IS required - and then I don't think there is a way around authentication, wether it's login/password, user specific (device specific?) keys, OpenID, etc... No matter what, you'll have to add to the user burden to some extent, although you can limit that burden by allowing authentication to persist (cookies, storage....)
I have a Facebook canvas app. I am using the JS SDK to authenticate the user on the browser-side and request various information via FB.api (e.g. name, friends, etc.).
I also want to persist some additional user information (not held on Facebook) to the database on my server by making an ajax call:
{ userFavouriteColour: "Red" }
To save this on the server and associate with the correct user, I need to know the Facebook uid and this presents a problem. How do I pass the uid from the client to the server.
Option 1: Add uid to the ajax request:
{ uid: "1234567890",
userFavouriteColour: "Red" }
This is obviously no good. It would be trivial for anyone to make an ajax request to my web service using someone else's Facebook Id and change their favourite colour.
Option 2: On the server, extract the uid from a cookie:
Is this even possible? I have read that Facebook sets a cookie containing the uid and access token but do I have access to this cookie on my domain? More importantly, can I securely extract the uid form the cookie or is this open to spoofing just like option 1.
Option 3: User server-side authentication on the server:
I could use the server-side authentication to validate the user identity on my server. But will this work if I am already using client-side authentication on the browser? Will I end up with two different access tokens? I would like to make FB.api requests from the browser so I need the access token on the client (not just on the server).
This must be a very common scenario so I think I'm missing something fundamental. I have read a lot of the Facebook documentation (various authentication flows, access tokens, signed_request, etc.) and many posts on SO, but I still don't understand how client-side authentication and server-side authentication play nicely together.
In short, I want to know the user's identity on the server but still make requests to the Facebook api from the client browser?
(I am using ASP.NET and the Facebook C# SDK on the server)
EDIT: Added bounty. I was hoping to get a more deifnitive, official recommendation on how to handle this situation, or even an example. As said, I have already read a lot of the official FB docs on authentication flows but I still can't find anything definitive on how client-side and server-side authentication work together.
Option 1:
The easiest way I can think of is to include the accessToken in JS and pass it with the ajax call.
Option 2:
Using the same as option 1, but instead of sending just the accessToken, send the signedRequest.
On the server side you can decode it using (TryParseSignedRequest method) which will give you the UserID :-)
Note: signedRequest is encrypted with the application Secret. you are the only one who should know it, so you are safe on that end.
Disclaimer:
I have no coding experience in C#, but a little search in google gave me this:
Facebook C# SDK for ASP.NET
Making AJAX Requests with the Facebook C# SDK
It's very simple actually.
When the user loads you app use the server side authentication, get the access token and load the user data by issuing an api request from the server.
On the server side you'll have everything you need and it's sandboxed.
When the page renders for the user, using the js sdk get the user authentication data, you should be able to use FB.getLoginStatus since the user already went through the server side authentication.
Now on the client side you also have an access token which you can use to get the user data from the graph api.
The two tokens will be different, and will also have different expiration, but that should not be a problem, both token should work properly as you'd expect them to.
Since both sides have their own token and a way to make requests to the api, there's no need to send any fb data between them.
So the 3rd option you mentioned, to me, sounds the best, and it's really simple to implement that too.
Edit
All facebook SDKs are just wrappers for http request since the entire fb api is made on http requests.
The SDKs just give you easy and shorter access to the data with out the need to build the url yourself (with all the different possible parameters), make the request and parse the response.
To be completely honest, I think that stop providing a way for the C# SDK to support server side authentication is a very bad decision.
What's the point in providing a SDK which does not implement the entire api?
The best answer to your question, from my experience, is to use both server and client side authentication, and since the C# SDK does not support it, my advice to you is to create your own SDK.
It's not complicated at all, I already implemented it for python and java (twice), and since you'll be developing it for your own needs it can be tailored for your exact needs, unlike a public SDK which should support all possible options.
2nd Edit
There's no need to create a completely new SDK, you can just "extend" the ones you're using and add the missing parts that you need, like sever side authentication support.
I don't know if it's language specific but using both server-side and client-side authentication does no harm.
You can work on option 2 but yes, that will be also vulnerable to spoofing.
Doing option 3, you will be having a single access token for that user session, so that would be the best choice according to me since you always have chance of spoofing when passing user information from client side.
I had exactly the same question recently. It's option 2. Check this post from the Facebook blog.
To be honest I am not enough of a hacker to know if you could spoof the UID in the cookie, but this seems to be the 'official' way to do it.
EDIT: to the other question under option 2, yes, I believe you have to access this cookie on your domain.
I'm developing a small CMS in PHP and we're putting on social integration.
The content is changed by a single administrator who as right for publishing news, events and so on...
I'd to add this feature, when the admin publishes something it's already posted on facebook wall. I'm not very familiar with facebook php SDK, and i'm a little bit confused about it.
If (make it an example) 10 different sites are using my CMS, do I have to create 10 different facebook application? (let's assume the 10 websites are all in different domains and servers)
2nd, is there a way for authenticating with just PHP (something like sending username&password directly) so that the user does not need to be logged on facebook?
thanks
You might want to break up your question in to smaller understandable units. Its very difficult to understand what you are driving at.
My understanding of your problem could be minimal, but here goes...
1_ No you do not create 10 different facebook application. Create a single facebook application and make it a service entry point. So that all your cms sites could talk to this one site to interact with facebook. ( A REST service layer).
2_ Facebook api does not support username and password authentication. They only support oauth2.0. Although Oauth is not trivial, but since they have provided library for that, implementing authentication is pretty trivial.
Please read up on http://developers.facebook.com/docs/.
Its really easy and straight forward and well explained.
Your question is so vague and extensive that it cannot be answered well here.
If you experience any specific implementation problems, this is the right place.
However to answer atleast a part of your question:
The most powerful tool when working with facebook applications is the Graph API.
Its principle is very simple. You can do almonst any action on behalf of any user or application. You have to generate a token first that identifies the user and the proper permissions. Those tokens can be made "permanent" so you can do background tasks. Usually they are only active a very short time so you can perform actions while interacting with the user. The process of generating tokens involves the user so that he/she has to confirm the privileges you are asking for.
For websites that publish something automatically you would probably generate a permanent token one time that is active as long as you remove the app in your privacy settings.
Basically yuo can work with any application on any website. There is no limitation. However there are two ways of generating tokens. One involves on an additional request and one is done client side, which is bound to one domain oyu specifiedin your apps settings.
Addendum:
#ArtoAle
you are right about every app beeing assighend to exactly one domain. however once you obtained a valid token it doesnt matter from where or who you use it within the graph api.
let me expalin this a little bit:
it would make no sense since it is you doing the request. there is no such thing as "where the request is coming from". of course there is the "referer" header information, but it can be freely specified and is not used in any context of this.
the domain you enter in your apps settings only restricts where facebook redirects the user to.
why?
this ensures that some bad guy cannot set up a website on any domain and let the user authorize an app and get an access token with YOUR application.
so this setting ensures that the user and the access token are redirected back to YOUR site and not to another bad site.
but there is an alternative. if you use the control flow for desktop applications you don't get an access token right after the user has been redirected back. you get a temporary SESSION-TOKEN that you can EXCCHANGE for an access token. this exchange is done server side over the REST api and requires your application secret. So at this point it is ensured that it is YOU who gets the token.
This method can be done on any domain or in case of desktop applications on no domain at all.
This is a quote from the faceboo docs:
To convert sessions, send a POST
request to
https://graph.facebook.com/oauth/exchange_sessions
with a comma-separated list of
sessions you want to convert:
curl client_id=your_app_id \
-F client_secret=your_app_secret \
-F sessions=2.DbavCpzL6Yc_XGEI0Ip9GA__.3600.1271649600-12345,2.aBdC...
\
https://graph.facebook.com/oauth/exchange_sessions
The response from the request is a
JSON array of OAuth access tokens in
the same order as the sessions given:
[ {
"access_token": "...",
"expires": 1271649600, }, ... ]
However you don't need this method as its a bit more complex. For your use case i would suggest using a central point of authorization.
So you would specify your ONE domain as a redirect url. This domain is than SHARED between your websites. there you can obtain the fully valid access token and seamlessly redirect the user back to your specific project website and pass along the access token.
This way you can use the traditional easy authentication flow that is probably also more future proof.
The fact remains. Once the access token is generated you can perform any action from any domain, there is no difference as ther is literally no "domain" where the request is coming from (see above).
apart from that, if you want some nice javascript features to work - like the comments box or like button, you need to setup up open graph tags correctly.
if you have some implementation problems or as you said "domain errors" please describe them more clearly, include the steps you made and if possible an error message.