Securing Dynamically Generated HTML

September 22nd, 2019
Posted in Security | No Comments

Implementing code that simply displays a user’s IP address as part of an HTML page may be considered easy. Without security considerations, it can be implemented in PHP simply with the following:

    echo "IP: " . $_SERVER['REMOTE_ADDR'];

2011 CWE/SANS Top 25: Monster Mitigations recommends establishing and maintaining “control over all your inputs” and “control over all of your outputs.” Since the IP address is output as part of an HTML page, the code is more securely implemented as follows:

    $ipAddrRemote = $_SERVER['REMOTE_ADDR'];
    if(my_is_ipaddr_valid($ipAddrRemote)) {
      $ipAddrEncoded = my_htmlencode($ipAddrRemote);
      "IP: ${ipAddrEncoded}";
    }

The remote IP address is retrieved from the global $_SERVER variable for validation then use. The validated address is encoded before it is used in the output HTML.

The difficulty of selecting appropriate validation and encoding functions is conveniently abstracted away here by user-defined functions: my_is_ipaddr_valid() and my_htmlencode(). The two code samples above demonstrate differences in effort between naive and secure implementations.

Introducing IAsyncDisposable

September 17th, 2019
Posted in C# | No Comments

Being sometimes required to call a particular method before an object is disposed emits a pungent code smell. In particular recently reviewed code, invoking an asynchronous Flush() method was sometimes necessary before a MyStream object was disposed, because asynchronous methods would be otherwise called from Dispose(), which does not wait for completion of those asynchronous methods.

An exception encountered with the following code sample motivates the workaround described above:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
class MyService : IDisposable
{
  private MemoryStream ms;
  public MyService(MyStream myStream)
  {
    ms = myStream.GetStream();
  }
  public async Task WriteAsync(string s)
  {
    byte[] buf = System.Text.Encoding.ASCII.GetBytes(s);
    await ms.WriteAsync(buf, 0, s.Length);
  }
  public async Task Flush()
  {
    try
    {
      await Task.Delay(50);
      int length = (int)ms.Length;
      byte[] buf = new byte[length];
      ms.Seek(0, System.IO.SeekOrigin.Begin);
      await ms.ReadAsync(buf, 0, length);
      foreach (byte b in buf)
        Console.Write((char)b);
      Console.WriteLine("");
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.ToString());
    }
    Program.Done();
  }
  public async void Dispose()
  {
    await Flush();
  }
}
class MyStream : IDisposable
{
  MemoryStream ms = new MemoryStream();
  public MemoryStream GetStream()
  {
    return ms;
  }
  public void Dispose()
  {
    ms.Close();
  }
}
class Program
{
  private static EventWaitHandle ewh = 
    new EventWaitHandle(false, EventResetMode.ManualReset);
  public static void Done()
  {
    ewh.Set();
  }
  public static async void Run()
  {
    using (var myStream = new MyStream())
    {
      using (var myService = new MyService(myStream))
      {
        await myService.WriteAsync("success");
      }
    }
  }
  public static void Main(string[] args)
  {
    Run();
    ewh.WaitOne();
  }
}

Calling async methods from Dispose(), which is non-async or async void, potentially causes the following exception:

    System.ObjectDisposedException: Cannot access a closed
    Stream.
        at System.IO.MemoryStream.get_Length()
        at MyService.Flush() in ...\Program.cs:line 22

The exception is caused by Flush() accessing the Length property of a MemoryStream object that has already been disposed. Although the lifetime of myStream is expected to encompass that of myService, the Flush() method is not actually performed until after the myStream object is invalidated by MyStream.Dispose().

MyService.Dispose() does not wait for Flush() to complete even though “async” is added to the MyService.Dispose() method signature and await is used on the Flush() call.1

Also, async void is “generally discouraged for code other than event handlers.”2

A workaround implemented in recently reviewed source code removed the Flush() call from the Dispose() method and introduced an IsFlushBeforeDisposeRequired() method. Then, all instances of the following code snippet:

    using (var myService = new MyService(myStream))
    {
      await myService.WriteAsync("success");
    }

were updated to the following:

    using (var myService = new MyService(myStream))
    {
      await myService.WriteAsync("success");
      if (myService.IsFlushBeforeDisposeRequired())
        await myService.Flush();
    }

Having to repeatedly check whether to call Flush() wherever MyService is disposed stinks! Simply calling Flush(), even if it is empty for derived classes of MyService also stinks!

System.IAsyncDisposable, introduced in .NET Standard 2.1 and .NET Core 3.0, addresses these code smells. async functions can be safely called from DisposeAsync(), which is a method of IAsyncDisposable, and boilerplate cleanup code can be avoided in using-blocks.

The following code is the above code updated to use IAsyncDisposable and works as expected by outputting “success” rather than an exception message:

