I am developing a web application that runs on Google App Engine. It has some HTTP GET methods to request data. I do not want any random web request to be able to receive data from the server. Only my web app (i.e., requests originating from my website) plus any mobile or desktop clients I develop should be able to request data from the server. How is this done? Note I am not talking about username/password authorization here. I am asking how to make sure that the client app who is making the request is authorized. Otherwise, anyone can make their client (e.g., a C# console app) and start using my data. I think the question is similar to this one: How to authenticate client application for trust of messages sent from it
Short answer is, you can't.
https://security.stackexchange.com/questions/826/how-can-i-securely-authenticate-the-client-application-sending-me-data
Long answer is, you can make it difficult for hackers. Usually this works by embedding a key in the application, obfuscating it, and obfuscating the code for getting the key. This doesn't make it impossible for someone to find the key, just harder.
One of the stronger consumer systems out there is Microsoft's Silverlight DRM, you might want to investigate how that work: http://www.iis.net/learn/media/iis-media-services/content-protection-in-silverlight
You can use 3scale. It provides authorization , stats, control of the requests made to your GAE application
https://code.google.com/p/appspotimage/wiki/APICreationArticle
Encrypt the request via your client. Decrypt at the server level. If decryption is successful and the request is well-formed, its authorized.
Otherwise, its an unauthorized client.
The catch?
Someone will be able to make an unauthorized client after they solve your method of encryption. This would most likely be after decompiling your program and trudging through obfuscated code, making it harder/time consuming, but it is still possible.
Related
I have a JAX-RS application deployed under tomcat and a mobile app.
I would like to know how to make the webservice usable only by the mobile application, in other words, allow access only for a given application
When a request comes in across the internet, there's not really a safe way to be sure what application sent the request. Applications can identify themselves however they want. You could, if you want, attempt to hide credentials in your application, somehow, and have it log in with those credentials. But if anyone discovers those credentials, they can write a program that uses them to pretend to the your application. The problem is that you cannot count on any control over the client system. The client system can always be altered to pretend to be something it is not.
From my perspective, you can add username/encrypted password in the invoke request, and then compare it with the ones saved in the server side
If you really want to, you could implement some form of cryptography. For example, the JAX-RS service can send a 401 forbidden and provide a nonce for the client to sign with its private key, and then send back to the server in the Authorization header. Otherwise, stick to HTTP authentication. If you are communicating via HTTPS, you should be fine with basic auth.
I am designing a REST API in Laravel to be used with my ios app. Currently I am stuck on the following point: How to secure my REST API to allow access to ONLY my ios app?
I have read about HTTP Basic Authentication, HMAC, oAuth2.
1) Basic authentication requires SSL and it requires you to send the username:password on every api call.
But this doesn't stop others from using the API from other applications assuming they post their login credentials to the endpoints?
2) I understand the HMAC method and how the client & server both know of a Public & Private key. The private key is encrypted along with the request and other data. The public key is sent in the headers. When the server receives the request it detects the public key in the headers and associates it with a private key in the DB. It then recalculates the hash and checks if it matches. So, I have the following questions:
How does a newly registered user get the private key to be stored in the IOS app if the private key is not to be sent over the wire?
Is this more geared towards applications that will utilize your app? I normally see this in a API dashboard like Instagram & Facebook where they give you an app secret key, right?
3) oAuth2 - To me this seems more like allowing people to login to my app utilizing another API. For ex, allowing users to login to my app with FB and allowing my API to utilize Facebooks data? I am not really needing to do this at the moment.
am I misunderstanding this?
It sort of sounds like I need to incorporate something similar to the HMAC method by granting my IOS APP a private key where I store this in my IOS APP code. When a request is ran from within the ios app i pass along a hash with the private key and other data and then when the request is received on the server I detect if the request came from a user within the app by recalculating the hash. I have no idea if this is secure & I would assume it isn't?
What knowledge am I lacking? I am so confused at the moment that writing this question was a big struggle. I will revise it as soon as things become more clear.
1.
You're right, this doesn't prevent non-approved clients.
2.
This isn't really a way to prevent unapproved clients, it's more about verifying that a message isn't tampered with over the wire.
3.
You're understanding oAuth correctly, it's about authenticating clients to use your API in a specific way as well as limiting permissions.
It's not really possible to lock down your API so only a specific client can use it, because there's no way to verify who the client really is. Additionally, any form of authentication or verification done on the client side can eventually be be reverse engineered, and then can be sent to the server as an 'approved' client.
Something like this could be done with a token. The server sends a token the the client, the client performs some known operation on the token, such as salting and hashing, with a known salt and hash operation, then returning the token to prove that the client is a real one.
The problem is, if someone reverse engineers your client, they can determine what that operation is, and then create their own client which authenticates the same way. Any form of client side authentication isn't true security and can't be trusted.
Another way this is broken, is if someone can MiTM your request. The request could be captured and modified before it reaches the server, and there's not really any ways to prevent that from happening aside from using SSL, which can be broken with something like SSLStrip.
Any attempt to prevent a non-approved client is basically security through obscurity, since there isn't a provably secure way to do what you're asking.
The best way to protect your API isn't by limiting which clients can access it, but by making it secure already. Best practices would include forcing SSL, only send the password once and use tokens for authentication from then on, etc.
Introduction
Hello,
I'm that typical programmer that know how to use api, but tend to realize that I should know more about using api, raises my shoulders and keep using what I know.
I know how to troubleshoot api (even though I hate doing it) and I know that most of the time it's a really good idea to heavily validate the data being sent to my own api, in case someone else likes to send their own values instead of intended.
Question
One thing I do can't grasp though is why is it considered necessary use SSL/https on api calls between 2 sites? For instance; my site does a curl to an api on another site. There is no user nor browser between the call of these 2 sites.
Perhaps I've missed some common rule in web practice, but where's the middle-man which can joink sent information at a situation like this?
I understand that a malicious software can collect your personal data when it's sent through your browser though.
The question is basicly; why is there a need for SSL when doings calls without any private user directly invovled in the call?
Extra thoughts
If it's the case where I've missed some really big information regarding api, let me know.
Thanks for your time!
A browser/user doesn't have to be directly involved to sniff network packets. Using cURL on your web server is the same as using a browser from your home computer except for the fact that the request is coming from a different computer/network and there is no GUI. Someone can still be listening somewhere in between the computer executing cURL (client) and the server that the API resides on (server).
It's best to require SSL for API calls because APIs usually require a key that grants access to the API. If this request is sent in plain text, anyone sniffing packets in between the server and client can see this API key and start using it. On the other hand, if the API request is set via SSL it will be encrypted and much more difficult to figure out.
I'm working on a Windows Phone 7 application, and to go with it I will need a web service to send out live tile push notifications. I will save the clients URI channel in a database and every hour or so I will send out the correct live tile to all the subscribed clients. I will not be sending out any sensitive data to the clients, nor do the clients send any data to the service save for their channel URI, and I've made sure to protect the database against any sql-injections.
The exposed methods are for registering and unregistering a client, as well as sending the correct live tile to a client that requests it.
Given this information, does anyone have any recommendations on how I should secure the service, or is security even needed to begin with in this case?
Thanks!
EDIT:
Thanks for the answers! My peers decided to not use any security at all though, other than purging faulty requests from the database, since the scope of the application is quite limited and no sensitive data is being transmitted. Let's hope it won't bite us in our behinds later on, eh!
Unfortunately the best solution to this problem (at the moment) is to generate a hash in your app and use that to verify the data is really coming from your app. Obviously you'll need to obfuscate tyour code if doing this.
This is the best you can do without any authentication against the backend.
If you can, have the users register and authenticate with the backend and then tie this authentication token to the ANID of the device and do everything over SSL.
Unfortunately, currenlty, security of services and prevention of spoffed requests is quite tricky with WP7 without requiring a login to the backend.
Make sure you secure your channel to your backend service with SSL. This way the data you send to the server such as a the ChannelUri will be secure.
Building a hash into your application isnt security. People could get your XAP and decompile it to get the hash.
IMHO you are better to ensure your ChannelUri (unique to your app and not "stored" in your XAP anywhere) is secured when you send it.
On the backend just make sure you purge records that fail when you try and send it a tile notification. This will get rid of any records entered by non-phone parties.
Bottom line is that you need a login infrastructure with your backend to properly ensure only valid users are using your service.
I have REST services that I was planning on protecting with Windows Integrated Authentication (NTLM), as it should only be accessible to those internal to the company, and it will end up being on a website that is accessible by the public.
But, then I thought about mobile applications and I realized that Android, for example, won't be able to pass the credentials needed, so now I am stuck on how to protect it.
This is written in WCF 4.0, and my thought was to get the credentials, then determine who the user is and then check if they can use the GET request and see the data.
I don't want to force the user to pass passwords, as this will then be in the IIS log, and so is a security hole.
My present concern is for the GET request, as POST will be handled by the same method I expect.
One solution, which I don't think is a good option, would be to have them log into Sharepoint, then accept only forwarded reqests from Sharepoint.
Another approach would be to put my SSO solution in front of these services, which would then force people to log in if they don't have credentials, so the authentication would be done by SSO, and since the web service directory could be a subdirectory of the main SSO page, then I could decrypt the cookie and get the username that way, but, that would be annoying for the mobile users, which would include the senior management.
So, what is a way to secure a REST service so that it is known whom is making the request so that authorization decisions can be made, and will work for iphones, android and blackberry smartphones.
I have the same problem so let me give you the details and would also appreciate feedback. Since you are using an internal system you have one extra option that I have listed.
My first option isn't perfect, yes it could be hacked but still - better than nothing. With each request you pass the device's unique identifier along with a hash. You generate the hash using a salt embedded in the application along with the id. On the server you match the incoming hash with one you generate at the server, with the passed unique identifier. If someone "roots" their device, and is smart enough they could find the salt - you can obscure it further but ultimately it could be stolen. Also, I keep all requests on SSL to just help hide the process. My "enhancement" to this process is to pass back new salts after each request. New devices get 1 chance to obtain the next salt or get locked out ... not sure about that step yet.
Now another approach, is to have the user enter a "salt" or username and password only an internal user would know - the device obtains a token and then passes it (on SSL) with each request. Nobody outside your company could obtain that so this is probably best. I can't use this since my app is in the app store.
Hope that helps! Let us all know if you ever found a good solution.
My current solution, in order to protect data in the system, is to force people to first log in to the application that the REST services support (our learning management system), as I have written an SSO solution that will write out a cookie with encrypted data.
Then, the REST service will look for that cookie, which disappears when you close the browser, and I don't care if the cookie is expired, I just need the username from it, then I can look in a config file to see if that user is allowed to use that REST service.
This isn't ideal, and what I want to do is redirect through the SSO code, and have it then send the person back to the REST service, but that is not as simple as I hoped.
My SSO code has lots of redirects, and will redirect someone to a spot they pick in the learning management system, I just need to get it to work with the other application.