IIS can run Server-Side Javascript since 1997

When I read articles about NodeJS, they almost all consider NodeJS like if Ryan Dahl invented Server-Side Javascript.

But, did you know that, in IIS 3.0 on Windows NT 4.0, it was possible to run server-side javascript?

On May 15, 1997, Microsoft released the Service Pack 3 of Windows NT4, introducing Active Server Page technology (ASP).

Classic ASP was built to run Active Script.  VBScript AND JScript are the first Active Script languages developped, and were included in all versions of Windows since 95.  And, that “Jscript”, can be used to run server-side javascript.

Wait, JScript is not JavaScript?  Yes it is. Just another name.  FireFox 1.0 run something named JavaScript 1.5, and IE6 run JScript 5.0  And, both were, in fact, ECMAScript 3.0. (more info)

That said, it means that if you still need to work with Classic ASP application, to maintain old software that can’t be rewritten, you can write some JavaScript to do that.  And, it is totally compatible with existing VBScript app!

Now, look at this sample of a 100% server-side javascript in an classic ASP file.

I’ll show you, in another article, how you can add some javascript in your existing Classic ASP / VBscript application.

How to change the default Log Files location for Filezilla Server

When you enable Logging in FileZilla Server, there’s no option in the configuration to change the location of these files.

By default, you get them in this folder:
C:\Program Files (x86)\FileZilla Server\Logs

As they say in their documentation, “This location cannot be changed.”

In my case, I like to get all my logs at the same place, e.g. d:\logs, where have all my iis, smtp, hmailserver, … log files.

So, why can’t I get filezilla logs too?

There’s a solution, just follow these steps.

  1. Stop Filezilla Service
  2. Open a command prompt, as admin.
  3. Go to C:\Program Files (x86)\FileZilla Server\ folder.
  4. Rename “Logs” to “Logs2”, (or just delete it)
  5. Type: “mklink Logs m:\logs\filezilla /d”
    1. (replace m:\logs\filezilla with any folder you want)
  6. Restart FileZilla Service

That’s it, Filezilla Server thinks that the local folder exists, but it is located elsewhere!

Useful url rewrite rules for IIS

These are some rules I use in IIS to make all my web sites works as expected.

What I need to automate in all site:

  • Remove prefix “www.”
  • Redirect “http” to “https”, as http will soon disappear, thanks to LetsEncrypt.

Also, for very simple static sites, I want to make all pages respond to the same fixed static page, and get no 404.

You can do that without any code, when using the IIS Rewrite extension.  You first need to install the extension to your existing IIS configuration. (link)

This is an example of my IIS configuration:

  • Site 1: “https://foxontherock.com”
  • Site 2: “https://fredericmalenfant.com”
  • Site 3: default (ip binding)

Bindings strategy

The first strategy can be to add these rules to all your sites, one by one.
Exemple for site 1, these are the 4 bindings configuration:

  • http://foxontherock.com
  • http://www.foxontherock.com
  • https://foxontherock.com
  • https://www.foxontherock.com

If you set your IIS bindings like that, you need to add the rewrite rules to all your sites, one by one.

But there’s another simple strategy that I prefer, by using a “default” site on IIS.
On the first and second sites, I only set the “final” binding, e.g. foxontherock.com and fredericmalenfant.com, both on port 443 without www.

On the “default” site, I configure the bindings to respond to all other requests on my public IP address.

That way, I only need to add the redirect rules on the default site, as the redirection will be handled by the redirected site after.

IIS Rewrite Rules

First rule: Remove www prefix.

<rule name="Remove www" stopProcessing="true">
 <match url="(.*)" ignoreCase="true" />
 <conditions logicalGrouping="MatchAll">
  <add input="{HTTP_HOST}" pattern="^www\.(.+)$" />
 </conditions>
 <action type="Redirect" url="https://{C:1}/{R:0}" redirectType="Permanent" />
</rule>

Second rule: redirect http to https

<rule name="Redirect to https" stopProcessing="true">
 <match url="(.*)" />
 <conditions>
  <add input="{HTTPS}" pattern="off" ignoreCase="true" />
 </conditions>
 <action type="Redirect" url="https://{HTTP_HOST}/{R:0}" redirectType="Permanent" />
