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.

RHEL 8 Application Streams and SCL

August 14th, 2019

Red Hat Enterprise Linux 8 introduces Application Streams. Software Collections (SCLs) are no longer needed in RHEL 8. According to Introducing Application Streams in RHEL 8, Application Streams, containerization, or virtualization can be used to fulfill needs met previously by SCLs.

I recently updated PHP and Apache httpd on a CentOS 6 server with Software Collections. Software Collections allowed installation of multiple software versions. Software depending on older versions of other software can continue functioning, while other software requiring new versions of that other software can be installed and used. SCLs helped me gradually transition my PHP applications from httpd+mod_php to httpd+php-fpm.

With anticipation of CentOS 8 soon being available through my virtual server provider, GoDaddy, I wanted to become familiar with RHEL 8. I wanted to deploy CentOS 8 for my next virtual server, and I wanted the server to use httpd and php via SCL only. I am now rethinking my plan to use SCL on CentOS 8 to allow future transitioning of applications toward newer software versions at a pace I control.

Development Team as a Jazz Band

August 13th, 2019

Working within a software development team is like being a member of a jazz band. Software architects convert specifications into overall designs. Engineers distill overall designs into detailed designs of individual modules. And, implementers convert detailed designs into source code. Each role has some degree of creative freedom. Each member improvises while keeping their contributions consistent with the whole software system.

In La La Land, Sebastian speaking about individual musicians of a jazz band captures the sentiment exactly:

“One after the other, everyone gets their moment… And you put it all together — each player, each sound — into one single story.” (La La Land)

La La Land. Dir. Damien Chazelle. Lionsgate, 2016. Film.

Exceptions vs. Error Return Codes

April 26th, 2019

I have been partly responsible for maintaining legacy source code. Almost all of the code is implemented in C and therefore does not use exceptions. Much of the error handling code follows the following pattern here implemented in C++ (imagine in this example, operator new returns 0 when no memory is available):

int function()
{
  MyTypeA * ptrValTypeA = 0;
  MyTypeB * ptrValTypeB = 0;

  ptrValTypeA = new MyTypeA();
  if(ptrValTypeA == 0)
  {
    /* error handling #1 */
    return -1; /* error, no memory */
  }

  ptrValTypeB = new MyTypeB();
  if(ptrValTypeB == 0)
  {
    /* error handling #2 */
    delete ptrValTypeA;
    return -1; /* error, no memory */
  }

  /* ... more code ... */

  if(function_call() == -1)
  {
    /* error handling #3 */
    delete ptrValTypeA;
    delete ptrValTypeB;
    return -1;
  }

  /* ... even more code ... */

  return 0; /* no error */
}

The above code could be reduced to the following (assuming the default behavior of operator new throwing an exception when memory is exhausted):

int function()
{
  MyTypeA * ptrValTypeA = 0;
  MyTypeB * ptrValTypeB = 0;

  try
  {
    ptrValTypeA = new MyTypeA();
    ptrValTypeB = new MyTypeB();

    /* ... more code ... */

    if(function_call() == -1)
      throw Exception();

    /* ... even more code ... */
  }
  catch(...)
  {
    /* error handling */
    delete ptrValTypeA;
    delete ptrValTypeB;
    return -1;
  }
  return 0; /* no error */
}

Error handling in the first code snippet is spread to multiple places in the code. This makes the code less readable and therefore less maintainable.

The second code snippet shows that error handling is localized. The normal flow of the code is easy to follow, and freeing allocated resources is performed in one place when an exception occurs.

I am currently tasked with designing and implementing a C# software component. There are software developers who insist on adopting error return codes over exceptions because of unmeasured performance concerns. For example, some developers demand database connection timeouts or failures should use error return codes. My experience with error handling in legacy C code makes me resist error return codes and prefer exceptions.

If exceptions are used properly for exceptional cases such as an offline database, then the performance impact will be rarely realized and the code can be cleanly written. A performance hit that only happens during unexpected or abnormal operation is a good trade for clean code without the cost of constant error checking during normal operation.

For further reading, see Why Exceptions Should Be Exceptional.