Cannot access files with Umlauts in virtual directory IIS

In case you have a file in the virtual directory with filename containing non-English characters like Umlauts e.g. รถ. When we try to access the path with it is becomes inaccessible, but the files with only English characters are accessible.

You can try the following IIS settings, first one is

Request Filtering:

  1. Open the iis, double click the ‘Request Filtering’ icon
  2. In the ‘File Name Extension’ right click->Edit Feature Settings…’ the file ‘web.config’
  3. Check the option ‘Allow double escaping’ (this option is unchecked by default)
  4. Repeat all above 3 steps for the ‘default website’ (or whatever you have given the name to your site)
  5. Re-start IIS.

UrlScan under ISAPI:

One of the possible causes could be you’re using UrlScan extension for IIS which is visible under ISAPI filters. It is applied to all sites by default. In our case, removing UrlScan for the site facing issue resolved the issue.

Advertisement

Add Strict-Transport-Security (HSTS) response header to IIS hosted site

The HTTP protocol by itself is clear text, meaning that any data that is
transmitted via HTTP can be captured and the contents viewed. To keep data private and prevent it from being intercepted, HTTP is often tunnelled through either Secure Sockets Layer (SSL) or Transport Layer Security (TLS). When either of these encryption standards are used, it is referred to as HTTPS.

HTTP Strict Transport Security (HSTS) is an optional response header that can be configured on the server to instruct the browser to only communicate via HTTPS. This will be enforced by the browser even if the user requests a HTTP resource on the same server.

Cyber-criminals will often attempt to compromise sensitive information passed from the client to the server using HTTP. This can be conducted via various Man-in-The-Middle (MiTM) attacks or through network packet captures.

Security Scanners would recommend to using adding a response header HTTP Strict-Transport-Security or HSTS when the application is using Https.

Depending on the framework being used the implementation methods will vary, however it is advised that the Strict-Transport-Security header be configured on the server. One of the options for this header is max-age, which is a representation (in milliseconds) determining the time in which the client’s browser will adhere to the header policy. The browser will memorize the HSTS policy for the period specified in max-age directive.
Within this period, if an user tries to visit the same website but types http:// or omits the scheme at all, the browser will automatically turn the insecure link to the secure one (https://) and make an HTTPS connection to the server. Depending on the environment and the application this time period could be from as low as minutes to as long as days.

Enabling includeSubDomains attribute of the element of the root domain further enhances the coverage of the HSTS policy to all its subdomains.
HSTS has a separate mechanism to preload a list of registered domains to the browser out of the box.

It is also usually recommended to redirect all http traffic to https. I’ve written another post on how to do that.

To add the HSTS Header, follow the steps below:

  1. Open IIS manager.
  2. Select your site.
  3. Open HTTP Response Headers option.
  4. Click on Add in the Actions section.
  5. In the Add Custom HTTP Response Header dialog, add the following values:
    Name: Strict-Transport-Security
    Value: max-age=31536000; includeSubDomains; preload

Or directly in web.config as below under system.webServer:

<httpProtocol>
	<customHeaders>
		<add name="Strict-Transport-Security" value="max-age=31536000; includeSubDomains; preload" />
	</customHeaders>
</httpProtocol>

Remove unwanted response headers from IIS hosted site

You may receive an e-mail from your Security team after a scan, that your Web application exposing certain Response Headers that might get exploited by attackers to gain unauthorized access to the System.
While it may not always be necessary to mitigate these kind of vulnerabilities, you still have to weigh the options. This might be true even for say, a Reactjs app hosted on IIS.

If you do need to remove certain Response Headers like Server, X-AspNet-version and X-Powered-By, these can be taken care of at the IIS Server level or in web.config file.

We will firstly use the URL rewrite option which requires to be installed on IIS Server if not already present. You can download the installer here.

For the Server and X-Powered-By Response Headers, create Server variables as under URL Rewrite option as shown below:

Set the variable names as RESPONSE_SERVER and RESPONSE_X-POWERED-BY respectively.

