Jmp Start

…where the Geek shall Inherit the Word

Do NOT recreate a ctor, use it!

Posted by CKret on July 19, 2012

Stackoverflow is a very popular site for developers.
There are tons of questions and answers and there is a good chance you’ll find the solution to your specific problem if you take the time to search a bit.

This post however is not about the correct answers but more about the ones who on the surface seem correct.

A question was asked and an answer was given.

The answer itself is not bad. It is a working solution. For now.
And that’s the key: for now.

An example (where A is a class in a third party assembly):

public class A
{
  public A()
  {
    Init();
  }

  protected void Init()
  {
    ...
    Initialize everything.
    ...
  }
}

public class B : A
{
  private int theNumber;
  public B(int num)
  {
    Init();

    theNumber = num;
  }
}

The constrcutor of B does exactly what the constructor of A does, calls Init, and some more.
So far so good.

But what happens if the constructor of A in an later update changed to:

public class A
{
  public A()
  {
    Init();
    FixSecurityProblem();
  }

  public void Init()
  {
    ...
    Initialize everything.
    ...
  }

  protected void FixSecurityProblem()
  {
    ...
    Do fix the security problem.
    ...
  }
}

This isn’t a breaking change. The code only introduces some internal security checks not visible to the “outside”.

How does this affect B?
Well. The creator of B would have to add a call to FixSecurityProblem in it’s constructor and distribute the new version to all clients.
Will this work?
Sure, but there will be a lot of headache.

Since all clients might not have the new A,
B has to determine exactly which version is installed and make some decisions based on that.
Then the new version of B has to be distributed to all clients.

An even bigger problem would be if FixSecurityProblem was a private method:

public class A
{
  private void FixSecurityProblem()
  {
    ...
    Do fix the security problem.
    ...
  }
}

Now B would have to call A‘s constructor instead! Which is exactly the point in this post.

Even if someone finds this a valid solution, the fundamental problem here is the negligance of NOT utilizing the existing constructor of A:

public class B : A
{
  private int theNumber;
  public B(int num) : base()
  {
    theNumber = num;
  }
}

This would, for all who have an updated class A, fix the security problem. Whithout any changes to B!
For those who have not updated, changes in B would not affect them anyway!

So, as the title says, “Do NOT recreate a ctor, use it!”.

Posted in .NET, Architecture, C# | Tagged: , , | Leave a Comment »

Sanitize user input

Posted by CKret on September 30, 2009

Today our local newspaper opened their brand new website to the public with every kind of publicity stunt you can think of.

“The new site is so much better then the old one.”
“We’ve got Web 2.0 functionality!”
are some of the sentences flying all over the place.

So I thought I’d check it out to see what all the fuzz is about. To my surprise I found a meager looking site with some performance issues. “It’s day one, maybe a lot of visitors”, I thought to myself. Eager to check out the community functionality I created an account. When I added information to my profile it hit me: “Why don’t I do a small penetration test on the site.”

Said and done I started with some simple XSS (Cross Site Scripting) attacks. First ones failed and the website seemed to be well protected. But then suddenly I struck gold.

They seemed to have some protection but it was not nearly as complete as they thought. From the launch of the site to a successfull XSS attack it took just minutes. This was, as their project manager put it, “Embarrassing”. I immediately contacted the site administrators about this and eventually got a reply stating my “attack” had given them a lot of problems with their administration interface. After a few emails back and forth they successfully fixed the security flaw. Well, atleast for that particular threat.

What can we learn from this?

Always sanitize user input correctly. There are guidlines and APIs to help you along. A couple of particularly good APIs are OWASPs AntiSamy and Microsofts AntiXSS. There is no need to use proprietary solutions when exisiting free open source solutions have been proven to be atleast as effective.

Posted in Security | Tagged: , | Leave a Comment »

Proper use of Rfc2898DeriveBytes

Posted by CKret on September 29, 2009

When you need encryption in your application, the recommended way to create the key and Initialization Vector (IV) is to use Rfc2898DeriveBytes. It is located in the namespace System.Security.Cryptography. To encrypt some data you would do something like:

