CHAPTER Six Database Driven Website
CHAPTER Six Database Driven Website
Database Driven
Websites
1
Outline
PHP/MySQL
Understanding the MySQL Privilege System
Locking and Concurrency
Speeding up database queries
General optimization tips
Different table types
Loading data from a file
Making your database more secure
Web security and cryptography theory
2
Static vs Dynamic Web Pages
Static Web pages
Data is stored in .html files
Won't change until someone changes their source
codes
Dynamic Web pages
Web pages that respond to users' requests and gather
information from them. Oftentimes, they have built-in
links to a database, from which they extract data
based on input from the users
Created in real time
3
What is a database-driven Web Site?
A database-driven Web site is a Web site that uses a
database to gather, display, or manipulate information
Example:
News sites: CNN.com and MSNBC.com
E-commerce companies: Amazon.com, which is a
Web interface of a big-sized database system
containing customer and transactional information.
What do we need to built a database-driven website?
A DBMS & a scripting language
4
How web database architecture works?
5
Choosing a DBMS
Commercial databases: Oracle, SQL Server
Cost: expensive
Hardware requirements: high
Have an impressive array of advanced features
Open-source databases: MySQL, PostgreSQL
Cost: cheap
Hardware requirements: low
Lack some advanced features
6
Choosing a Scripting language
Open-source scripting languages
PHP
JSP
Perl
Proprietary scripting languages
ASP.NET
Cold Fusion
7
MySQL & PHP
MySQL is the de-facto standard database system
for
web sites with HUGE volumes of both data and
end-
users (like Facebook, Twitter, and Wikipedia).
PHP combined with MySQL are cross-platform
(you can develop in Windows and serve on a
Unix platform)
8
What is MySQL?
MySQL is ideal for both small and large
applications
MySQL is very fast, reliable, and easy to use
MySQL uses standard SQL
MySQL compiles on a number of platforms
MySQL is free to download and use
MySQL is developed, distributed, and supported
by Oracle Corporation
MySQL is named after co-founder Monty
Widenius's daughter: My
9
PHP & MySQL
PHP5 and later can work with a MySQL
database using:
MySQLi extension (the "i" stands for improved)
only work with MySQL databases
supports both procedural and OO PHP
PDO (PHP Data Objects)
will work on 12 different database systems
Supports only OO PHP
10
PHP connecting to MySQL database
Connecting to MySQL server via PHP
• $con = mysqli_connect(servername,
username, password);
$con is a connection resource type. We use
this variable to refer to the connection created
To select a specific database
mysqli_select_db(database_name,
$con);
11
PHP connecting to MySQL Server Example
<?php
$servername = "localhost"; $username = "username";
$password = "password";
// Create connection
$conn = mysqli_connect($servername, $username, $password);
// Check connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());} else echo
"Connected successfully";
?>
Equivalent to
<?php
$conn = mysqli_connect("localhost","username", "password") or
die("Connection failed: " . mysqli_connect_error());
echo "Connected successfully";
?> 12
Making SQL queries
PHP function for making queries:
mysqli_query(query_string, con_resource);
Queries that return information, such as
SELECT: returns a result set
$result = mysqli_query(query_string,
$con);
In this case, the result set is stored in the
variable $result
Other queries, returns TRUE upon success and
FALSE on failure. Best practice is to handle the
13
SQL Queries
CREATE DATABASE dbname
CREATE TABLE table_name (column_name
data_type(size), column_name data_type(size) …)
INSERT INTO table_name (column1, column2, column3,...)
VALUES (value1, value2, value3,...)
SELECT column1, column2 … FROM
table_name
WHERE some_column=some_value
UPDATE table_name
SET column1=value, column2=value2,...
WHERE
some_column=some_value
DELETE FROM table_name
14
PHP Making Query Strings
Rules to follow while making query
strings
The SQL query must be quoted
String values inside the SQL query
must be quoted
Numeric values must not be quoted
The word NULL must not be quoted
15
PHP Create MySQL Database
<?php
// Create connection
$conn = mysqli_connect("localhost", "username",
"password") or die("Connection failed: ".
mysqli_connect_error());
// Create database
$sql = "CREATE DATABASE myDB";
if (mysqli_query($conn, $sql)) {
echo "Database created successfully";
}else{
echo "Error creating database".
mysqli_error($conn);
} 16
PHP Create Table
<?php
// Create connection
$conn = mysqli_connect("localhost","username", "password“,
”mydb”) or
die("Connection failed: ". mysqli_connect_error());
// sql to create table
$sql = "CREATE TABLE MyGuests (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30) NOT NULL,
email VARCHAR(50),
reg_date TIMESTAMP)";
if (mysqli_query($conn, $sql)) {
echo "Table MyGuests created successfully";
} else {
echo "Error creating table: " . mysqli_error($conn);
} 17
PHP Insert data
<?php
$servername = "localhost"; $username = "username";
$password = "password"; $dbname = "myDB";
// Create connection
$conn = mysqli_connect($servername, $username,
$password, $dbname) or die("Connection failed: ".
mysqli_connect_error());
$sql = "INSERT INTO MyGuests (firstname,
lastname, email) VALUES ('John', 'Doe',
'[email protected]')";
mysqli_query($conn, $sql)) or die("Error: “ .
mysqli_error($conn));
18
PHP Update Record
<?php
$servername = "localhost"; $username = "username";
$password = "password"; $dbname = "myDB“;
// Create connection
$conn = mysqli_connect($servername, $username,
$password, $dbname) or
die("Connection failed: ". mysqli_connect_error());
//Create Query
$sql = “UPDATE MyGuests SET lastname= ‘Doe’ WHERE
id=2”;
//Execute Query
Mysqli_query($conn, $sql)) or die (“Error:” .
Mysqli_error($conn));
echo “Record updated”; 19
PHP Delete Record
<?php
$servername = "localhost"; $username = "username";
$password = "password"; $dbname = "myDB“;
// Create connection
$conn = mysqli_connect($servername, $username,
$password, $dbname) or
die("Connection failed: ". mysqli_connect_error());
// Create Query
$sql ="DELETE FROM MyGuests WHERE id=3";
// Execute Query
mysqli_query($conn, $sql)) or die("Error: “ .
mysqli_error($conn));
echo “Record Deleted";
mysqli_close($conn); 20
Retrieving information from a resultset
The PHP function num_rows() is used to check if there
are more than zero rows returned
The function fetch_assoc() puts all the results into an
associative array that we can loop through
Example
$result = mysqli_query(query, $con); if
(mysqli_num_rows($result) > 0) {
while ($row = mysqli_fetch_assoc($result)) {
$col1 = $row['column_1_name'];
$col2 = $row['column_2_name'];
//and so forth...
} } 21
PHP Select Data
<?php
$servername = "localhost"; $username = "username";
$password = "password"; $dbname = "myDB";
$conn = mysqli_connect($servername, $username,
$password,
$dbname) or die("Connection failed: ".
mysqli_connect_error());
$sql = "SELECT id, fname, lname FROM MyGuests";
mysqli_query($conn, $sql)) or die("Error: “ .
mysqli_error($conn)); if (mysqli_num_rows($result) >
0) {
while($row = mysqli_fetch_assoc($result)) {
echo "id:". $row["id"]. "Name:".$row[“fname"].” “.
$row["lname"]."<br>"; 22
Prepared Statements
A prepared statement is a feature used to execute
the same (or similar) SQL statements repeatedly with
high efficiency.
Prepared statements basically work like this:
Prepare: An SQL statement template is created and sent to the
database. Certain values are left unspecified, called parameters
(labeled "?").
Example: INSERT INTO MyGuests VALUES(?, ?, ?)
The database parses, compiles, and performs query
optimization on the SQL statement template, and stores the
result without executing it
Execute: At a later time, the application binds the values to
the parameters, and the database executes the statement.23
Prepared Statements Cont’d
Compared to executing SQL statements directly,
prepared statements have two main advantages:
Prepared statements reduces parsing time as the
preparation on the query is done only once (although the
statement is executed multiple times)
Bound parameters minimize bandwidth to the server as
you need to send only the parameters each time, and not
the whole query
Prepared statements are very useful against SQL
injections, because parameter values, which are
transmitted later using a different protocol, need not be
correctly escaped. If the original statement template is
24
Loading Data From a File
The LOAD DATA INFILE statement
Is used to load table data in from a file
It executes very quickly
Syntax:
LOAD DATA INFILE filename INTO TABLE
tablename;
By default, data fields in the file must be
separated by tabs and enclosed in single
quotation marks, and each row must be
separated by a newline 25
Speeding Up Queries
In Database-Driven Websites or web based
applications speed is a big issue
There are a lot of techniques that you can use to speed
up execution of queries. Some are:
Using Indexes
Optimization Techniques
26
Speeding Up Queries: Using Indexes
A database index is a data structure that improves the
speed of data retrieval operations on a database table at
the cost of additional writes and storage space to maintain
the index data structure.
The SQL to add an index to column of a table is
ALTER TABLE table ADD INDEX (column);
Indexes are best used on columns that are frequently used
in where clauses, and in any kind of sorting, such as "order
by".
you can check which indexes are being used by running
EXPLAIN
don't create indexes that are not being used by your
27
Speeding Up Queries: Optimization Tips
Design Optimization
Everything (data & data types) in a database should be
as small as possible
Minimize redundancy
Minimize nulls
Make your primary key as short as possible
Avoid variable length columns if possible (varchar, text
and blob).
Fixed-length fields are faster but might take up a little
more space
Wherever possible, use default values for columns and
insert data only if it differs from the default. This
reduces the time taken to execute the INSERT 28
Speeding Up Queries: Optimization Tips
Table Optimization
If a table has been in use for a period of time, data can
become
• fragmented as updates and deletions are process
This fragmentation increases the time taken to find things
in this table
This problem can be fixed by using the statement
OPTIMIZE TABLE tablename; or
myisamchk -r tablename at the command prompt
Simplify permissions
Queries are checked against the permission system
before being executed
The simpler the permission process is the faster your 29
Locking & Concurrency
Database-Driven Web Applications are full of concurrent
database operations
So the question is
How can we manage concurrent access to records,
tables & databases?
Solutions
Using Concurrency Control Mechanisms
Locking
30
Locking & Concurrency Cont’d
Concurrency control and locking mechanism
is used by DBMSs for the sharing of data
the primary use of locking is to solve concurrency
problems
is necessary to ensure data consistency when there is
a possibility of multiple clients accessing and possibly
modifying the same data at the same time.
Locking Types:
table-level locks &
row-level locks.
31
Locking & Concurrency Cont’d
Table-level locks
locks the entire table while performing operations on
the table
allows only one session to update a table at a time
other sessions that want to modify the table must wait
until the current DML statement finishes
deadlocks can be fairly easily avoided
has poor performance in applications that do a large
number of concurrent reads and writes
suitable for read-only, read-mostly, or single-user
applications
MySQL uses table-level locking for MyISAM, MEMORY, 32
Locking & Concurrency Cont’d
Row-level locks
possible to lock a single row while other sessions are
still able to access the rest of the table
simultaneous write access by multiple sessions
allow high performance at a very high level of
concurrency at the cost of greater complexity in the
implementation
slower performance for applications that have a low
probability of lock contention as well as higher
probability of bugs.
very difficult to completely avoid deadlocks
MySQL uses row-level locking for InnoDB tables
33
Locking & Concurrency Cont’d
Types of locks
Read lock
The session that holds the lock can read the table
(but not write it).
Multiple sessions can acquire a READ lock for the
table at the same time.
Other sessions are not allowed to acquire a WRITE
lock
Write lock
The session that holds the lock can read and write to
the table
Only the session that holds the lock can access the
34
table. No other session can access it until the lock is
Locking & Concurrency Cont’d
SQL to lock a table
LOCK TABLES table_name lock-type;
-- execute queries here
UNLOCK TABLES;
lock-type is either READ OR WRITE
Example
mysqli_query($db, "LOCK TABLES mytest WRITE;");
for ($i = 1; $i < 100000; ++$i) {
mysqli_query($db, "INSERT INTO mytest VALUES ($i,
$i, $i);"); }
mysqli_query($db, "UNLOCK TABLES;");
35
What is a Storage Engine?
Storage Engine (Table Type)
is what stores, handles, and retrieves information from a
table.
The
MyISAM The
standard engines supported
common bystorage
MySQL are:
engines
InnoDB MyISAM and InnoDB
MERGE The default storage engine
MEMORY (HEAP) MyISAM
BDB You can also assign a storage engine to
(BerkeleyDB) a specific table with the following
EXAMPLE
syntax:
ARCHIVE CREATE TABLE tblname(col1, col2, ..)
CSV
BLACKHOLE ENGINE = storageEngine;
All storage engines can be selected per
36
ISAM
MyISAM Storage Engine
MyISAM
Is the default storage engine for MySQL servers.
Is a branch, or child, of the ISAM engine.
Doesn’t support transaction,
Supports table-level locking as opposed to row-level
locking,
Has the best performance and functionality
is great for sites that have a very low
INSERT/UPDATE rate and a very high SELECT rate.
Do not support foreign keys
The max number of rows supported for MyISAM is
~4.29E+09 with up to 37
64 indexes per table. Fields
InnoDB Storage Engine
InnoDB
compared to MyISAM, InnoDB provides many more
feature to increase performance.
supports row-level locking, as opposed to table-level
locking
This allows parallel INSERT/UPDATE/DELETE queries to
be run on the same table, unlike MyISAM where each
query has to wait its turn to run.
provides foreign key functionality.
supports Transactions
provides caching for data and indexes in memory, as
well as on disk, which provides a large increase in 38
Merge Storage Engine
MERGE
Allows users to treat collection of identical
MyISAM tables as a single table for the purpose
of querying.
There are constraints to this type, such as all
tables needs to have the same definition.
Example Scenario
If you store sales transactions on your site in a daily
table, and want to pull a report for the month, this
would allow you to execute a query against a single
table to pull all sales for the month. 39
Memory & BDB Storage Engines
MEMORY (HEAP)
Tables of this type are stored in memory and their
indexes are
hashed
Makes memory tables extremely fast, but, in the event
of a crash, your data will be lost
Ideal for storing temporary or derived data
Doesn’t support BLOB, TEXT, or AUTO INCREMENT
columns
BDB (BerkeleyDB)
Supports transactions and uses a hash-based storage
system
40
This allows for some of the quickest reading of data,
The MySQL Privilege System
The MySQL server
stores privilege information in the grant tables (user,
host, db, tables_priv & columns_priv) of the mysql
database (that is, in the database named mysql)
reads the contents of these tables into memory when
it starts and bases access-control decisions on the in-
memory copies of the grant tables
41
The MySQL Grant Tables
user table
determines whether a user can connect to a MySQL
server and
whether a user has any global privileges that apply to
every database in the server
host table
determines which host(s) can connect to the MySQL
server
db table
determines which user can access which database from
which host
tables_priv
determines which user can access which tables from
42
MySQL Access Control
MySQL Access Control
MySQL uses the grant tables to determine what a
user is allowed to do in a two-stage process
1. Connection Verification
The MySQL server checks if a user is allowed to
connect, based on the information from the user
and host table
2. Request Verification
After a connection is established, the server checks
each statement you issue to determine whether
you have sufficient privileges to perform it
43
Updating Privileges
The MySQL server reads the grant tables when it is
started
When you update the grant tables using grant and
revoke statements the MySQL server will not notice that
they have changed
To point out to server that a change has occurred, you
can run the following commands
flush privileges //from mysql command line
mysqladmin flush-privileges //from the operating
system
mysqladmin reload //from the operating system
44
Making Your MySQL Database Secure
1. Running MySQL server as a root
is a bad idea if you are running a Unix-Like OS
doing this gives a MySQL user with a full set of privileges. The
right to read and write files anywhere in the operating system
Instead, setup a MySQL user specifically for the purpose of
running mysqld
2. Setup the MySQL server behind firewall, to stop connection
from
unauthorized machines
The default port to connect to the mysql server is 3306
3. Make sure that all your users have passwords and that they
are well chosen and regularly changed, as with operating
system passwords
4. Write you PHP scripts that are used to connect to the database 45
Making Your MySQL Database Secure Cont’d
Don’t store passwords in plain text in your database
You can encrypt passwords using MySQL SHA1(). When you run
select, you will need to use the same function again to check
the password a user has typed
Don’t grant more privileges to any user than he/she needs .
Don’t grant the PROCESS, FILE, SHUTDOWN and RELOAD
privileges to any user other than an administrator
The PROCESS privileges can be used to see what other users are doing and typing,
including their passwords
The FILE privilege can be used to read and write files to and from the operating
system
Grant users access only from the hosts that they will be
connecting from like jane@localhost
You can further increase security by using IP addresses rather
than domain names in your host table 46
MySQL SHA1() Function
Secure Hash Algorithm
String sha1(String str [, bool raw_output])
Returns pseudo random 40-character string
If raw_output is set true
It returns random 20-character string of binary data
The password cannot be decrypted back
If(sha1($password)==lajsdf0asdfj323j8258hasdf93q)
Example
Select count(*) from authorized_users where
name=$username
• and password=sha1($password)
The password column should have varchar(40)
47
Connecting MySQL database to
the web
Connecting MySQL database to the web raises special
security issues
Set up a special user just for the purpose of web
connections
Give the minimum privilege necessary and not grant
DROP, ALTER and CREATE privileges to that user
Unless you are using SSL user's password will be
transmitted from the browser to the server in plain text
Do a general data clean up before sending anything
to the MySQL database
Addslashes(), stripslashes() to get rid of any
problematic characters in strings
48
SQL Injection
SQL injection is a technique where malicious
users can inject SQL commands into an SQL
statement, via web page input.
Injected SQL commands can alter SQL statement
and compromise the security of a web application.
49
SQL Injection Cont’d
SQL Injection Based on 1=1 is Always True
txtSQL = "SELECT * FROM Users WHERE UserId = " +
userinput
Let's say that the original purpose of the above code was to
create an SQL statement to select a user with a given user id.
If there is nothing to prevent a user from entering "wrong"
input, the user can enter some "smart" input like this:
Server Result
SELECT * FROM Users WHERE UserId = 105 or 1=1
this will return all rows from the table Users, since
50
SQL Injection Cont’d
SQL Injection Based on Batched SQL Statements
Most databases support batched SQL statement, separated by
semicolon.
Example
txtSQL = "SELECT * FROM Users WHERE UserId = " + userinput
User inputs the following
Result
The code at the server would create a valid SQL statement like
this:
SELECT * FROM Users WHERE UserId = 105; DROP TABLE
Suppliers
51
Screening User Inputs
Use addslashes() to filter data before it is passed to a
database
escapes out characters that might be troublesome to a
database
you can use the stripslashes() function to return the data to its
original form
Switch on magic_quotes_gpc and magic_quotes_runtime
directives in php.ini
automatically adds and strip slashes for incoming GET,
POST and
COOKIE variables to and from databases
Use the escapeshellcmd() when passing user data to a system()
or exec() call
52
Screening User Inputs Cont’d
The strip_tags() strips out HTML and PHP tags
from a string
prevents users from planting a malicious script
in user data
htmlspecialchars() PHP function converts
characters to HTML entities
for example, < is converted to < this
function converts any
script tags to harmless characters
trim() strips unnecessary characters (extra
space, tab, newline) from the user input data 53
Screening User Inputs Example
<?php
$name = $email = $gender = $comment = $website = ""; if
($_SERVER["REQUEST_METHOD"] == "POST") {
$name = test_input($_POST["name"]);
$email = test_input($_POST["email"]);
$website = test_input($_POST["website"]);
$gender = test_input($_POST["gender"]);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data); return $data;
}
?> 54
P
55
P
56