What We Will Cover
Elucidations
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 web-programming classes:
- CIS 131: Perl Programming in a Unix Environment (Summer)
- CIS 132: Introduction to Internet Programming (classroom and online sections available)
- Other programming courses to sharpen your skills:
- CS-11: Introduction to Programming Concepts and Methodology, C++
- CS-12J: Introduction to Programming Concepts and Methodology, Java
- CS-19: C++ Programming
- CS-20J: Java Programming
^ top
13.1: Security Threats
Learner Outcomes
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
|
^ top
13.1.1: 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
- Beyond the scope of this course
- See CIS-164: Intro. to Managing and Securing a Web Server
- 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
^ top
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 own 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
^ top
13.1.3: Encrypting Confidential Data
Reversing Encryption
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
- Also, you may want to check if your ISP has mcrypt installed
- Also, PHP has a library for OpenSSL
What to Encrypt
- Encrypting confidential data may seem like a good idea
- Encryption hides data from someone who has control of your database
- However, encryption may have little value if you need to decrypt it automatically:
- Decryption requires storing keys and using decryption functions or programs
- Anyone cracking your site would have access to your passwords, functions and programs if they can read your data
- However, encryption can protect data if you do not need to decrypt it automatically
- For instance, 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 some cookies you can use
base64_encode() and base64_decode():
<?php
ob_start();
$name = "cartID";
$value = "8122c5b69a5721cc95263b10540c9720";
echo "<h4>Original values</h4>\n";
echo "<p>name=$name</p>\n";
echo "<p>value=$value</p>\n";
$name = base64_encode($name);
$value = base64_encode($value);
//setcookie($name, $value, time() + 14400);
echo "<h4>Encrypted values</h4>\n";
echo "<p>name=$name</p>\n";
echo "<p>value=$value</p>\n";
$name = base64_decode($name);
$value = base64_decode($value);
echo "<h4>Decrypted values</h4>\n";
echo "<p>name=$name</p>\n";
echo "<p>value=$value</p>\n";
?>
Try it!
- Base64 is well known and easy to reverse without knowing a key value
- For sensitive data, you should use a stronger encryption function
Further Information
^ top
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
Digital Signature Example
To send an authenticatable secret message from Alice to Bob:
- Alice encrypts her message with her private key
- Alice encrypts her message with Bob's public key
- Alice transmit the message and Bob receives the message
- Bob decrypts the message with his private key
- 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 making 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
^ top
13.1.5: Securing Transmission of Confidential Data
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
Further Information
^ top
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
^ top
13.1.7: 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
SQL Injection Defenses
- Verify 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
- Use SQL string escaping for suspicious characters
- Limit database permissions and segregate users:
- If you are only reading the database, connect to the database as a user who only has read permissions
- Never connect as a database administrator in your web application
- Be careful when reporting error messages:
- Default errors give away information valuable to attackers like table and column names
- We discussed how to control error messages in lesson 12.1: Encapsulating the Database
- We will explore these defenses in the rest of today's lesson
More Information
^ top
Exercise 13.1
In this exercise, we explore how SQL injection works. We will discuss the questions after you complete the exercises.
Specifications
- Open the XAMPP Control Panel by double-clicking the icon on the desktop or by using the Apache Friends entry in the start menu.

- Start the Apache and MySQL modules, if they are not already running.

