Sicheres Hashing in PHP

PHP bringt prinzipiell alles mit, um anständiges Hashing zu betreiben. bcrypt ist der Way To Go, aber auch ohne bcrypt kann man mit vernünftigem Einsatz der vorhanden Hashing-Algorithmen (Iterationen + Salt) gut zurechtkommen – Symfony machts im MessageDigestPasswordEncoder.php richtig. Hauptproblem ist aber, dass vom Durchschnitts-Nutzer zuviel Wissen abverlangt wird, um wirklich sicheres Hashing zu betreiben. Deswegen schickt sich jetzt in PHP 5.5 eine Hashing-Library an, es besser zu machen. Bis es soweit ist und die Funktionalität im Core ankommt, gibt es für PHP >= 5.3.7 eine Compatiblity-Library, die das Verhalten der kommenden Hashing-Funktionen nachbildet.

Die Signaturen der Funktionen aus der Compat-Library sind wie folgt: password_hash($password, $algo, $options = array())

Veröffentlicht unter php, Security, webdev | 2 Kommentare

Vagrant Tutorial

Vagrant (zu Deutsch: „umherwandernd“) ist ein klasse Tool für verteilte Entwicklung. Muss man sich so vorstellen: Entwickler A soll soll einen Bug fixen, holt die entsprechende Vagrant-Box hervor und findet in ihr die komplette Projektumgebung wieder – Apache, MySQL, PHP in der jeweils korrekten Version, Anbindung an den CI-Server und alles was man eben so benötigt. Nach getaner Arbeit wird das Projekt deployed und die Vagrant Box gespeichert. Wenn dann später wieder jemand an diesem Projekt arbeitet, schnappt er sich einfach die Box und legt los. Kein lästiges Umherkämpfen mit vhosts, falschen Softwareversionen und allem, worauf eigentlich niemand Lust hat. Aber der Reihe nach.

Veröffentlicht unter webdev, Linux, misc IT | 6 Kommentare

Windows: Herausfinden, welche Anwendung Port belegt

Kleiner Quicktipp: Apache kann nicht starten, weil irgendwas Port 80 und/oder 443 belegt?

netstat -ano | findstr /r 0.0:80 && netstat -ano | findstr 0.0:443

netstat

netstat

Ausgespuckt werden die Prozess-IDs (ganz rechts). Zusätzliche Infos, worum es sich bei diesem Prozess handelt, gibts im Taskmanager oder – wenn man schonmal in der cmd ist – per:

tasklist /FI "PID eq 1040" /FO TABLE

tasklist

tasklist

Skype war also der Übeltäter! Nun entweder per Taskmanager schließen oder per:

taskkill /pid 4244 /f

Eventuell sind dafür Admin-Rechte nötig, die cmd also als Admin starten.

Veröffentlicht unter Quicktips, misc IT | 7 Kommentare

htmlspecialchars richtig nutzen – Fallstricke

In der PHP-Welt scheint der Mythos vorzuherrschen, dass die Nutzung von htmlspecialchars sämtlichen Input in sämtlichen Situation sicher macht. Quasi die „one fits all“ – Funktion. Beginnen wir gleich mal mit einem Beispiel. Kein Witz, so gesehen:

function get_user_id($db)
{
	$username = htmlspecialchars(trim($_POST['username']));
	$res = $db->query("SELECT `id` FROM `accounts` WHERE `login` = '$username' LIMIT 1");
	return $res[0]['id'];
}

Cool! Schauen wir uns doch mal die Signatur von htmlspecialchars an:

string htmlspecialchars ( string $string [, int $flags = ENT_COMPAT | ENT_HTML401 [, string $encoding = 'UTF-8' [, bool $double_encode = true ]]] )

Das verflixte Hochkomma

Besonderes Augenmerk sei auf die Flags gelegt. ENT_COMPAT heißt „Konvertiert nur doppelte Anführungszeichen und lässt einfache Anführungszeichen unverändert.„. Also: Perfektes Einfallstor für SQL-Injection.

