HttpOnly

什么是HttpOnly?

根据Microsoft开发人员网络,HttpOnly是Set-Cookie HTTP响应头中包含附加标志生成cookie时使用HttpOnly标志有助于减轻客户端脚本访问受保护的cookie的风险(如果浏览器支持)。

  • 下面的示例显示了HTTP响应头中使用的语法:
Set-Cookie: <name>=<value>[; <Max-Age>=<age>]
[; expires=<date>][; domain=<domain_name>]
[; path=<some_path>][; secure][; HttpOnly]

如果HttpOnly标志(可选)包含在HTTP响应标头中,则无法通过客户端脚本访问cookie(再次,如果浏览器支持此标志)。因此,即使存在跨站点脚本(XSS)缺陷,并且用户意外访问利用此缺陷的链接,浏览器(主要是Internet Explorer)将不会向第三方显示该cookie。

如果浏览器不支持HttpOnly,并且网站尝试设置一个HttpOnly cookie,则HttpOnly标志将被浏览器忽略,从而创建一个传统的脚本可访问cookie。因此,cookie(通常是您的会话cookie)易于被恶意脚本窃取修改。缓解

使用HttpOnly减轻最常见的XSS攻击

据Microsoft Windows安全Windows计划组的高级安全项目经理迈克尔·霍华德Michael Howard)表示,大多数XSS攻击都是针对窃取会话Cookie的。服务器可以通过在其创建的cookie上设置HttpOnly标志来帮助缓解此问题,表示该客户端不能访问cookie。

如果支持HttpOnly的浏览器检测到包含HttpOnly标志的cookie,并且客户端脚本代码尝试读取cookie,则浏览器返回一个空字符串作为结果。这样可以防止恶意(通常是XSS)代码将数据发送到攻击者的网站,从而导致攻击失败。

使用Java设置HttpOnly

由于采用了Java Servlet 3.0技术的Java Enterprise Edition 6(JEE 6),它在编程上易于在Cookie上设置HttpOnly标志。

事实上setHttpOnlyisHttpOnly方法在Cookie接口[1]中可用,也可用于会话cookie(JSESSIONID)[2]

Cookie cookie = getMyCookie("myCookieName");
cookie.setHttpOnly(true);

此外,由于JEE 6还HttpOnly通过在部署描述符中应用以下配置在会话cookie中声明式地设置标志WEB-INF/web.xml

<session-config> 
 <cookie-config> 
  <http-only> true </ http-only> 
 </ cookie-config> 
</ session-config>

对于JEE 6 之前的 Java Enterprise Edition版本,常见的解决方法SET-COOKIE使用明确附加该HttpOnly标志的会话cookie值来覆盖HTTP响应头:

String sessionid = request.getSession().getId();
// be careful overwriting: JSESSIONID may have been set with other flags
response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid + "; HttpOnly");

在这种情况下,尽管适用于该HttpOnly标志,覆盖也是不鼓励的,因为JSESSIONID可能已经设置为其他标志。一个更好的解决方法是照顾先前设置的标志或使用ESAPI#Java_EE库:实际上addCookieSecurityWrapperResponse [3]的方法会为我们处理以前设置的falgs。所以我们可以编写一个servlet过滤器,如下所示:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    HttpServletResponse httpServletResponse = (HttpServletResponse) response;
    // if errors exist then create a sanitized cookie header and continue
    SecurityWrapperResponse securityWrapperResponse = new SecurityWrapperResponse(httpServletResponse, "sanitize");
    Cookie[] cookies = httpServletRequest.getCookies();
    if (cookies != null) {
        for (int i = 0; i < cookies.length; i++) {
            Cookie cookie = cookies[i];
            if (cookie != null) {
                // ESAPI.securityConfiguration().getHttpSessionIdName() returns JSESSIONID by default configuration
                if (ESAPI.securityConfiguration().getHttpSessionIdName().equals(cookie.getName())) {
                    securityWrapperResponse.addCookie(cookie);
                }
            }
        }
    }
    filterChain.doFilter(request, response);
}

一些实现JEE 5的Web应用程序服务器和实现Java Servlet 2.5(JEE 5的一部分)的servlet容器也允许创建HttpOnly会话cookie:

  • 的Tomcat 6context.xml设定context标记的属性useHttpOnly [4]如下:
<?xml version =“1.0”encoding =“UTF-8”?> 
<Context path =“/ myWebApplicationPath”useHttpOnly =“true”>
  • JBoss的5.0.1JBOSS EAP 5.0.1\server\<myJBossServerInstance>\deploy\jbossweb.sar\context.xml设置SessionCookie标签[5]如下:
<Context cookies =“true”crossContext =“true”> 
  <SessionCookie secure =“true”httpOnly =“true”/>
  • IBM Websphere为会话cookie提供HTTPOnly作为配置选项。

