Tag Archives: IIS

The file is there, but returns with 404

I am trying to load an ASPX URL, but it fails. Well, it loads when I try from IIS Express with the source code, but after I publish it to IIS, it fails with 404.

The file is right there where it should be, it just cannot be downloaded. I turn on Failed Request Tracing, hopefully it will show something. It does: 388 log entries for a single HTTP request. Fortunately the Request Summary view highlights the only warning:


ModuleName: ManagedPipelineHandler


HttpStatus: 404

HttpReason: Not Found

HttpSubStatus: 0

ErrorCode: The operation completed successfully. (0x0)

Not a big help, but it shows which module is guilty. Little joy. I look up the entry in the Complete Request Trace and check the previous entries. AspNetParse and AspNetCompile entries. Hmmm, maybe something is wrong with the ASPX file? Probably not, because it runs on IIS Express, and I have it from a NuGet package.

Anyway, I check the source code. The first line looks suspicious: the @Page directive contains a CodeFile attribute. Unusual. I change it to CodeBehind. Compile, publish.

It works.


Technorati-címkék: ,,

IIS Express shuts down after debugging

If you use the IIS Express which comes with Visual Studio 2013, you may notice that as opposed to the previous versions, the webserver shuts down when you stop debugging. This behavior is thanks to the fact that from VS 2013 you not only have Edit and Continue support in 64-bit environments, but this feature is enabled by default for web applications:


If you don’t need this feature, and you turn it off, IIS Express will remain running.


Technorati-címkék: ,

Cleaning up IIS Express configuration

IIS Express stores its configuration settings in the %USERPROFILE%\Documents\IIS Express\config\applicationHost.config file which eliminates the need for administrative permissions for changing it. As a consequence when you uninstall Visual Studio, the webserver configuration remains in the user’s profile folder.

It may happen, that you uninstall VS 2012, install VS 2013 and then when you create a new web application it behaves very strange, for example it asks for Windows authentication every time. This may be caused because you have created a website with the same name earlier in IIS Express, and its settings are preserver in the configuration file.

If you often create new web applications in Visual Studio, it is a good practice to clean up IIS configuration once in a while. Because there is no GUI for IIS Express, you can edit the applicationHost.config file directly or you can use the command line.

You can find the appcmd.exe for IIS Express in the C:\Program Files (x86)\IIS Express folder. You can use it to list the websites:

