16

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.

LuckyLuke
  • 47,771
  • 85
  • 270
  • 434

5 Answers5

8

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.

Community
  • 1
  • 1
Marvin Pinto
  • 30,138
  • 7
  • 37
  • 54
  • I see, I do not need to make it secure as a bank :) I only want to at least limit or stop the most obious way that people could use the API. – LuckyLuke Jan 21 '12 at 19:37
  • @Pjotr Then yes, SSL and wrapping all your payloads in `POST` requests should do what you need. I just wanted to point out where it _could_ go wrong. – Marvin Pinto Jan 21 '12 at 19:38
  • how is POST in any way more secure than GET? – MK. Jan 21 '12 at 19:40
  • I see, thank you :) Just to be sure that I understand you correctly you tell me to send all data from my app with the POST method right? (thats what you mean by payloads?) – LuckyLuke Jan 21 '12 at 19:41
  • there is no need to wrapping all info input POST request when using SSL. SSL encrypts the full request body, including path and query string. – wangii Jan 21 '12 at 19:44
  • @wangii Point taken.. I've edited my answer to reflect this. Thanks :) – Marvin Pinto Jan 21 '12 at 19:47
  • @MK. You're right, I've edited my answer to reflect this. Thanks :) – Marvin Pinto Jan 21 '12 at 19:51
4

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.
MK.
  • 33,605
  • 18
  • 74
  • 111
  • I only need some basic security :) So what you say is that I could just send a parameter like this: "MyMagicKey" : "MagicNumber030349" from the iOS app and check that it matches in my web application? – LuckyLuke Jan 21 '12 at 19:39
  • Yes. But this provides only very basic level of security, of course, as it is trivial to snoop these requests. If you use https it will be significantly more difficult (but still very much possible, just requiring above average skills) to figure it out. – MK. Jan 21 '12 at 19:44
1

my suggestions are:

  1. use https instead of http. there are free ssl certificate avaliable, get one and install.
  2. 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.

wangii
  • 2,570
  • 1
  • 22
  • 29
  • in https entire request is encrypted, not just the url. – MK. Jan 21 '12 at 19:39
  • um... obviously yes, the address you connect to is not encrypted. – MK. Jan 21 '12 at 19:42
  • This works provided the end-user binary is safe from inspection (is it?). If not, the path is probably easier to extract from that end than trying to decrypt tls. The complex path need only be compromised once and he's back at having an unsecured protocol. – ccoakley Jan 21 '12 at 19:45
  • @ccoakley good point. however, what i mean is not to use url like https://api.server/ios/register that'll be too easy to guess than beat tls, nor extract binary from an iphone. – wangii Jan 21 '12 at 19:57
0

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

0

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.

carpamon
  • 6,515
  • 3
  • 38
  • 51