Adding Depth to WebApp Defense

3 February 2015

The principle of defense in depth is widely understood in the information security space. The idea is to provide layers of protection so that if one fails, an attacker doesn't necessarily compromise an entire machine.

Web application defense often begins with patching vulnerabilities like SQL injection and cross site scripting in the source code. Often times, however, administrators are responsible for deploying and maintaining applications with unknown source code quality and may not be able to audit or fix the source code. In situations like this administrators should assume that applications contain vulnerabilities and apply additional defensive measures to ensure that application compromises are contained.

Prevent Filesystem Changes in Web Root

Many web application attackers seek to install web shells, or web accessible back doors in compromised applications. They may accomplish this any number of ways, but the idea is to gain persistence through the use of the shell. Web shells are generally files written in the same scripting language as the web application, such as PHP. These files are dropped into a location where the web server can serve them up at an accessible URL (such as http://192.168.0.2/c99.php).

There are a number of techniques used to install web shells. Remote file inclusion, local file inclusion, writing the shell to a stand alone file, overwriting an existing file, or appending the shell to an existing file. Of these techniques the remote file inclusion vulnerability is the hardest to defend against from the web root. This method involves using a flaw in an application and scripting language capabilities so it is best addressed by customizing the settings of the scripting language to disable this functionality (see Hardening PHP from php.ini - http://www.madirish.net/199).

Preventing an attacker from putting a web shell into the web root can be as simple as disabling all privileges for the web server to write anywhere in the web root. Changing permissions so that the web server account (apache or httpd) has no write permissions to any directory in the web root means that an attacker can't place new files, overwrite or append to existing files. This will frustrate most attacks. Be aware, however, that by making this permission on all subdirectories in the web root you could break some applications that write logs or cache files in the web root, so keep a close eye on the server error logs while you're making this change.

Another strategy for preventing alteration of the web root is to place the contents of the web root in a revision control system like Git or CVS. Once the contents are in a revision control you can check the status of the web root to check and see if there are any changes. This approach has the added bonus of allowing you to roll back any changes quickly and easily. Be aware, however, that if you do this you must be careful not to expose any artifacts from the revision control system in the web root (such as .git directories) since these could expose configuration files to attackers. Using an .htaccess file or similar to limit access to any .git or .cvs directory is a great way to protect access to these artifacts.

At the very least be sure to check timestamps on files in the web root and keep an eye on any new ones that show up. This can be a good way to baseline the places where applications require the ability to write files as well as a good strategy for finding malicious files.

Protect the Database

Web applications often use databases for persistent storage. Most database systems will allow for remote access. Be sure to close off any access to the database except from the web server, especially if the web server is local. Closing the TCP port using a firewall is a quick and easy way to do this, but tweaking permissions in the database is also effective. Attackers will seek to expose database credentials through web application vulnerabilities. If these credentials allow the attacker to log into the database server remotely it makes the job of an attacker much easier. By limiting access to the database server you ensure that web applications can still connect but remote systems cannot.

Isolate Database Permissions

Most databases have some sort of administrative account and default testing account. Be sure that applications are not configured to use either of these. Many database systems have privileges for the administrative account that cannot be limited or revoked. These include the ability to read and write files to the filesystem. This privilege quickly allows an attacker to turn a SQL injection attack into a vector to write a web shell or other backdoor onto the filesystem.

Each web application should have its own dedicated set of credentials. Additionally each application should have its own database. If all applications use the same database then a compromise in one application could allow access to data from other applications. By creating a specific account for each application and only giving the account access to the application's specific database you can greatly limit the impact of a compromise.

Track Database Changes

Many web applications will allow administrative users to store dynamic code in the database that can then be run by the application. Attackers will seek to utilize this functionality to inject backdoors into the database of an application. Most database systems allow for quick and simple backups by dumping data to files. Performing regular backups and tracking changes with a tool like diff will allow you to spot malicious changes quickly and easily. Searching through the text files of backups for evidence of JavaScript, PHP, or other scripting language will allow you to quickly spot malicious content in the database. Furthermore, having regular, reliable, backups allows you to restore and application if you suspect a compromise.

Monitor Logs

Most web applications will rely on the web server to log traffic. It's important to tune your logs to have access to as much data as possible. Logging requests, including URL variables, may be critical to spotting an attack. Ensure that logs are working, rotating regularly, and are monitored. You can perform simple log monitoring using tools like OSSEC (http://www.ossec.net).

Blacklist Bad Actors

It's simple enough to spot malicious activity against your web applications, but if you allow the activity to continue you provide an attacker the opportunity to explore your systems and probe for weaknesses. Simple honeytraps placed in your robots.txt (http://www.madirish.net/194) file are often effective at driving away attackers or thwarting automated tools. Using the active response capabilities in OSSEC can also be very good at stopping attackers during their probing phases.

Limit Admin Access

Many dynamic web applications provide some sort of administrative interface or include some sort or elevated functionality (such as PHPMyAdmin). Use .htaccess files or configuration changes to limite access to those features to specific IP addresses. Just because a site is running Drupal, say, doesn't mean that you need to allow unlimited access to the update.php file or even to any URL that includes /admin.

Patch, Patch, Patch!

One of the most common ways that web applications fall victim to attack is that they are running outdated versions of software or third party modules. Almost any modern web application system will have a reporting and updating interface. Be sure to check to make sure you're running the most up to date versions of software. If you can avail yourself of operating system supported versions of applications (using apt or yum) that is a quick and easy way to implement changes.