C:\Program Files (x86)\IIS Express>appcmd list site
SITE "WebSite1" (id:1,bindings:http/:8080:localhost,state:Unknown)
SITE "MyProject" (id:2,bindings:http/*:44441:localhost,https/*:44300:localhost,state:Unknown)
SITE "WebSite1(1)" (id:3,bindings:http/*:44468:localhost,state:Unknown)
SITE "WebSite2" (id:4,bindings:http/*:44465:localhost,state:Unknown)

If the names of the websites do not tell too much, then you can list the virtual directories, because that list shows the physical paths as well:

C:\Program Files (x86)\IIS Express>appcmd list vdir
VDIR "WebSite1/" (physicalPath:%IIS_SITES_HOME%\WebSite1)
VDIR "MyProject/" (physicalPath:W:\Projektek\MyProject)
VDIR "WebSite1(1)/" (physicalPath:W:\Temp\WebSite1)
VDIR "WebSite2/" (physicalPath:W:\Desktop\WebSite2)

You can even give them meaningful names by renaming them:

C:\Program Files (x86)\IIS Express>appcmd set site WebSite1(1) -name:Master
SITE object "WebSite1(1)" changed

And you can delete the sites you don’t need any more:

C:\Program Files (x86)\IIS Express>appcmd delete site WebSite2
SITE object "WebSite2" deleted


Technorati-címkék: ,,

Removing chatty HTTP headers

If you look into the traffic of your ASP.NET application, you can notice the following headers in the HTTP response:

Server: Microsoft-IIS/8.0
X-Powered-By: ASP.NET
X-AspNet-Version: 4.0.30319
X-AspNetMvc-Version: 5.0

These headers have no effect on your application in any way, they are just there to provide more information to the Bing bot about your website.

Unfortunately these response headers make the attackers’ jobs easier, because if they know what platform and what version do you use, they can try only those exploits that work in this special environment. Therefore for security reasons it is a good practice to change the defaults and remove these headers.



Broadcasting the Server header is hardwired into IIS, I’m not aware of any configuration switch you could use to remove it. You can use UrlScan, but that tool was updated last time in 2008. If you have an ASP.NET application, you can remove this header in the global.asax, just before the response leaves the server:

protected void Application_PreSendRequestHeaders()
  this.Response.Headers.Remove( "Server" ); }



The X-Powered-By header is added by IIS to the HTTP response, so you can remove it even on server level via IIS Manager:



Or of course you can use web.config directly:

       <remove name="X-Powered-By" />



The ASP.NET runtime provides a configuration option to easily turn off the X-AspNet-Version header in web.config:

<httpRuntime enableVersionHeader="false" />



To remove the X-AspNet-Version header, execute the following code when your application starts:

protected void Application_Start()
MvcHandler.DisableMvcResponseHeader = true; }


If you want to make security easier, you can rely on the NWebsec free project on CodePlex. This project besides simplifying configuration security, provides additional features for session hardening and specifically for MVC and Azure projects. These features are available independently in the form of NuGet packages as well.


Technorati-címkék: ,,

IIS configuration auditing

It is not difficult to find an IIS configuration setting that you can flip and make your webserver instantly insecure. For this reason it is very important to monitor and track the changes of the IIS configuration. Fortunately IIS provides this feature, but you cannot turn it on in IIS Manager.

Instead start Event Viewer, and navigate to the Application and Services Logs –> Microsoft –> Windows –> IIS Configuration –> Operational branch. Right click on this log and click Enable Log to turn on auditing:


From now on all IIS configuration changes appear in this log:


The General view doesn’t provide too much information beside the modified setting, the modification date and the user, but you can find more in the Details view:


It’s important to know that only those changes show up in the log that are done via IIS Manager, appcmd or the object model; if you use Notepad and edit the applicationHost.config directly it won’t be logged.


Technorati-címkék: ,,,

IIS remote management from Windows 8.1

One of the coolest features of the Internet Information Services (IIS) Manager (inetmgr.exe) is that you can run it locally on your client computer, and you can remotely manage your IIS server with it on a graphical user interface. Just start inetmgr.exe, then click the Connect to a Server item in the File menu:


This starts a simple wizard, and if the server has the Web Management Service installed, you can instantly connect to your server, to your website or to your web application.

It is very quick and simple, if and only if you have that menu item. Because it doesn’t exist neither on Windows 7, nor on Windows 8 or 8.1 by default. (Wait, you have a Save Connections (well, in disabled state), but why?)


In case of Windows 7 I understand the historical reasons, but I couldn’t find any logical explanation for the newer client operating systems. If if has to be a separate download it could be a part of RSAT.

Stop whining and let’s fix this issue instead. Start Web Platform Installer where you can search for example for “remote” to find the IIS Manager for Remote Administration v1.1:


Don’t be shocked by the 2011 release date, it is exactly the tool what you need. Click Add in the row, then Install on the bottom, and finally click I Accept in the next dialog to accept the license terms. The download and the installations starts, but suddenly stops with the following error:


The installation failed because it requires Windows 7 or newer. Come on, I’m on Windows 8.1, dude!

OK, try it again, but at this time click the Direct Download Link link in the license dialog:


This triggers your default browser which downloads the MSI installer into the folder you select. By the way you can find the download URL in the installation log as well by clicking the View log here link in the previous error dialog. In my case the installer was downloaded from here:


Before starting the installer, open the Properties dialog of the MSI file and check the Run this program in compatibility mode checkbox:


Click through the wizard, restart IIS Manager and now you can connect to your remote webserver. On the first connection IIS Manager may download additional modules just as usual:



Technorati-címkék: ,

Installing WSUS on Windows Server 2012

Installing Windows Server Update Services on Windows Server 2012 is not a complicated task in theory: because it is now a part of the OS, you even don’t have to download it, just click through the step-by-step installation wizard in Server Manager. If you don’t believe me, take a look at this step-by-step tutorial with screenshots.

For me it was not that easy. I’m obviously an install-failed-error magnet, but according to the tremendous amount of forum posts in the topic, I’m not alone. So here are my solutions.

A kind notice:
The solutions below worked for me, but use them on your own risk!

The server is a fresh WS 2012 install, promoted to a domain controller. I have not found any documentation that would state that this is a non-supported scenario.

NTFS permissions

According to the Prepare for Your WSUS Deployment TechNet article, the NT Authority\Network Service account must have Full Control permissions to the following folders, otherwise the WSUS Administration snap-in may fail:

  • %windir%\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files
  • %windir%\Temp

The beauty is that – as you can read in the doc – the first folder might not exist if IIS is not installed. WSUS requires IIS, and fortunately the installer is smart enough to install the Web Role as well. What’s more, it installs only those IIS components that are required to WSUS, so if you follow the “minimal install” principle, you probably want to let the WSUS installer setup IIS as well. But how to set the folder permissions before starting the installer, if the installer creates the folder?

Role Services

In a sunny Friday afternoon you may reach this step in the install wizard:

WSUS install wizard: Select role services

If you want to click all three components, be prepared to the following error message:

The following features cannot be installed on the same server: Database, WID Database.

The following features cannot be installed on the same server: Database, WID Database.

A little background info:

  • The WID Database (which is checked by default) means that the setup installs the Windows Internal Database, which is a mini SQL Server engine. It has some limitations, but perfectly suitable for WSUS, especially in a single server scenario.
  • The Database (which is not checked by default) means, that the setup creates the WSUS database in an existing SQL Server instance, which can even reside on another computer. If you want to select this option, please read the WSUS database requirements section of the documentation.

The important is that the default two checks are perfect, you don’t need all three.

Restart without results

The installer may run fine for a while, until:

The request to add or remove features on the specified server failed.

The operation cannot be completed, because the server that you specified requires a restart.

The operation cannot be completed, because the server that you specified requires restart.

Of course you can restart your server, but that won’t solve anything. After restarting the server, you have to restart the WSUS installation which will end with the same results again and again.

The solution is to modify your group policy. Start the Group Policy Management Console and edit the Default Domain Controllers Policy. In the Computer Configuration –> Policies –> Windows Settings –> Security Settings –> Local Policies –> User Rights Assignment branch, edit the Log on as a service setting, and add the following accounts: IIS_WPG, NETWORK, NETWORK SERVICE, SERVICE.

After saving the GPO, don’t forget the update the policy:

gpupdate /target:computer

Post-Installation tasks

After the installation wizard completes, you will see – if you really look for it – a Launch Post-Installation tasks link which you must click. This essentially continues the installation.

Until it fails:

Configuration failed. A log file was created at C:\Users\username\AppData\Local\Temp\tmpXXXX.tmp


I encourage you to look into the log file, because it is detailed and very readable. For example:

Config file did not contain a value "ContentDirectory"
A required configuration value was not found in the system.

Yes, it is missing a setting which you probably entered in the graphical wizard! If you are a command line guru there is a tool for you called wsusutil.exe in the C:\Program Files\Update Services\Tools folder, however it fails with the same error.

Both the GUI and the command line tool are missing the value from the C:\Windows\System32\ServerManager\ComponentConfiguration\UpdateServices-Services.xml file. If you open this file, you will find this (I added line breaks for readability):

<?xml version="1.0" encoding="utf-16"?>
<INSTANCE CLASSNAME="ServerComponent_UpdateServices_Services">
<PROPERTY NAME="ContentDirectory" TYPE="string">
<PROPERTY NAME="ContentLocal" TYPE="boolean">

If you have eyes for XML, you see immediately, that that ContentDirectory value is definitely missing. No problem, just add it:

<?xml version="1.0" encoding="utf-16"?>
<INSTANCE CLASSNAME="ServerComponent_UpdateServices_Services">
<PROPERTY NAME="ContentDirectory" TYPE="string">

<PROPERTY NAME="ContentLocal" TYPE="boolean">

It you run Notepad as administrator, you will be able to save the changes. Click the Launch Post-Installation tasks link again, it will run longer.


For me it ran longer, but failed later. It created another log file in the Temp folder, this time with the following error:

Fatal Error: SqlException (0x80131904): Invalid object name ‘SUSDB.dbo.tbSchemaVersion’.

This means something is wrong with the database. If you read the log you can see, that the database exists, the installer could connect to it, however the specified table is missing.

I checked the C:\Windows\WID\Data folder where I found the SUSDB.mdf and SUSDB_log.ldf files, so the database really existed, probably because it was created by a previous installation attempt. However its 2112 KB size was suspicious, because it closely matched to the size of the model.mdf. My guess was that the database was created, but it is still empty.

My idea was to delete the database and hopefully the installer will create it again. Deleting the files was surprisingly easy, but when I checked the error.log file in the Log folder after restarting the service, it because obvious that the database server is missing the files.

So the correct solution is to connect to the database server and drop the database. If you don’t want to install SQL Server Management Studio, you can go with the SQLCMD command line tool which is available as a very small standalone installer from here: Microsoft Command Line Utilities 11 for SQL Server

If you don’t read the System Requirements section the MSI installer will warn you that it requires the ODBC Driver 11 for SQL Server as well.

Downloading these two MSI files is not obvious from Internet Explorer at all. First it aggressively blocks the popup windows, and second:

Security Alert: Your current security settings do not allow this file to be downloaded.


If you don’t want to fight with the browser, you can download this 7MB content on another computer and move it to the server via Remote Desktop.

Now you have SQLCMD in this folder:

C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\110\Tools\Binn

You will also need the connection string to WID:


I prefer using SQLCMD with a command file, because that makes editing and re-executing SQL commands easy. So you can create a file called wsus.sql with this content:

select name from sys.sysdatabases
drop database susdb
select name from sys.sysdatabases

And run it from the command prompt:

sqlcmd -S np:\\.\pipe\MICROSOFT##WID\tsql\query -i c:\temp\wsus.sql

With this you’ve dropped the WSUS database, but thankfully the WSUS installer will create it again with the correct table structure. After completing the install wizard and the post-installation tasks you can start the WSUS Administration console and run the server configuration wizard.

The WSUS server is installed now, but you still have to configure the clients and setup SSL.


Technorati-címkék: ,,

Mitigating DoS attacks in ASP.NET

According to a widely accepted view, there is no effective countermeasure against (Distributed) Denial of Service attacks. End of story.

That’s kinda true, especially if the attack is based on sending numerous small requests to the webserver. However, websites can also be DoS’ed by sending huge HTTP requests, which can cause memory issues on the server. Actually the same can happen when non-malicious users upload files that are much bigger than expected.

You can mitigate this threat by setting the maximum accepted size for a HTTP request. It is important to understand that implementing such checking in an ASP.NET event handler is far too late, because when that handler is called, the request is already arrived to the server. Thankfully both ASP.NET and IIS provides endpoints in the earlier phases of the request pipeline.

ASP.NET provides the maxRequestLength attribute which you can configure in web.config. The default value is 4096 and that means 4096 kilobytes:

<httpRuntime targetFramework="4.5" maxRequestLength="4096"/>

So by default ASP.NET aborts all requests which are larger than 4MB with a HttpException:

HttpException (0x80004005): Maximum request length exceeded.

Unfortunately this exception is far too general, you cannot use any of its properties (beside the localized error message) to identify this special issue, but this workaround works well:

void Application_Error( object sender, EventArgs e )
  HttpRuntimeSection section = ConfigurationManager.GetSection( 
"system.web/httpRuntime" ) as
HttpRuntimeSection; int maxRequestLength = section.MaxRequestLength; if( this.Request.ContentLength > maxRequestLength * 1024 ) { this.Server.ClearError(); // Log and redirect to a friendly error page etc. } }

IIS provides the Request Filtering module which (beside many other useful features) also allows you to set the maximum allowed request length in the maxAllowedContentLength attribute. The default is 30000000 here and it means about 28.6MB, because it is measured in bytes:

      <requestLimits maxAllowedContentLength="30000000" />

When this limit is reached, IIS issues a response with HTTP Error 404.13:


You can handle this error as well in global.asx, but this time you need to implement the Application_EndRequest event handler:

protected void Application_EndRequest( object sender, EventArgs e )
  if( this.Response.StatusCode == 404 && this.Response.SubStatusCode == 13 )
    // Log, redirect, etc.


Technorati-címkék: ,,,,,

Publishing a WCF service on IIS 8

WCF services don’t run on IIS 8 with the default configuration, because the webserver doesn’t know, how to handle incoming requests targeting .svc files. You can teach it in two steps:

1. Add a new MIME type:

Extension: .svc
MIME type: application/octet-stream



2. Add a new Managed HTTP Handler:

Request path: *.svc
Type: System.ServiceModel.Activation.HttpHandler
Name: svc-Integrated


That’s it!


Technorati-címkék: ,,

HTML5 MIME types on IIS 8

If you have a website that uses HTML5 file types, and you run the site on IIS 7/7.5, you have to manually add the special file extensions in the IIS MIME Types list to make sure the webserver allows the clients to access them. You can add something like this to your web.config:

  <mimeMap fileExtension=".mp4" mimeType="video/mp4" />
  <mimeMap fileExtension=".m4v" mimeType="video/m4v" />
  <mimeMap fileExtension=".ogg" mimeType="video/ogg" />
  <mimeMap fileExtension=".ogv" mimeType="video/ogg" />
  <mimeMap fileExtension=".webm" mimeType="video/webm" />
  <mimeMap fileExtension=".oga" mimeType="audio/ogg" />
  <mimeMap fileExtension=".spx" mimeType="audio/ogg" />
  <mimeMap fileExtension=".svg" mimeType="image/svg+xml" />
  <mimeMap fileExtension=".svgz" mimeType="image/svg+xml" />
  <remove fileExtension=".eot" />
  <mimeMap fileExtension=".eot" mimeType="application/vnd.ms-fontobject" />
  <mimeMap fileExtension=".otf" mimeType="font/otf" />
  <mimeMap fileExtension=".woff" mimeType="font/x-woff" />

However, when you upgrade your server and move your site to IIS 8, then you’ll get a nice 500.19 Internal Server Error.


If you enable detailed error messages, you can see that the error is in the mimeMap section of the web.config file:

Cannot add duplicate collection entry of type ‘mimeMap’ with unique key attribute ‘fileExtension’ set to ‘.m4v’

The root of the problem is, that IIS 8 supports the most widely used MIME types out of the box, and they are registered at the server level, therefore all websites inherit them.

The solution is to get rid of the manual registration from your web.config file. In my case, I had to remove the following extensions:

mp4, m4v, m4a, ogv, oga, ogg, webm, spx, svg, svgz, otf, woff

Please don’t forget to update your installers and setup scripts!


Technorati-címkék: ,,