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>

Enable PUT and DELETE Http verbs for WebAPI with Cors on IIS 8.5

WebAPI in .Net by default allows only the GET, POST, OPTIONS and HEAD verbs. To allow PUT and DELETE, you need to remove the WebDAV handler and module from the request pipeline by making the following changes to the Web.Config.

The WebDAV element contains the settings that configure Web Distributed Authoring and Versioning (WebDAV) for Internet Information Services (IIS) 7 or above. WebDAV is an Internet-based open standard that enables editing Web sites over HTTP and HTTPS connections. You may get a 405 error code due to WebDAV.

<system.webServer>
    <handlers>
      <remove name="WebDAV" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
      <remove name="OPTIONSVerbHandler" />
      <remove name="TRACEVerbHandler" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
      <remove name="WebDAVModule" />
    </modules>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://somedomain" />
        <add name="Access-Control-Expose-Headers" value="Content-Type, Accept, expiry, uid, access-token, token-type" />
        <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS,PUT,DELETE" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Also, the ExtensionlessUrlHandler-Integrated-4.0 handler needs to allow all verbs with a * or a manual entry for specific verbs. The minimum runtime requirement is 4.0 to make this work.

The last bit to check for a message that says e.g. PUT /Rejected-By-UrlScan . Check the logs under C:\Windows\System32\inetsrv\urlscan\Logs on the Server. You may need to edit the config file to allow those verbs or remove the UrlScan 3.1 service in the ISAPI tab of your Service in IIS which points to urlscan.dll. This is usually mentioned last in the list.

CustomHeaders are part of enabling Cors. Please note that Access-Control-Allow-Origin should not allow “*” . It should mentions specific domain that requires to be allowed for Cors. You can expose custom headers using Access-Control-Expose-Headers and allow specific methods using Access-Control-Allow-Methods.

Show some love for the pit in my PayPal account.

ASP.Net Server side Http Web Request with Custom Headers

This post shows how to make HttpWebRequest from Asp.Net page using c#. Here, the requirement is to call an external API with Custom headers and sending json data in the page_load method. Reading the Html response from the stream and write it on the Aspx page. Gluid is the Global Unique Identifier generated in c#.

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL + "?pID=" + pID);

NameValueCollection nameValueCollection = new NameValueCollection
{
{ "firstName", firstName },
{ "lastName", lastName },
{ "x-requestKey", Gluid },
};
request.Headers.Add(nameValueCollection);
request.Accept = "application/json";
request.ContentType = "application/json";
request.Method = "POST";
request.AllowAutoRedirect = true;
byte[] bytes = Encoding.ASCII.GetBytes(dataSent);

request.ContentLength = bytes.Length;
Stream os = request.GetRequestStream();
os.Write(bytes, 0, bytes.Length); //Push it out there
os.Close();

Stream responseStream = httpWebResponse.GetResponseStream();
StreamReader streamReader = new StreamReader(responseStream, Encoding.UTF8);
string html = streamReader.ReadToEnd();
Response.Write(html);

dataSent is the is json data read from a json file and sent as bytes.

For generating Gluid, use the following C# code:

public string GetUniqueIdentifier()
{
var guid = Guid.NewGuid().ToString();
return guid;
}

For similar Http POST request using jquery ajax, check out this post.