Anhand der GET-Parameter und einer weiteren geheimen Zeichenkette wird hier
ein MD5-Hash ermittelt.
Beim Aufruf der URL kann man dann leicht feststellen, ob die Parameter unverändert sind.
Ein mögliches Anwendungsbeispiel wäre eine Gästebuch das jeden neuen Eintrag
per Email an den Administrator verschickt.
In der Email steht eine URL die beim Aufruf den neuen Eintrag direkt löscht.
Der Administrator muss sich also nicht erst einloggen.
Da die Parameter, also z.B. die ID des Datensatzes, ggf. als GET-Parameter, also im Klartext, übergeben werden stellt die Überprüfung des MD5-Hash sicher, dass wirklich nur dieser eine Datensatz gelöscht werden kann.
Um das Beispiel auszuprobieren einfach die GET-Parameter der URL in der Adresszeile des Browser manipulieren und absenden.
<?php
class QueryMD5
{
var $GetParameter = array();
var $SecretKey = 'hRz655.5-';
var $Key = 'urlkey';
var $IgnoreSessionID = true;
var $IgnoreOrder = true;
function setIgnoreOrder($bool)
{
$this->IgnoreOrder = (bool) $bool;
}
function setIgnoreSessionID($bool)
{
$this->IgnoreSessionID = (bool) $bool;
}
function QueryMD5($arr)
{
if (is_array($arr)){
$this->GetParameter = $arr;
}else{
parse_str($arr, $tmp);
$this->GetParameter = $tmp;
}
}
function getQuery()
{
$s = $this->joinParameter($this->GetParameter);
$k = $this->calcMD5($s);
$s .= '&'.$this->Key.'='.$k;
return $s;
}
function calcMD5($s)
{
$tmp = md5($this->SecretKey.$s);
return $tmp;
}
function joinParameter($arr)
{
if ($this->IgnoreOrder){
ksort($arr);
}
$tmp = array();
foreach($arr as $k => $v){
$tmp[] = $k.'='.urlencode($v);
}
$s = join('&', $tmp);
return $s;
}
function checkQuery($s)
{
parse_str($s, $tmp);
$key = '';
if (array_key_exists($this->Key, $tmp)){
$key = $tmp[$this->Key];
unset ($tmp[$this->Key]);
}
if ($this->IgnoreSessionID){
unset ($tmp[session_name()]);
}
$s = $this->joinParameter($tmp);
$success = $key == $this->calcMD5($s);
return $success;
}
} /* end class */
$para = array(
'id' => 21,
'tid' => 17,
'action' => 'delete',
);
$tmp = new QueryMD5($para);
$q = $tmp -> getQuery();
printf ('<h1>Die originale URL</h1>');
printf ('<a href="?%1$s">klicken ja, aber nicht an den Parametern rumeditieren</a>', $q);
if (!empty($_SERVER['QUERY_STRING'])){
echo '<hr>';
$bool = $tmp->checkQuery($_SERVER['QUERY_STRING']);
if ($bool){
print ('OK, der Querystring ist gültig');
}else{
print ('Fehler, der Querystring ist verändert');
}
}
?>