- Verify your computer has the following connection information in a file named
dbconvars.php in a subdirectory named includes of the phptest directory:
<?php
$dbhost = "localhost";
$dbuser = "root";
$dbpwd = "";
$dbname = "artzy";
?>
If needed, change the values assigned to $dbuser and $dbpwd to match your MySQL installation. In the classroom, $dbuser = root; and $dbpwd = password;. For more information see lesson 6.3.1: Connecting to a MySQL Database.
- Also, verify that the Artzy database is installed as described in lesson 2.1.5: Importing and Exporting Data.
- Copy the following HTML page into a text editor, save the file in your
htdocs/phptest directory as loginexer.html, and then view the file as a Web page in your browser using the address: http://localhost/phptest/loginexer.html
<html>
<head>
<title>Login Form</title>
<style type="text/css">
input { position: absolute; left:6em; }
</style>
</head>
<body>
<h1>Please Login</h1>
<form action="loginexer.php" method="post">
<p>Username: <input type="text" name="login"></p>
<p>Password: <input type="password" name="pwd"></p>
<p><input type="submit" value="Click To Login"></p>
</form>
</body>
</html>
The page is a simple login form.
- Copy the following PHP script into a text editor, save the file in your
htdocs/phptest directory as loginexer.php
<?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);
$pwd = stripslashes($pwd);
}
// Make the query
$sql = "SELECT * FROM users
WHERE UserName='$login'
AND Userpwd=OLD_PASSWORD('$pwd')";
$result = mysql_query($sql) or die("Query failed");
// Check results of query
if (mysql_num_rows($result) > 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=\"1\">\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);
?>
Read through the script and make sure you understand how it verifies the username and password. For more information on the MySQL function OLD_PASSWORD() see: OLD_PASSWORD(str).
- Try entering a random username and password into the form to see if you can login. After trying to login with an invalid username and password, then login with the following:
- Username: jbond
- Password: bond007
You should be able to login successfully with the above username and password. If you cannot, then ask another student or the instructor for help.
- Try using other usernames and passwords chosen at random.
Only move to the next step when you are convinced that you cannot login without a valid username and password.
- 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 (').
jbond' or 1=1 or '1
Try entering other usernames instead of jbond but keeping the SQL code after the username: ' or 1=1 or '1. Observe the SQL code displayed by the loginexer.php page and be prepared to discuss how the SQL injection attack works. We will discuss how to avoid these attacks in the following parts of the lesson.
As time permits, be prepared to answer the Check Yourself questions in the following section.
^ top
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
- Preventing SQL Injection
- We discussed how to meet these responsibilities in the previous sections
- In later sections, we will discuss how to avoid SQL injection
Check Yourself
- Why do web developers need to worry about security? (13.1.1)
- What is the best way to avoid losing credit card data? (13.1.2)
- What is the problem with adding features to you web site that you do not end up using? (13.1.2)
- Why is non-reversible encryption useful? (13.1.3)
- What is the problem with secret key encryption when you want to transmit encrypted data? (13.1.3)
- How does public key encryption solve the problem with secret keys? (13.1.3)
- What is a digital signature? (13.1.4)
- When should you authenticate users? (13.1.4)
- On the web, how do you transmit confidential data? (13.1.5)
- How do you test a form for security problems? (13.1.6)
- What is SQL injection? (13.1.7)
^ top
13.2: Safeguarding Against User Input
Learner Outcomes
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
|
^ top
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
Verifying User Input
- Verify data types where possible
- Restrict the length of the input
- Escape database string quotes and other special characters
- Scan user input for correct format
^ top
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
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:
- Check if the value
is_numeric()
- If so, convert the value to an integer using
intval() and then
- Check if the converted value is equivalent to the original value.
Checking for Floating-Point Values
^ top
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
- Many attacks depend on long user input
- 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, robust code is usually a worthwhile tradeoff
^ top
13.2.4: PHP Magic Quotes
- Even valid data may pose problems for database data
- For example, text that contains single or double quotes
- 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
- For more information see the PHP Manual: Magic Quotes
- Note that Magic Quotes has been deprecated and removed from PHP 6
Using Magic Quotes
Commonly Used Magic Quote Functions
More Information
^ top
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()
- 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>";
?>
|
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 can include a list of tags you do NOT want removed as well
- 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>");
?>
- 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
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. |
^ top
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.
Specifications
- Verify your web server is started and all the support files are installed as specified in the first 4 steps of exercise 13.1.
We will modify the loginexer.php script from exercise 13.1.
- Verify you can still attack the login script by entering the following for the Username in the form:
jbond' or 1=1 or '1
- In the
loginexer.php script from exercise 13.1, change the following code from:
if (get_magic_quotes_gpc()) {
$login = stripslashes($login);
$pwd = stripslashes($pwd);
}
to:
if (!get_magic_quotes_gpc()) {
$login = addslashes($login);
$pwd = addslashes($pwd);
}
Rather than removing quotes, we are adding quotes. For more information see section 13.2.4: PHP Magic Quotes.
- Try attacking the login script again and notice that you can no longer bypass the login. Also notice the difference in the SQL query:
SELECT * FROM users
WHERE UserName='jbond\' or 1=1 or \'1'
AND Userpwd=OLD_PASSWORD('password')
The quotes that were entered are now escaped with a leading backslash (\).
Note that escaping quotes is only part of the solution. We still need to verify the length of the input and the format of the input. These checks are done easier within the framework of FormVerifier.
As time permits, be prepared to answer the Check Yourself questions in the following section.
^ top
13.2.6: Summary
Check Yourself
As time permits, be prepared to answer these questions. You can find more information by following the links after the question.
- Why is user input validation so important? (13.2.1)
- What is the algorithm for determining if the input field of a form is an integer value? (13.2.2)
- What PHP function can you use to determine the size of a database column? (13.2.3)
- What characters are quoted by PHP's Magic Quotes? (13.2.4)
- True or false? Magic quotes will protect your application from all malicious data entered by a user. (13.2.5)
^ top
13.3: Finishing the Course
Learner Outcomes
At the end of the lesson the student will be able to:
- Discuss the final preparation for the project presentation
- Advise the instructor on how to improve future courses
|
^ top
13.3.1: About the Final Project Presentation
Important Final Exam Information
Date and Time: 7:00 pm-9:50 pm Monday, June 1
Location: Room 2501 (regular classroom)
Mandatory attendance for online and face-to-face sections
|
Before the Presentation
- Submit your project to Blackboard before the presentation:
- Bring a written report on paper to give to the instructor before the presentation
During the Presentation
The presentation should have the following:
- Your name and your project's name
- A brief introduction describing the purpose of your project
- A demonstration and discussion of the user interface including:
- Entry page
- Page layout
- Navigation features
- A demonstration of a multi-form sequence where you pass information from one page to another
- A demonstration of user-input error handling:
- Checking of form input for errors
- Highlighting of errors so users easily see them
- Explanation to user of how to correct errors
- Retention of prior entries on error (except passwords)
- A discussion or demonstration of user authentication:
- How the database is used for authentication
- How passwords are encrypted in database
- A discussion or demonstration of security features:
- How data types are checked before insertion into a database
- How data sizes are checked before insertion into a database
- How taint checking of special characters is implemented (e.g.
'"$#)
- How special symbols and spaces do not cause database errors
- A discussion or demonstration of cool features:
- Point them out so we can all appreciate them
- Feel free to display your written report during the presentation
- Keep the presentation to 10 minutes or less
After the Presentation
- Feel free to leave (or stay) after your presentation
- You can present to the instructor alone after the other presentations are through
^ top
13.3.2: Lecture Finale
- During the semester we have covered many topics and learned at least two languages: SQL and PHP
- With this knowledge you can develop professional-looking database-driven Web sites
- Your project will allow you to demonstrate what you have learned:
- There is no substitute for a working application!
- I hope that everyone has enjoyed taking the course as much as I have enjoyed presenting it
- I am always open to suggestions for improving the course
^ top
Wrap Up
Due Next: Final Project Report and Presentation (6/1/09)
When class is over, please shut down your computer if it is on
Work on your project!
^ top
Home
| WebCT
| Announcements
| Course info
| Expectations
| Schedule
Project
| Help
| FAQ's
| HowTo's
| Links
Last Updated: May 31 2009 @22:02:08
|