Setting an httponly cookie with javax.servlet 2.5
Asked Answered
H

9

24

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?

Harar answered 30/10, 2012 at 20:29 Comment(1)
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?Sotted
I
10

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));
Intrusive answered 21/3, 2014 at 2:51 Comment(3)
where do I set this class? or how do I configure it?Ethelind
thanks @Intrusive but I still have doubt, I see the class and all its properties, but, how can I enable this on my app?Ethelind
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);Thecla
M
5

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);
}
Mephitic answered 5/8, 2014 at 14:26 Comment(1)
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.Haddix
N
5

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());
    }
Nasty answered 27/5, 2015 at 16:42 Comment(0)
O
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

Overzealous answered 25/1, 2017 at 15:17 Comment(0)
H
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.

Hurter answered 18/1, 2016 at 16:24 Comment(0)
P
2

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.

Pirtle answered 3/6, 2016 at 9:57 Comment(2)
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.Sonata
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.Schneider
E
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);
}
Emaciation answered 18/4, 2017 at 6:46 Comment(0)
S
0

The example of @Yuci to add a cookie to the response header has some failures in my environment. Mainly the date formatting was wrong and if you addHeader you don't remove other cookies as with setHeader. So this is my working code to set a HttpOnly and Secure cookie with Servlet API 2.5:

public static void addHttpOnlyCookie(HttpServletResponse response,
                                     String cookieName,
                                     String cookieValue,
                                     String cookiePath,
                                     long maxAgeInSeconds) {

    Date expireDate = new Date();
    expireDate.setTime(expireDate.getTime() + 1000L * maxAgeInSeconds);
    DateFormat df = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
    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("; Secure; HttpOnly");

    response.addHeader("SET-COOKIE", sb.toString());
}

And beware, these setPath hacks definitely do not work. Don't do these, they do not work with Safari: cookie.setPath(";HttpOnly;");. <= wrong

Samurai answered 26/6, 2021 at 8:58 Comment(0)
O
-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!

Oilstone answered 9/2, 2017 at 9:9 Comment(1)
I tried this and it just puts HttpOnly inside a quoted comment and the browser ignores it.Schneider

© 2022 - 2024 — McMap. All rights reserved.