public static byte[] EncryptRfc(byte[] plainText, string password, byte[] salt)
{
  var keyGen = new Rfc2898DeriveBytes(password, salt);
  var key = keyGen.GetBytes(32);
  var iv = keyGen.GetBytes(16);

  var cipher = new RijndaelManaged { Key = key, IV = iv };

  byte[] cipherText;
  using (var encryptor = cipher.CreateEncryptor()) {
    using (var ms = new MemoryStream()) {
      using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) {
        cs.Write(plainText, 0, plainText.Length);
        cs.FlushFinalBlock();
        cipherText = ms.ToArray();
      }
    }
  }
  return cipherText;
}

This is straightforward enough:

  • derive the encryption key and IV from the password and salt.
  • create a new instance of the encryptor with the key and IV.
  • encrypt the plaintext.

If you run this it seems to be quite fast. However, nothing can be further from the truth.

Analysis of Rfc2898DeriveBytes

I created a console application with the above method and called it from main.

Then I profiled the application and analyzed the result.

One method call stood out like a sore thumb:

Function Name Inclusive Samples Exclusive Samples Inclusive Samples % Exclusive Samples %
System.Security.Cryptography.Rfc2898DeriveBytes.GetBytes(int32) 944 0 91,12 0,00

The call to GetBytes took up 91.12% of the execution time!!

“So what!?”, you say.

When encrypting a single batch of data this isn’t really an issue since most of the time the encryption takes longer than generating the key and IV. If you however need to encrypt a lot of different data and the data sizes are small then you will have a lot of overhead like in this case. In the above example encrypting the data took at most 8% of the execution time while generating the key and IV took over 91%.

How does it concern me?

This example takes about 80ms on my computer. That’s not bad but that is a single encryption. If I would encrypt 1000 messages then it would run in 80 seconds. Which of course is unacceptable.

Why does it perform so badly?

Rfc2898DeriveBytes uses a pseudo-random number generator based on HMACSHA1. When calling GetBytes it initializes a new instance of HMAC which takes some time. (More than 50% of the execution time in the above example). Subsequent calls to GetBytes does not need to do this initialization.

What can we do to fix this?

There is a fundamental flaw in the above code example. There’s no need create a new instance of Rfc2898DeriveBytes for each call to encrypt. If you have to send 1000 separate messages to a recipient then you’ll want to use the same key but change the IV for each message. Lift out Rfc2898DeriveBytes from the Encrypt method and pass along the key and IV instead of the password and salt. For each new message you call GetBytes() to generate a new IV.

Conclusion

Using Rfc2898DeriveBytes incorrectly will have a severe performance impact on your application. Taking proper steps to avoid this is easy enough but you should always make sure you understand why things work the way they do.

Posted in .NET, C#, Cryptography, Security | Tagged: , , , , | 4 Comments »

SafeNet SoftRemoteLt on Windows 7

Posted by CKret on September 16, 2009

At our company we use SafeNets SoftRemoteLT VPN solution for secure communication with our DB servers.
In Windows XP and Vista this works fine.

Since the release of Windows 7 RC I’ve tried to get SoftRemoteLt working but have had no luck.
That is until now…

In this post I will show you how to configure Windows 7 and Virtual Windows XP Mode to route VPN traffic through XP.

First you need to make sure you’ve got the prerequisits:
(Instructions for prerequisits are not covered by this post.)

  • Windows 7 Professional or Ultimate
  • Intel® Virtualization Technology or AMD-V™ feature is enabled in BIOS
    Microsoft issued an update that eliminates this prerequisit. See KB977206.
  • Windows Virtual PC RC
  • Windows XP Mode RC
  • SafeNet SoftRemoteLt installed on Virtual Windows XP.
    These instructions should work for other clients as well.
  • Make sure Internet and VPN is working.

(Windows Virtual PC RC and Windows XP Mode RC can be downloaded from here.)

There are several things we need to configure on both Windows 7 (host) and Windows XP Mode (guest):

  1. Add a Loopback adapter to the host.
  2. Configure the Loopback adapter.
  3. Add a Virtual adapter to the guest.
  4. Configure the Virtual adapter.
  5. Disable Internet Connection Sharing and Firewall on the guest.
  6. Enable routing on the guest.
  7. Configure routing on the guest.
  8. Configure routing on the host.

Let’s get started then.

Add a Loopback adapter to the host

