Recommendations
To address the identified vulnerabilities, our recommendations included the following steps:
- Implement an intrusion-detection system with rules to identify XSS and SQL injection.
- Perform a code review.
- Perform log analysis.
Let's look at these steps in detail.
Step 1: Implement an Intrusion-Detection System
Given that the client's go-live date was in a matter of days, with clearly no time (or management interest) in delaying launch in order to complete a more thorough code review, we suggested taking measures to detect and filter such attacks by deploying an intrusion detection/prevention system, such as the Snort IDS/IPS, with specific regular expressions (regex) designed to identify these attacks.
For example, the Snort regex for a simple XSS attack is as follows:
/((\%3C) <)((\%2F) \/)*[a-z0-9\%]+((\%3E) >)/ix
This can be added into a Snort rule as follows:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"NII Cross-Site Scripting attempt";flow:to_server,established; pcre:"/((\%3C) <)((\%2F) \/)*[a-z0-9\%]+((\%3E) >)/i"; classtype:Web-application-attack;sid:9000; rev:5;)
A paranoid regex for XSS attacks:
/((\%3C) <)[^\n]+((\%3E) >)/I
This signature identifies for the opening HTML tag (or its hex equivalent) followed by one or more characters other than the new line, and then followed by the closing tag (or hex equivalent). While in some cases the expression has been seen to produce a small number of false positives, it is virtually assured of identifying a cross-site scripting attack.
The Snort IDS can also be used to identify SQL injection attacks through a collection of regular expressions and Snort rules, including but not limited to the following:
Regex for detection of SQL meta-characters:
/(\%27) (\') (\-\-) (\%23) (#)/ix
It's added into a Snort rule as follows:
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"SQL Injection - Paranoid"; flow:to_server,established;uricontent:".pl";pcre:"/(\%27) (\') (\-\-) (%23) (#)/i"; classtype:Web-application-attack; sid:9099; rev:5;)
Regex for detecting SQL injection attacks on a Microsoft SQL server:
/exec(\s \+)+(s x)p\w+/ix
Regex for typical SQL injection attacks:
/\w*((\%27) (\'))((\%6F) o (\%4F))((\%72) r (\%52))/ix
Regex for detecting SQL injection with the UNION keyword:
/((\%27) (\'))union/ix (\%27) (\')
Additional expressions can be written for other SQL queries, including SELECT, INSERT, UPDATE, DELETE, DROP, and so on.
Installing the IDS with these rules will help to identify attempted cross-site scripting and SQL injection attacks, adding a layer of defense against these vulnerabilities. This possibility also presents an additional issue we haven't discussed thus far: When hosting your application and your data in the cloud with a hosting provider, it's often overlooked that suddenly your security practices and policies must be implemented and followed by at least two partiesboth you and the vendor.
This level of coordination can be difficult to achieve and hard to verify on an ongoing basis. By asking the vendor to deploy certain IDS rules (as opposed to simply asking the vendor to deploy an IDS), you're implicitly asking the vendor to follow and adopt your security practices. Further, making a request this detailed and specific increases the likelihood that it will be followed.
Step 2: Perform a Code Review
The next recommendation involved actually performing the security code review. While there wasn't time to do it before going live, this step was strongly recommended for any web-based application at least once per year, and whenever changes to the application source code are made.
A code review to identify and change all instances of XSS and SQL injection is the primary means to remove these vulnerabilities. In addition to detecting the vulnerability through an IDS, we recommended a full security code review in the near term, such as within six months and/or prior to releasing any version upgrade of the software.
Specifically, the code review ensures the proper filtration and validation of all user-supplied data, as well as the encoding of all user-supplied data to prevent inserted scripts from being sent to end users in an executable format.
Input validation checks must include more than the default ASP.NET validation controls. The validation of user-supplied data involves verifying that input matches the strictest definition of valid allowable input. (It also implies that the universe of valid user-supplied inputs must be tightly defined.) User-supplied input should be limited to alphanumeric characters and, where necessary, support only a small set of identified HTML tags (such as boldfacing, italicizing, underlining), and only if strictly necessary.
Step 3: Perform Log Analysis
Checking the database access logs, server access logs, and transaction logs on a regular basis, such as monthly, will help you to understand the normal behavior of the network. Having a log analysis tool also allows you to keep up with the pace of log generation, scanning the logs on an ongoing basis while focusing on the truly critical events that need to be examined. This is another recommendation that may not be implementable in the short term; however, it should be strongly considered within the first six months.