</rule>

The third rule can be set to all sites, and is used to get a fixed page always responding, without 404.

<rule name="Default page" stopProcessing="true">
 <match url=".*" />
 <conditions>
  <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
  <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
 </conditions>
 <action type="Rewrite" url="index.html" />
</rule>

Finally, you can add the “canonical” meta on that page to make robots index only 1 page, not all possible url.

(index.html)
<head>
...
<link rel="canonical" href="https://foxontherock.com/" />
</head>

How to decode a base64 string in VB.NET

Sometimes, we receive an e-mail that we can’t really open directly, but we have the base64 source.

I may receive an attached EML file, that is, an outlook express email attached with another e-mail.

I have all the original source of this file, but I do not have Outlook Express installed.

So, I created a really simple decoder and it work fine.  You just have to look at the boundary of your email.  Find the beginning of attachment by searching for “filename=” and you’ll have the filename of the attached file.

Then, copy the following code, all the “binary string” code, and only this, without the leading MIME informations, to a text file.  In my sample, I called it “c:base64.txt”.  Then, I saw that the filename is a pdf.  I choose “c:base64.pdf” as my output.

This is the code you can use to decode a base64 attachment.

   Dim bytes() As Byte
   Dim reader As New System.IO.StreamReader("c:base64.txt")
   Dim str As String = reader.ReadToEnd
   reader.Close()
   reader.Dispose()
   bytes = System.Convert.FromBase64String(str)
   Dim writer As New System.IO.BinaryWriter(IO.File.Open("c:base64.pdf", IO.FileMode.Create))
   writer.Write(bytes)
   writer.Close()
That’s all!

How to get response headers on all jquery ajax requests

REST / Ajax querie are part of our day as a web developer.

Recently, we had to handle response headers (when communicating with Basecamp3 API).

The default jqXHR object is not very helpful to give us a beautiful list of all response headers.

There are 2 functions available:

  • getResponseHeader(key…) that returns the value of that key, but you need to know which one you need.
  • getAllResponseHeaders, that returns a “string” of all headers, in key-value pair, but all stuck in 1 big string.

Solution

So, we create something that is, on every call, parsing that string and set it in a easy-to-use object embedded to the jqXHR.

$.ajaxPrefilter(function (options, originalOptions, jqXHR) {
  jqXHR.done(function (results, responseText, jqXHR) {
    getResponseHeaders(jqXHR);
  })
}

function getResponseHeaders(jqXHR){
  jqXHR.responseHeaders = {};
  var headers = jqXHR.getAllResponseHeaders();
  headers = headers.split("\n");
  headers.forEach(function (header) {
    header = header.split(": ");
    var key = header.shift();
    if (key.length == 0) return
    // chrome60+ force lowercase, other browsers can be different
    key = key.toLowerCase(); 
    jqXHR.responseHeaders[key] = header.join(": ");
  });
}

Now, you can get, jqXHR.responseHeaders.etag value directly. (lowercase)

Because the “.done” set in ajaxPreFilter is set before the one of the caller, we can fill the responseHeaders property on all call.  And, when the caller gets its .done event executed, that third parameter, jqXHR, contains the responseHeaders already filled.

Warning

You will be able to retrieve these headers, if you do same-domain query.  For cross-domain queries, the server needs to return that header: Access-Control-Expose-Headers (more details)

How to do video capture on windows 10 without third party

I’ll show how to do a video capture in windows 10, without installing any third party app.  It’s all integrated freely in the OS.

How already know how to take a static snapshot of your app without any third party, by sending an image to clipboard like this:

  • Print Screen Key: All your visible screens, of all monitors.
  • Alt + Print Screen Key: Copy Current app to Clipboard
  • WARNING: Alt + Shift + Print Screen = Active the “high contrast” !!!

But now, you want to do a video capture of your app.

When you search the internet for that, found lots of browser plugins and extensions, or complete apps like SnagIt or Greenshot.

Windows 10 integrates features for gamers.  One of them is the “Game Bar“.  It’s used to record your game and share it with friends on the Xbox app.

But, you can use it for other apps that are not games, like your Web Browser or even Notepad.

Instructions

Open the app you need to record, and hit Win + G key.

The bar will initialize, asking you if the app is a game.  Just click the box, and the record bar will appear.

If you use it for the first time in that app, you will need to confirm that the app is a game, even if it’s not.

Then, the record bar will appear.

Click the Record button, and now start clicking or typing in your app.

While recording, the bar is shown smaller on the right of that application.

When you have finished, click stop.

The recorded files can be accessed by the Xbox Windows10 app, or you can go to the “My Video\Captures” folder, that can be hit directly by using Win+R key, and pasting:

shell:My Video\Captures + Enter.

(that’s another hidden Windows trick) (more details…)

These captures uses the .mp4 extension, are well compressed to offer a good quality with a small file size.

This is how the final result looks like:

The small record bar is not visible in the video, even if you see by following the mouse that I click on the “stop” button at the end.

 

Disable ssl3 for more security

SSL3 is over.  Some servers keep it active because they need to serve pages to IE6/XP users.  But, these days are over, as most of the updated to, at least IE8, and they have all the last updates allowing to connect using TLS 1.1 or 1.2.

SSL3 can also be enabled by default on older Windows Servers, like 2008 R2, even if you installed all Windows Updates.

Now, it’s time to disable SSL3 completely.

If your SSL3 is active, you may get one of these warnings from Qualys SSL Test:

  • This server is vulnerable to the POODLE attack. If possible, disable SSL 3 to mitigate. Grade capped to C.
  • This server uses SSL 3, which is obsolete and insecure. Grade capped to B.

It’s easy to disable it from a Windows registry, as described here.

Solution

Create a file, called DisableSSL3.reg, and copy that content on it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server]
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"Enabled"=dword:00000000

