Developing Secure Web Applications

An Introduction to the OWASP Top Ten

Darian Anthony Patrick

Senior Programmer Analyst, Application Security
University of Pennsylvania, ISC Networking & Telecommunications
darianp@isc.upenn.edu

What is the OWASP Top 10?

"The primary aim of the OWASP Top 10 is to educate developers, designers, architects and organizations about the consequences of the most common web application security vulnerabilities." — OWASP Top 10 2007

The OWASP Top 10 is a community-reviewed document detailing the most critical and most prevalent security vulnerabilities since the document's previous publication. In simpler terms, it lists what got most people in trouble and how to avoid repeating their mistakes. It is currently treated as an industry-standard jumping-off point from which application developers may gauge their comprehension of the defects most likely to exist or be created in their applications.

The Top 10

The Top 10 Continued

A1 Cross Site Scripting (XSS): The Details

"XSS flaws occur whenever an application takes data that originated from a user and sends it to a web browser without first validating or encoding that content. XSS allows attackers to execute script in the victim's browser, which can hijack user sessions, deface web sites, insert hostile content, conduct phishing attacks, and take over the user's browser using scripting malware."

Three types:

The differences here are subtle but important. DOM-based XSS is the hardest variation to understand and won't be covered here. Stored XSS is typically found in applications that store user-supplied data, then present that data to other users, as in bulletin board systems, blogs, classified ads, etc. Reflected XSS is often found in applications that accept input to temporarily control the behavior of the application or cater its output to the requirements of a user, such as search engines. It is also found in applications that validate user input, returning error messages containing the original un-escaped input, as in login forms, shopping carts, etc.

A1 Cross Site Scripting (XSS): The Exploit

WebGoat Demonstration

[ Reflected XSS Attacks Video ]
[ Stored XSS Attacks Video ]

A1 Cross Site Scripting (XSS): The Fix

All output should be escaped all the time, unless their is a clear reason not to do so. This reason should be documented in-place in your code and available at audit time.

A1 Cross Site Scripting (XSS): Defense In Depth

Treat external data sources as "input" as well, and be defensive about what you present to the browser from those sources. One of those sources could fall victim to an attacker who may substitute legitimate data with malicious script meant to exploit your users. Use a web application firewall such as mod_security for Apache and tie that in to your existing alerting infrastructure. Detect, block, and log XSS attempts. Knowing what is happening to your web application may be key to stopping an attack or detecting the reconnaissance steps of a larger attack.

A2 Injection Flaws: The Details

"Injection occurs when user-supplied data is sent to an interpreter as part of a command or query. Attackers trick the interpreter into executing unintended commands by supplying specially crafted data."

Broad Assortment of Injection Flaws

The most commonly referenced form of injection flaw is SQL injection, however there are many types. Injection diversity is a result of the many types of backend systems to which we provide web applications access. Any time data is passed from a user, through a web application, and to a backend system there is a risk of an injection flaw.

A2 Injection Flaws: Demonstration

WebGoat Demonstration

[ String SQL Injection Video ]
[ Blind SQL Injection Video ]
[ Command Injection Video ]

A2 Injection Flaws: The Exploit

Vulnerability exists where user input is passed to a backend system without being validated and filtered.

PHP w/ dynamic mysql_query()
$q = "SELECT * FROM student_records
           WHERE id='".$_REQUEST['id']."'";
$result = mysql_query($q);

Here $_REQUEST['id'] is vulnerable to command injection.

A2 Injection Flaws: The Fix

Vulnerability corrected with type-appropriate filtering and parameterized queries.

PHP w/ ctype_digit() and PDO
if ( !ctype_digit((string)$_POST['id']) ) {
    /* return invalid input error to browser,
       using htmlentities() to escape output */
}

