【问题标题】:Setting HTTPONLY for Classic Asp Session Cookie为经典 Asp 会话 Cookie 设置 HTTPONLY
【发布时间】:2011-02-28 18:15:06
【问题描述】:

有人知道如何在经典的 ASP 会话 cookie 上设置 HTTPONLY 吗?

这是在漏洞扫描中被标记的最后一件事,需要尽快修复,因此感谢您的帮助。

~~~关于我的问题的更多信息~~~

谁能帮我解决这个问题?

我需要知道如何在 ASP & IIS 默认创建的 ASPSESSION cookie 上设置 HTTPONLY。

这是服务器自动为所有asp页面创建的cookie。

如果需要,我可以在整个站点的所有 cookie 上设置 HTTPONLY。

任何有关如何做到这一点的帮助将不胜感激。

谢谢

谢谢 艾略特

【问题讨论】:

  • 这是个好问题。你知道怎么做吗?
  • 你目前的解决方案是什么???

标签: asp-classic httponly session-cookies


【解决方案1】:

Microsoft 包含一个对所有出站 cookie 使用 ISAPI 过滤器的示例:http://msdn.microsoft.com/en-us/library/ms972826

或者可以使用URL重写http://forums.iis.net/p/1168473/1946312.aspx

<rewrite>
        <outboundRules>
            <rule name="Add HttpOnly" preCondition="No HttpOnly">
                <match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
                <action type="Rewrite" value="{R:0}; HttpOnly" />
                <conditions>
                </conditions>
            </rule>
            <preConditions>
                <preCondition name="No HttpOnly">
                    <add input="{RESPONSE_Set_Cookie}" pattern="." />
                    <add input="{RESPONSE_Set_Cookie}" pattern="; HttpOnly" negate="true" />
                </preCondition>
            </preConditions>
        </outboundRules>
    </rewrite>

