some more on user- authentication. a web-page which requires that the user be logged-in page is...
TRANSCRIPT
A web-page which requires that the user be logged-in
• Page is here: http://csweb.ucc.ie/cs1064/jabowen/IPSC/cs4408/frontPage.php
• User's login status is verified by sending a cookie
<?php
if ($_COOKIE["loginCookie"])
{?> <h1>This is secured content</h1>
<p>You can only see this content because you are logged in</p>
<?php }
else
{?> <h1>Access forbidden</h1>
<p>You cannot see secure content unless you are logged in.</p>
<p><a href="login.php">Login</a></p>
<?php }
?>
The login.php program
• In this simple program, only one user-name and password are accepted
• In reality, – there would be a database of user-names and
passwords– different users would have different login
cookies
The login.php program<?php
ob_start();
if ((!$_POST["userName"]) || (!$_POST["password"]))
{?><form method="post" action="<?php echo $PHP_SELF; ?>">
<p>User name: <input type=text name=userName></p>
<p>Password: <input type=password name=password></p>
<button type=submit>Login</button>
</form> <?php }
else {$userName=$_POST["userName"];
$password=$_POST["password"];
if (($userName=='bob') && ($password=='dylan'))
{setcookie("loginCookie","$userName",time()+3600);
?><h1>You are logged in for 60 minutes</h1>
<a href="frontPage.php">Click here for front page</a>
<?php }
else {?><h1>Incorrect username or password</h1> <?php }
ob_end_flush();
?>
Danger with previous scheme
• Users' passwords are sent in the clear
• Somebody sniffing packets on the internet could steal a user's password
• Indeed, somebody could forge a cookie
Protecting passwords
• First, we will address the issue of protecting passwords
• Later, we will address the issue of protecting cookies
Encrypting passwords• To avoid theft of passwords, we could
require that, when they are sent over the internet, they are passed in encrypted form
• One commonly-user encryption technique is called MD5
• We could send the MD5 encryptions of passwords over the internet
• For this, the login page would have to use MD5
MD5• MD5 is a hashing algorithm developed in 1991, when its
predecessor, MD4, was found to be insecure• In 1996, a flaw was found with the design of MD5;
• While it was not a clearly fatal weakness, cryptographers began to recommend using other algorithms, such as SHA-1
– recent claims suggest that SHA-1 has been broken, however)
• In 2004, more serious flaws were discovered making further use of the MD5 algorithm for security purposes questionable
• At present, however, MD5 is still widely used
• But expect it to be replaced in the near future
MD5 continued• MD5 takes a string and returns a 128-bit hash value
which is derived from the string• Usually, these 128 bits are represented as 32 hex-digits• MD5("The quick brown fox jumps over the lazy dog") =
9e107d9d372bb6826bd81d3542a419d6 • Even a small change in the message will (with
overwhelming probability) result in a completely different hash
• For example changing d to c in the above message produces
• MD5("The quick brown fox jumps over the lazy cog") = 1055d3e698d289f2af8663725127bd4b
Implementations of MD5• PHP
– an implementation of MD5 is provided in the PHP library of string functions:
string md5 ( string str )
• Javascript:– no implementation of MD5 is built into the language;– however, an implementation is available in this file
http://www.cs.ucc.ie/j.bowen/usefulResources/md5.js
• The function is called
string hex_md5( string str )
login2.php (part 1)<?php ob_start(); ?>
<script src="http://www.cs.ucc.ie/j.bowen/usefulResources/md5.js"></script>
<script>
function encodePassword()
{loginForm.password.value=hex_md5(loginForm.password.value); }
</script>
<?php
if ( (!$_POST["userName"]) || (!$_POST["password"]) )
{?> <form name=loginForm method="post" action="<?php echo $PHP_SELF; ?>">
<p>User name: <input type=text name=userName></p>
<p>Password: <input type=password name=password></p>
<button type=button onClick="encodePassword();loginForm.submit();" >
Login</button>
</form>
<?php
}
login2.php (part 2)else
{$userName=$_POST["userName"];
$password=$_POST["password"];
if ( ($userName=="bob") && ( $password== md5("dylan") ) )
{ setcookie("loginCookie","bob",time()+3600);
?><h1>You are logged in for 60 minutes</h1>
<a href="frontPage.php">Click here for front page</a>
<?php }
else {?>Incorrect login <?php }
}
ob_end_flush();
?>
This is better, but ...
• Somebody who is sniffing packets could simply steal the MD5-encrypted password and use that
Make theft pointless
• There will always be packet-sniffing thieves
• The only defence against them is to make what they can steal worthless to them
• We can do this by making encoded passwords valid for only a short time
• We do this by using a nonce-word in such messages– a nonce word is 'a word coined and used
only for a particular occasion'
login3.php (part 1)<?php ob_start(); ?><script src="http://www.cs.ucc.ie/j.bowen/usefulResources/md5.js"></script><script>
function encodePassword()
{loginForm.password.value=
hex_md5(loginForm.password.value+loginForm.nonceWord.value); }
</script>
<?php
if ( (!$_POST["userName"]) || (!$_POST["password"]) )
{$now=getdate();
$now=$now["year"].$now["month"].$now["mday"].$now["hours"].$now["minutes"];
$nonceWord=md5("someSecretWord".$now);
?><form name=loginForm
method="post" action="<?php echo $PHP_SELF; ?>">
<input type=hidden name=nonceWord value="<?php echo $nonceWord;?>">
<p>User name: <input type=text name=userName></p>
<p>Password: <input type=password name=password></p>
<button type=button onClick="encodePassword();loginForm.submit();">Login</button>
</form>
<?php
}
login3.php (part 2)
else
{ $userName=$_POST["userName"];
$password=$_POST["password"];
$nonceWord=$_POST["nonceWord"];
if ( ($userName=="bob") && ($password== md5("dylan".$nonceWord)) )
{ setcookie("loginCookie","bob",time()+3600);
?><h1>You are logged in for 60 minutes</h1>
<a href="frontPage.php">Click here for front page</a>
<?php }
else {?>Incorrect login <?php }
}
ob_end_flush();
?>
Can't someone just steal the nonce-word as
well as the encrypted password?• Yes, but ...
• The trick is to impose a time-limit on the acceptability of each nonce-word
login4.php (part 1)
<?php ob_start(); ?><script src="http://www.cs.ucc.ie/j.bowen/usefulResources/md5.js"></script>
<script>
function encodePassword()
{loginForm.password.value=
hex_md5(loginForm.password.value+loginForm.nonceWord.value); }
</script>
<?php
function fresh($nonceWord)
{$now=getdate();
$now=$now["year"].$now["month"].$now["mday"].$now["hours"].$now["minutes"];
$currentNonceWord=md5("someSecretWord".$now);
if ($nonceWord == $currentNonceWord)
{ return 1; }
else { return false; }
}
login4.php (part 2)if ( (!$_POST["userName"]) || (!$_POST["password"]) )
{$now=getdate(); $now=$now["year"].$now["month"].$now["mday"].$now["hours"].$now["minutes"];
$nonceWord=md5("someSecretWord".$now);
?>
<form name=loginForm
method="post" action="<?php echo $PHP_SELF; ?>">
<input type=hidden name=nonceWord value="<?php echo $nonceWord;?>">
<h1>You have one minute to login</h1>
<p>User name: <input type=text name=userName></p>
<p>Password: <input type=password name=password></p>
<button type=button
onClick="encodePassword();loginForm.submit();">Login</button>
</form>
<?php
}
login4.php (part 3)
else
{$userName=$_POST["userName"];
$password=$_POST["password"];
$nonceWord=$_POST["nonceWord"];
if (fresh($nonceWord))
{ if ( ($userName=="bob") && ($password== md5("dylan".$nonceWord)) )
{ setcookie("loginCookie","bob",time()+3600);
?><h1>You are logged in for 60 minutes</h1>
<a href="frontPage.php">Click here for front page</a> <?php }
else {?>Incorrect login <?php }
}
else {?><h1>Unacceptable delay</h1>
<p>You took too long to fill in the login form</p>
<p><a href="<?php echo $PHP_SELF;?>">Try again</a></p>
<?php }
}
ob_end_flush();?>
But, couldn't someone just steal the cookie?
• Yes, but similarly MD5 encryption and nonce-words can be used to reduce the usefulness of stealing cookies
• However, at this stage, it might be worthwhile considering the use of SSL
What’s wrong with Basic authentication?
• Basic authentication is insecure
• The username and password are sent unencrypted across the internet
• Anybody who is “sniffing” packets can steal this information