13. Improving Security

What We Will Cover


Elucidations

Questions from last class?

Questions about your project?

What to take next?

  • Schedule of Classes
  • Beginning computer courses related to the Internet
    • CIS 81: Networking Fundamentals and Theory
    • CIS 90: Introduction to UNIX/Linux
    • CIS 172: Introduction to Operating Systems
  • Other computer-related courses on which you can use your programming skills
    • CIS-160GP: Game Programming in Java
    • CIS-165PH: Introduction to Programming Database-Driven Web Sites with PHP (may be taken 2 times)

13.1: Security Threats

Objectives

At the end of the lesson the student will be able to:

  • Describe the need for security
  • Identify security responsibilities of the programmer
  • Describe what the programmer should do to reduce security risks

13.1.1: Introduction to Security

Why We Need Security

  • How important is your web site's information?
    • Most database-driven web sites have some important data
    • Important data needs protection
  • However, protecting information comes at a cost
    • Cost of security devices, services and software
    • Reduced web-site usability
  • Security must be balanced with usability
    • Web sites that allow access to nobody are secure but useless
  • As the developer, you need to find the right balance
  • Note that not all data may need the same level of protection
  • For instance, how important is each of the following data? (scale 1-10)
    • Customer credit-card transactions
    • User logins and passwords
    • User e-mail addresses
    • Product descriptions displayed in a catalog
    • Web-sites HTML code

Security Practices for Database-Driven Web Sites

  • Much of a web site's protection comes from the web server's configuration
  • However, the web-site developer is responsible for some aspects of security including:
    • Designing to reduce security exposures
    • Encrypting confidential data
    • Authenticating users when required
    • Securing transmission of confidential data
    • Testing for security
    • Validating user input
  • We consider these aspects in the sections that follow

13.1.2: Designing to Reduce Security Exposures

  • In this section we consider how the overall web-site design affects security

Deciding What Data to Store

  • Make certain you only keep confidential data that you really need
  • Do you really need to keep a customers credit card data?
  • If you do not keep the data, they cannot be stolen

Deciding On Services and Features

  • Remove unused or unnecessary features to reduce potential weaknesses
  • The more features you add, the more complicated your site
  • A common developer phenomena is adding features that are not used
    • But you may need them some day
  • As your code becomes more complicated, you tend to overlook things
  • The solution is to keep your code as simple as possible, but no simpler
  • Implement all the features you need now, but no others

Limiting Access

  • Be careful where you store confidential data
  • For example, do not store anything with Web server access that you do not want seen
    • It is very unlikely that your Web server will send PHP pages as plain text
    • If you are concerned, you can keep login and password information where the Web server cannot access them
    • Then use include files to access the data kept outside the Web document directories
    • However, please do not use this approach for your project
    • It makes it too difficult for the instructor to install and test your code
  • Limit access to database information from the Web server
    • Our most important data tends to be kept in our databases
    • Use a database account with restricted access for your PHP scripts
    • This is usually a concern only if you run your owb server
    • Most ISPs do not allow you to have root database-user access
  • Use the file permissions of the operating system to restrict access
    • Make certain your scripts cannot be written to by anyone but the owner
    • Also make certain that directories cannot be written to by anonymous users
    • If someone can install a script, they can perform many malicious acts to your Web site
    • If you use external files in your program, set permissions appropriately