【讨论】:

  • 虽然这行得通 - 我必须建议,如果您的任何经典 ASP 页面有 Response.Buffer=false ,该页面将是纯垃圾。
  • 任何人在实现此代码时遇到问题,您必须首先为 IIS 启用 URL 重写 [iis.net/downloads/microsoft/url-rewrite]
  • 对我来说,开发工具中的 HTTP 标志设置为 true,但一秒钟后,该标志将被删除。这和使用 HTTPS 有关系吗?
  • 遗憾的是,IIS 的 URL 重写在集群中不起作用:-(
【解决方案2】:

如果您有 IIS7 +,则需要确保安装了 URL 重写模块。您可以使用 Web 平台安装程序安装它。 Web 平台安装程序可以在您网站的功能视图中找到。您需要以管理员身份运行 IIS 管理器。

在您网站的功能视图中单击 Web 平台安装程序:

确保安装了 URL 重写服务器产品。如果不是,请安装它。

安装 URL 重写服务器产品后,您可以使用网站上的 URL 重写功能添加规则,为您的会话 ID cookie 添加 HttpOnly。

如果不存在,您应该会看到为您的 ASP 站点创建的 web.config 文件。它将具有以下内容:

如果您在 Firefox 中使用 Firebug 来检查您的 cookie,您现在应该会看到 HttpOnly 标志集:

【讨论】:

  • 很好解释..干得好!!
  • 可爱的解释。我将添加以下详细信息。您需要创建一个前提条件。这样做时,将其命名为“No HttpOnly”。使用“正则表达式”,本地分组“匹配所有”。添加两个条件。首先,{RESPONSE_SET_COOKIE},匹配模式,“.” (不带引号)。第二,{RESPONSE_SET_COOKIE},不匹配模式,“;No HttpOnly”(不带引号)。
【解决方案3】:
Response.AddHeader "Set-Cookie", "CookieName=CookieValue; path=/; HttpOnly" 

来源:http://www.asp101.com/tips/index.asp?id=160

【讨论】:

  • 因为这个 cookie 默认是由 ASP 和 IIS 创建的,所以我们没有机会以编程方式添加它。我想知道它是否是其他地方的其他设置???我更新了 IIS Metabase.xml 中的 KeepASPCookieSecure,我想知道这是否可能是类似的修复??
  • 请注意,使用“addheader”添加 cookie 不会在同一个请求中将 cookie 添加到 ASP 中的 request.cookies() 集合中。 cookie 仅在浏览器往返后的 request.cookies 范围内可见。这与常规的 response.cookies() 命令不同,后者将使 cookie 在同一请求的 request.cookies 范围内可用。
【解决方案4】:

我编译了Microsoft's ISAPI filter example。这解决了我的问题。

ISAPI DLL 是 here

欢迎下载。

【讨论】:

    【解决方案5】:

    可以在 web.config 中使用 URLrewrite 将 ASP 会话 cookie 设置为 HttpOnly:

    <rewrite>
        <outboundRules>
            <rule name="Secure ASP session cookie">
                <match serverVariable="RESPONSE_Set_Cookie" pattern="ASPSESSIONID(.*)" negate="false" />
                <!--<action type="Rewrite" value="ASPSESSIONID{R:1}; HttpOnly; Secure" />-->
                <action type="Rewrite" value="ASPSESSIONID{R:1}; HttpOnly" />
            </rule> 
        </outboundRules>
    </rewrite>
    

    也可以使用 URLrewrite 使所有 cookie 为 HttpOnly / Secure,但有时您需要 cookie 在 JavaScript 中是可读的,所以这是我前段时间编写的用于创建常规 cookie 的函数和子例程的集合,可以启用或禁用“HttpOnly”和“Secure”:

    ' *********************************************************************************************************
    ' Set a cookie
    ' *********************************************************************************************************
    
    sub set_cookie(cookie_name,cookie_value,cookie_path,http_only,secure,expire)
    
        Dim cookie_header, split_expire, expire_value
    
        ' Set the cookie name and value. The value must be URL encoded.
    
        cookie_header = cookie_name & "=" & server.URLEncode(cookie_value) & "; "
    
        ' To set cookies that can be accessed by sub domains, you need to specify the domain as
        ' ".mydomain.com". If no domain is specified then the cookie will be set as "host only",
        ' and only be accessible to the domain it was set on. Un-comment to disable host only:
    
        'cookie_header = cookie_header & "Domain=.mydomain.com; "
    
        ' Check the expire value for a specific expiry length (e.g; "1 year")
        ' For session cookies, the expiry should be set to null.
    
        if NOT isDate(expire) AND NOT isNull(expire) then
    
            ' Remove any double spaces and trim the value.
    
            expire = replace(expire,"  "," ")
            expire = trim(expire)
    
            ' Split on space to separate the expiry value from the expiry unit.
    
            split_expire = split(expire," ")
    
            ' A uBound value of 1 is expected
    
            if uBound(split_expire) = 1 then
    
                expire_value = split_expire(0)
                if NOT isNumeric(expire_value) then exit sub
                expire_value = int(expire_value)
    
                select case lCase(split_expire(1))
    
                    case "minute","minutes"
                        expire = DateAdd("n",expire_value,Now())
                    case "hour","hours"
                        expire = DateAdd("h",expire_value,Now())
                    case "day","days"
                        expire = DateAdd("d",expire_value,Now())
                    case "week","weeks"
                        expire = DateAdd("ww",expire_value,Now())
                    case "month","months"
                        expire = DateAdd("m",expire_value,Now())
                    case "year","years"
                        expire = DateAdd("yyyy",expire_value,Now())
                    case else
                        ' unknown expiry unit, exit sub
                        exit sub
                end select
    
            else
    
                ' Unexpected uBound. This means no space was included when specifying the expiry length
                ' or multiple spaces were included. 
    
                exit sub
    
            end if
    
        end if
    
        ' Set the expiry date if there is one. If the expiry value is null then no expiry date will be set and 
        ' the cookie will expire when the session does (a session cookie).
    
        ' The expiry date can only be UTC or GMT. Be sure to check your servers timezone and adjust accordingly.
    
        if isDate(expire) then
    
            ' The cookie date needs to be formatted as:
            ' WeekDayName(shortened), day-monthName(shortened)-year timestamp(00:00:00) GMT/UTC
    
            expire = cDate(expire)
            cookie_header = cookie_header & "expires=" &_ 
            weekday_name(WeekDay(expire),true) & ", " &_ 
            ZeroPad(Day(expire)) & "-" &_ 
            month_name(Month(expire),true) & "-" &_ 
            year(expire) & " " &_ 
            timeFromDate(expire) & " UTC; "
    
        end if
    
        cookie_header = cookie_header & "path=" & cookie_path & "; "
    
        ' HttpOnly means cookies can only be read over a HTTP (or HTTPS) connection.
        ' This prevents JavaScript from being able to read any cookies set as HttpOnly.
        ' HttpOnly should always be used unless you're setting a cookie that needs to
        ' be accessed by JavaScript (a CSRF token cookie for example).
    
        if http_only then
            cookie_header = cookie_header & "HttpOnly; "
        end if
    
        ' A "secure" cookie means the cookie can only be accessed over a HTTPS connection.
        ' If we try to create a secure cookie over a none HTTPS connection it will be 
        ' rejected by most browsers. So check the HTTPS protocol is ON before setting a
        ' cookie as secure. This check is particularly useful when running on a localhost,
        ' most localhosts don't use HTTPS, so trying to set a Secure cookie won't work. 
    
        if secure AND uCase(request.ServerVariables("HTTPS")) = "ON" then
            cookie_header = cookie_header & "Secure; "
        end if          
    
        ' Add the header and remove the trailing ";"
    
        response.AddHeader "Set-Cookie",left(cookie_header,len(cookie_header)-2)
    
    end sub
    
    
    ' *********************************************************************************************************
    ' Delete a cookie   
    ' *********************************************************************************************************
    
    sub delete_cookie(cookie_name)
    
        ' There is no header for deleting cookies. Instead, cookies are modified to a date that
        ' has already expired and the users browser will delete the expired cookie for us.
    
        response.AddHeader "Set-Cookie",cookie_name & "=; " &_
        "expires=Thu, 01-Jan-1970 00:00:00 UTC; path=/"
    
    end sub
    
    
    ' *********************************************************************************************************
    ' When the LCID is set to 1033 (us) vbLongTime formats in 12hr with AM / PM, this is invalid for a cookie
    ' timestamp. Instead, we use vbShortTime which returns the hour and minute as 24hr with any LCID, then use
    ' vbLongTime to get the seconds, and join the two together.
    ' *********************************************************************************************************
    
    function timeFromDate(ByVal theDate)
        Dim ts_secs : ts_secs = split(FormatDateTime(theDate,vbLongTime),":")       
        if uBound(ts_secs) = 2 then
            timeFromDate = FormatDateTime(theDate,vbShortTime) & ":" & left(ts_secs(2),2)
        else
            timeFromDate = "00:00:00"   
        end if
    end function
    
    
    ' *********************************************************************************************************
    ' WeekDayName and MonthName will return a value in the native language based on the LCID.
    ' These are custom functions used to return the weekday and month names in english, 
    ' reguardless of the LCID
    ' *********************************************************************************************************
    
    function weekday_name(weekday_val, shorten)
    
        select case weekday_val
    
            case 1
                if shorten then weekday_name = "Sun" else weekday_name = "Sunday"
            case 2
                if shorten then weekday_name = "Mon" else weekday_name = "Monday"
            case 3
                if shorten then weekday_name = "Tue" else weekday_name = "Tuesday"
            case 4
                if shorten then weekday_name = "Wed" else weekday_name = "Wednesday"
            case 5
                if shorten then weekday_name = "Thu" else weekday_name = "Thursday"
            case 6
                if shorten then weekday_name = "Fri" else weekday_name = "Friday"
            case 7
                if shorten then weekday_name = "Sat" else weekday_name = "Saturday"
    
        end select
    
    end function
    
    function month_name(month_val, shorten)
    
        select case month_val
    
            case 1
                if shorten then month_name = "Jan" else month_name = "January"
            case 2
                if shorten then month_name = "Feb" else month_name = "February"
            case 3
                if shorten then month_name = "Mar" else month_name = "March"
            case 4
                if shorten then month_name = "Apr" else month_name = "April"
            case 5
                month_name = "May"
            case 6
                if shorten then month_name = "Jun" else month_name = "June"
            case 7
                if shorten then month_name = "Jul" else month_name = "July"
            case 8
                if shorten then month_name = "Aug" else month_name = "August"
            case 9
                if shorten then month_name = "Sep" else month_name = "September"
            case 10
                if shorten then month_name = "Oct" else month_name = "October"
            case 11
                if shorten then month_name = "Nov" else month_name = "November"
            case 12
                if shorten then month_name = "Dec" else month_name = "December"
    
        end select
    
    end function
    
    
    ' *********************************************************************************************************
    ' Prefix a 1 digit number with a 0. Used in date formatting
    ' *********************************************************************************************************
    
    function zeroPad(theNum)
        if len(theNum) = 1 then
            zeroPad = cStr("0" & theNum)
        else
            zeroPad = theNum
        end if
    end function
    

    例子:

    ' **************************************************************************************************************
    ' set_cookie(COOKIE NAME, COOKIE VALUE, COOKIE PATH, HTTPONLY (BOOLEAN), SECURE (BOOLEAN), EXPIRY DATE / LENGTH)
    ' **************************************************************************************************************
    
    ' Expire on a specific date: 
    
    call set_cookie("cookie_name1","cookie value","/",true,true,"15 Jan 2019 12:12:12")
    call set_cookie("cookie_name2","cookie value","/",true,true,"15 January 2019 12:12:12")
    
    call set_cookie("cookie_name3","cookie value","/",true,true,"Jan 15 2019 12:12:12")
    call set_cookie("cookie_name4","cookie value","/",true,true,"January 15 2019 12:12:12")
    
    call set_cookie("cookie_name5","cookie value","/",true,true,"Jan 15 2019")
    call set_cookie("cookie_name6","cookie value","/",true,true,"January 15 2019")
    
    ' Expire when the session ends (a sesson cookie):
    
    call set_cookie("cookie_name7","cookie value","/",true,true,null)
    
    ' Specify an expiry length:
    
    call set_cookie("cookie_name8","cookie value","/",true,true,"20 minutes")
    call set_cookie("cookie_name9","cookie value","/",true,true,"1 hour")
    call set_cookie("cookie_name10","cookie value","/",true,true,"10 days")
    call set_cookie("cookie_name11","cookie value","/",true,true,"3 weeks")
    call set_cookie("cookie_name12","cookie value","/",true,true,"1 year")
    
    ' Delete a cookie:
    
    call delete_cookie("cookie_name")
    
    ' This would also work for deleting a cookie:
    
    call set_cookie("cookie_name","","/",false,false,"-1 year")
    

    【讨论】:

      【解决方案6】:

      旧但不错,将其添加到全局包含的 asp 中:

      Dim AspSessionCookie
      AspSessionCookie = Request.ServerVariables("HTTP_COOKIE")
      
      If instr(AspSessionCookie,"ASPSESSIONID") > 0 Then
          AspSessionCookie = "ASPSESSIONID" & Split(AspSessionCookie,"ASPSESSIONID")(1)
          If  InStr(1,AspSessionCookie,";") then
              AspSessionCookie = Split(AspSessionCookie,";")(0)        
          End If
      
          Response.AddHeader "Set-Cookie", AspSessionCookie & ";HttpOnly"
      End If
      

      【讨论】:

        【解决方案7】:

        This page 有很多与您的问题相关的信息。

        .NET 1.1 没有添加 HttpOnly,因为它还没有被发明出来。

        如果您的应用程序将在 .NET 2.0 下运行(我将几个 Classic ASP 站点移至 2.0 几乎没有改变)默认设置 HttpOnly。

        如果我没看错的话,您可以获取 Session cookie 并将; HttpOnly; 添加到它上面。他举了一个java例子:

        String sessionid = request.getSession().getId();
        response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid + "; HttpOnly");
        

        最后,他建议:

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

        编辑添加:对于那些认为迁移到 .NET(可以适应大多数经典 ASP 代码不变)过于剧烈的变化而无法获得如此小的功能的人,我对 ISAPI 过滤器的体验是他们也可能是一个主要的痛苦,在一些常见的情况下(共享主机)你根本不能使用它们。

        【讨论】:

        • 很抱歉,如果您的反对意见不清楚,但是将整个站点从经典 ASP 更改为 .NET 似乎是一项相当重大的任务,只是为了获得 HttpOnly 会话 cookie。我认为这就是反对票的原因。
        猜你喜欢
        • 2016-06-04
        • 2017-02-04
        • 2016-04-15
        • 1970-01-01
        • 2012-11-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多