How to secure a REST web service in Java EE 6 - java

I have made a web application using Java EE 6 (using reference implementations) and I want to expose it as a REST web service.
The background is that I want to be able to retrieve data from the web application to a iOS app I made. The question is how would I secure the application? I only want my application to use the web service. Is that possible and how would I do this? I only need to know what I should search for and read and not the actual code.

Unfortunately, your webservice will never be completely secure but here are few of the basic things you can do:
Use SSL
Wrap all your (app) outbound payloads in POST requests. This will prevent casual snooping to find out how your webservice works (in order to reverse engineer the protocol).
Somehow validate your app's users. Ideally this will involve OAUTH for example using Google credentials, but you get the idea.
Now I'm going to point out why this won't be completely secure:
If someone gets a hold of your app and reverse engineers it, everything you just did is out the window. The only thing that will hold is your user validation.
Embedding a client certificate (as other people have pointed out) does nothing to help you in this scenario. If I just reverse enginneered your app, I also have your client certificate.
What can you do?
Validate the accounts on your backend and monitor them for anomalous usage.
Of course this all goes out the window when someone comes along, reverse engineers your app, builds another one to mimic it, and you wouldn't (generally) know any better. These are all just points to keep in mind.
Edit: Also, if it wasn't already obvious, use POST (or GET) requests for all app queries (to your server). This, combined with the SSL should thwart your casual snoopers.
Edit2: Seems as if I'm wrong re: POST being more secure than GET. This answer was quite useful in pointing that out. So I suppose you can use GET or POST interchangeably here.

Depends on how secure you want to make it.
If you don't really care, just embed a secret word in your application and include in all the requests.
If you care a little more do the above and only expose the service via https.
If you want it to be secure, issue a client certificate to your app and require a
valid client certificate to be present when the service is accessed.

my suggestions are:
use https instead of http. there are free ssl certificate avaliable,
get one and install.
use a complex path such as 4324234AA_fdfsaf/ as the root end point.
due to the nature of http protocol, the path part is encrypted in the https request. therefore it's very safe. there are ways to decrypt the request through man-in-the-middle attack but it requires full control over the client device including install an ilegal ssl certificate. but, i'd spend more time on my app to make it successful.

Create a rule on the machine which hosts your Web Service to only allow your application to access it through some port. In Amazon EC2, this is done creating a rule in the instance Security Group.

We have used RestEasy as a part to securing our exposed RESTful webservices. There should be lot of example out there but here is the one which might get you started.
http://howtodoinjava.com/2013/06/26/jax-rs-resteasy-basic-authentication-and-authorization-tutorial/
You can also use OAUTH:
http://oltu.apache.org/index.html

Related

Does Java handle HTTPS encoding behind the scenes when I call my SOAP service?

In Java, I am building a stand alone web service client that manipulates records in a cloud based CRM by using its SOAP API. I generated my classes using the wsimport utility with WSDLs that all have addresses prefixed with https in the port binding section of the WSDL. Is Java handling behind the scenes all the wire-level security simply because the address is https? If so, how can I confirm that the SOAP message is being encrypted? My code does work, and I have not needed to worry about security until now, because I am developing in a staging environment with temporary passwords.
Thank you for your help!
Putting https in the URL will almost always do the trick. Even if your code is not capable of https, the webserver at the other end will almost never allow you to talk in HTTP when using the HTTPS port. At least, I've never seen one that does.
It's not a 100% guarantee that you'd bet your business on, but it is close.
If the code you write works on any website that does require https, you are the rest of the way there in terms of assurances.
You can confirm the traffic is encrypted by running a traffic analyzer aka packet sniffer.

Java servlet: only allow own client