Next create outbound rules using URL Re-write in IIS specifically for the Website. If you create these rules at the Server level, it’ll be applied to all Websites.

With Pre-condition set to None, make the below configuration using URL re-write in the Outbound rule. The same configuration requires to be done for RESPONSE_X-POWERED-BY server variable.

You can then test these Response Headers values should come as blank in the Dev Tools of your Browser.

For the X-AspNet-version Response Header, make the below entry in your Web.Config file. This will remove the Response Header altogether.

Add the following line in your web.config in the <system.Web> section:
<httpRuntime enableVersionHeader="false" />

Handle client side routes with IIS on Page refresh React App

When trying to handle Client side routing for your React App hosted on IIS say using react-router-dom, you might need to handle situations where users access specific sections of your App like http://testapp/courses. Users might even save these URLs in their favorites and try to access them later.

This problem is not known while debugging the App in localhost until you host the App on an IIS Server. Since your React App is a Single Page Application (SPA), the Server is unaware of any static files like courses and will give 404 error. To solve this, send all your requests back to IIS with URL rewrite to the index.html static file and let the React App handle the routing.

First install the URL Rewrite module on the IIS Server. Then create a web.config file for your App or create a new one with code as shown below:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
		<rewrite>
		  <rules>
			<rule name="ReactRouter Routes" stopProcessing="true">
			  <match url=".*" />
			  <conditions logicalGrouping="MatchAll">
				<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
			  </conditions>
			  <action type="Rewrite" url="index.html" />
			</rule>

		  </rules>
		</rewrite>
    </system.webServer>
</configuration>

This should work well for your App when the user tries to access a Client side route and refresh the page or when trying to access the route later.

Serve static json files on IIS hosted React App

When you have a React App hosted on IIS Server, you might need to access the static json files in your application for various purposes like json translations etc.

When you try to access these static files directly in browser or through code e.g. http://app/translation.json, you’ll get a 404 File Not Found error because the MIME type is not set by default in IIS. This is true for any other static file like woff files for fonts.

Under your Web.config file configuration section, place the below sample code within system.webServer tags.

<staticContent>
		<mimeMap fileExtension=".woff" mimeType="application/octet-stream" />
		<mimeMap fileExtension=".json" mimeType="application/json" />
	</staticContent>

The Web.config file is not available by default for a React App. You can either create one manually or make a change in the IIS Server Website configuration which will generate the Web.config file automatically and then you can add the above changes.

Encrypt web.config with RSA encryption

Encryption done locally on a Server using command line can be used only if the Application is hosted on the same machine. If the Application is hosted in a load-balanced environment, the encryption should be done in a way so that the private key can be imported on all the load-balanced machines.
The commands need to be run with Admin permissions on the machine.

Run the following commands in Command Prompt in the similar order with Admin permissions:

Traverse to the path as per .Net Framework-

cd C:\Windows\Microsoft.NET\Framework\v4.0.30319

Encrypting Config file without using RSA Provider

aspnet_regiis.exe -pef <section name>  <path to the config file>

-pef is the action to be performed for encryption.

e.g. aspnet_regiis.exe -pef “connectionStrings” “C:\Data\TestWebApp”

All the connection strings present in the above example will be encrypted.

Encrypting Config file using RSA Provider

Creating Key containers:

Aspnet_regiis.exe -pc “<name of Key container>” -exp

Asymmetric private keys should always be stored in a key container.

Add configProtectedData section in web.config to be encrypted:

<configProtectedData>
<providers>

<add name="MyRSAProvider"

type="System.Configuration.RsaProtectedConfigurationProvider, System.Configuration, Version=4.0.30319.0,

Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a,processorArchitecture=MSIL"

keyContainerName="MyRSAKey"

useMachineContainer="true" />

</providers>

</configProtectedData>


The above section can only be added after < configSections > else it’ll be removed automatically.

The PublicKeyToken above can be found for the System.Configuration dll using the sn utility:

sn -T "C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Configuration.dll"

The key container name and the Provider name used above can be used in the example commands below.

