we are required to enable HttpOnly in all our servers because it presents a potential XSS vulnerability. For more information on httpOnly, please read https://www.owasp.org/index.php/HttpOnly.
It’s very easy to enable it globally in .Net and Apache/PHP.
.Net 2.0+
//add the following line to the web.config system.web section
<httpCookies httpOnlyCookies="true">
Apache
//add the following line to the http.conf. Make sure mod_headers is enabled
Header edit Set-Cookie ^(.*)$ $1;HttpOnly
The sad story is that, one of our legacy server is running classic ASP…
I googled a few days and cannot find a working solution. Microsoft has one example on how to set cookie to httponly through ISAPI Filter (http://msdn.microsoft.com/en-us/library/ms972826), but only works for one cookie situation, which means no cookie because there is already one by default: ASPSESSIONIDxxxx.
After reading some documentation, I modified the Microsoft example to make it work for multiple cookies.
First, you need create a new Win32 Dynamic-Link Library project in Visual C++ 6.0 and create two files: httponly.cpp and httponlydef. Below are the source code for both files.
httponly.cpp
#define STRSAFE_NO_DEPRECATE
#include <windows.h>
#include <httpfilt.h>
#include "tchar.h"
#include "strsafe.h"
BOOL WINAPI GetFilterVersion(HTTP_FILTER_VERSION *pVer)
{
pVer->dwFlags = SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_SEND_RESPONSE;
pVer->dwFilterVersion = HTTP_FILTER_REVISION;
strcpy(pVer->lpszFilterDesc, "HttpOnly Filter, Version 1.0");
return TRUE;
}
// Portion of HttpOnly
DWORD WINAPI HttpFilterProc(
PHTTP_FILTER_CONTEXT pfc,
DWORD dwNotificationType,
LPVOID pvNotification) {
// Hard coded cookie length (2k bytes)
CHAR szCookie[2048];
DWORD cbCookieOriginal = sizeof(szCookie) / sizeof(szCookie[0]);
DWORD cbCookie = cbCookieOriginal;
HTTP_FILTER_SEND_RESPONSE *pResponse =
(HTTP_FILTER_SEND_RESPONSE*)pvNotification;
CHAR *szHeader = "Set-Cookie:";
CHAR *szHttpOnly = "; HttpOnly";
if (pResponse->GetHeader(pfc,szHeader,szCookie,&cbCookie)) {
/*if (SUCCEEDED(StringCchCat(szCookie,
cbCookieOriginal,
szHttpOnly))) {
if (!pResponse->SetHeader(pfc,
szHeader,
szCookie)) {
// Fail securely - send no cookie!
pResponse->SetHeader(pfc,szHeader,"");
}
} else {
pResponse->SetHeader(pfc,szHeader,"");
}*/
pResponse->SetHeader(pfc,szHeader,"");
CHAR outCookie[2048];
char * token;
// the last occurence of semicolon
char * semi;
token = strtok (szCookie,",");
while (token != NULL)
{
strcpy(outCookie, "");
strcat (outCookie, token);
semi = strrchr(token, ';');
//if the last character is ;
if(semi - token == strlen(token) - 1){
strcat (outCookie, " HttpOnly");
}
else{
strcat (outCookie, "; HttpOnly");
}
pResponse->AddHeader(pfc, szHeader, outCookie);
memset(outCookie, 0, 2048);
token = strtok (NULL, ",");
}
}
return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
httponly.def
LIBRARY HttpOnly
EXPORTS
GetFilterVersion
HttpFilterProc
For information on how to create a ISAPI filter using Visual C++, you can refer to http://blogs.msdn.com/b/david.wang/archive/2005/12/19/howto-compile-and-use-my-isapi-code-samples.aspx.