Tag Archives: Java

Session ID in the URL : is it a vulnerability ?

Problem

I noticed at authentication of several JAVA web applications, the Session ID attached at the url like this http://mywebsite.com/function?value=blah&jsessionid=fgd457dfsd7sde4g4df…

When first authenticated, the website reveals in the URL a sensitive information “the session ID”. This is a security risk according to OWASP reference.
http://owasp-aasvs.readthedocs.io/en/latest/requirement-3.6.html
Indeed if an attacker get the session ID it can lead to the vulnerability of session fixation.

Scanner like Acunetix will detect is as a security risk too:
https://www.acunetix.com/vulnerabilities/web/session-token-in-url

Why the session id is passed to the URL ?

According to this post, it is by design of JavaEE:

This isn’t a bug, it’s by design. When a new session is created, the server isn’t sure if the client supports cookies or not, and so it generates a cookie as well as the jsessionid on the URL. When the client comes back the second time, and presents the cookie, the server knows the jsessionid isn’t necessary, and drops it for the rest of the session. If the client comes back with no cookie, then the server needs to continue to use jsessionid rewriting.
You may not explicitly use cookies, but you do implicitly have a session, and the container needs to track that session.

https://stackoverflow.com/questions/4079378/why-is-my-session-id-in-my-url

What is a Session Fixation ?

Session Fixation is an attack that permits an attacker to hijack a valid user session.
https://www.owasp.org/index.php/Session_fixation

This vulnerability is part of Top 10 2013-A2-Broken Authentication and Session Management

How to test for Session Fixation ?

https://www.owasp.org/index.php/Testing_for_Session_Fixation_(OTG-SESS-003)

What is a Session ?

HTTP protocol and Web Servers are stateless, what it means is that for web server every request is a new request to process and they can’t identify if it’s coming from client that has been sending request previously.

But sometimes in web applications, we should know who the client is and process the request accordingly. For example, a shopping cart application should know who is sending the request to add an item and in which cart the item has to be added or who is sending checkout request so that it can charge the amount to correct client.

http://www.journaldev.com/1907/java-session-management-servlet-httpsession-url-rewriting

This is a link to Servlet specification to understand better the session scope in Java :
https://jcp.org/aboutJava/communityprocess/final/jsr154/index.html

SRV.7.3 Session Scope
HttpSession objects must be scoped at the application (or servlet context) level. The underlying mechanism, such as the cookie used to establish the session, can be the same for different contexts, but the object referenced, including the attributes in that object, must never be shared between contexts by the container.

Solution

Validate Session Id on server side
For sometimes i thought that cookies or hidden input fields is the solution against the “session ID” in the url. According to the link below it is a limited solution. Even if it is hard to copy paste cookies and hidden fields it is still possible to retrieve the Session ID information with special tools on unencrypted website.

Depending of the website it is possible that the sessionId on the URL is not a security risk. If the web application is well designed and the session ID is validated on server side, this is not a problem :
https://security.stackexchange.com/questions/14093/why-is-passing-the-session-id-as-url-parameter-insecure

The best practice , in all case is to validate on the server side.
Other solutions are possible : https://en.wikipedia.org/wiki/Session_fixation

Use Filter to get rid of Session ID in URL

Here is an example of using a Filter to get rid of session Id in the URL :
https://stackoverflow.com/questions/1045668/jsessionid-is-occurred-in-all-urls-which-are-generated-by-jstl-curl-tag/4019476#4019476

I believe this solution is not necessary if good validation of session ID is done on the server Side.

Spring Security Framework

Probably the best solution for JavaEE is to use well tested framework like spring security framework. It is also a default security against other common vulnerabilities.
The authentication form using spring security provide high security against common vulnerabilities :
http://docs.spring.io/spring-security/site/docs/current/guides/html5//helloworld-javaconfig.html

The SecurityConfig will:

Require authentication to every URL in your application

Generate a login form for you

Allow the user with the Username user and the Password password to authenticate with form based authentication

Allow the user to logout

CSRF attack prevention

Session Fixation protection

Security Header integration

HTTP Strict Transport Security for secure requests

X-Content-Type-Options integration

Cache Control (can be overridden later by your application to allow caching of your static resources)

X-XSS-Protection integration

X-Frame-Options integration to help prevent Clickjacking

Integrate with the following Servlet API methods