http://pic.dhe.ibm.com/infocenter/tivihelp/v33r1/topic/com.ibm.mam.inswas.doc/install/t_configuringthehttponlyattribute.html

使用.NET设置HttpOnly
  • 通过默认情况下.NET 2.0套HTTPOnly属性的
    1. 会话ID
    2. 表单验证cookie


在.NET 2.0中,也可以通过HttpCookie对象为所有自定义应用程序cookie设置HttpOnly

  • 通过web.config在system.web / httpCookies元素中
<httpCookies httpOnlyCookies =“true”...> 
  • 或以编程方式

C#代码:

HttpCookie myCookie = new HttpCookie("myCookie");
myCookie.HttpOnly = true;
Response.AppendCookie(myCookie);

VB.NET代码:

Dim myCookie As HttpCookie = new HttpCookie("myCookie")
myCookie.HttpOnly = True
Response.AppendCookie(myCookie)
  • 但是,在.NET 1.1中,您必须手动执行此操作,例如,
Response.Cookies [cookie] .Path + =“; HttpOnly”;
使用Python(cherryPy)设置HttpOnly

Python代码(cherryPy):
要在Cherrypy会话中使用HTTP-only Cookie,只需在配置文件中添加以下行:

tools.sessions.httponly = True

如果您使用SLL,您还可以使您的Cookie安全(加密),以避免“中间人”的cookies读取:

tools.sessions.secure = True
使用PHP设置HttpOnly

PHP支持自5.2.0版(2006年11月)起设置HttpOnly标志。

对于由PHP管理的会话cookie,该标志通过参数永久设置HttpOnly的 php.ini PHP手册中

session.cookie_httponly = True

或通过函数[6]在一个脚本中和之间:

void session_set_cookie_params(int $ lifetime [,string $ path [,string $ domain   
                                  [,bool $ secure = false [,bool $ httponly = false]]]]

对于setcookie()中的应用程序cookie最后一个参数设置HttpOnly标志[7]

bool setcookie(string $ name [,string $ value [,int $ expire = 0 [,string $ path   
                 [,string $ domain [,bool $ secure = false [,bool $ httponly = false]]]]]]

Web应用程序防火墙

如果代码更改不可行,Web应用程序防火墙可用于将HttpOnly添加到会话cookie中:

  • Mod_security - 使用SecRule和Header指令[8]
  • ESAPI WAF [9]使用add-http-only-flag指令[10]

测试Web浏览器的HttpOnly支持

在两个浏览器(Internet Explorer 7Opera 9.22)上进行了以下测试,以便在HttpOnly标志正确执行时演示结果。如你所见,IE7正确地执行了HttpOnly标志,而Opera没有正确地执行HttpOnly标志。

禁用HttpOnly
1)选择关闭HttpOnly的选项,如图2所示。
图2 - 禁用HttpOnly
2)关闭HttpOnly后,选择“读取Cookie”按钮。 
  • 屏幕上将显示警告对话框,通知您,由于HttpOnly未启用“unique2u”cookie已成功读取,如图3所示。
图3 - 用HttpOnly关闭成功读取Cookie
3)当HttpOnly保持禁用时,选择“写Cookie”按钮。
  • 屏幕上将显示警告对话框,通知您,由于HttpOnly未启用“unique2u”cookie在客户端已成功修改,如图4所示
图4 - Cookie成功用HttpOnly关闭
  • 如你所见,到目前为止,浏览没有HttpOnly是一个潜在的威胁。接下来,我们将启用HttpOnly来演示这个标志如何保护cookie。
启用HttpOnly
4)选择单选按钮启用HttpOnly,如图5所示。
图5 - 启用HttpOnly
5)启用HttpOnly后,选择“读取Cookie”按钮。
  • 如果浏览器正确地执行了HttpOnly标志,则警报对话框将仅显示会话ID,而不显示“unique2u”cookie的内容,如图6所示
图6 - 强制Cookie读取保护
  • 但是,如果浏览器没有正确执行HttpOnly标志,则警报对话框将显示“unique2u”cookie和会话ID,如下图7所示。
图7 - 未强制的Cookie读取保护
  • 最后,我们将测试浏览器是否允许使用HttpOnly启用对cookie的写入访问
6)选择“写Cookie”按钮。
  • 如果浏览器正确地执行了HttpOnly标志,则客户端修改将在写入“unique2u”cookie时失败,并且将显示仅包含会话ID的警报对话框,如图8所示
图8 - 强制Cookie写保护
  • 但是,如果浏览器不强制“unique2u”cookie的HttpOnly标志的写保护属性,那么cookie将在客户端被成功修改为HACKED如图9所示。
图9 - 非强制Cookie写保护
 
【注】本文转自:https://www.owasp.org/index.php/HttpOnly#Testing_Web_Browsers_for_HttpOnly_Support
posted @ 2017-06-27 23:00  0nth3way  阅读(2247)  评论(0编辑  收藏  举报