The "White Screen" Bug in IE with ASP.NET

3:06 PM j. montgomery 5 Comments

Recently I ran across a pretty odd issue on an ASP.NET web site that I was able to work through. 

Setup
1. Internet Explorer
2. Smart Card Authentication with SSL/TLS
3. ASP.NET 2.0 web site running on IIS 6.0 on Win2k3

Symptoms
When using the web site, users complained that at certain points when using the site, they would click on something and the page in IE would go 'white' - the page would look exactly like the 'about:blank' page. While not necessarily a very technical name, it was certainly descriptive of what was happening.

After trouble-shooting further it was determined that the page only went white after the user left the web browser sit for a couple minutes. Then when the user did a POST, the page went blank.

At this point the cause was speculated to be anything from a piece of networking equipment (a proxy?) between IE and web server, to the web server itself, to the .NET web application (depending on who you asked).

Troubleshooting
My first goal was to duplicate the problem on my system and I was able to reproduce it as described in MOST cases, but not 100% of the time.

Next, on the blank page, I did a "View Source", turns out it had  the entire contents of the previous page before the POST occurred.

Out of habit I saved the HTML source and check it's file size...the page was over 1MB.  Turns out the developer isn't managing ViewState properly with a GridView.  My initial thought is that this is worth pursuing as the root cause.  I did the same test on a page with a small ViewState and the error did not occur.

So at this point, I think I know what the solution is, but I don't know what the actual problem really is, so there's more work to do.

Next I pull out Fiddler, a HTTP debugging proxy - even though the ViewState is large, IE should still be able to render the page so I want a lower level look at what's going on. There's also this strange timing issue where the bug only occurs after two minutes. After firing up Fiddler, loading the first page then waiting two minutes before POSTing more data, the following HTTP error is reported in the Fiddler output.

HTTP/1.1 413 Request Entity Too Large

This error message didn't immediately reveal what the issue was - only after some extensive searching that combined the "HTTP 413 Request Entity Too Large" error combined with search terms related to Client Certificates did the appropriate Microsoft Article actually come up.

The REAL Issue
This issue is a problem in the underlying protocol (SSL/TLS) authentication specification; this is not a Microsoft or an IIS problem nor is it necessarily a developer problem as long as care is taken to keep certain “features” of ASP.NET in check. This problem will show up on any web site that attempts to do an HTTP POST with a large amount of data to an IIS web server while at the same time, re-establishing the SSL/TLS encrypted channel (HTTP CONNECT). This is why this particular problem is seen only after allowing a period to pass.

This problem is typically seen when uploading files to a web server and rarely seen when submitting a HTTP POST of Form variables, because rarely do they need to be larger then a few kilobytes.

According to Microsoft Technet article on this issue:

“If client renegotiation is requested, the request entity body must be preloaded using SSL preload. SSL preload will use the value of the UploadReadAheadSize metabase property, which is used for ISAPI extensions. However, if UploadReadAheadSize is smaller than the content length, an HTTP 413 error is returned, and the connection is closed to prevent deadlock. (Deadlock occurs because a client is waiting to complete sending a request entity, while the server is waiting for renegotiation to complete, but renegotiation requires that the client to be able to send data, which it cannot do).” [1]

To summarize, the UploadReadAheadSize metabase property in IIS 6.0 needs to be large enough to load the SSL POST entity body such that on Client Certificate (CAC) renegotiation, a deadlock does not occur.

It would be unwise to increase blindly the UploadReadAheadSize metabase property without consideration of the consequences (it has a max value of 4GB). If the size is set too large it becomes an attack vector for Denial of Service attacks (DoS) since we might exhaust resources on the system.

The default size for UploadReadAheadSize metabase property in IIS 6.0 is 49,152 bytes.

The Solution
The solution to the problem is not necessarily to just increase the UploadReadAheadSize site limit as you will always be able to create a page on a web site that will cause this problem unless you increase the POST size so large as to create a security issue that creates the DoS situation. The best way to remediate this problem is to reduce data POST sizes when possible instead of playing a guessing game with the UploadReadAheadSize metabase property.

With this in mind, Developers must familiarize themselves with ASP.NET best practices as they apply to ViewState size especially in any DoD environment which requires Client Certificates (CAC / Smart Cards) for authentication making a non-issue, an issue. Dino Esposito, an authority on ASP.NET development, has some information on the topic of recommended ViewState sizes here: ASP.NET 2.0: ViewState Numbers. He recommends ViewState not exceed 7KB. My personal view is that his number, in some cases, might be a bit conservative. I take the stance that the ViewState size should not exceed the size of what the industry has deemed acceptable optimized image size that can reasonably be displayed on a web site. This number is often greater then 7KB as rarely is it an issue to download an image of even 10 KB to 20 KB, but that’s on the very high end and is probably a bit excessive for ViewState especially if your web site is already graphics intensive.

Now the fact that Internet Explorer just displayed a blank page when encountering a 413, I think could be classified as a bug. Reporting the "HTTP 413 Request Entity Too Large" error back up to the user seems appropriate.


References

[1] - Client cannot renegotiate request and returns an HTTP 413 error (IIS 6.0)

  NOTE: This KB article seems to have a mistake:
  cscript adsutil.vbs set w3svc/1/uploadreadaheadsize 200

  Should read:
  cscript adsutil.vbs set w3svc/1/uploadreadaheadsize 204800

According to the IIS documentation, the argument is in bytes - not in kilobytes. See UploadReadAheadSize Metabase Property in the Microsoft IIS 6.0 Reference.

5 comments:

  1. I know this is an older post, but this helped me a lot with a similar situation.

    ReplyDelete
  2. jjp02 says:
    Thanks, looks like that may be an issue I'm running into with IIS6.0/ SSL (no CAC authentication, although got here reading up on how to implement that).

    ReplyDelete
  3. No problem- hope it helps out. Do you happen to be using a client certificate instead?

    ReplyDelete
  4. Thanks for the post. Really helpful...

    This link may also help:

    http://forums.asp.net/p/1330260/2672514.aspx

    It recommends modifying SSLAlwaysNegoClientCert in the metabase

    ReplyDelete
  5. > http://forums.asp.net/p/1330260/2672514.aspx

    Thanks!
    That's good additional info! Thanks for posting.

    ReplyDelete