Im developing a little serverside api to use with a java client (which i wrote too).
The api is written with jersey (RESTful) und running on a tomcat server. The data it provides is passed to the client as Json-String and all communication is performed via Http.
I now want to ensure that only my own client programm is able to access the api (At the moment, as its http, everyone could receive the json data via an ordinary browser). Therefor, im looking for a way to "identify" my clientside programm to the api with a key or something like that. I first thought about using the user-agent for identification, but this could easily be copied. So i need some kind of key which changes dynamically or something like that.
Whats a good way to do that?
I searched in the net but didnt find a proper answer (maybe wrong keywords?), so im happy for every hint and/or link about that topic.
Edit: The client side programm is an android app. I want to make sure noone is creating a similar app and use my server for his purpose.
If the attacker has a the client in his possession, there's almost no security that can't eventually be compromised.
A good start, that's fairly out of box is bi-directional SSL authentication (Client and Server certificates). This is supported out of the box and requires little code changes.

Authorized Flash Client to Java Server connection

I'm building a Flash-based Facebook game with a Java backend, and I'm planning to use a RESTful approach to connect the two of them (not a persistent socket connection). I'm using the AS3 library to connect the client to Facebook, so that's where I have my session information stored. However, how do I authorize client connections back to the server? I can't leave the callback URLs open since that'd let people manipulate game state without playing the game. I need to make sure that the calls are coming from a valid client and through a valid session.
At the moment, users have no direct login to the backend server -- it's all handled through the client frontend. Can I pass the Facebook OAuth2 access token to the backend in a way that the backend can verify its validity? Should that be enough to trust a valid frontend connection?
I could do a two legged OAuth signed request or just use a simple shared secret, but the keys would have to be packed in with the flash client, which makes that almost useless for this use case.
Somebody has to have solved this problem, but I can't find it.
If you are using Java as a backend, I would consider using BlazeDS. It is a great library for doing AMF connections (which are async so fit your non-persistent socket requirement). If you are using Spring on the backend at all, I'd highly recommend using Spring-Flex as well. It adds a bunch of goodies that make exposing AMF services a breeze. Also, it adds hooks to allow 'easy' integration of Spring Security.
For the oAuth stuff, I would move the oAuth portion to the web side instead of the flash client (which I think I understand is what you do now). This way you can authenticate the web session on the server side and secure the page that contains the .swf. Then when your user loads the .swf in your code (assuming you're using spring security integrated into BlazeDS) you can call cs.authenticated on your cs:mx.messaging.ChannelSet. This will work, but may be more reword than you want to do.
We had similar problem in one of our project. What we ended up doing was used the following token passing method:
1) Fresh client connects to the server and get a token that's valid for x amount of time.
2) The client has an obfuscated part of code that uses an algorithm to change the token (and this algorithm changes at some frequency in sync with the server). The client uses the algorithm to change the token and includes it in the next request to the server.
3) The server knows the original token and the algorithm so now it can check to see if the new token in valid and it's from a valid client.
4) The cycle continues.
This is no 100% secure, since someone can really spend time and analyze the communication and eventually understand the pattern, but you can play around with the algorithm so much and change it often enough to make it hard for someone to guess it.
Hope this helps.
P.S. The application that I'm talking about that uses this has been in production for past 5 years and gets ~300k unique users a day and no one has broken in yet.

Secure connection between client and server

