Java Web 应用 Cookie 安全指南

背景

Java Web 应用中,如果没有对 JESSIONID 这类 Cookie 信息设置 httpOnly 属性,就存中这种风险:

可以通过 js 的 document.cookie 打印会话信息,并窃取或操纵客户会话和 cookie,它们可能用于模仿合法用户,从而使黑客能够以该用户身份查 看或变更用户记录以及执行事务。

此外,会话 ID 应该在登陆成功后重置,迫使客户端得到一个新的会话 ID,这两项是会话相关的安全内容。本文将整理重置会话的方法和不同服务器对 httpOnly 属性支持的情况。

登陆成功后重置 httpSession

会话标识更新操作,是指在用户登录成功后,将旧的 Request 信息获取到一个临时对象中,然后调用会话对象的 invalidate 方法,再重新回写到新的会话对象,常规代码如下:

/**
     * 重置sessionid,原session中的数据自动转存到新session中
     * @param request
     */
    private  HttpSession renewSessionId(HttpServletRequest request){
        HttpSession session = request.getSession(false);
        //首先将原session中的数据转移至一临时map中
        Map<String,Object> tempMap = new HashMap<String,Object>();
        Enumeration<String> sessionNames = session.getAttributeNames();
        while(sessionNames.hasMoreElements()){
            String sessionName = sessionNames.nextElement();
            tempMap.put(sessionName, session.getAttribute(sessionName));
        }

        //注销原session,为的是重置sessionId
        session.invalidate();

        //将临时map中的数据转移至新session
        session = request.getSession(true);
        logger.info("after session id: " + session.getId());
        for(Map.Entry<String, Object> entry : tempMap.entrySet()){
            session.setAttribute(entry.getKey(), entry.getValue());
        }

        return session;
    }
复制代码

httpOnly 属性

Tomcat 下,request 的 Cookie 数量只有一个 JSESSIONID ,但是 Jboss 下有两个,为什么呢?

在这里插入图片描述

Tomcat 和 Jboss 的 httpOnly 配置

Tomcat 默认是开启了 httpOnly 的,它在 context.xml 配置中是通过

Context useHttpOnly="true"
复制代码

属性控制的,默认是 true 开启的,所以我们在一个 web 应用中,抓包的响应头域会自动带着这个属性。

在这里插入图片描述
使用 js 获取 cookie 是空的,
在这里插入图片描述

Jboss 的 httpOnly

部署在 jboss 服务器上的应用,它的会话是可以通过 js 获取到的:

在这里插入图片描述
所以为了兼容所有服务器,保守的措施是,在登陆成功后,对 Response 的 Header 中关于会话的信息单独添加 httpOnly 属性:

response.setHeader("Set-Cookie",httpResponse.getHeader("Set-Cookie")+";HttpOnly");
复制代码

编程启示录

从这个 httpOlny 属性来看, Tomcat 的安全配置比 Jboss 要好呢。因为本地一直用 Tomcat 部署,所以总是无法复现这个问题,后来对比想了一下可能是部署服务器不同,继续验证果然在此。

猜你喜欢

转载自juejin.im/post/5eae2bab5188256d6d6ba966