KEMBAR78
2014 database - course 3 - PHP and MySQL | PDF
PHP - MySQL
Ensky / 林宏昱
Load data from database
GET /enskylin HTTP/1.1
Host: www.facebook.com
HTTP/1.1 200 OK
HTML
generate HTML
GET /enskylin HTTP/1.1
Host: www.facebook.com
HTTP/1.1 200 OK
HTML
How to access database?
• today's topic :D
Establish a connection
(you should set it up during your installation)
(If you use cscc account, then follow the instruction on cscc
MySQL website)
username: root
password: nctu5566
login successfully
Do some Queries
Insert: Create
Select: Read
Update: Update
Delete: Delete
INSERT INTO users (id, pw) VALUES ('jlhuang', 'iLove5566')
Query OK, 1 rows affected
Dealing with Results
Generate the correspond HTML
SELECT * FROM users
100 row in set (0.00 sec)
That's all.
Hello world! - connect
Establish a connection:
$db_host = "host_name";
$db_name = "database_name";
$db_user = "user_name";
$db_password = "password";
$dsn = "mysql:host=$db_host;dbname=$db_name";
$db = new PDO($dsn, $db_user, $db_password);
Hello world! - Insert
SQL
--
INSERT INTO `users` (id, username, gender)
VALUES(1, 'Ensky', 'male')
PHP
--
$sql = "INSERT INTO `users` (id, username, gender)"
. " VALUES(?, ?, ?)";
$sth = $db->prepare($sql);
$sth->execute(array(1, 'ensky', 'male'));
id username gender
1 Ensky male
Hello world! - Select
$sql = "SELECT * FROM `users`"
. " WHERE `username` = ? AND `password` = ?";
$sth = $db->prepare($sql);
$sth->execute(array('ensky', 'nctu5566'));
id username password gender
1 Ensky nctu5566 male
2 Emily sdfasdf female
Hello world! - Retrieve
$sql = "SELECT username, gender FROM `users`"
. " WHERE `username` = ? AND `password` = ?";
$sth = $db->prepare($sql);
$sth->execute(array('ensky', 'nctu5566'));
while ($result = $sth->fetchObject()) {
echo $result->name . $result->gender;
}
// Ensky male
// Emily female
// … id username password gender
1 Ensky nctu5566 male
2 Emily sdfasdf female
Named parameters
$sql = "SELECT username, gender FROM `users`"
. " WHERE `username` = ? AND `password` = ?";
$sth = $db->prepare($sql);
$sth->execute(array('ensky', 'nctu5566'));
is equal to
$sql = "SELECT username, gender FROM `users`"
. " WHERE `username` = :un AND `password` = :pw";
$sth = $db->prepare($sql);
$sth->execute(array(
':un' => 'ensky',
':pw' => 'nctu5566'));
PHP Data Objects
• PDO is an OO style class
• Classes
– PDO
• PDO __construct ( string $dsn, [, string $username [, string
$password ]])
• PDOStatement prepare( string $statement )
• PDOStatement query( string $statement )
– PDOStatement
• bool execute ([ array $input_parameters ] )
• mixed fetchObject ([ string $class_name = "stdClass" [, array
$ctor_args ]] )
Don't use mysql_*
• There are many libraries to help you connect to
MySQL database
– MySQL
– MySQLi
– PDO
• If your books recommends you to use mysql_xxx
functions, throws it.
Don't use mysql_*
• What's the problem of mysql_ functions?
– It is deprecated in PHP 5.5.0, and will be removed in PHP6
– SQL Injection problem
• no prepared statement
– Only support MySQL(PDO supports 12 different databases)
What's SQL injection?
Simple query(use mysql ext)
login_action.php
--
<?php
mysql_connect($db_host, $db_user, $db_password);
mysql_select_db($dn_name);
$result = mysql_query(
"SELECT * FROM `users`"
." WHERE `email` = '{$_POST['email']}'"
." AND `password = '{$_POST['password']}'"
);
// …
Simple query(use mysql ext)
login_form.php
login_action.php
--
$result = mysql_query(
"SELECT * FROM `users`"
." WHERE `email` = '{$_POST['email']}'"
." AND `password = '{$_POST['password']}'"
);
Simple query(use mysql ext)
login_form.php
login_action.php
--
$result = mysql_query(
"SELECT * FROM `users`"
." WHERE `email` = 'enskylin@gmail.com'"
." AND `password = 'nctu5566'"
);
Simple query(use mysql ext)
$result = mysql_query(
"SELECT * FROM `users`"
." WHERE `email` = 'enskylin@gmail.com'"
." AND `password = 'nctu5566'"
);
SELECT * FROM `users`
WHERE `email` = 'enskylin@gmail.com'
AND `password` = 'nctu5566'
SQL injection
"--" in SQL represents "comments"
SELECT * FROM `users` -- I want to select all from user
SELECT * FROM `users` -- today is a good day
SQL injection
If a cracker knows your query logic:
SELECT * FROM `users`
WHERE `email` = 'user_account'
AND `password = 'user_password'
give a try:
user_account = ' OR 1=1 --
SELECT * FROM `users`
WHERE `email` = '' OR 1=1 --'
AND `password = 'user_password'
OOPS!
SQL injection
SELECT * FROM `users`
WHERE `email` = '' OR 1=1 --'
AND `password = 'user_password'
Since 1=1 is obviously true in any circumstances, and below
messages are commented out, this instruction will select all
users instead of logged in user.
Prepared statement
• By prepare query statement before execute,
we can prevent SQL injection
PREPARE SELECT * FROM `user` WHERE `id`=? AND `password`=?
OK, prepared
EXECUTE "enskylin", "nctu5566"
1 row in set (0.00 sec)
Password Hashing
• Let's look at User creation
INSERT INTO (id, password) VALUES ('ensky', 'nctu5566')
• Actually, it is very dangerous!
• Note that Database server is able to be cracked
If hackers can get your "real password", than it is a
big problem
• Even more, if database administrator can access your
real password, than it should be a problem, too.
more plaintext passwords:
https://www.facebook.com/PlainPass
How to solve the plaintext
password problem?
Password Hashing
Hashing!
a many-to-one no inverse function
http://www.php.net/manual/en/function.hash.php#104987
Password Hashed PW
hello 5d41402abc4 …
world 7d793037a07 …
Flow
• register
• login
• Reset
hello 5d41402abc4 … 5d41402abc4 …
generate hashed password save to database
hello 5d41402abc4 … 5d41402abc4 …
generate hashed password verify with database's hash
world 7d793037a07 … 7d793037a07 …
generate new hashed password save to database
Crack
• One common crack method is "rainbow table"
– detail algorithm: wiki
• password hashing can be cracked by using
predefined hash tables
• However it can be prevented by using "random salt"
for each password
Best practice
• Best practice to deal with hashing is to hash with
"random salt"
• Save
1. generate a random salt
2. hashing password use this random salt
3. save "hashed password" with random salt to database
• Verify
1. query hashed password with random salt by user
2. regenerate hashed password and verify with real data
PHP support
• PHP 5.5 supports password_hash, password_verify
functions to deal with password hashing problem
http://www.php.net/manual/en/function.password-hash.php
• However, CSCC only provides PHP 5.3
so you should use crypt function instead
http://www.php.net/manual/en/function.crypt.php
• Since crypt is not easy enough to use,
TA provided TA's version:
http://pastebin.com/aDdWvhXm
Usage
// create a hash
$hash = password_hash($_POST['password']);
// verify a hash
if (password_verify($_POST['password'], $hash))
{
echo 'Password is valid!';
} else {
echo 'Invalid password.';
}
References
• PDO: http://tw2.php.net/manual/en/class.pdo.php
• crypt: http://tw2.php.net/manual/en/function.crypt.php
• plainpassword: https://www.facebook.com/PlainPass
• pdo-mysql-mysqli:
http://blog.roga.tw/2010/06/%E6%B7%BA%E8%AB%87-php-mysql-php-
mysqli-pdo-%E7%9A%84%E5%B7%AE%E7%95%B0/

2014 database - course 3 - PHP and MySQL

  • 1.
    PHP - MySQL Ensky/ 林宏昱
  • 2.
    Load data fromdatabase GET /enskylin HTTP/1.1 Host: www.facebook.com HTTP/1.1 200 OK HTML
  • 3.
    generate HTML GET /enskylinHTTP/1.1 Host: www.facebook.com HTTP/1.1 200 OK HTML
  • 4.
    How to accessdatabase? • today's topic :D
  • 5.
    Establish a connection (youshould set it up during your installation) (If you use cscc account, then follow the instruction on cscc MySQL website) username: root password: nctu5566 login successfully
  • 6.
    Do some Queries Insert:Create Select: Read Update: Update Delete: Delete INSERT INTO users (id, pw) VALUES ('jlhuang', 'iLove5566') Query OK, 1 rows affected
  • 7.
    Dealing with Results Generatethe correspond HTML SELECT * FROM users 100 row in set (0.00 sec)
  • 8.
  • 9.
    Hello world! -connect Establish a connection: $db_host = "host_name"; $db_name = "database_name"; $db_user = "user_name"; $db_password = "password"; $dsn = "mysql:host=$db_host;dbname=$db_name"; $db = new PDO($dsn, $db_user, $db_password);
  • 10.
    Hello world! -Insert SQL -- INSERT INTO `users` (id, username, gender) VALUES(1, 'Ensky', 'male') PHP -- $sql = "INSERT INTO `users` (id, username, gender)" . " VALUES(?, ?, ?)"; $sth = $db->prepare($sql); $sth->execute(array(1, 'ensky', 'male')); id username gender 1 Ensky male
  • 11.
    Hello world! -Select $sql = "SELECT * FROM `users`" . " WHERE `username` = ? AND `password` = ?"; $sth = $db->prepare($sql); $sth->execute(array('ensky', 'nctu5566')); id username password gender 1 Ensky nctu5566 male 2 Emily sdfasdf female
  • 12.
    Hello world! -Retrieve $sql = "SELECT username, gender FROM `users`" . " WHERE `username` = ? AND `password` = ?"; $sth = $db->prepare($sql); $sth->execute(array('ensky', 'nctu5566')); while ($result = $sth->fetchObject()) { echo $result->name . $result->gender; } // Ensky male // Emily female // … id username password gender 1 Ensky nctu5566 male 2 Emily sdfasdf female
  • 13.
    Named parameters $sql ="SELECT username, gender FROM `users`" . " WHERE `username` = ? AND `password` = ?"; $sth = $db->prepare($sql); $sth->execute(array('ensky', 'nctu5566')); is equal to $sql = "SELECT username, gender FROM `users`" . " WHERE `username` = :un AND `password` = :pw"; $sth = $db->prepare($sql); $sth->execute(array( ':un' => 'ensky', ':pw' => 'nctu5566'));
  • 14.
    PHP Data Objects •PDO is an OO style class • Classes – PDO • PDO __construct ( string $dsn, [, string $username [, string $password ]]) • PDOStatement prepare( string $statement ) • PDOStatement query( string $statement ) – PDOStatement • bool execute ([ array $input_parameters ] ) • mixed fetchObject ([ string $class_name = "stdClass" [, array $ctor_args ]] )
  • 15.
    Don't use mysql_* •There are many libraries to help you connect to MySQL database – MySQL – MySQLi – PDO • If your books recommends you to use mysql_xxx functions, throws it.
  • 16.
    Don't use mysql_* •What's the problem of mysql_ functions? – It is deprecated in PHP 5.5.0, and will be removed in PHP6 – SQL Injection problem • no prepared statement – Only support MySQL(PDO supports 12 different databases)
  • 17.
  • 18.
    Simple query(use mysqlext) login_action.php -- <?php mysql_connect($db_host, $db_user, $db_password); mysql_select_db($dn_name); $result = mysql_query( "SELECT * FROM `users`" ." WHERE `email` = '{$_POST['email']}'" ." AND `password = '{$_POST['password']}'" ); // …
  • 19.
    Simple query(use mysqlext) login_form.php login_action.php -- $result = mysql_query( "SELECT * FROM `users`" ." WHERE `email` = '{$_POST['email']}'" ." AND `password = '{$_POST['password']}'" );
  • 20.
    Simple query(use mysqlext) login_form.php login_action.php -- $result = mysql_query( "SELECT * FROM `users`" ." WHERE `email` = 'enskylin@gmail.com'" ." AND `password = 'nctu5566'" );
  • 21.
    Simple query(use mysqlext) $result = mysql_query( "SELECT * FROM `users`" ." WHERE `email` = 'enskylin@gmail.com'" ." AND `password = 'nctu5566'" ); SELECT * FROM `users` WHERE `email` = 'enskylin@gmail.com' AND `password` = 'nctu5566'
  • 22.
    SQL injection "--" inSQL represents "comments" SELECT * FROM `users` -- I want to select all from user SELECT * FROM `users` -- today is a good day
  • 23.
    SQL injection If acracker knows your query logic: SELECT * FROM `users` WHERE `email` = 'user_account' AND `password = 'user_password' give a try: user_account = ' OR 1=1 -- SELECT * FROM `users` WHERE `email` = '' OR 1=1 --' AND `password = 'user_password' OOPS!
  • 24.
    SQL injection SELECT *FROM `users` WHERE `email` = '' OR 1=1 --' AND `password = 'user_password' Since 1=1 is obviously true in any circumstances, and below messages are commented out, this instruction will select all users instead of logged in user.
  • 25.
    Prepared statement • Byprepare query statement before execute, we can prevent SQL injection PREPARE SELECT * FROM `user` WHERE `id`=? AND `password`=? OK, prepared EXECUTE "enskylin", "nctu5566" 1 row in set (0.00 sec)
  • 26.
    Password Hashing • Let'slook at User creation INSERT INTO (id, password) VALUES ('ensky', 'nctu5566') • Actually, it is very dangerous! • Note that Database server is able to be cracked If hackers can get your "real password", than it is a big problem • Even more, if database administrator can access your real password, than it should be a problem, too. more plaintext passwords: https://www.facebook.com/PlainPass
  • 27.
    How to solvethe plaintext password problem? Password Hashing
  • 28.
    Hashing! a many-to-one noinverse function http://www.php.net/manual/en/function.hash.php#104987 Password Hashed PW hello 5d41402abc4 … world 7d793037a07 …
  • 29.
    Flow • register • login •Reset hello 5d41402abc4 … 5d41402abc4 … generate hashed password save to database hello 5d41402abc4 … 5d41402abc4 … generate hashed password verify with database's hash world 7d793037a07 … 7d793037a07 … generate new hashed password save to database
  • 30.
    Crack • One commoncrack method is "rainbow table" – detail algorithm: wiki • password hashing can be cracked by using predefined hash tables • However it can be prevented by using "random salt" for each password
  • 31.
    Best practice • Bestpractice to deal with hashing is to hash with "random salt" • Save 1. generate a random salt 2. hashing password use this random salt 3. save "hashed password" with random salt to database • Verify 1. query hashed password with random salt by user 2. regenerate hashed password and verify with real data
  • 32.
    PHP support • PHP5.5 supports password_hash, password_verify functions to deal with password hashing problem http://www.php.net/manual/en/function.password-hash.php • However, CSCC only provides PHP 5.3 so you should use crypt function instead http://www.php.net/manual/en/function.crypt.php • Since crypt is not easy enough to use, TA provided TA's version: http://pastebin.com/aDdWvhXm
  • 33.
    Usage // create ahash $hash = password_hash($_POST['password']); // verify a hash if (password_verify($_POST['password'], $hash)) { echo 'Password is valid!'; } else { echo 'Invalid password.'; }
  • 34.
    References • PDO: http://tw2.php.net/manual/en/class.pdo.php •crypt: http://tw2.php.net/manual/en/function.crypt.php • plainpassword: https://www.facebook.com/PlainPass • pdo-mysql-mysqli: http://blog.roga.tw/2010/06/%E6%B7%BA%E8%AB%87-php-mysql-php- mysqli-pdo-%E7%9A%84%E5%B7%AE%E7%95%B0/