We are developing a webportal for our users. This webportal includes functions to find the users address. In the backend we use Java to provide a rest resource. Since we donĀ“t want the user to login we wonder, how to secure this rest resource so no one else can use it.
Any suggestions, keywords or best practises?
Well one simple solution if you want to avoid logged in users is to use a header param with a secret value then it is a bit harder to break into the system. This header is then sent from the webportal and read and validated by your backend system. And use https.
Related
I know that CAS is a single sign-on protocol for the web. Its purpose is to permit a user to access multiple applications while providing their credentials (such as userid and password) only once. It also allows web applications to authenticate users without gaining access to a user's security credentials, such as a password.
So, How can i use Jasig CAS server for android mobile applications ? some guidelines would be very useful!
Actually there exist two ways of doing this, each of them has some drawbacks.
1) Expose the REST interface (here you'll find a simple JAVA client that consumes them and a iOS sample how to use it on a mobile)
The problem here is that if somebody downloads your application from the store and checks the network traffic in it (or simply decomposes it) he'll find the calls you make. With this he could create an APP that does the same as you do, and log the passwords entered by the users (like a man-in-the-middle attack)
2) Open the real website in a web view inside your APP
You'll need to create a modle login page, or a responsive one on your CAS server so that it looks nice. Obviously even here somebody could theoretically copy your APP and the Website on your CAS fake both to look like your APP grab the username and password and send it in background to your CAS to give to the user the impression that everything went right but it is much more complex.
However even here u'll need to tweak the CAS; CAS is designed to accept a login for a service to which it would redirect after successful login. Therefore in this case you'll need to add a fake service to the CAS configuration and check if the webview will redirect to it. when that happens u'll find the TGT in the CASTGC cookie.
In our first APPs we used the REST version, but then as we use our CAS for websites too we wanted to restrict the REST access only to other servers in the facility, so we came up with the second solution which seems to fit better, but overall CAS seems not to be prepared for mobile APPs
You can set up CAS in order to expose REST service, this allow to validate credentials.
Documentation: https://wiki.jasig.org/display/casum/restful+api
What is the value of using a authentication token when using a REST webservice instead of sending a username, password over HTTPS/Encryption each time you make a request?
I understand that for instance OAUTH has some benefits cause you don't need to give away your password to 3rd parties, you can pass a token to trusted 3rd parties whom you dont want to share the username/password..etc
But other than this special benefits above which I certainly dont need in my case, why would I use tokens instead of sending username/password everytime.
This might be to make life easy for client, and it does not have to send the username/password everytime. Well ok but then now client has to remember my token and send me the token on every request. So instead of remembering/sending username/password now it will do the same for tokens! So client implementation code does not get any less.
So what is the real value here?
It really depends on the scenario - it's hard to tell without knowing more about the API - but usage of "authentication tokens" is far from universal, you're right that many APIs don't need (and don't use) them. Many APIs simply require an API key to be sent with every request (often via HTTPS to prevent it from being intercepted), or require an API key to identify the user and also a digital signature with a "secret key" to prove the user's identity (see When working with most APIs, why do they require two types of authentication, namely a key and a secret? ).
Usernames/passwords are not often used in public APIs because they're not flexible enough and do not provide enough "separation" between the user identity and the application identity. E.g. you register as a developer to use the Flickr API and create an iPhone app that uses that API - would you really want your developer username/password to be built into the app? What if you change your password later? What if you want to develop 5 apps and track usage for them separately and be able to shut off any app at any time without affecting the others?
However, for cases where you truly want to identify a human user only, not an appplication (e.g. a private API back-end that will only serve your own applications, not a public API), in most scenarios I don't see anything wrong with what you suggested, i.e. username/password over HTTPS with every request. Oh, by the way, auth tokens have the added advantage of being "restrictable" (can expire at a certain time, can be restricted to certain actions only, etc), but obviously this is only useful in very specific scenarios.
ALSO: As user "Dan" pointed out above, when designing an API that requires sending the username/password with every request (or with any request really, even if it's just the login request), be careful how you do it. If you're using a technique which browsers support by default (e.g. HTTP Basic Auth), you're preventing yourself from ever exposing the API safely to cross-domain users (i.e. most likely your API can never be safely called directly from the browser, i.e. from AJAX / Flash / Silverlight code).
This is a complex topic which can't be explained fully here, but just remember that if your API is relying on any security credentials that the browser can remember and then "silently" inject in every request (e.g. HTTP Basic Auth, cookies), then it's NOT safe to enable cross-domain access to that API using any cross-domain technique (CORS, JSONP, crossdomain.xml, etc).
The best way I can answer this is to point you to this page describing REST security. It belongs to the restlet wiki, not to Jersey, but it can be applied to Jersey as well as they are both REST implementations.
This is extracted from the link I provided:
"For the most resistance, the server can present the client with an application level authorization token, an opaque value that the server can verify belongs to the right authenticated user.
Such a token should be be difficult for a third party to calculate, e.g. a server-salted MD5 or SHA1 hash of the user's identification credential.
To defeat XSRF, this application-level token needs to be transmitted by means that the user-agent does not automatically return with each request. For example, it can be sent in the HTML of a form as a hidden field, and returned via POST in the encoded form entity."
My company is building a RESTful API that will return moderately sensitive information (i.e. financial information, but not account numbers). I have control over the RESTful API code/server and also am building the Android app. I've setup the API to use OAuth 2 with authorization code grant flow (with client ID and secret), and I auto-approve users without them having to approve the client since we own both client and provider. We use CAS for SSO and I am using this for the Authorization server as part of the OAuth 2 process when the user logs in to retrieve the token.
I am contemplating various ways to secure the data on the Android app. I've concluded that storing the client id and secret on the device is definitely not going to happen, but am thinking that storing the auth token might work, since it is only risk to the individual user (and really only if they happen to have a rooted phone).
Here are two options I have thought of. They both require me to have a sort of proxy server that is CAS protected, does the dance with the API server, and returns the auth token. This gets rid of the need for storing the client id and secret in the app code.
Here are what I've come up with:
1) Require the user to enter their password to access data each time they startup the App. This is definitely the most foolproof method. If this were done, I'd probably want to save the userID for convenience, but in that case couldn't use the CAS login (since it's web-based). I might be able to use a headless browser on the backend to log the user into CAS and retrieve the token based on what they enter in the Android form, but this seems hacky. Saving the userID is similar to what the Chase app does (if you happen to use this one) - it saves the userID but not your password between sessions.
2) Store the auth token on the Android device. This is a little less secure, but almost foolproof. When the user starts the app for the first time, open the webpage to the CAS login of the proxy server that returns the token (similar to https://developers.google.com/accounts/docs/MobileApps). After the user logs in and the token is returned to the app, encrypt it and store it private to the application. Also, use ProGuard to obfuscate the code, making the encryption algorithm more difficult to reverse engineer. I could also work in a token refresh, but I think this would be more of a false sense of security.
3) Don't use CAS but come up with another way to get an auth token for the service.
Any advice of how others have implemented similar scenarios (if it's been done)?
Thanks.
Well the reason why standards like OAuth are developed is that not everyone has to rethink the same attack vectors again and again. So most often it is your best choice to stick to something already available instead of baking your own thing.
The first problem with clients that are not capable of secretly storing data is that the user's data could be accessed by some attacker. As it is technically not possible to prevent this (code obfuscation won't help you against an expert attacker), the access token in OAuth 2 typically expires after short time and doesn't give an attacker full access (bounded by scope). Certainly you shouldn't store any refresh token on such a device.
The second problem is client impersonation. An attacker could steal your client secret and access your API in his own (maybe malicious) app. The user would still have to login there himself. The OAuth draft there requires the server to do everything it can to prevent this, but it is really hard.
The authorization server MUST authenticate the client whenever possible. If the authorization server cannot authenticate the client due to the client's nature, the authorization server MUST require the registration of any redirection URI used for receiving authorization responses, and SHOULD utilize other means to protect resource owners from such potentially malicious clients. For example, the authorization server can engage the resource owner to assist in identifying the client and its origin.
I think Google are the first to try another approach to authenticate a client on such devices, by checking the signature of the application, but they are not yet ready for prime time. If you want more insight into that approach, see my answer here.
For now, your best bet is to stay on the OAuth way, i.e. having the access token, client ID and client secrect (when using the authorization code grant flow) on the device, and configure your server to do additional checks. If you feel more secure obfuscating these, just do it, but always think of it as if these values were publicly available.
We need to design a secure web application. I would like to propose a session handling mechanism which does a challenge-response on every request, not only during login using a CRAM method.
The reason is to harden the web application against session hijacking (eg by CSRF) and replay or man-in-the-middle attacks.
Using a nonce is suggested in some places, but in our webapp it seems impractical, as asynchronous requests can go on, or the user could open new windows, hit the back button etc.
Idea: The client and the server have a shared secret (a previously established user password), every subsequent request does again a challenge/response based on that secret, e.g 'response = hash(challenge + hashedPassword)'. The server executes the request only if the response to the challenge matches. Much like during CRAM, but ongoing for every request.
The question: Is this a feasible idea? If so, it surely has been implemented or is even some standard? How would we use this in a java or php based webapp?
The question really comes down to what you want to achieve. If you want to fight CSRF-Attacks, a secret token in addition to the session key is your way to go. However, changing the token in every request will cause problems - not only will the back-button kill the session, but as one webpage usually contains a lot of asynchronously and parallel loaded data (images, css, javascript, etc.), your approach will not enable any additional data to be loaded afterwards, as each additional request will change the required token, thus killing the session.
You may get around this by embedding all resources into the page via BASE64 and other tricks, but that will seriously hinder your possibilities and may have compatibility issues with some browsers.
So, in the end, your approach will not add much security, but will most likely create a whole set of potential problems for your customers. I'd stick to one secret token per session in the URL to fight CSRF and concentrate on securing against other attacks like XSS and user-friendly security measures like two-factor authentication with a smartphone or something similar. After all, the user is the #1 attack vector nowadays.
Update (2012-06-14)
The token will not fight XSS-attacks, but it will defend against basic CSRF-attacks (e.g. by implanting a bogus url call in an image). I've actually had a situation at work today, where I needed to secure a get-request against user modification and worked up some code. The code may be also usable to secure static, session-timeout form- and link-tokens (right your problem).
The idea is to have a server-secret, which is used to generate a hash/AuthToken over data to secure. If a rogue javascript would try to change any of the given data, the AuthToken would not match. In my specific problem, I have one server authenticating a user and have to send his information over to a third party (username, mailaddress, name, etc.). This GET-Request might be easily changed by any user after authentication, so I have to authenticate the GET-Request-Parameters. By rerunning the AuthenticationToken-Process, the third party can compare the resulting AuthTokens, thus validating the incoming data. Without the shared secret, it is (near-to) impossible to forge the data.
On your problem: Having a static token on GET and POST-requests (or a dynamic one like the project of mine) will protect you against simple CSRF-attacks via e.g. links in forums, which a user has to click to get attacked. As the link will never contain the correct token, your webpage is secure. However, if an attacker manages to load a javascript into the webpage via XSS, you're screwed and no technique in the world will help against it, as the javascript can scan the whole DOM-tree of the page to find an capture any tokens whatsoever.
So, it comes down to this:
use tokens on GET and POST-requests to fight CSRF
secure your page against XSS-injections
I find the OWASP cheat sheets are a good resource for such design decisions:
CSRF Prevention Cheat Sheet
XSS Prevention Cheat Sheet
Your scheme sounds similar to the HTTP digest authentication without establishing any kind of session post authentication. Which is probably an improvement over HTTP Basic. And that is assuming both are over TLS!
I am not sure how feasible your scheme might be or how vulnerable to replay attacks or MITM it might be.
If it is an option you might consider the new <keygen> html5 tag which can help establish a two way TLS session. This would be the most secure option..
I am in the middle of developing a PHP social media web application which will be supported by various web services each operating a REST API. Web services will probably be implemented in Java with MySQL data layer but the whole point of what I am trying to do is make it really easy to implement modules in different languages/data stores depending on what is approriate.
So for example when the user logs into the application via a login form the PHP code connects to a web service and POSTs the username and password to check if they should be authenticated. I would normally at this point start a session and store it in a session data store.
Another example could be if a user sends a private message to another user. The message would be POSTed to the private messaging web service which would take care of all the storage. Similarly the web service could be contacted to retrieve messages for a user.
Although I understand how to implement the REST web service in Java and make the connection to it in PHP I am totally unsure as to how to secure the data being passed and make sure that it is the users data being returned. If for example I want to get all of user As private messages how does the web service know to return that users. I could pass that users identifier as part of the GET url but then surely any old user could just figure out the GET url and use it to look up other peoples messages. I thought maybe I could pass over the session identifier and IP address which would allow me to check the session data store and make sure it is the correct user?
To secure the data that is important - like the username/password I thought I would just pass it over SSL.
Hope this explains my problem better.
Thanks
Take a look at HTTP Digest authentication. Most clients should support it, and it means the auth details can be passed securely with each request as part of the headers without interfering with the payload of the request itself.
I think requiring OAuth is a good choice. Your end users should appreciate that other websites don't need to ask usernames and passwords to access their data. As far as SSL, it's clearly worth doing if you can. You'll have to see if the performance trade-off is acceptable.
Keep in mind that your api must mimic the HTTP protocol.
Http is stateless, and by adding any Sessions or so, you're trying to fake an "Alwaysconnected" method.
With a LoginForm, it's like I'll have to send two requests for each calls ;)
These are basically 2 questions.
When privacy is a concern I'd go for the safest option: Serve data over SSL (via HTTPS).
As far as authentication is concerned, there are several possibilities. Basic over SSL is one of them, but a simple login form with a cookie can be another one. (ASP.Net Forms Authentication for example.) This all depends on how you want to implement your authentication mechanism.