Home     Products      Support      Corporate     Sign In 
Support Knowledge Base, Article 1320
Product
FileUpEE
Title
Session loss in ASP.NET 2.0 using XFileEE with FileUpEE
Problem
Your file transfer application running in ASP.NET 2.0 and using XFileEE on the client may experience session loss during requests with chunked transfer-encoding turned on or the UseWinInet property of the XFrequest object set to false.

If your application is running under ASP.NET 2.0, during upload/download requests with XFRequest object’s TransferEncoding property set to 1 or UseWinInet property set to false, by default XFile will not include the ASP.NET session cookie when sending the request to the server. This behavior is not actually a problem with XFile, but rather it is being caused by a change in the way the session cookies are set in ASP.NET 2.0, which always create the session cookies with an HttpOnly attribute (see the MS KB article http://support.microsoft.com/kb/917412). This is a security feature added in the .NET Framework 2.0 to prevent cross-site scripting. This attribute makes the session cookie inaccessible through client-side script. The web browser that supports the HttpOnly attribute, for instance IE 6 SP1 and higher, retains the session cookie and sends it back when communicating with the server but it doesn’t share it with any third party (for further information see the MSDN article http://msdn.microsoft.com/en-us/library/ms533046.aspx).

When chunked-encoding is turned off or UseWinInet property is set to true (these are the default settings), XFile uses internally the WinInet APIs. WinInet is a system dll that is integrated with Internet Explorer. As the HTTP-only session cookie is accessible to the browser, WinInet has access to it and will send it along in the request to the server. On the other hand, when chunked-encoding is turned on or UseWinInet is set to false, XFile does not use WinInet, instead it uses its own HTTP-client when sending requests. Since the browser will not share HTTP-only session cookies, XFile is not able to pick it up and send along in the request. This would be the same for any client-side control or script.
Solution
There are two solutions to this problem:

Solution 1: Set the HttpOnly attribute for the session cookie to the false

You can programmatically access the session cookie and overwrite its HttpOnly setting to “false” by adding the following code in the global.asax file in your .NET application:

[C#] [VB.NET]  

  void Application_EndRequest(Object sender, EventArgs e)
  {
      if (Response.Cookies.Count > 0)
      {
          foreach (string s in Response.Cookies.AllKeys)
          {
              if (s == "ASP.NET_SessionId")
              {
                  Response.Cookies[s].HttpOnly = false;
              }
          }
      }
   }


This code simply loops through the response cookies collection and sets the HttpOnly attribute of the ASP.NET session cookie explicitly to false. After this change, XFile will be able to access the session cookie using its own HTTP-client and send it along in the request to the server.

Solution 2: Encrypt the HttpOnly session cookie using FileUpEE’s “Encryption” class and manually pass it to XFile’s headers collection

In FileUpEE version 5.3.0, we have added a new Encryption class to FileUpEE and a new AddEncryptedRequestHttpHeader method of XFile. By using these new features, you can programmatically access the session cookie and encrypt it using FileUpEE’s Encryption class in the Page_Load event handler in the server-side code of your XFile page. Then in the client-side XFile script, you can add the encrypted session cookie manually to the Cookie request header using XFRequest object’s AddEncryptedRequestHttpHeader method.

Encrypt the Http-Only ASP.NET session cookie using FileUpEE's new Encryption class inside the Page_Load event handler in the server-side code of the XFile page:

protected string sessionCookie;
protected string sessionCookieEncrypted;
protected int hasCookie;
    
protected void Page_Load(object sender, EventArgs e)
{
  //--- When the XFile page is loaded, check to see 
  //--- whether the request includes any cookies
  //--- If there are cookies, check if they include 
  //--- the ASP.NET session cookie. If found,
  //--- encrypt its value using the new "Encryption" class of FileUpEE
        
  if (!String.IsNullOrEmpty(Request.ServerVariables["HTTP_COOKIE"]))
  {
    string[] cookies =
       Request.ServerVariables["HTTP_COOKIE"].Split(new string[] { "; " },
 StringSplitOptions.RemoveEmptyEntries);

    foreach (string str in cookies)
    {
       if (str.Contains("ASP.NET_SessionId"))
               sessionCookie = str;
    } 

    if (sessionCookie != null)
    {
       hasCookie = 1;
       sessionCookieEncrypted = 
SoftArtisans.Net.Utilities.Encryption.Encrypt(sessionCookie);
    }    
  }           
}

Add the encrypted session cookie to the Cookie request header using XFRequest object’s new AddEncryptedRequestHttpHeader method in the client-side script of the XFile page:
function send() 
{
  //--- First make sure files have been selected to send.
  if(AXFFile.Count == 0)
  {
     alert("There are no files to upload.");
  }
  else
  {         
     //--- Disable the Upload button
     document.getElementById("btnUpload").disabled = true;            
             
     //--- Set timeout for XFile (in seconds). -1 is infinity
     AXFFile.XFRequest.Timeout = -1;
                      
     //--- This setting will turn on chunked transfer-encoding on XFile
     //--- Note: ASP.NET will not accept upload requests larger than 2 GB. 
     //--- To overcome this request size limitation, chunked transfer-encoding
     //--- must be used when sending the upload.
     AXFFile.XFRequest.TransferEncoding = 1;
            
     //--- Turn off UseWinInet to use XFile's own HTTP-client to send the request
     //AXFFile.XFRequest.UseWinInet = false;
            
     //--- Set the URL where you will upload the file to
     AXFFile.XFRequest.CurrentUrl = serverURL;
             
     var hasCookie = <%= hasCookie %>
     //--- If chunked turned on (or UseWinInet set to false) and has a
     //--- ASP.NET session cookie, manually add the encrypted session cookie 
     //--- to the Cookie request header using the
     //--- new "AddEncryptedRequestHttpHeader" method 
     //--- of the XFRequest object                                  
     if ((AXFFile.XFRequest.TransferEncoding > 0) ||
                     (!AXFFile.XFRequest.UseWinInet))
     {
         if(hasCookie > 0) 
         {
            AXFFile.XFRequest.AddEncryptedRequestHttpHeader("Cookie",
                                    "<%=sessionCookieEncrypted %>", true);
         }   
     } 

     try
     {
          //--- Begin the transfer
          AXFFile.Start();

     }
     catch(errorObject)
     {

     }
  }
}

By doing so, XFile will internally decrypt the session cookie value and send it as decrypted in the request to the server. Since the cookie value will be encrypted when passed to XFile, when viewing the XFile page’s source in the browser, the script will simply show a long chain of alpha-numeric characters with no indication for what the encryption was for. Using this approach, XFile will be able to send the session cookie along in the request using its own HTTP-client without needing to disable the HttpOnly attribute. This security feature added in .NET 2.0 will remain in place.

The attached sample project demonstrates how FileUpEE’s new encryption feature can be used during an upload with chunked-encoding turned on and a download with “UseWinInet” property set to false, while preserving the HttpOnly attribute of the session cookie. Follow the instructions below to set up the sample.

Setting up the attached sample:
  1. Extract the attached zipped project (KB1320_TwoTierNonResumableWebServer.zip) to a directory called "TwoTierNonResumableWebServer" and then create a virtual directory with the same name in IIS and map it to that physical location where you extracted the project folder.
  2. In IIS, make sure the sample's virtual directory is set to use ASP.NET 2.0.
  3. Create the "C:\Temp\FileUpEE\cache" directory on the server and make sure that the account that the sample application is running under in IIS has the "Read/Write/Modify" permissions to this directory. This will be the temporary caching location for FileUpEE's HttpModule in the upload sample.
  4. To make the configuration easier, the main application directory includes a "temp" folder. This folder in return includes the "DestinationDir" folder (the destination location where the upload sample will save the uploaded files) and the "samplefiles" folder which contains the sample download files (testfile1_1MB.txt and testfile2_1MB.txt) used in the download sample. Make sure the account that the application is running under in IIS has the "Read/Write/Modify" permissions to the "\temp" directory.
  5. The sample's Bin folder doesn't include the required FileUpEE dlls. You need to put your copy of the "FileUpEe.dll" and "FileUpEeModule.dll" into the Bin folder. You need to have FileUpEE version 5.3.0 or above.
  6. In the web.config file, update the "version" attribute for the FileUpEeModule in the <httpModules> section with your copy of the FileUpEeModule.dll (to find out the version, right-click the dll, go to Properties then the "version" tab)
  7. The sample's cab folder doesn't include XFileEE's cab file. Put your copy of the "SAXFileEE.cab" file in this folder. You need to use the cab file of XFileEE version 2.5.0 or above.
  8. In the "UploadXFileVisualEncryption.aspx" and "DownloadXFileVisualEncryption.aspx" files, update the version string in the "codebase" attribute in the <object> tag using your version of XFileEE (to find out the exact version of XFileEE that you are using, right-click your copy of the "xfileee.dll", go to Properties and then "version" tab). Make sure the version digits are separated with comma, not period.
Attachments
Attachments/KB1320_TwoTierNonResumableWebServer.zip
Created : 1/20/2010 1:20:16 PM (last modified : 1/20/2010 1:20:16 PM)
Rate this article!
Comments