Save it, double-click on it, and accept.

Finally, reboot, and all SSL3 server services are disabled on your Windows server.

How to get “A” Rating on Qualys SSL Labs Test

That blog is hosted on an Amazon EC2 Instance, running Windows 2012 R2 Server.  And our SSL certificated is provided by Let’s Encrypt.

Starting from that default configuration, we ran the SSL test, and we got a B note.  We wanted to get the “A” Rating, and these are the 2 major warning we had to solve.

  • “This server supports weak Diffie-Hellman (DH) key exchange parameters”
  • “This server accepts RC4 cipher, but only with older protocols”

Solution

We were able to fix these issues with some simple registry tweaks that we describe in these articles

Then, after we ran these steps, we now have our A Grade!

Now, if you want an even better grade, you can continue to solve these little warnings that the SSLLabs test can give you.

How to solve RC4 warning on Qualys SSLLabs Test

In a previous article, I talked about how you can solve the Diffie-Hellman warning on Qualys SSLLabs test, by applying a registry configuration.

Now, we’ll talk about another common warning that most AWS EC2 customer can get.  By default, we got that security issue from SSLLabs:

This server accepts RC4 cipher, but only with older protocols. Grade capped to B.

Solution

Microsoft proposes a solution for disabling the 3 weak RC4 cipher suites in that article.
You need to create 1 new registry entry.  Create an empty text file called rc4fix.reg, and paste that content to it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 128/128]
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 40/128]
"Enabled"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\RC4 56/128]
"Enabled"=dword:00000000

Then, double-click on it to apply these settings, an reboot.

Finally, run your SSL test again, that warning disappeared.

How to solve Diffie-Hellman warning on Qualys SSLLabs Test

In a previous article, I talked about how you can get a better note on Qualys SSLLabs test, by configuring CAA DNS entry.

Today, we’ll talk about another warning most of us must resolve to get the “A” Rating.

On our AWS EC2 Windows 2012 R2 server, by default, we got that security issue from SSLLabs:

This server supports weak Diffie-Hellman (DH) key exchange parameters. Grade capped to B.

Solution

That is caused by the Diffie-Hellman protocol accepted at 1024 bits.  The fix proposed by Microsoft (article) is to still accept that protocole, but only at 2048+ bits.

You need to create 1 new registry entry.  Create an empty file called df.reg, and paste that content to it:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman]
"ServerMinKeyBitLength"=dword:00000800

Then, double-click on it to apply these settings, an reboot.

Run your SSL test again, that warning disappeared.