Tuesday 20 August 2013

Basic Security - Part 2 - Basic Auth for your Servlet

In our previous article we went over how to implement SSL certifications to our Tomcat7 server using a combination of an unsigned SSL certification, a keystore and enabling a secure port and protocol to be used for HTTPS requests.

The next step is to provide basic authentication for your servlets running on the Tomcat instance. After validating that the server the client is connecting to is the one they actually meant to connect to, we should require them to login before sending encrypted sensitive material to them.

Open up your tomcat-users.xml file and make sure you have a unique login and password created referencing a unique role. (which we did initially in step 1)

<tomcat-users>
   <role rolename="security_role_101"/>
   <role rolename="security_role_something" />
   <user username="UniqueUsernameForSomething"
      password="SuperLongPassword6666"
      roles="valid_mobile_user"/>
   <user username="super_admin_login"
      password="superComplicatedPass6"
      roles="security_role_101"/>
</tomcat-users>

Once a user-connects we are going to make the servlet challenge for username UniqueUsernameForSomething.

To do this, open your project and go to the web.xml file. Generally this is found under the folder WebContent/WEB-INF/

Add the following between the fields.

<security-constraint>
   <web-resource-collection>
      <web-resource-name>App-Name</web-resource-name>
      <url-pattern>/*</url-pattern>
   </web-resource-collection>
   <auth-constraint>
      <role-name>security_role_101</role-name>
   </auth-constraint>
   <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
   </user-data-constraint>
</security-constraint>

<login-config>
   <auth-method>BASIC</auth-method>

</login-config>

This forces basic auth on any URL route for www.servername.com/* and checks that the passed in username and password is in the role "security_role_101". The transport guarantee of CONFIDENTIAL tells the app to only send the data in a way which ensures the information cannot be changed or observed during transmission.

Compile your war and redeploy. Browse to your test URL of www.servername.com:secureport/mypage and it should now prompt you for your login details.

Enjoy.

Friday 16 August 2013

Basic Security - Part 1 - Secure your Server

Often in the mad dash to get a feature out or even the coveted MVP for your new startup the first thing that gets left behind is security.

In this tutorial I'm going to give you the bare-bones required to secure a Tomcat7 server (on a UNIX system) to try and reduce your risk. It's by no means an in-depth look at security but this article and the next few I'll write will let you have some measure of surety that any Tom, Dick and Harry are not listening to your every message over the internet.

First we are going to look into our Tomcat users file and ensure there are no default usernames/passwords being used. Early in development while you are still chopping and changing code and technology we lock in these basic authentication mechanisms with dummy or simple data so we can get on with what we need to do. Then of course, forget to go back and strengthen the security.

Open you Tomcat Users configuration file and make sure your passwords are atleast 10 characters long and your usernames are unique. Don't use admin, don't use default, make it unique please.

$ sudo vi /etc/tomcat7/tomcat-users.xml

You can also strip roles from users unless they are required. You don't need every user to have roles manager and manager-gui. These for example should either be unused or with a master-admin user-account.

<tomcat-users>
   <role rolename="security_role_101"/>
   <role rolename="security_role_something" />
   <user username="UniqueUsernameForSomething"
      password="SuperLongPassword6666"
      roles="valid_mobile_user"/>
   <user username="super_admin_login"
      password="superComplicatedPass6"
      roles="manager,manager-gui"/>
</tomcat-users>

I also secure how a user connects to our server based upon how they are connecting. For example, someone trying to access www.servername.com/admin/* will be going through a different security mechanism using a completely unique username and password than say an encrypted message being sent from a users device to www.servername.com:secureport/rest/*.

Next step is to provided some surety to users connecting that this server is the correct server they were wanting to connect to. Below we are going to update our Tomcat instance to use an unsigned SSL certificated. In production you would replace your unsigned SSL certificate for a signed certificate.

To generate your own unsigned certificate type in the following:

$ /usr/bin/keytool -genkey -alias tomcat -keyalg RSA

What's this doing? keytool is a certificate utility that is generating you a RSA certificate known as 'tomcat'. It places this in your home-directory (unless otherwise specified) in the .keystore file. Make sure set and don't forget the keystore password you'll be prompted to enter.

Next we need to update our Tomcat server configuration to use this keystore.

$ sudo vi /etc/tomcat7/server.xml

Then put in the following, be sure to remove any other defaults like a connector for port 8080.

<!-- Our original open, insecure port for development
<Connector executor="tomcatThreadPool"
   port="8080" protocol="HTTP/1.1"
   connectionTimeout="20000"
   redirectPort="8443" />
-->

<Connector port="8443" SSLEnabled="true"
   maxThreads="150" scheme="https" secure="true"
   protocol="org.apache.coyote.http11.Http11NioProtocol"
   keystoreFile="/path/to/.keystore" keystorePass="password"
   clientAuth="false" sslProtocol="TLS" />

Save the settings and reload your Tomcat7 service.

$ sudo service tomcat7 restart

You can test if this works by by going to:

https://www.servername.com:secureport/

Browsers like Chrome will check with you before proceeding to the site because it has an unsigned SSL certificate.

Next article will be adding basic auth to your servlet running on Tomcat and then getting an iPhone device to authenticate properly before sending data.