Monthly Archives: December 2013

MSB4175: The task factory "CodeTaskFactory" could not be loaded

I received the following error message when I tried to compile a project:

C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\CodeAnalysis\Microsoft.CodeAnalysis.targets(214,5): error MSB4175: The task factory "CodeTaskFactory" could not be loaded from the assembly "C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Build.Tasks.v12.0.dll".

Could not load file or assembly ‘file:///C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Build.Tasks.v12.0.dll’ or one of its dependencies.

The system cannot find the file specified.

The specialty of the case is that this machine had no VS 2012 installed, but only VS 2013.

The root cause of the issue may be that from VS 2013 MSBuild is part of Visual Studio instead of the .NET Framework, and therefore the related files are relocated in the file system. The error message says that the system looks for the Microsoft.Build.Tasks.v12.0.dll file in the C:\Windows\Microsoft.NET\Framework64\v4.0.30319 folder, however I have that file in the C:\Program Files (x86)\MSBuild\12.0\Bin directory. So, I simply copied the file and voila, the error was gone.

This is probably not the most elegant solution to fix this error. But because I couldn’t change the source environment, and the fix works on my machine, I can live with it very well.

 

Technorati-címkék: ,,

Suppressing forms authentication redirects

One of the most terrible pain points of correctly implementing authentication is to define how to handle unauthorized requests. So for example neither unauthenticated users, nor users who are not the members of the Admins group can request the /admin URL.

Thankfully the FormsAuthenticationModule in ASP.NET provides a built-in solution to this problem. When the module is initialized, it subscribes to the EndRequest event with the OnLeave event handler, and when the HTTP status code is 401, this event handler redirects the user to the login page. This is a very convenient feature for classic requests, however it may cause serious headaches for Ajax.

When the module redirects the request, the client receives a HTTP 302 Redirect header instead of the original 401 Unauthorized error code. As defined in the standard, the XMLHttpRequest client transparently follows the redirect and downloads the content from the URI specified in the Location header, which is usually the Login.aspx page. So when the success handler of the XHR is called, it will see the HTML markup of the login page as the result of the call, and the result code will be 200 OK which indicates success. Well, how you can handle this easily?

Until .NET 4.0  you had no other option to fix this behavior than adding a custom HTTP module to the ASP.NET pipeline. But ASP.NET 4.5 introduced a new HttpResponse.SuppressFormsAuthenticationRedirect property, which you can set to true to avoid the redirect, and force the FormsAuthenticationModule to send the original 401 error code to the browser. Because this property is attached to the Response, you cannot set it globally, but instead you have to flip this switch in every handler that requires this behavior. If you want to set it for every response, then you can implement this in the Application_EndRequest handler in global.asax.

Now it is the client’s task to handle the specific error code as required, for example by displaying a login box or a warning message in JavaScript. But you already have that logic, haven’t you?

 

Technorati-címkék: ,,

How unique is your machine key?

Most cryptography related features of the ASP.NET platform relies on the machine key, therefore it is very important to assign unique machine keys to independent applications. Thankfully the default configuration looks like ensuring this both for the validation key and the decryption key:

<machineKey validationKey="AutoGenerate,IsolateApps" 
decryptionKey="AutoGenerate,IsolateApps" />

The AutoGenerate option frees you from manually setting the keys, and the IsolateApps options ensures that unique keys are generated for every application.

But not always!

ASP.NET will definitely generate a key, but it is neither the validation key, nor the decryption key, but instead a base key (let’s call it the machine key), which is then transformed into the validation key and the decryption key. The base machine key is stored in the registry in the following location:

HKCU\Software\Microsoft\ASP.NET\4.0.30319.0\AutoGenKeyV4

Note that this key sits in the HKEY_CURRENT_USER hive, so the generated machine key belongs to the user’s that runs the application profile. This means that if you have two applications in IIS which are running with the same process identity, they will use the same machine key! One more reason why you should forget the SYSTEM, LOCAL SERVICE and NETWORK SERVICE accounts, and run all your web applications with separate ApplicationPoolIdentity. This also shows that the application pool is the real app isolation boundary.

Having two applications that share the same base key is not necessary a problem, because the keys used to validate and encrypt are created with additional transformations from this key. This transformation is determined by the second modifier after AutoGenerate. If you set IsolateApps, the runtime will use the value of the HttpRuntime.AppDomainAppVirtualPath property, which is different for two applications sitting in different virtual directories on the same website, so the generated keys will be different (which is good).

On the other hand, if you have two applications in the same path but on different websites, the value of this property will be the same for both apps. For example for an app that sits in the site root, the value is “/”, so IsolateApps does not provide you the isolation you expect!

To solve this problem ASP.NET 4.5 introduced a new modifier called IsolateByAppId, which uses the HttpRuntime.AppDomainAppId property instead of the AppDomainAppVirtualPath. The value of this property is something like this:

/LM/W3SVC/3/ROOT 

The “3” in the middle is the ID of the site in my case, and “ROOT” means that the app sits in the site root.

To summarize: the default AutoGenerate,IsolateApps setting does not necessarily provides you with unique keys, but if you host your apps in their own application pools which are running with ApplicationPoolIdentity, and you use IsolateByAppId instead of IsolateApps you can be sure, that your apps will use unique autogenerated keys.

The simplest way to test these setting is to use the localtest.me domain to create two separate websites, and then create a simple webpage that uses Milan Negovan’s code to retrieve and display the autogenerated keys.

 

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:

iis-express-edit-and-continue

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.

 

Server

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" ); }

 

X-Powered-By

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:

header-x-powered-by

 

Or of course you can use web.config directly:

<system.webServer>
   <httpProtocol>
     <customHeaders>
       <remove name="X-Powered-By" />
     </customHeaders>
   </httpProtocol>
</system.webServer>

 

X-AspNet-Version

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

<httpRuntime enableVersionHeader="false" />

 

X-AspNetMvc-Version

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: ,,