I'm developing a server component that will serve requests for a embedded client, which is also under my control.
Right now everything is beta and the security works like this:
client sends username / password over https.
server returns access token.
client makes further requests over http with the access token in a custom header.
This is fine for a demo, but it has some problems that need to be fixed before releasing it:
Anyone can copy a login request, re-send it and get an access token back. As some users replied this is not an issue since it goes over https. My mistake.
Anyone can listen and get an access key just by inspecting the request headers.
I can think of a symmetric key encryption, with a timestamp so I can reject duplicate requests, but I was wondering if there are some well known good practices for this scenario (that seems a pretty common).
Thanks a lot for the insight.
PS: I'm using Java for the server and the client is coded in C++, just in case.
I don't get the first part, If the login request is https, how can anyone just copy it?
Regarding the second part, t This is a pretty standard session hijacking scenario. See this question. Of course you don't have the built-in browser options here, but the basic idea is the same - either send the token only over a secure connection when it matters, or in some way associate the token with the sending device.
In a browser, basically all you have is IP address (which isn't very good), but in your case you may be able to express something specific about your device that you validate against the request to ensure the same token isn't being used from somewhere else.
Edit: You could just be lucky here and be able to rule out the IP address changing behind proxies, and actually use it for this purpose.
But at the end of the day, it is much more secure to use https from a well-known and reviewed library rather than trying to roll your own here. I realize that https is an overhead, but rolling your own has big risks around missing obvious things that an attacker can exploit.
First question, just to get it out there: if you're concerned enough about nefarious client-impersonator accesses, why not carry out the entire conversation over HTTPS? Is the minimal performance hit significant enough for this application that it's not worth the added layer of security?
Second, how can someone replay the login request? If I'm not mistaken, that's taking place over HTTPS; if the connection is set up correctly, HTTPS prevents replay attacks using one-time nonces (see here).
One of the common recommendations is - use https
https man in the middle attack aside using https for the entire session should be reliable enough. You do not even need to worry about access tokens - https takes care of this for you.
Using http for further requests seems to introduce some vulnerabilities. Now anybody with a network sniffer can intercept your traffic steal the token and spoof your requests. you can build protection to prevent it - token encryption, use once tokens, etc. but in doing so you will be re-creating https.
Going back to the https man in the middle attack - it is based on somebody's ability to insert himself between your server and your client and funnel your requests through their code. It is all doable i.e. in case the attacker has access to the physical network. The problem such attacker will face is that he will not be able to give you a proper digital certificat - he does not have the private key you used to sign it. When https is accessed through a browser, the browser gives you a warning but still can let you through to the page.
In your case it is your client who will communicate with the server. And you can make sure that all proper validations of the certificate are in place. If you do that you should be fine
Edit
Seconding Yishai - yes some overhead is involved, primarily CPU, but if this additional overhead pushes your server over board, you have bigger problems with your app

My program needs to access information (key/value) from my hosted server. What web architecture would be best for this?

My program needs to download object definitions (basically xml files, maybe binary files) on demand via the net. The program will request objects from my server during runtime. The only thing the program has to send the server is a string that identifies the object it needs (e.g. RedCubeIn3DSpace23). So a basic Key, Value system. My app also has to have some basic authentication mechanism to make sure only legitimate programs access my server’s info. Maybe send the license number and a password.
What is the best way to go about implementing this? I have 0 web knowledge so I'm not sure exactly what technologies I need. I have implemented socket programs in college so maybe that is what I need? Are there frameworks for this type of thing? There could be thousands of users/clients simultaneously; maybe more but I don’t know.
One super important requirement is that I need security to be flawless on the server side. That is, I can't have some hacker replacing object definitions with malicious one that clients download. That would be disastrous.
My first thoughts:
-Set up an ftp server and have each xml file will be named by the key value. Program logs in with its product_id and fixed password and just does downloads. If I use a good ftp server, that is pretty impervious to a hacker modifying definitions. Drawback is that it's very non expandable nor flexible.
-RESTful type system. I just learned about this when searching stackoverflow. I can make categories of objects using URL but how do I do authentication and other actions. Might be hard to program but is this a better approach? Is there a prebuilt library for this?
-Sockets using Java/C#. Java/C# would protect me from overflow attacks and then it is just a matter of spawning a thread on each connection and setting up simple messaging protocol and file transfers.
-SOAP. Just learned about it while searching. Don't know much.
-EC2. I think it (and other?) cloud services add a db layer over it.
That's what I can come up with, what do you think given my requirements? I just need a little guidance.
HTTP seems a better fit than ftp, since you only want to download stuff. That is, you would set up a web server (e.g. Apache), configure it for whatever authentication scheme you need, and have it serve that content.
SOAP is clearly overkill for this, and using raw sockets would be reinventing the wheel (i.e. a web server).
I'd do security on the socket level, using HTTPS. That way, the client will verify the identity of the server prior when establishing the connection, and nobody can intercept the password sent to the server. Again, a decent webserver will support this out-of-the-box, you just need to configure it properly.

Categories