21

here is a function that sets a cookie:

public void addCookie(String cookieName, String cookieValue, Integer maxAge, HttpServletResponse response) {
    Cookie cookie = new Cookie(cookieName, cookieValue);
    cookie.setPath("/mycampaigns");
    cookie.setSecure(isSecureCookie);
    cookie.setMaxAge(maxAge);
    response.addCookie(cookie);
}

I believe in servlet 3.0, there is a way to do this directly. Unfortunately my organization uses 2.5 and UPGRADING at this juncture IS NOT AN OPTION.

is there way to use the response to set the cookie? Here's an example i found online

response.setHeader("SET-COOKIE", "[SOME STUFF]" +"; HttpOnly")

If this is the only way to do what i want, what would i replace "[SOME STUFF]" with so that i don't lose any of the data that my function currently stores in the cookie?

aamiri
  • 2,260
  • 4
  • 31
  • 57
  • 2
    I realize this is an old question but I came up with a solution - see my answer for [How do you configure HttpOnly cookies in tomcat / java webapps?](http://stackoverflow.com/a/14610452/9822) – Jesse Vogt Jan 30 '13 at 17:52

8 Answers8

9

You are right, manually setting header is the right way to achive your goal.

You can also use javax.ws.rs.core.NewCookie or any other class with useful toString method to print cookie to a header to make things more simple.

public static String getHttpOnlyCookieHeader(Cookie cookie) {

    NewCookie newCookie = new NewCookie(cookie.getName(), cookie.getValue(), 
            cookie.getPath(), cookie.getDomain(), cookie.getVersion(), 
            cookie.getComment(), cookie.getMaxAge(), cookie.getSecure());

    return newCookie + "; HttpOnly";
}

And the usage:

response.setHeader("SET-COOKIE", getHttpOnlyCookieHeader(myOriginalCookie));
Val
  • 422
  • 4
  • 10
  • where do I set this class? or how do I configure it? – jpganz18 Feb 16 '16 at 00:31
  • thanks @Val but I still have doubt, I see the class and all its properties, but, how can I enable this on my app? – jpganz18 Feb 16 '16 at 15:45
  • a bit late but since 2.0, javax.ws.rs.core.NewCookie has a constructor with httpOnly, you do not need to append it to toString() : NewCookie nc = new NewCookie("name","value","path","domain","comment",3600,true, true); – Laurent Perez Jul 28 '17 at 23:29
4

This code works without using response.setHeader():

public void addCookie(String cookieName, String cookieValue, Integer maxAge, HttpServletResponse response) {  
    Cookie cookie = new Cookie(cookieName, cookieValue);
    cookie.setPath("; HttpOnly;");
    cookie.setSecure(isSecureCookie);
    cookie.setMaxAge(maxAge);
    response.addCookie(cookie);
}
nobody
  • 19,010
  • 17
  • 53
  • 73
  • 4
    When I need to use path "/" and use cookie.setPath("/; HttpOnly;") it generates cookie with Path="/; HttpOnly;" and Chrome wrongly evaluates the path as "/ value (note the quotation mark). Even though I upvoted this answer first I ended up with another answer here which uses the getHttpOnlyCookieHeader(...) helper method. – petrsyn Nov 28 '14 at 14:39
4

For Java Enterprise Edition versions prior to JEE 6, say Servlet 2.5, you could find a workaround from here at OWASP. Below is an example:

    /**
     * Issue a cookie to the browser
     * 
     * @param response
     * @param cookieName
     * @param cookieValue
     * @param cookiePath
     * @param maxAgeInSeconds
     */
    public static void issueCookieHttpOnly(HttpServletResponse response, 
            String cookieName, 
            String cookieValue, 
            String cookiePath, 
            long maxAgeInSeconds) {

        Date expireDate= new Date();
        expireDate.setTime (expireDate.getTime() + (1000 * maxAgeInSeconds));
        // The following pattern does not work for IE.
        // DateFormat df = new SimpleDateFormat("dd MMM yyyy kk:mm:ss z");

        // This pattern works for Firefox, Chrome, Safari and Opera, as well as IE.
        DateFormat df = new SimpleDateFormat("EEE, dd-MMM-yyyy kk:mm:ss z");
        df.setTimeZone(TimeZone.getTimeZone("GMT"));
        String cookieExpire = df.format(expireDate);

        StringBuilder sb = new StringBuilder(cookieName);
        sb.append("=");
        sb.append(cookieValue);
        sb.append(";expires=");
        sb.append(cookieExpire);
        sb.append(";path=");
        sb.append(cookiePath);
        sb.append(";HttpOnly");

        response.setHeader("SET-COOKIE", sb.toString());
    }
Yuci
  • 17,258
  • 5
  • 80
  • 93
4

If you don't want to use:

response.addHeader("Set-Cookie","name=value; HttpOnly");

then you can use the below code in servlet 2.5. It will work perfect in chrome, firefox and IE11 .

Cookie cookie = new Cookie(cookieName, cookieValue);

cookie.setPath(";Path=/;HttpOnly;");
cookie.setSecure(isSecureCookie);
cookie.setMaxAge(maxAge);

response.addCookie(cookie);

Note : As you know that we don't have setHttpOnly() method in servlet 2.5 version, so instead of this you can use:

setPath(";Path=/;HttpOnly;");

it will create a cookie with the path "/" and make the Cookie as HttpOnly

Draken
  • 3,049
  • 13
  • 32
  • 49
shrikant
  • 504
  • 5
  • 11
3

For Servlet API 2.5, you can use

response.addHeader("Set-Cookie","name=value; HttpOnly");

Be careful with the use of response.setHeader() because it deletes all the other cookies, for example, the JSESSIONID cookie.

dpinya
  • 514
  • 5
  • 13
1

Spring does this using reflection without breaking on servlet 2.5 containers.

Method setHttpOnlyMethod = ReflectionUtils.findMethod(Cookie.class, "setHttpOnly", boolean.class);
if (setHttpOnlyMethod != null) {
    ReflectionUtils.invokeMethod(setHttpOnlyMethod, cookie, Boolean.TRUE);      
}

However setHttpOnly method is only available on Servlet 3.0 onward only.

Fahim Farook
  • 1,408
  • 2
  • 12
  • 33
  • 1
    It's not a good Idea: If you can use reflection to find the setHttpOnly method on your production / develop environment, than you should fix your project dependencies first. Its not what OP was asking about. – mrak Sep 08 '16 at 08:23
  • This worked for me when deploying a servlet 2.5 app to a servlet 3.0+ container. Trying to append HttpOnly in the comment did not work as the comment gets quoted. I believe adding it to the path would have the same result but I did not try that. – splashout May 20 '20 at 00:55
1

If you don't want to hardcode HttpOnly; or don't like to add header, use apache shiro like this:

void addCookie(javax.servlet.http.Cookie httpCookie,
               HttpServletRequest request,
               HttpServletResponse response) {
    org.apache.shiro.web.servlet.Cookie cookie =
                 new org.apache.shiro.web.servlet.SimpleCookie(httpCookie.getName());

    cookie.setValue(httpCookie.getValue());
    cookie.setPath(httpCookie.getPath());
    // set other stuff from the original httpCookie
    cookie.setHttpOnly(true);

    cookie.saveTo(request, response);
}
Ean V
  • 4,451
  • 5
  • 28
  • 35
-1
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setPath("/");
cookie.setMaxAge(-1);
response.addCookie(cookie);

Actually in my case, this code not work exactly.
Path value are not "/"

But add this cookie.setComment("; HttpOnly;"); works fine!

sayingu
  • 1,921
  • 3
  • 16
  • 24