using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
class MyService : IAsyncDisposable
{
  private MemoryStream ms;
  public MyService(MyStream myStream)
  {
    ms = myStream.GetStream();
  }
  public async Task WriteAsync(string s)
  {
    byte[] buf = System.Text.Encoding.ASCII.GetBytes(s);
    await ms.WriteAsync(buf, 0, s.Length);
  }
  public async Task Flush()
  {
    try
    {
      await Task.Delay(50);
      int length = (int)ms.Length;
      byte[] buf = new byte[length];
      ms.Seek(0, System.IO.SeekOrigin.Begin);
      await ms.ReadAsync(buf, 0, length);
      foreach (byte b in buf)
        Console.Write((char)b);
      Console.WriteLine("");
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.ToString());
    }
    Program.Done();
  }
  public async ValueTask DisposeAsync()
  {
    await Flush();
  }
}
class MyStream : IDisposable
{
  MemoryStream ms = new MemoryStream();
  public MemoryStream GetStream()
  {
    return ms;
  }
  public void Dispose()
  {
    ms.Close();
  }
}
class Program
{
  private static EventWaitHandle ewh = 
    new EventWaitHandle(false, EventResetMode.ManualReset);
  public static void Done()
  {
    ewh.Set();
  }
  public static async void Run()
  {
    using (var myStream = new MyStream())
    {
      await using (var myService = new MyService(myStream))
      {
        await myService.WriteAsync("success");
      }
    }
  }
  public static void Main(string[] args)
  {
    Run();
    ewh.WaitOne();
  }
}

Implementation of the IAsyncDisposable interface, the method signature of DisposeAsync(), and use of await using allows await Flush() to wait for completion before myStream is disposed. The updated code works as expected by outputting “success” instead of an exception message.

250,000 Miles

September 14th, 2019

My 2004 Honda Civic LX Sedan reached 250,000 miles
on August 29, 2019.

Security Review 2019

September 13th, 2019
Posted in Security | No Comments

Recent assignments that focus my efforts on securing web applications have motivated me to review the security of my personal websites. PHP code that I implemented 15 years ago is still used by my websites today. With the experience I gained over the years, and my current effort to acquire deep familiarization with security practices, I was able to quickly identify and address potential security risks.

I learned a lot from performing a security review on my own web applications. My past dependency on security through obscurity is cringeworthy. Also, my code for unexpected cases had depended on PHP extension module functions throwing exceptions, which possibly are not thrown with specially crafted inputs. I just recently updated my PHP code to proactively validate used $_GET, $_POST, or $_SERVER values. Values are now tested against explicitly specified acceptable values. I am more confident in the security of my personal websites. My recent updates bring my personal web application code closer to being secure by default.

David Sklansky’s fundamental theorem of poker applies when implementing secure software or performing a security review. The theorem states:

Every time you play a hand differently from the way you would have played it if you could see all your opponents’ cards, they gain; and every time you play your hand the same way you would have played it if you could see their cards, they lose. Conversely, every time opponents play their hands differently from the way they would have if they could see all your cards, you gain; and every time they play their hands the same way they would have played if they could see all your cards, you lose.

If there is discomfort with code when knowing that malicious actors can potentially see it, then the code is not secure and changes need implementing to increase security and peace of mind.

Upgraded to GoDaddy VPS – CentOS 7

September 1st, 2019

I lost access to my GoDaddy VPS CentOS 6 server after fat-fingering an openssl update and clobbering sshd in the process. GoDaddy technical support was unable to reinstall openssl then restart the server. They might not have physical access or a means of simulating physical access to my VPS instance. (With physical access to a non-virtual server, one would boot into single-user mode, reinstall openssl, and reboot normally.) It is my fault that I lost a server that was operational for almost 10 years. I learned not to hot update system libraries, ordered a new VPS running CentOS 7, and I am rebuilding. I am so glad I established data backup procedures!

I want to now share my experience with the GoDaddy VPS CentOS 7 installation.

Iptables is incomplete.

I recommend disabling iptables (“systemctl disable iptables”) before experimenting with it. This allows the server to reboot without the risk of applying inadvertently saved bad iptable rules, especially when a rule causes SSH to be inaccessible unexpectedly.

I have used iptables for my GoDaddy VPS running CentOS 6, but upon a fresh provisioning of GoDaddy VPS running CentOS 7, the following status is returned for iptables:

  # systemctl -l status iptables
  iptables: Applying firewall rules: iptables-restore: line 14
  failed

Iptables can be started (“systemctl start iptables”) after fixing the “line 14 failed” issue with the following command:

  # /usr/libexec/iptables/iptables.init save

In particular, issuing the following command fails:

  # iptables -A INPUT -m state --state ESTABLISHED,RELATED \
    -j ACCEPT
  iptables: No chain/target/match by that name.

The iptables extension module responsible for ‘state’ is installed but unloadable. Attempts to load the modules are ignored.

SELinux also does not work.
The configuration file, /etc/selinux/config, suggests that it is enforcing, but getenforce shows that SELinux is disabled. Furthermore, setenforce apparently ignores the command and confirms SELinux is disabled:

  # setenforce Enforcing
  setenforce: SELinux is disabled

swapon also does not work.

Entering the following commands yields the following:

  # fallocate -l 4G /.swapfile
  # chmod 600 /.swapfile
  # mkswap /.swapfile
  Setting up swapspace version 1, size = 4194300 KiB
  no label, UUID=722XXXXX-XXXX-XXXX-XXXX-000000004a36
  # swapon /.swapfile
  swapon: /.swapfile: swapon failed: Operation not permitted

The VPS I ordered only has 1GB of memory. I am prevented from enabling a swap file, but I accept the challenge of maximally utilizing constrained resources.

Although GoDaddy’s VPS configuration prevents me from deploying iptables and SELinux, I successfully hardened my installation by configuring MariaDB, rh-php720-php-fpm, and rbcbind to bind to 127.0.0.1 or ::1. I also deployed httpd with a certificate from Let’s Encrypt. Port scanners identified as open only ports that I exposed. Qualys SSL Labs SSL Server Test gave my server an “A” overall rating. And, I am pleased with the results of my effort.