1

After a security scan for xss vulnerabilities in our web application, we had some issues related to cookies set via javascript.

Exact Security tool provided Issue:

CWE-1004 - Cookies set via JavaScript does not have an associated Http response header.

Servlet 2.4 weblogic version 12c Struts 1.0 version

Analysis

For cookies which were set in java were easily handled by implementing a filter where HttpOnly and Secure attributes were set as below in filter

cookie.setPath(";Path=/;HttpOnly;"); cookie.setSecure(true);

Since, servlet version is under 3.0 I found this is the only way to apply the attributes.

However, for cookies set in javascript, I found it difficult to secure. I have tried many solutions but in vain.

For Securing js cookie, I tried to read that document.cookie (tmot) in jsp and send it to filter to apply httponly and secure in server side as below

 <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<%
    Cookie[] cookies = request.getCookies();
    String tomotcookie = null;
    for(Cookie cookie : cookies) {
        if("tmot".equals(cookie.getName())){
            tomotcookie = cookie.getValue();
            out.print("user naem in cookie " + tomotcookie);
        }
        
        //cookie.setSecure(true);
        response.addCookie(cookie);
    }
%>

<script>
var date = new Date().toString();
document.cookie = "tmot=" + date;
</script>
<body>
tmot cookie added ....
</body>
</html>

Filter implemented to intercept is as below

    
package com.javatpoint;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.log4j.Logger;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import com.javatpoint.SecurityWrapper.ResponseWrapper;

/**
 * Servlet Filter implementation class SecurityFilter
 */
public class SecurityFilter implements Filter {
    // private Logger logger = (Logger) Logger.getLogger(SecurityFilter.class);

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {
        System.out.println("inside the sf filter...........................................................");
        ((HttpServletRequest) request).getSession();
        response = new ResponseWrapper((HttpServletResponse) response);

        Cookie[] cookieArray = ((HttpServletRequest) request).getCookies();

        try {

            int reqcookieslength = cookieArray.length;
            System.out.println("length of the array..." + reqcookieslength);
            if (reqcookieslength != 0) {
                for (int i = 0; i < cookieArray.length; i++) {

                    System.out.println("name " + cookieArray[i].getName() + " path  " + cookieArray[i].getPath()
                            + "secure  " + cookieArray[i].getSecure());
                    if ((cookieArray[i].getPath() == null && ((cookieArray[i].getSecure()) == false))) {
                        System.out.println("entered the dragaon.......");
                        cookieArray[i].setPath(";Path=/;HttpOnly;");
                        // cookieArray[i].setSecure(true);
                        System.out.println("cookies PATH are " + cookieArray[i].getPath().toString());
                        System.out.println("cookies secure are " + cookieArray[i].getSecure());

                        System.out.println("cookie content is..." + cookieArray[i].toString());
                        System.out.println("cookies KEY are " + cookieArray[i].getName().toString());

                        System.out.println("cookies max age are " + cookieArray[i].getMaxAge());

                        System.out.println("cookie domain is " + cookieArray[i].getDomain());

                    }

                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("end of looping the cookies....................................................");

        (((HttpServletResponse) response)).addHeader("Set-Cookie",
                "loginid=" + ((HttpServletRequest) request).getSession().getId() + ";Path=/");

        filterChain.doFilter(request, response);

    }

    private class ResponseWrapper extends HttpServletResponseWrapper {

        private List<Cookie> cookies = new ArrayList<Cookie>();

        public ResponseWrapper(HttpServletResponse response) {
            super(response);
        }

        public void addCookie(Cookie cookie) {
            System.out.println(
                    "inside the add cookie method condition checks..................................................");

            try {
                boolean httpsecure = false;
                if ((cookie.getPath() == null) && (cookie.getSecure() == false)) {
                    cookie.setPath(";Path=/;HttpOnly;");
                    cookie.setSecure(true);
                    super.addCookie(cookie);
                } else if ((cookie.getPath() == null) && (cookie.getSecure() == true)) {
                    cookie.setPath(";Path=/;HttpOnly;");
                    super.addCookie(cookie);
                } else if (cookie.getPath() != null && (cookie.getSecure() == true)) {
                    cookie.setSecure(true);
                    super.addCookie(cookie);
                } else if ((cookie.getPath() != null) && (cookie.getSecure() == true)) {
                    httpsecure = true;
                } else {
                    System.out.println("its all good");
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("Exception in cookie if chceksss....");
            }

            cookie.setPath(";Path=/;HttpOnly;");
            cookie.setSecure(false);
            cookie.setMaxAge(60 * 60);

            cookies.add(cookie);
            System.out.println("inside the addCookeii " + cookies.size());
            System.out.println("cookie is " + cookie.getName());
            System.out.println("cookie is " + cookie.getPath()); //
            super.addCookie(cookie);
        }

        /*
         * public void addCookie(Cookie cookie) {
         * System.out.println("response cookies added up here....without secure ..");
         * cookie.setPath(";Path=/;HttpOnly;"); super.addCookie(cookie); }
         */

        @Override
        public void addHeader(String name, String value) {
            System.out.println("inside addHeader method..." + "name " + name + "value..." + value);
            if ((name.equals("Set-Cookie")) && (!value.matches("(^|.*;)\\s*Secure"))) {
                value = value + ";HttpOnly";
                System.out.println("value is " + value);
            }
            super.addHeader(name, value);
        }

        @Override
        public void setHeader(String name, String value) {
            System.out.println("inside setHeader method..." + "name " + name + "value..." + value);
            if ((name.equals("Set-Cookie")) && (!value.matches("(^|.*;)\\s*Secure"))) {
                value = value + ";HttpOnly";
                System.out.println("value is " + value);
            }
            super.setHeader(name, value);
        }

        public List<Cookie> getCookies() {
            System.out.println("inside getCookies of wrapper respone...");
            return Collections.unmodifiableList(cookies);
        }

    }

    @Override
    public void destroy() {

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}

tmot cookie request and response image attached. enter image description here Under response, httponly is applied but when the new request is showing up it ends up empty as shown.

Could anyone please provide any possible solutions on how to handle this vulnerability especially cookie set via javascript

Manou
  • 11
  • 2

0 Answers0