HttpServletRequest#getRemoteUser()

HttpServletRequest.html#getUserPrincipal()

HttpServletRequest.html#isUserInRole(java.lang.String)

HttpServletRequest.html#login(java.lang.String, java.lang.String)

HttpServletRequest.html#logout()

Advertisements

How to verify your java libraries have known security vulnerabilities ?

A maven plugin can check you Java libaries for known vulnerabilities. It is called dependency-check-maven.

The OWASP Dependency Check utility uses NIST’s National Vulnerability Database (NVD) to identify the vulnerable dependencies, so the list is always up-to-date.

  <plugin>
                <groupId>org.owasp</groupId>
                <artifactId>dependency-check-maven</artifactId>
                <version>1.4.4</version>
                <configuration>
                    <skip>false</skip>
                    <skipTestScope>false</skipTestScope>
                    <skipProvidedScope>false</skipProvidedScope>
                    <skipRuntimeScope>false</skipRuntimeScope>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>check</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

https://blog.lanyonm.org/articles/2015/12/22/continuous-security-owasp-java-vulnerability-check.html

Requirements

You will need the following to use Owasp Maven dependency Check.

  • Maven version superior to 3.1
  • Tips to quickly check only some libraires

    Let’s say you can not compile all the project because some jars/files are missing. Then you cannot use the plugin immediately. You need to compile the project first. If you don’t need to compile the project entirely, you can just create a simple pom with all dependencies to check.

    Example :

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    	<groupId>com.mytest.framework</groupId>
    	<artifactId>mytestframe</artifactId>
    	<packaging>pom</packaging>
    	<name>com.mytest.framework.mytestframe</name>
    	<version>1.0.0-SNAPSHOT</version>
    		
    	<properties>
    		<spring.version>1.0.0.RELEASE</spring.version>
            </properties>
    
    
    	<build>
    		<pluginManagement>
    			<plugins>
    				
    				  <plugin>
                    <groupId>org.owasp</groupId>
                    <artifactId>dependency-check-maven</artifactId>
                    <version>1.4.4</version>
                    <configuration>
                        <skip>false</skip>
                        <skipTestScope>false</skipTestScope>
                        <skipProvidedScope>false</skipProvidedScope>
                        <skipRuntimeScope>false</skipRuntimeScope>
                    </configuration>
                    <executions>
                        <execution>
                            <goals>
                                <goal>check</goal>
                            </goals>
                        </execution>
                    </executions>
                   </plugin>
                          </plugins>
            </pluginManagement>
             </build>
    
           <dependencies>
    	   <dependency>
    		<groupId>org.springframework</groupId>
    		<artifactId>spring-webmvc</artifactId>
    		<version>${spring.version}</version>
    	  </dependency>
           </dependencies>
    </project>
    
    

    Check maven dependencies with this command :

    mvn dependency-check:check
    

    Reporting

    Check the link above to use reporting for your continuous integration. Otherwise here is an example of reporting once you launch the maven plugin :

    One or more dependencies were identified with known vulnerabilities in my_project:
     
    logback-core-1.1.3.jar (ch.qos.logback:logback-core:1.1.3, cpe:/a:logback:logback:1.1.3) : CVE-2017-5929
    commons-collections-3.2.1.jar (commons-collections:commons-collections:3.2.1, cpe:/a:apache:commons_collections:3.2.1) : CVE-2015-6420

    Troubleshooting

    If you have the following error

    -Dmaven.multiModuleProjectDirectory system property is not set
    

    then you need to modify the java configuration like this in eclipse :owasp_check_maven

    How to simulate a MQ server ?

    The problem

    Our application is retrieving information from a distant server using IBM Websphere Mq messaging system. In production we need to install two MQ servers , one on machine A and another one on machine B:

    Creation Fil MQ

    We want to avoid installing MQ Server on two machines for the qualification platform. How to simulate machine B ‘s MQ Server ?

    The solution

    This article will explain several steps taken to simulate the communication between two MQ servers. These are the steps explained :

  • Create a MQ server on machine A
  • Run a Java application on machine B within tomcat which listens to inqueue QueueManager and send back information to Outqueue MQ queue manager
  • Create a MQ server on machine A

    A IBM MQ server is composed of a queue manager, local queues, channels. Channels allow the queues to communicate between each other. Aliases can also be used to give an alias to queues.

    https://wordpress.com/post/julienprog.wordpress.com/1235

    Simulate a MQ server on machine B

    First of all install tomcat on the machine B. The solution is using Java to catch JMS information from our MQ Server on machine A. To simulate the MQ Server these are the steps :

  • Add a listener in web.xml
  • The Java class listener will be launched at tomcat startup.
  • At statup , the listener starts one Thread or multiple ones to listen one or multiples queue managers
  • Let’s assume we have one thread listening to one Queue manager
  • When a Thread is cathing a JMS message, from receiver/in queue of machine A, it will parse the message
  • Based on the parsed message we check a database or filesystem for a DataSet response
  • Finally we send the dataset response to the Out/sender queue of machine A
  • The application in machine A reads the out/sender queue and process it like normal not knowing it is consuming messages from the simulator
  • That’s it : the machine B simulated a MQ Server
  • Add a listener to tomcat web.xml

    <web-app>
    	<display-name>MQ-Sim</display-name>
    
    	<listener>
    		<listener-class>my.com.MQListener</listener-class>
    	</listener>
    
    

    At startup of tomcat the MQlistener will be launched. The thread is started within the listener like this :

    final MqThread mq= new MqThread (mqinfo);
    MqThread .start();
    

    Read MQ configuration detailed from a file

    We need to know to which receiver/in queue we will listen to and which sender/out queue we will send message to.

    Example of properties file containing these information :

    hostname	  = myserver
    port		  = 9999
    queueManager = MYQUEUEMANAGER
    queue.in	  = QUEUE.OUT
    queue.out	  = QUEUE.IN
    

    “queue.in” represents the queue we are lestening to. “queue.out” is the queue we are going to send message to.

    Start a thread listening to a receiver queue

    The MqThread extends Thread class. It contains a run() method which will be executed when the thread is started.

    The MqThread constructor prepares an active connection with the queue manager and the queue receiver and sender in order to communicate with the MQ server .

    
    import javax.jms.QueueConnection;
    ...
    public MqThread (MqInfo mqInfo) throws JMSException {
           
    final MQQueueConnectionFactory queueConnectionFactory = new MQQueueConnectionFactory();
    			queueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
    			queueConnectionFactory.setQueueManager(mqInfo.getQueueManager());
    			queueConnectionFactory.setHostName(mqInfo.getHostname());
    			queueConnectionFactory.setPort(mqInfo.getPort());
    
          queueConnection = queueConnectionFactory.createQueueConnection(mqInfo.user, mqInfo.password);
          queueConnection.start();
          // A QueueConnection object is
          // an active connection to a point-to-point JMS provider.
    
          this.queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
          // A QueueConnection can be used 
          // to create a QueueSession, 
          // from which specialized 
          // queue-related objects can be created
          this.receiver = session.createReceiver(mqInfo.receiverQueue);
          // Creates a QueueReceiver object to receive 
          // messages from the specified queue.
          this.sender = session.createSender(mqInfo.senderQueue);
          // Creates a QueueSender object to send 
          // messages to the specified queue.
    }
    

    More information about QueueConnection
    http://docs.oracle.com/javaee/6/api/javax/jms/QueueConnection.html

    The thread will be listening to MQ receiver queue. When a JMS message is sent to that queue the thread will consume and parse the message.

    public run() {
    
    		this.queueManager = queueManager;
                    while (isThreadTerminated) {
    		    final Message message = receiver.receive(1000);
    		    proccessMessage(message );
                     } 
    }
    

    The run() method is listening to queue receiver to handle messages from this queue.

    Receives the next message that arrives within the specified timeout interval.

    http://docs.oracle.com/javaee/6/api/javax/jms/MessageConsumer.html#receive(long)

    Based on the parsed message we check a database or filesystem for a DataSet response

    Once the message is parsed we can retrieve a DataSet response from a file system. This example is not complet but give an idea what to do :

    
    	private String getDataSetResponse(String inputMessage) {
    
    		final String filename = getFileNameDataSet(inputMessage);
    		return getFile(filename );
    	}
    

    Finally we send the dataset to the Out/sender queue of machine A

    private void sendMessage(String message, String messageId) throws JMSException {
           final TextMessage dataSetMessage = session.createTextMessage(message);
           dataSetMessage.setJMSCorrelationID(messageId);
           dataSetMessage.setJMSMessageID(messageId);
           sender.send(dataSetMessage );
    }
    

    That ‘s it

    Difference between join fetch Hsql and standard SQL request.

    Introduction

    I stumbled upon a problem with a HSQL request recently(Hibernate SQL language). The application using a Hsql request was not retrieving the information we wanted and we did not know why.

    The SQL request retrieving correctly the information

    The tables from the database(simplified) :

    
    ALARM                                                         
            ID          NAME    
            122        NAME_X
    
    
    MY_TABLE
            MY_ID     MY_NAME       VarA 
            231       NAME_Y        value_expected
            Null      NAME_X        value_expected
    

    This SQL request executed from SQL developer would retrieve the expected outcome from the tables.

    SELECT a FROM MY_TABLE t, ALARM a WHERE
    t.VarA = 'value_expected' and
    a.NAME=t.MY_NAME and (a.ID=t.MY_ID or a.ID is null).
    

    Outcome :

    Null           NAME_Y
    

    The different behavior with looking similar HSQL request

    The HSQL request( used with entities) in the java code was supposed to give the same results as the previous sql request. Here is the code of the hsql request :

    StringBuilder clause = new StringBuilder(
    "from MyAlarm a join fetch a.mytable t"
    +" where t.VarA = 'value_expected' and"
    +"(a.ID=t.MY_ID or a.ID is null)");
    

    The problem when using this hsql request is that some of the request is done through entity objects (from MyAlarm a join fetch a.mytabl). The join is done in the entity class of the Entity MyAlarm :

    @Entity
    @Table(name = "MY_ALARM")
    @Cache(usage = CacheConcurrencyStrategy.NONE)
    public class MyAlarm implements Serializable {
        @Column(name = "NAME")
        private String Name;
        @Column(name = "ID")
        private String Id;
    
     @ManyToOne(targetEntity=MyTable.class, optional = true, fetch=FetchType.LAZY)
        <b>@JoinColumns({
            @JoinColumn(name="NAME",  
    referencedColumnName="MY_NAME"     
    ,nullable = true, insertable = false
    , updatable = false),
            @JoinColumn(name="ID",    
    referencedColumnName="MY_ID"     
    ,nullable = true
    , insertable = false
    , updatable = false)</b>
        })
    

    This following join from the entity will never retrieve the row of the table MY_TABLE where ID is null because there is no ID null in the table ALARM. Therefore this hsql request is not not equivalent to the SQL request above.

    Explanation about join fetch

    The documentation about join fetch : “14.3. Associations and joins”
    https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html

    A good explanation of the difference between join and join fetch here :
    http://stackoverflow.com/questions/17431312/difference-between-join-and-join-fetch-in-hibernate

    How did I find the solution ?

    As i said previously unit testing is the key to find the resolution of coding problems. It enables you to reproduce problems faster and it adds a regression test to your product. More information about unit testing https://julienprog.wordpress.com/2015/03/15/the-power-of-unit-testing/

    I reproduced the problem inside a unit test.It helped me a lot to understand the problem and how to solve it. To realise a unit test of hibernate request i use hsqldb,spring framework ,maven,etc..

    The solution

    I join the two tables “MyAlarm” and “MyTable” with the following conditions. The important part was to add (a.ID=t.MY_ID or a.ID is null). It is a condition necessary to respect the needs of the customer.

    <b>select a from MyAlarm a, MyTable t</b> where 
    t.VarA = 'value_expected' and
    a.NAME=t.MY_NAME (a.ID=t.MY_ID or a.ID is null)
    

    Mock HibernateTemplate with Mockito

    Introduction

    Mockito is a useful Java library to create mock Objects for Java Unit Testing.
    http://site.mockito.org/

    I used the framework Mockito in order to test objects difficult to test otherwise such as Struts method, Servlet, Hibernate , etc…

    HibernateTemplate object to mock

    This is the legacy code i wanted to test with Mockito. HibernateTemplate is a deprecated class but it is still used in this code.

    Package com.dao.myclass;
    
    import org.springframework.dao.DataAccessException;
    import org.springframework.orm.hibernate4.support.HibernateDaoSupport;
    
    import com.dao.ImyDAO;
    import com.dao.exception.MyException;
    import com.dao.myEntity;
    import com.util.Logger;
    
    public class MyHibernateImpl extends HibernateDaoSupport implements ImyDAO {
    
        @Override
        public myEntity getMyEntity(String myNumber) throws MyException {
            try {
                if (myNumber == null) {
                    Logger.getLogger(MyHibernateImpl.class)
                            .error("myNumber : " + myNumber);
                    return null;
                }
                if (myNumber != null && myNumber.length() > 1) {
                   process(MyNumber);
                }
                myEntity thismyentity = (myEntity) getHibernateTemplate().get("com.dao.myEntity", myNumber);
                return thismyentity;
            } catch (final DataAccessException e) {
                throw new MyException("error.CodeMyEntity", e);
            }
        }
    
    }
    

    The line of code i had to difficulty to test without Mockito :

    myEntity thismyentity = (myEntity) getHibernateTemplate().get("com.dao.myEntity", myNumber);
    

    The code for myEntity :

    @Entity
    @Table (name="MY_TABLE")
    public class myEntity implements Serializable {
    
        private static final long serialVersionUID = 5447862515324364L;
    
        @Id
        private String myNumber;
    
        @Column (name="MYCOLUMN")
        private String myColumn;
    
        public String getmyNumber() {
            return myNumber;
        }
        public void setmyNumber(String myNumber) {
            this.myNumber = myNumber;
        }
        public String getmyColumn() {
            return myColumn;
        }
        public void setmyColumn(String myColumn) {
            this.myColumn = myColumn;
        }
    }
    

    Mock the object HibernateTemplate

    I need to mock the object HibernateTemplate in order to test this function. Here is my test class with Junit :

    public class TestMyHibernateImpl {
    
        @Mock
        HibernateTemplate mockTemplate;
    

    I used the annotation @Mock for the creation of a mock object of HibernateTemplate. To use @Mock it is necessary to initialise MockitoAnnotations :

        @Before
        public void initMocks() {
            MockitoAnnotations.initMocks(this);
        }
    

    This is how I test the function getMyEntity:

        @Test
        public void testCasEntityReturned() throws MyException {
    
            myEntity entity = new myEntity();
            String myNumber = "S54564121SD”;
            String myColumnValue = "myColumn";
            entity.setmyNumber(myNumber);
            entity.setmyColumn(myColumnValue);
    
            (Mockito.doReturn(entity).when(mockTemplate)).get("com.dao.myEntity", myNumber);
    <b>// I tell Mockito to return an entity when this code is used later in getMyEntity(..)</b>
    
            MyHibernateImpl myColumn = new MyHibernateImpl();
            myColumn.setHibernateTemplate(mockTemplate);
            
            myEntity thismyentity = myColumn.getMyEntity(myNumber);
            Assert.assertNotNull(thismyentity);
            Assert.assertEquals(myNumber, thismyentity.getmyNumber());
            Assert.assertEquals(myColumnValue, thismyentity.getmyColumn());
    
        }
    

    Unit Testing of Jsp Custom Tag Before Version Spring 2.5

    As it is described on this link, it is easier to mock Custom Tag with Spring 2.5 :http://blog.agilelogicsolutions.com/2011/02/unit-testing-jsp-custom-tag-using.html .

    If for whatever reason you are stuck with a version of Spring before 2.5, you can still test Jsp Custom Tag.This is the class i would like to unit test :

    
    public final class CustomTag extends javax.servlet.jsp.tagext.BodyTagSupport{
    
        public void writeMyTag() throws JspException {
    
                  pageContext.getOut().write("<th> … text here <th>");              
    
       }
    
    }
    
    
    

    My problem is : how to mock the object pageContext ? My solution is to use Mockito.

    I did the following unit test and mock pageContext and jspWriter:

    
    public class CustomTagTest {
    
    @Mock
    
    PageContext pageContext;
    
    @Mock
    
    JspWriter jspWriter;
    
    @Before
    
    public void setup(){
    
    MockitoAnnotations.initMocks(this);
    
    }
    
    @Test
    
    public void testwriteMyTag() throws JspException, IOException {
    
    CustomTag tag = new CustomTag ();
    
    (Mockito.doReturn(jspWriter).when(pageContext)).getOut();
    
    tag.setPageContext(pageContext );
    
    tag.writeMyTag();
    
    }
    
    }
    
    

    Here we go : i covered the custom tag code. However it does not test the output result of JspWriter.