13.1.3: Encrypting Confidential Data

  • The foundation of many security techniques is the encryption of data
  • Encryption transforms data into a seemingly unreadable string
  • Plaintext is the information before encryption and after decryption
  • Ciphertext is a term for encrypted data
  • For example, if we encode the plaintext "password" using PHP's md5() function:
  • <? echo md5("password"?>

  • The resulting ciphertext looks like
  • 5f4dcc3b5aa765d61d8327deb882cf99

  • As you can see, the ciphertext looks nothing like the plaintext

Reversing Encryption

  • You can reverse many, but not all, encryption processes
    • Why is non-reversible encryption useful?
  • The reverse process of encryption is called decryption
  • For reversible encryption algorithms, you must have a value known as a key
    • If you do not know the key value, you cannot reverse the process
  • Some encryption schemes use the same key to encrypt and decrypt a message
    • Called a secret (or private) key because you must keep it secret
  • Some algorithms allow you to use one key to encrypt data and another to decrypt data
  • This two-key system is known as public key encryption
    • Allows you to keep one key private
    • You publish the other key to allow people to send you encrypted data
    • Only you can decrypt the data using your private key

PHP's Encryption Functions

  • PHP offers a wrapper to C's crypt() function
  • Also provides implementations of md5 and sha1
  • All the above are for one-way encryption of string data
  • PHP also provides one set of easy to use encryption and decryption functions:
  • For stronger reversible encryption, PHP has an extension for the mcrypt library
  • To use mcrypt() at home, you may need to install additional DLLs

What to Encrypt

  • Encrypting confidential data may seem like a good idea
  • However, encryption probably has little value if you need to decrypt it
    • Decryption requires storing keys and using decryption programs
    • Anyone cracking your site would have access to your passwords and programs if they can read your data
  • Even so, you should store passwords using one-way (non-reversible) encryption
    • Prevents anyone but the user from knowing their passwords
    • Even someone who cracks your site cannot get the passwords
  • Password verification with encryption is straightforward
    • User enters a password
    • Password gets encrypted
    • Encrypted version of the entered password is compared against the stored version of encrypted password
  • You may be able to use a similar approach for storing other confidential data such as credit card numbers
  • Cookie data usually should be encrypted with a reversible algorithm
    • Prevents the user from modifying their cookie data
    • Prevents hackers from discerning the structure of your cookie data
  • For most cookies you can use base64_encode() and base64_decode():
  • <?php
    $name 
    base64_encode($name);
    $value base64_encode($value);
    setcookie($name$value);
    ?>

  • For more sensitive data, you should use a stronger encryption function

Further Information

13.1.4: Authenticating Users When Required

  • There is a difference between authorization and authentication
  • Authorization establishes your authority to perform some act
  • Authentication establishes that you are not false or an imitation
  • One common method of authentication is a login name and password
  • Logins and passwords are relatively simple to implement and use
    • We explored how to do this previously
  • A stronger form of authentication is the digital signature

Digital Signatures

  • A digital signature is the electronic version of a physical signature
  • With paper and pen, a person signs a document with a physical signature
  • In the digital world, users and machines sign documents or data using a digital signature
  • Digital signatures are most often based on public-key cryptography
  • As was mentioned earlier, public and private keys come in pairs
  • Only the owner of the public and private key pair knows the private key
  • Encrypting using one key requires the other key for decryption
  • Any message encrypted by the private key can be decrypted by the public key
  • Thus any message encrypted by the private key can use the public key to verify it came from the owner
  • This allows authentication that a message in fact originated from the identity it appears to have originated from

For Example

    To send an authenticatable secret message from Alice to Bob:

  1. Alice encrypts her message with her private key
  2. Alice encrypts her message with Bob's public key
  3. Alice transmit the message and Bob receives the message
  4. Bob decrypts the message with his private key
  5. Bob decrypts the message with Alice's public key

When to Authenticate

  • Use authentication when you need surety of whom you are dealing with
    • For example, when make a financial transaction such as with a credit card
    • Without authentication, the credit card holder may deny having authorized the purchase
  • Another example is when you provide special privileges or higher authorization levels
    • For instance, when accessing administrative pages
  • Yet another time to use authentication is when providing confidential data
    • For example, when allowing users to change passwords or view their personal information

13.1.5: Securing Transmission of Confidential Data

  • Data is at risk while traversing a network
  • Often passes through 10 to 20 machines to reach a destination
  • You can examine how a packet moves over the Internet
  • On UNIX, run the traceroute program
  • On Windows, run the tracert program
    • From the Start menu, select Run
    • Type in command for Win9X/ME or cmd for WinNT/2000/XP
    • At the command prompt, type tracert and a destination
  • From the Internet, use a traceroute utility
  • For example:
  • C:\> tracert php.net

    Tracing route to php.net [64.246.30.37]
    over a maximum of 30 hops:

    1 <10 ms 1 ms <10 ms rocky.cabrillo.cc.ca.us [172.16.1.1]
    2 1 ms 1 ms 2 ms seahawk.cabrillo.cc.ca.us [207.62.185.33]
    3 2 ms 2 ms 2 ms 207.62.184.1
    ...
    18 56 ms 55 ms 55 ms rs1.php.net [64.246.30.37]

    Trace complete.

  • This shows it took 18 "hops" for packets to travel from my PC to php.net
  • Oftentimes a firewall will block ping requests

Protecting Data Transmission

  • The most common way to secure transmissions is using Secure Sockets Layer (SSL)
  • SSL provides data encryption and other services for TCP/IP (Internet) transmissions:
  • SSL comes in two key strengths: 40-bit and 128-bit
    • Longer keys makes breaking encryption more difficult
  • To implement, you must arrange with your hosting service to install a certificate
  • You can obtain certificates from Verisign, Thawte (owned by Verisign) and others
  • Many hosting services have their own certificate your can use
  • You can also create your own certificate (self-signed)

Using SSL

  • To invoke a secure channel, use the https protocol in your URLs
  • <form action="https://some url/page.php" method="post">
    
  • For instance: edparrish.com
  • Some ISPs require you to use HTML when using SSL for security reasons
  • Use https for transmitting all confidential data

Further Information

13.1.6: Testing for Security

  • As a developer, you are responsible for testing your code
  • Programs that successfully complete their intended task still may not be correct
  • Sometimes developers use poor programming practices that have potential security risks
  • When you test your scripts, try entering extreme or even ridiculous values
  • Such values will often cause the program to crash or have unintended side effects
  • Crackers often exploit these types of bugs

Testing Your Web Forms

    Following are adapted from the MySQL Documentation: General Security Guidelines on how to test your Web forms:

  • Try to enter (') and (") in all your web forms. If you get any kind of database error, the Web application is not checking user input properly.
  • Try to modify dynamic URLs by adding %22 ("), %23 (#), and %27 (') in the URL.
  • Try to modify data types in dynamic URLs from numeric ones to character ones containing characters from previous examples. Web applications should check for these types of insertions.
  • Try to enter characters, spaces, and special symbols instead of numbers in numeric fields. Your application should remove them before passing them to a database or your application should generate an error.
  • Check data sizes before passing them to the database.
  • Have the application connect to the database using a user name with the absolute minimum privileges needed.
  • Do not give your applications any more access privileges than they need.

Further Information

13.1.7: Validating User Input

  • Validation of user input is critical in Web applications
  • You need to make sure the data meets database constraints
  • Failure to build in error checking can cause wrong results or worse
  • We will review this important activity in more detail in the rest of the lesson

SQL Injection

  • There is one widespread problem in database-driven Web sites
  • SQL Injection: passing SQL code into an application in a way that was not intended by the developer
  • An attacker tries to create or alter existing SQL commands from scripts
  • We will explore this problem in the next exercise

13.1.8: Summary

  • Much of a web site's protection comes from the web server's configuration
  • However, the web-site programmer is responsible for some aspects of security including:
    • Designing to reduce security exposures
    • Encrypting confidential data
    • Authenticating users when required
    • Securing transmission of confidential data
    • Testing for security
    • Validating user input
  • We discussed how to meet these responsibilities in the previous sections

Further Information

Exercise 13.1

In this exercise, we explore how SQL injection works. We will discuss the questions after you complete the exercises.

Exercises and Questions

    For this exercise, you will need the Artzy database and dbconvars.php file.

  1. Save the following file as loginexer.html in your public_html directory. Replace existing files if any.
  2. <html>
    <head> <title>Login Form</title> </head>
    <body>
    <h1>Please Login</h1>
    <form action="loginexer.php" method="post" >
    <p>Username:
    <input type="text" size="15" maxlength="20" name="login">
    <br>Password:
    <input type="password" size="15" maxlength="20" name="pwd">
    </p>
    <br> <input type="submit" value="Click To Login">
    <input type="reset" value="Erase and Restart">
    </form>
    </body>
    </html>
    

    Q1: What is the purpose of the HTML code?

  3. Create a script using the PHP code below and save it as "loginexer.php" in your public_html directory.
  4. <?php
    require_once("includes/dbconvars.php");
    
    // Open the connection
    @$db = mysql_connect($dbhost, $dbuser, $dbpwd)
        or die("Could not connect");
    @mysql_select_db($dbname, $db)
        or die("Could not select database");
    
    //Retrieve form data
    $login = $_POST['login'];
    $pwd = $_POST['pwd'];
    if (get_magic_quotes_gpc()) {
        $login = stripslashes($login);
    }
    
    // Make the query
    $sql = "SELECT Count(*) FROM users
    WHERE UserName='$login'
    AND Userpwd=Password('$pwd')";
    @$result = mysql_query($sql) or die("Query failed");
    
    // Check results of query
    $row = mysql_fetch_array($result);
    if ($row[0] > 0 ) {
        echo "<h1>You have logged in successfully</h1>\n";
    } else {
        echo "<h1>Loggin failed</h1>\n";
    }
    
    // Display the data
    echo "<h4>Your SQL query was:</h4>";
    echo "<pre>$sql</pre>\n";
    echo "<h4>The results of the SQL query were:</h4>";
    @$result = mysql_query($sql) or die("Query failed");
    echo "<p><table border>\n";
    echo "<tr>\n";
    $meta = mysql_fetch_field($result);
    for ($i = 0; $i < mysql_num_fields($result); $i++) {
        print "<th>".$meta->name."</th>\n";
        $meta = mysql_fetch_field($result);
    }
    echo "</tr>\n";
    while ($row = mysql_fetch_array($result)) {
        echo "<tr>\n";
        for ($i = 0; $i < mysql_num_fields($result); $i++) {
            echo "<td>".stripslashes($row[$i])."</td>\n";
        }
        echo "</tr>\n";
    }
    echo "</table></p>\n";
    
    // Clean up
    mysql_free_result($result);
    mysql_close($db);
    ?>
    

    Q2: What does the script do?

  5. Try entering a user name and password using the login form. This form will send the username and password to the script. One login and password that should work is:
    • Username: jbond
    • Password: bond007

    Q3: Are you able to login successfully? If so, what login and password did you use?

  6. Try using other logins and passwords chosen at random.
  7. Q4: Do randomly-chosen logins and passwords fail to login?

  8. Now enter the following code in its entirety into the Username field and then enter any password you like in the Password field. Make sure to use the entire line in the Username field including the single-quote marks (').
  9. jbond' or 1=1 or '1

    Note: you may use any name you like instead of jbond.

    Q5: Does the script show that you logged in? Why?

    Q6: What, if anything, do you think is wrong with the loginexer.php script?

13.2: Safeguarding Against User Input

Objectives

At the end of the lesson the student will be able to:

  • Describe PHP functions to use in protecting database data
  • Protect applications from embedded HTML and Javascript

13.2.1: Introduction

  • Data verification is an important safeguard for applications that rely on user input
  • Failure to build in error checking can cause wrong results or worse
  • We discussed how to design validation into our applications using the FormLib class
  • Many times choosing which validation techniques to use are obvious
    • Sometimes they are not so obvious
  • In this section we will focus primarily on how to protect your database from user input

13.2.2: Validating Database Column Types

  • It is important to make sure user data meets database constraints
  • If data does not meet constraints, MySQL will usually fail to update and issue an error
  • You then need to trap these errors to ensure data is not lost
  • Trapping the errors is difficult with lots of overhead for both PHP and MySQL
  • Presenting these errors to the user in a meaningful way is hard
  • A better approach is to validate the data and not rely on the database
  • We covered how to solve this problem with the FormLib class
  • Most database constraints involve type checking user input
  • PHP provides a number of functions for type checking

Commonly Used Variable Handling Functions for Type Checking

Function Description
floatval($var) Returns the float value of $var.
intval($var) Returns the integer value of $var.
is_float($var) Returns TRUE if $var is a floating-point number.
is_int($var) Returns TRUE if $var is an integer number.
is_numeric($var) Returns TRUE if $var is a number.
is_string($var) Returns TRUE if $var is a string.

Checking for Integers

  • Checking if a form variable is an integer is more difficult than it seems at first glance
  • A form variable is always a string, so using is_int() alone will fail
  • To check if something is an integer value, you need to:
    1. Check if the value is_numeric()
    2. If so, convert the value to an integer using intval() and then
    3. Check if the converted value is equivalent to the original value.

Checking for Floating-Point Values

  • Checking for a floating-point value is similar, but complicated by questions of precision
    • Many decimal numbers (e.g. 0.1) cannot be represented exactly
    • Thus, testing for equality for such numbers may fail
  • To compare two floating-point values, you compare if they are "close enough":
  • abs($valueOne - $valueTwo) < .000001

13.2.3: Checking Database Column Size

  • If a user enters more data into a text field than your database can hold, MySQL truncates the entry
  • For text fields, you should validate user input to the column size
    • Prevents losing user data
    • Adds security by restricting the size of the input data
  • Note that PHP has a function that returns the length of a field: mysql_field_len()
  • You could use this function rather than hard coding the length
  • Then if you ever change the column size, your code still works
  • While it does add overhead to PHP and MySQL, the overhead is usually a worthwhile tradeoff

13.2.4: PHP Magic Quotes

  • Even valid data may pose problems for database data
  • For example, text that contains single or double quotes
    • Like the name: O'Reilly
  • PHP has a feature known as "magic quotes" that works on external variables
    • All GET, POST, and Cookie variables
  • Magic quotes automatically insert a backslash (\) before the following characters
    • single-quote (')
    • double quote (")
    • backslash (\)
    • ASCII NULL (\0)
  • For example: "foo's bar and\or baz" becomes "foo\'s bar and\\or baz"
  • The purpose of magic quotes is to prevent the quoted characters from being inserted directly into a database
    • Similar to the MySQL QUOTE() function
  • Quoting prevents problems in database queries where these characters may be used
  • However, magic quotes may unexpectedly cause backslash characters to appear in your data
  • You can remove the backslashes with the stripslashes() function

Using Magic Quotes

  • Some hosts have magic quotes turned off and some have them turned on
  • You can use the get_magic_quotes_gpc() function so your code works under either condition
  • if (!get_magic_quotes_gpc()) {
        $myVar = addslashes($myVar);
    }
    
  • The approach you should use is to store data with magic quotes (slashes)
  • When retrieving data from the database, remove the slashes before use
  • if (!get_magic_quotes_gpc()) {
        $myVar = stripslashes($myVar);
    }
    

Commonly Used Magic Quote Functions

Function Description
addslashes() Returns a string with backslashes before characters that need to be quoted in database queries.
stripslashes() Returns a string with backslashes stripped off.
get_magic_quotes_gpc() Returns TRUE if magic quotes is enabled in the system.
get_magic_quotes_runtime() Returns TRUE if magic quotes is enabled for external data such as databases.
set_magic_quotes_runtime() Set the current active configuration setting external data such as databases.

13.2.5: Dealing With Embedded HTML Tags

  • You may want to develop a script that allows users to save textual information
  • Later, on another page, you display that information
  • Unless you are careful, users can enter malicious code
  • For example, consider the following form:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head><title>Message Form</title></head>
<body>
<h1>Your Message Is Heard!</h1>
<form action="msgexer.php" method="post" >
<p>Name:<br>
<input type="text" size="30" name="user">
<p>Comments:<br>
<textarea rows="4" cols="50" name="comment">
Your comments here
</textarea></p>
<br> <input type="submit" value="Click To Post">
<input type="reset" value="Erase and Restart">
</form>
</body>
</html>
  • You save the messages in your database, carefully using addslashes()
    • Database code not shown
  • Later you retrieve the messages from the database for others to read
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// Code to retrieve from database here...

// Remove slashes for display
$user = stripslashes($_POST['user']);
$comment = stripslashes($_POST['comment']);

// Display the data
include("includes/header.php");
echo "<h1>We Heard You!</h1>";
echo "<h4>From: $user</h4>\n";
echo "<p>Comment: $comment</p>\n";
echo "</body>\n</html>";
?>
  • What, if anything, is wrong with this script?
  • What if some entered the following in the comment field?
  • <input type="button" onmouseover="JavaScript: alert('Beware of crackers' )" value="See my message!">

  • What if something more annoying was entered?

Using strip_tags()

  • Function strip_tags() tries to remove all SGML tags from a string
  • $comment = strip_tags($comment);
  • This includes HTML and PHP tags
  • This function prevents users from planting malicious scripts in user data that you might echo back to the browser
  • You may include a list of tags you do not want removed
  • For example:
  • <?php
    $text = "<p style=\"color:red\"><b>Line one</b><br>
    <font size=+5>Line two</font></p>";
    echo "<h4>Original Text:</h4>\n";
    echo $text;
    echo "<h4>Stripped Text:</h4>\n";
    echo strip_tags($text, "<p>");
    ?>
    

    Try it and view the source.

  • Produces the output:
  • Original Text:

    Line one
    Line two

    Stripped Text:

    Line one Line two

  • Note that attributes of tags you allow are not removed
  • You would normally use strip_tags() before saving data in a database

Translating to HTML Entities

  • Some characters have special meaning in HTML
    • Like the less than sign (<)
    • Defines the start of an HTML tag
  • To display the character, we need to translate it to an HTML entity
  • An HTML entity is a special HTML code for a character
    • For instance, the code for the less than sign (<) is: &lt;
  • Function htmlentities() translates many characters into HTML entities
    • Useful for displaying HTML code in a Web page.
  • html_entity_decode() performs the reverse operation of htmlentities()
    • Converts entities into HTML characters
  • Function htmlspecialchars() works like htmlentities but only translates a smaller set
    • Characters that have special significance in HTML
    • Useful in preventing user-supplied text from containing HTML markup
  • For example, the code:
  • <?php
    $new = htmlspecialchars("<a href='test'>Test</a>");
    echo $new; // &lt;a href='test'&gt;Test&lt;/a&gt;
    ?>
    
  • Produces the output: <a href='test'>Test</a>

Commonly Used Functions for Working With HTML Tags

Function Description
strip_tags() Tries to remove all SGML tags from a string. Prevents users from planting malicious scripts in user data that you might echo back to the browser.
htmlentities() Translates certain characters into HTML entities. This is useful for displaying HTML code in a Web page.
html_entity_decode() Converts HTML entities into HTML characters.
htmlspecialchars() Translates HTML characters with special meaning. Useful in preventing user-supplied text from containing HTML markup.

13.2.6: Summary

  • Data verification is an important safeguard for applications that rely on user input
  • In this section, we discussed techniques to safeguard your data from user input
  • One important safeguard is to verify that the data is the correct type for a database column
  • This can be trickier than you might expect for integer and floating-point types
  • Another important safeguard is to verify that textual data does not exceed the allowed length
  • Even valid data may pose problems for database data
  • For example, text that contains single or double quotes
    • Such as a name like O'Reilly
  • Fortunately, PHP provides "magic quotes" to handle this problem
  • Some hosts have magic quotes turned off and some have them turned on
  • To allow your code to work under either condition, you can test for the condition
  • if (!get_magic_quotes_gpc()) {
        $myVar = addslashes($myVar);
    }
    
  • You should store your data quoted and remove the quotes before display
  • User input that you redisplay can pose additional problems
    • It is easy to insert malicious HTML or script
  • To preclude this possibility, you should use strip_tags() or htmlspecialchars()

Exercise 13.2

In this exercise we consider how to protect our scripts from SQL injection like we saw in the previous exercise. We will discuss the solution after about 5 minutes.

Specified Question

What changes should you make to the application shown in the previous exercise to prevent SQL injection? Which of the techniques we just discussed could be used?

Feel free to discuss your ideas with your partner or other students.

Wrap Up

    Reminders

    Due Next: Final Project Report and Presentation (5/31/06)

  • When class is over, please shut down your computer
  • There is no need to turn in this weeks exercises
  • Work on your project!

Home | WebCT | Announcements | Course info | Expectations | Schedule
Project | Help | FAQ's | HowTo's | Links

Last Updated: April 30 2006 @21:36:14