Gleiches ergibt sich im Formularhandling:

<?php
$_GET['firstname'] = "'onmouseover='alert(/xss!/)'";
$firstname = htmlspecialchars($_GET['firstname'], ENT_COMPAT);
?>
<input name='firstname' value='<?php echo $firstname ?>'>

Veröffentlicht unter php, Security, webdev | 4 Kommentare

Content Security Policy – Tutorial

Das Problem Cross-Site-Scripting / XSS ist präsenter denn je – ständig hört man von neuen Angriffen mit teils verheerenden Folgen, die weit über das Entstellen von Gästebüchern hinausgehen. Seit 2009 in der Entwicklung und mittlerweile mit einer fast vollständigen Implementierung in Chrome und Firefox schickt sich die Content Security Policy nun an, XSS den Kampf anzusagen. Aktuell befindet sich die CSP noch im Status W3C Working Draft und wird speziell um HTML5-relevante Features wie etwa Web-Sockets ergänzt. Das heißt umgekehrt, dass man sie bereits heute problemlos verwenden kann. Aber von vorne.

Veröffentlicht unter php, Security, webdev | 5 Kommentare

Why URL validation with filter_var might not be a good idea

Since PHP 5.2 brought us the filter_var function, the time of such monsters was over (taken from here):

$urlregex = "^(https?|ftp)\:\/\/([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?[a-z0-9+\$_-]+(\.[a-z0-9+\$_-]+)*(\:[0-9]{2,5})?(\/([a-z0-9+\$_-]\.?)+)*\/?(\?[a-z+&\$_.-][a-z0-9;:@/&%=+\$_.-]*)?(#[a-z_.-][a-z0-9+\$_.-]*)?\$";
if (eregi($urlregex, $url)) {echo "good";} else {echo "bad";}

The simple, yet effective syntax:

filter_var($url, FILTER_VALIDATE_URL)

As third parameter, filter flags can be passed. Considering URL validation, the following 4 flags are availible:

FILTER_FLAG_SCHEME_REQUIRED
FILTER_FLAG_HOST_REQUIRED
FILTER_FLAG_PATH_REQUIRED 
FILTER_FLAG_QUERY_REQUIRED 

The first two FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED are the default.

Get started!

Alright, let’s look at some critical examples.

filter_var('http://example.com/"><script>alert("xss")</script>', FILTER_VALIDATE_URL) !== false; //true

Well, nobody said that filter_var was built to fight XSS. Let’s accept this and move on:

filter_var('php://filter/read=convert.base64-encode/resource=/etc/passwd', FILTER_VALIDATE_URL) !== false; //true

Veröffentlicht unter php, Security, PHP-WTF, webdev | 8 Kommentare

„Windows 8 – Die gekachelte Zukunft des Computing?“ – Präsentation auf dem Webmontag

Nachdem ich im Artikel Windows 8 – neues Feld für Webentwickler schon etwas in die Anwendungsentwicklung mit Webtechniken unter Windows 8 eingetaucht bin, gibts jetzt meinen Vortrag auf dem Webmontag #41 in Frankfurt vom 17.09.2012.

Webmontag - Blick vom Speakerpult kurz vor der Präsentation

Webmontag – Blick vom Speakerpult kurz vor der Präsentation

War meine erste Präsentation vor 150 – 200 Leuten, echt eine Erfahrung. Resonanzen auf den Vortrag sind soweit positiv gewesen, natürlich schwingt unter Webdesignern und Social-Media-Experten immer eine gewisse Windows-Skepsis mit, was ja auch vollkommen okay ist. Möchte auch niemanden umerziehen und nur einen Einblick ins neue System geben. Dass mir Windows 8 selbst ganz gut gefällt, hört man sicher raus.