For the host to utilize the VPN located on the guest we need more than unidirectional communication.
VPN traffic goes from the host to the guest, thrugh the VPN and out on the Internet.
When receiving data the guest needs to be able to route it back to the host.
Therefor we need another communication channel.

  • Open up Device Manager and right click the root node.
  • Select “Add Legacy Hardware” then click “Next”.
  • Select “Install the hardware that I manually select from a list (Advanced)” and click “Next”.
  • Select “Network Adapters” then click “Next”.
  • In the left pane select “Microsoft”.
  • In the right pane select “Microsoft Loopback Adapter” then click “Next”.
  • On the confirmation screen click “Next”.
  • When the installation is finished, click “Finish”.

Now you should have a new network adapter in the Network Connections.

Configure the Loopback adapter

Now it’s time to choose a subnet and IP address for your network connection.
I chose a subnet that wouldn’t collide with my home or work networks.

192.168.199.199 with subnet mask 255.255.255.0

  • Open up the Network Connections.
  • Find the new network adapter.
    Mine is called “Local Area Connection 4″.
  • Right click the icon and select “Properties”.
  • Select “Internet Protocol Version 4 (TCP/IPv4)” then click “Properties”.
  • Select “Use the following IP address”.
  • Enter the IP address and subnet mask and click “OK”.
  • Click “OK”.

We’re almost done configuring the host. However, before we can finish we will configure the guest.

Add a Virtual adapter to the guest

Before we start you’ll need to shut down Windows XP Mode completely. Hibernation will not work.

  • Open up Virtual Machines.
  • Select “Windows XP Mode”.
  • Click “Settings”.
  • Select “Networking”.
  • Set the number of network adapters to 2.
  • For the second adapter, select “Microsoft Loopback Adapter” then click “OK”.

Moving on…

Configure the Virtual adapter

For the Virtual Adapter we should now choose an IP address in the same range as we chose before:

192.168.199.200 with subnet mask 255.255.255.0

  • Start Windows XP Mode.
  • Open up Network Connections.

You should now see two connections. Mine are called “Local Area Connection” and “Local Area Connection 2″.
The first one is your “Internet Connection” and the second one is the “Loopback Connection”.

  • Right click your “Loopback Connection” then select “Properties”.
  • Select “Internet Protocol (TCP/IP)” and click “Properties”.
  • Select “Use the following IP address”.
  • Enter the IP address and subnet mask and click “OK”.
  • Click “OK”.

Disable Internet Connection Sharing and Firewall on the guest

We need to create or own routing and we do not want windows to interfere with our setup.

  • Open “Services”.
  • Find “Windows Firewall/Internet Connection Sharing (ICS)”.
  • Right click the node and select “Properties”.
  • Set “Startup type” to “Disabled” then click “Stop”.
  • Click “OK”.

Don’t close “Services” just yet.

Enable routing on the guest

To enable routing we need to do two things:

  • Start RegEdit.
  • Find the key “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\IPEnableRouter”
  • The default value should be “0×00000000″, change it to “0×00000001″.
  • Close RegEdit.
  • Back in “Services” find “Routing and Remote Access”.
  • Right click the node and select “Properties”.
  • Set “Startup type” to “Automatic” then click “Start”.
  • Click “OK”.

You may now close “Services”.
At this point you might need to restart Windows XP Mode.

Configure routing on the guest

In this step we’ll set up the routing needed for the host to be able to communicate through the guests VPN.

  • Start a “Command Prompt”.
  • Enter “netsh routing ip nat install”.
    This will install NAT routing.
  • Enter “netsh routing ip nat add interface “Local Area Connection” full”.
    This will route traffic through your “Internet Connection”.
  • Enter “netsh routing ip nat add interface “Local Area Connection 2″ private”.
    This will route traffic through your “Loopback Connection”.

Guest is done! Only one more thing to do.

Configure routing on the host

You’ll need to know which subnet your VPN network is using.
We will configure the routing so that all traffic meant for your VPN network goes through the “Loopback adapter”.
Let’s say your VPN subnet is

172.16.16.0 with netmask 255.255.255.0

  • Start a “Command Prompt” as Administrator. (Run as Administrator).
  • Enter “route -p add 172.16.16.0 mask 255.255.255.0 192.168.199.200″
    Note that 192.168.199.200 is the IP address of the guests Virtual Adapter we set earlier.

All done.

From now on all you need to do is start SoftRemoteLt from the “Windows Virtual PC” folder in the Start Menu and you’re all set.

Posted in Security | Tagged: , , , , , , , | 26 Comments »

 
Follow

Get every new post delivered to your Inbox.