Validating User Input
&
Handling and Avoiding Errors

CS418 - Web Programming - Spring 2015

Old Dominion University

Mat Kelly (mkelly@cs.odu.edu)
http://www.cs.odu.edu/~mkelly/cs418 Adapted from slides by Michele C. Weigle

What this lecture will cover

  • Server-side Validation
  • Handling Errors

Validating User Input

  • Why do we need input validation?
    • Typos
    • Malicious Input
  • We'll look at validating:
    • Simple string values
    • Integer values
    • Formatted text input

Why server and not client side validation?

  • Client-side security == no security
    • malicious or broken clients
  • JavaScript (client-side) might be disabled

PHP has built-in functions (for nearly everything!)

When the Input doesn't validate...

  1. Generate errors on same page
    • don't load a different URI
  2. Load separate URI that is just for handling errors
  3. Reload same page with an error argument

Same URI to Handle Errors

if (empty($var1)) {
	$errors .= "$var1 should not be empty";
}
if (!is_numeric($var2)) {
	$errors .= "$var2 should be a number";
}
// check all anticipated error conditions
…
if (empty($errors)) {
	// do interesting work
} else {
	internal_error_function($errors);
}
function internal_error_function ($errors) {
	// generate pretty HTML response
	// provide link to start over
}
						

Separate URI to Handle Errors

if (empty($var1)) {
	$errors .= "$var1 should not be empty";
}
if (!is_numeric($var2)) {
	$errors .= "$var2 should be a number";
}
// check all anticipated error conditions
…
if (empty($errors)) {
	// do interesting work
} else {
	$errors = urlencode($errors);
	header("Location: http://foo.edu/error.php?error=$errors");
}

Encoding/Decoding URLs

Same URI with Error Argument

if (empty($var1)) {
	$errors .= "$var1 should not be empty";
}
if (!is_numeric($var2)) {
	$errors .= "$var2 should be a number";
}
// check all anticipated error conditions
…
if (empty($errors)) {
	// do interesting work
} else {
	$errors = urlencode($errors);
	header("Location:".$_SERVER["REQUEST_URI"]."?errors=$errors");
}

Formatted text

  • To do formatted text (e.g., date) validation, use regular expressions
  • DD-MM-YYYY format for date
    • ([0-9]{2})-([0-9]{2})-([0-9]{4})
    • 2 digits between 0-9
    • "-" character
    • 2 digits between 0-9
    • "-" character
    • 4 digits between 0-9

Regular Expressions

if ( !preg_match("/([0-9]{2})-([0-9]{2})-([0-9]{4})/",
     $_POST['movie_release'], $reldatepart) ) {
	$error .= "Please+enter+a+date+with+the+dd-mm-yyyy+format";
} 
  • if $_POST['movie_release'] is 31-05-1969 then:
    • $reldatepart[0] = 31-05-1969
    • $reldatepart[1] = 31
    • $reldatepart[2] = 05
    • $reldatepart[3] = 1969

Date/Time

  • Change the date string into a timestamp (to store in the database) using mktime()
  • Takes as parameters: hour, min, seconds, month, day, year
  • If valid date, returns the number of seconds since Jan 1, 1970
  • If not a valid date (e.g., 99-99-9999), returns -1
$movie_release = mktime (0, 0, 0, $reldatepart['2'],
$reldatepart['1'], $reldatepart['3']);

Same Thing with MySQL

  • UNIX_TIMESTAMP()
    • takes YYYY-MM-DD HH:MM:SS format string
    • creates a timestamp
    • 
      $reldate = $reldatepart['3'] . "-" .
                 $reldatepart['2'] . "-" .
                 $reldatepart['1'] . " 00:00:00";
      $sql = "INSERT INTO movie_main (release_date) " .
             "VALUES (UNIX_TIMESTAMP('$reldate'))";
      

Escaping HTML

Apache httpd.conf

#
# Customizable error responses come in three flavors:
# 1) plain text 2) local redirects 3) external redirects
#
# Some examples:
#ErrorDocument 500 "The server experienced an error."
#ErrorDocument 404 /missing.html
ErrorDocument 404 /error.php?404
#ErrorDocument 404 "/cgi-bin/missing_handler.pl"
#ErrorDocument 402 http://www.example.com/subscription_info.html
#
...
  • No access to httpd.conf?
    • put ErrorDocument directives in .htaccess
ErrorDocument 404 "

Sorry, nothing here

"
ErrorDocument 404 /404.html

.htaccess demo

Send Email on Error

  • PHP syntax:
    mail($to,$subject,$body,$header);
  • body can be HTML formatted
  • headers:
MIME-Version: 1.0\r\n
Content-type: text/html; charset=iso-8859-1\r\n
From: Apache Error <host@yourdomain.com>\r\n
http://www.cs.odu.edu/~mkelly/tmp/mailtest.php

Overriding PHP Error Settings

  • on fast.cs.odu.edu:
error_reporting(-1);
ini_set('display_errors', 'On');
  • To file:
function dump_error_to_file($errno, $errstr) {
	file_put_contents('/tmp/phpErrors', date('Y-m-d H:i:s - ') . $errstr, FILE_APPEND);
}
set_error_handler('dump_error_to_file');