Granting Access to an RSA Key Container to the AppPool:

aspnet_regiis -pa “<name of Key container>” “NT AUTHORITY\NETWORK SERVICE” -full

Encrypt command using Provider:

aspnet_regiis.exe -pef <name of config section> <path to the Config file> -prov “<name of Provider>”

Exporting the Key Container in Order to be used on Other Machines:

aspnet_regiis -px “< name of Key container >” <Path for Keys XML file> -pri

Import Key Container on another machine:

aspnet_regiis -pi “< name of Key container>” <Path for Keys XML file>

Path for keys e.g. C:\rsakeys.xml. The xml file can be copied to the same path on the other machine.

Delete the Xml File from Your Server

ASP.Net will automatically decrypt the Connection String using the grant permission given above to the AppPool and hence you need to access the Connection String in the same way as you would do normally.

To decrypt the config section locally using aspnet_regiis.exe use the below command:

Decrypt command: aspnet_regiis.exe -pdf < name of config section> <Path to the Config file>

e.g. aspnet_regiis.exe -pdf “connectionStrings” “C:\Data\TestWebApp”

Host create-react-app on IIS Server

Install the latest version of nodejs from https://nodejs.org/ site.

Install create-react-app globally as below:

npm i -g create-react-app

Create the react-app in the folder of your choice on your local machine:

create-react-app hell-world-app

Modify the index.js file as shown below:

import React from "react";
import ReactDOM from "react-dom";

const element = <h1>Hello World</h1>;

//console.log(element);

ReactDOM.render(element, document.getElementById("root"));

Test the app on localhost:

npm start

Build the production optimized app:

npm run-script build

Copy the contents of the build folder and paste it on the Server at the location where you want to host it e.g. C:\data\testreactapp. Open IIS on the Server and add Website by right-clicking on Sites as shown below. Give it the required hostname or port to test it in browser e.g. http://helloworldapp.

The index.html file is already present at the Physical path created by the build which the IIS Server will look for as the default document.

Authentication can be Anonymous for testing purpose. However, please change as per your requirement. The AppPool by default runs with CLR 4.0 version and Integrated mode.

This approach is especially helpful when you have a back-end .Net Web API hosted on the same IIS Server to improve speed.

Create Virtual Directory in IIS

Create the Website under IIS as shown below on port 80 so it can be accessed using http and give the appropriate hostname as required. The hostname should be available in the DNS records to access over Internet/Intranet.

Create the virtual directory as shown below. Use the default Pass-through authentication for demo purpose. You can also use Physical Path credentials on your folder if required and manage using Connect as button.

The below image shows how the Virtual Directory will look like under your website in IIS. So if you have a file saved under the Attachments folder under C:\Data\Attachments\doc1.docx, the URL to access the document will be http://mywebsite/attachments/doc1.docx. The folder can also be created on another physical drive on the same Server or can also be accessed using a UNC path.

Are you suffering from diabetes? Click here to know how you can change your life!

Redirect website traffic to https with IIS hosting

Securing the traffic coming to your website is of utmost importance. Websites today running without an SSL certificate or without https cannot be trusted. If your application is hosted on IIS, one trick to redirect (not re-write URL) all traffic via https is to create a new Website in IIS and add httpRedirect in your web.config. HTTP Redirection is not available on the default installation of IIS 7 and later.

If your website domain is e.g. https://www.abc.com, this means the IIS binding on port 443 for your website is using host name “www.abc.com”.
The dns requires to be created pointing to the Hosting Application Server. The new Website that you create for redirection should have a port 80 binding with the same domain name.

Also, add the below configuration in your web.config file:

<configuration>
	<system.webServer>
		<httpRedirect enabled="true" destination="https://www.abc.com$Q" exactDestination="true" httpResponseStatus="Permanent" />
	</system.webServer>
</configuration>

The $Q in the destination URL will preserve the Query strings if any. The httpResponseStatus with value Permanent will redirect the traffic to the destination URL with status code 301. Set exactDestination to false if you want to preserve the relative paths during redirects.