$clean_id = $_POST['id'];
$sth = $dbh->prepare('SELECT *
                      FROM student_records
                      WHERE id=?');
$sth->execute(array($clean_id));
$results = $sth->fetchAll();

A2 Injection Flaws: The Exploit II

Again, vulnerability exists where user input is passed to a backend system without being validated and filtered.

PHP w/ exec()
exec("ls /tmp/uploaded_assignments/$_POST['id']",
    $assignments);
foreach ($assignments as $assignment)
{
    echo '<li>'.htmlentities($assignment)."</li>\n";
}

Here $_GET['id'] is vulnerable to command injection.

A2 Injection Flaws: The Fix II

Vulnerability corrected with type-appropriate filtering and shell argument escaping.

PHP w/ exec() and escapeshellarg()
if ( !ctype_digit((string)$_POST['id']) ) {
    /* return invalid input error to browser */
}

exec('ls /tmp/uploaded_assignments/'
        . escapeshellarg($_POST['id']),
    $assignments);
foreach ($assignments as $assignment)
{
    echo '<li>'.htmlentities($assignment)."</li>\n";
}

An Aside: Filtering v. Sanitizing

FilteringSanitizing
Match input against known good; reject if input doesn't matchParse known good from input; continue along happily if known good could be found in input

Which wins? Filtering or Sanitizing

DO NOT SANITIZE!

DO NOT SANITIZE!

A3 Malicious File Execution: The Details

"Developers will often directly use or concatenate potentially hostile input with file or stream functions, or improperly trust input files. On many platforms, frameworks allow the use of external object references, such as URLs or file system references. This allows attackers to perform remote code execution... This attack is particularly prevalent on PHP..."

A3 Malicious File Execution: The Exploit

Vulnerability exists in use of unfiltered input to reference the base of an included filename.

PHP w/ include construct
include($_REQUEST['view'].'.php');

A3 Malicious File Execution: The Fix

Match input against known good and disable remote file inclusion.

PHP w/ include construct and filtering
$allowable_views = array('home', 'preferences');
if ( !in_array($_REQUEST['view'], $allowable_views) )
{
    // throw an error or perhaps redirect to home page
}
include($_REQUEST['view'].'.php');
php.ini w/ allow_url_fopen disabled
allow_url_fopen = Off ; Disable URLs as files
allow_url_include = Off ; and in include/require
This demonstrates just one of many ways to malicious file execution may be accomplished. Read section A3 of the Top 10 for a more thorough treament. And see Essential PHP Security by Chris Shiflett.

A4 Insecure Direct Object Reference: The Details

"A direct object reference occurs when a developer exposes a reference to an internal implementation object, such as a file, directory, database record, or key, as a URL or form parameter. An attacker can manipulate direct object references to access other objects without authorization, unless an access control check is in place."

A4 Insecure Direct Object Reference: Demo

WebGoat Demonstration

[ Stage 3: Bypass Data Layer Access Control Live Demo ]

A4 Insecure Direct Object Reference: The Exploit

Vulnerability exists because $_POST['id'] is not verified to have access to requested records.

PHP w/ ctype_digit() and PDO
if ( !ctype_digit((string)$_POST['id']) ) {
    /* return invalid input error to browser,
       using htmlentities() to escape output */
}

$clean_id = $_POST['id'];
$sth = $dbh->prepare('SELECT *
                      FROM student_records
                      WHERE id=?');
$sth->execute(array($clean_id));
$results = $sth->fetchAll();

Here $_REQUEST['id'] is vulnerable to command injection.

A4 Insecure Direct Object Reference: The Fix

Vulnerability corrected with access control check.

PHP w/ ctype_digit() and PDO
// ID has previously been verified to be clean
if ( !allowed_to_view($current_user_id, $clean_id) )
{
    // kick them out with an error message
}

$sth = $dbh->prepare('SELECT *
                      FROM student_records
                      WHERE id=?');
$sth->execute(array($clean_id));
$results = $sth->fetchAll();

A close cousin.

A4 Insecure Direct Object Reference is closely related to A10 Failure to Restrict URL Access. Where there is one there is often the other, and they share the same fix.

A10 Failure to Restrict URL Access: The Details

"Frequently, the only protection for a URL is that links to that page are not presented to unauthorized users. However, a motivated, skilled, or just plain lucky attacker may be able to find and access these pages, invoke functions, and view data. Security by obscurity is not sufficient to protect sensitive functions and data in an application. Access control checks must be performed before a request to a sensitive function is granted, which ensures that the user is authorized to access that function."

A10 Failure to Restrict URL Access: Demo

WebGoat Demonstration

[ Stage 1: Bypass Presentational Layer Access Control Live Demo ]

A10 Failure to Restrict URL Access: Etc.

Other Considerations


Joomla include file protection
// no direct access
defined( '_VALID_MOS' ) or die( 'Restricted access' );

A5 Cross Site Request Forgery (CSRF): The Details

"Frequently, the only protection for a URL is that links to that page are not presented to unauthorized users. However, a motivated, skilled, or just plain lucky attacker may be able to find and access these pages, invoke functions, and view data. Security by obscurity is not sufficient to protect sensitive functions and data in an application. Access control checks must be performed before a request to a sensitive function is granted, which ensures that the user is authorized to access that function."

"...these attacks work because the user's authorization credential (typically the session cookie) is automatically included with such requests by the browser, even though the attacker didn't supply that credential."

"When building defenses against CSRF attacks, you must also focus on eliminating XSS vulnerabilities in your application since such flaws can be used to get around most CSRF defenses you might put in place. "

A5 Cross Site Request Forgery (CSRF): Demo

WebGoat Demonstration

[ Cross Site Request Forgery (CSRF) Live Demo ]

A5 Cross Site Request Forgery (CSRF): The Fix


CSRF protection token
<form action="/transfer.do" method="post">
<input type="hidden" name="adbd843dc277ef30"
	value="438473edaf84383">
...
</form>

A6 Information Leakage and Improper Error Handling: The Details

"Applications can unintentionally leak information about their configuration, internal workings, or violate privacy through a variety of application problems. Applications can also leak internal state via how long they take to process certain operations or via different responses to differing inputs, such as displaying the same error text with different error numbers. Web applications will often leak information about their internal state through detailed or debug error messages. Often, this information can be leveraged to launch or even automate more powerful attacks."

A6 Information Leakage and Improper Error Handling: Case Study

A popular instant messaging server contains the following login logic the following in it's admin console:

Login logic excerpt
if (authorizedUsernames != null
  && !authorizedUsernames.isEmpty()) {
  if (!authorizedUsernames.containsKey(username)) {
    throw new UnauthorizedException(
      "User '" + username + "' no allowed to login.");
  }
} else {
  if (!"admin".equals(username)) {
    throw new UnauthorizedException(
      "Only user 'admin' may login.");
  }
}
These error messages are way to descriptive and allow an attacker to enumerate whether or not alternative users to "admin" have been granted administrative permission, and to enumerate who those users are, based on a harvested list of possible usernames for the target IM domain.

A6 Information Leakage and Improper Error Handling: The Fix

A8 Insecure Cryptographic Storage: The Details

"Simply failing to encrypt sensitive data is very widespread. Applications that do encrypt frequently contain poorly designed cryptography, either using inappropriate ciphers or making serious mistakes using strong ciphers. These flaws can lead to disclosure of sensitive data and compliance violations."

A8 Insecure Cryptographic Storage: Case Study

A popular courseware suite contains the following markup on its user preferences page:

What were they thinking?
<INPUT TYPE="hidden" NAME="userName"
	VALUE="johnquser">
<INPUT TYPE="hidden" NAME="password"
	VALUE="3389DAE361AF79C15D9C8E7057F60CC6">
<INPUT TYPE="hidden" NAME="verifyPassword"
	VALUE="3389DAE361AF79C15D9C8E7057F60CC6">

Note, that the user cannot even change the password on this page! It is changed in a different section of the application!

What in the world were they thinking?!?! Here the password is hashed, presumably using MD5, but then the hash is returned to the browser leaving it completely vulnerable to pilfering and offline dictionary attack if there is an XSS vulnerability in this preferences page.

A8 Insecure Cryptographic Storage: The Fix

A9 Insecure Communication: The Details

"Encryption (usually SSL) must be used for all authenticated connections, especially Internet-accessible web pages, but backend connections as well. Otherwise, the application will expose an authentication or session token. In addition, encryption should be used whenever sensitive data, such as credit card or health information is transmitted."

"Using SSL for communications with end users is critical, as they are very likely to be using insecure networks to access applications."

A9 Insecure Communication: Demo

Cookie Theft Demonstration

[ Cookie Theft Live Demo ]

A9 Insecure Communication: The Fix

Web Security: Build it in

The key to achieving web application security consistency is building security into your development process, to the point that it becomes second-nature to you and your colleagues.

Resources

General

XSS

Remote File Inclusion

About WebGoat

"WebGoat is a deliberately insecure J2EE web application maintained by OWASP designed to teach web application security lessons."

http://www.owasp.org/index.php/OWASP_WebGoat_Project

Thank you

(Corrected) Slides available at http://darianpatrick.com