Veröffentlicht unter Software Engineering, misc IT, Persönlich | Hinterlasse einen Kommentar

IE und Chrome mit Standard-XSS-Filter (X-XSS-Protection)

Ich war gerade sehr überrascht, als ich im Zuge des Herumexperimentierens mit der Content Security Policy (kommt auch bald noch ein Artikel dazu – Update: Content Security Policy – Tutorial) folgendes Standard-Beispiel aufgebaut habe …

<input type="text" value="<?php echo $_GET['value']; ?>" />

… und dann das Standard-XSS-Pattern ?value=“><script>alert(1234)</script> übermittelt habe. Resultat im Chrome:

Chrome Filter

Chrome Filter

Bezieht sich übrigens nur auf die Injection von <script>-Tags, ein <b> – Tag geht also durch. Soweit ganz sinnvoll, kann mir jedenfalls keinen legitimen Fall vorstellen, wo ein script-Tag per URL-Parameter benötigt werden könnte. Im IE (ab Version 8) dasselbe Spiel:

IE XSS Filter

IE XSS Filter

Veröffentlicht unter php, Security, Quicktips, webdev | 1 Kommentar

Warum URL-Validierung mit filter_var keine gute Idee ist

Als uns mit PHP 5.2 die filter_var-Funktion geschenkt wurde, war die Zeit solcher Monster vorbei (hier entliehen):

$urlregex = "^(https?|ftp)\:\/\/([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?[a-z0-9+\$_-]+(\.[a-z0-9+\$_-]+)*(\:[0-9]{2,5})?(\/([a-z0-9+\$_-]\.?)+)*\/?(\?[a-z+&\$_.-][a-z0-9;:@/&%=+\$_.-]*)?(#[a-z_.-][a-z0-9+\$_.-]*)?\$";
if (eregi($urlregex, $url)) {echo "good";} else {echo "bad";}

Die simple, aber effektive Syntax:

filter_var($url, FILTER_VALIDATE_URL)

Als dritten Parameter können Filter-Flags übergeben werden, im Bezug auf die URL-Validierung gibt es die folgenden 4 Kandidaten:

FILTER_FLAG_SCHEME_REQUIRED
FILTER_FLAG_HOST_REQUIRED
FILTER_FLAG_PATH_REQUIRED 
FILTER_FLAG_QUERY_REQUIRED 

Dabei sind die ersten beiden FILTER_FLAG_SCHEME_REQUIRED und FILTER_FLAG_HOST_REQUIRED default.

Ans Eingemachte

So, dann schauen wir uns doch mal ein paar kritische Kandidaten an:

filter_var('http://example.com/"><script>alert("xss")</script>', FILTER_VALIDATE_URL) !== false; //true

Gut, hat ja auch niemand gesagt, dass der URL-Filter XSS bekämpfen soll – also ok. Weiter im Takt:

Veröffentlicht unter php, Security, webdev | 2 Kommentare

PHP WTF #8

$array = array(true, null);

var_dump(in_array('', $array)); // true
var_dump(in_array(0, $array)); // true
var_dump(in_array(763, $array)); // true
var_dump(in_array('cheese', $array)); // true
var_dump(in_array(new stdClass(), $array)); // true
var_dump(in_array([], $array)); // true

Tja, PHP und seine automatische Typumwandlung. Wahnsinn, was so alles in dem Array drin ist! in_array bitte nur mit dem dritten Parameter strict auf true benutzen. Sollte ohnehin default sein.

bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )

Schon besser:

$array = array(true, null);

var_dump(in_array('', $array, true)); // false
var_dump(in_array(0, $array, true)); // false
var_dump(in_array(763, $array, true)); // false
var_dump(in_array('cheese', $array, true)); // false
var_dump(in_array(new stdClass(), $array, true)); // false
var_dump(in_array([], $array, true)); // false

Veröffentlicht unter php, PHP-WTF, webdev | 1 Kommentar