Sicherheit in PHP

Okay, ich hab jetzt hier mein schickes, neues PHP 5.2.0 mit Suhosin-Patch und Suhosin-Extension.
Wie gesagt, mit dem Hardening-Patch hatte ich zuvor keinerlei Probleme, vor allem in Hinblick auf Fertig-Ware wie PHPMyAdmin und SquirrelMail.
Mit Suhosin sieht das offensichtlich ein wenig anders aus, denn Suhosin legt scheinbar PHPMyAdmin lahm. Wenn lediglich der Patch aktiv ist kann ich mich zwar einloggen, aber kann irgendwie keine Datenbank auswaehlen (PHPMyAdmin hab ich grad frisch aktualisiert um auszuschliessen, dass es an meiner alten Version liegt). Wenn ich dann auch noch die Extension aktiviere ist das Chaos komplett, dann ist selbst das Login nicht mehr moeglich. Ich seh dann lediglich folgendes:
Warning: mcrypt_encrypt() [function.mcrypt-encrypt]: The IV parameter must be as long as the blocksize in /usr/local/apache2/htdocs/phpmyadmin/libraries/mcrypt.lib.php on line 73

Warning: Cannot modify header information - headers already sent by (output started at /usr/local/apache2/htdocs/phpmyadmin/libraries/mcrypt.lib.php:73) in /usr/local/apache2/htdocs/phpmyadmin/libraries/auth/cookie.auth.lib.php on line 439

Warning: mcrypt_encrypt() [function.mcrypt-encrypt]: The IV parameter must be as long as the blocksize in /usr/local/apache2/htdocs/phpmyadmin/libraries/mcrypt.lib.php on line 73

Warning: Cannot modify header information - headers already sent by (output started at /usr/local/apache2/htdocs/phpmyadmin/libraries/mcrypt.lib.php:73) in /usr/local/apache2/htdocs/phpmyadmin/libraries/auth/cookie.auth.lib.php on line 447

Warning: Cannot modify header information - headers already sent by (output started at /usr/local/apache2/htdocs/phpmyadmin/libraries/mcrypt.lib.php:73) in /usr/local/apache2/htdocs/phpmyadmin/libraries/common.lib.php on line 1154
Als naechstes werde ich mal meine Website durchtesten und sehen ob es da irgendwelche lustigen "Nebenwirkungen" gibt. Wer auf PHPMyAdmin angewiesen ist sollte aber, wie es zur Zeit aussieht, noch die Finger von Suhosin lassen. Der Hardening-Patch hingegen scheint nicht so restriktiv zu sein, sodass PHPMyAdmin damit kein Problem darstellt. PHPPgAdmin, also fuer PostgreSQL-Datenbanken, hingegen scheint von Suhosin nicht beeindruckt zu sein.

Weitere Infos in Kuerze.

Nachtrag: Wenn man PHPMyAdmin auf HTTP-Authentication stellt kann man sich zumindest einloggen, auch wenn die Suhosin-Extension aktiv ist. Jedoch scheint weiterhin die Auswahl einer Datenbank, und somit sinnvolle Arbeit in PHPMyAdmin, unmoeglich zu sein.

Nachtrag 2: Okay, das PHPMyAdmin-Login funktioniert doch, man muss aber zuvor sicherstellen, dass man alle PHPMyAdmin-Cookies loescht, denn ansonsten scheint man den oben angefuehrten Fehler zu bekommen. Nur die Auswahl der Datenbanken geht noch immer nicht. Ich werd mal ein wenig im Code wuehlen und schauen woran das liegen koennte.

Nachtrag 3: Die Auswahl der Datenbanken funktioniert scheinbar nur ueber Links, aber nicht ueber die Combobox im linken Frame. Wenn man also dem Link "Databases" folgt und dann auf einen der Links fuer die Datenbanken klickt kommt man auch zur Datenbank.
Dadurch wuerde ich jetzt erstmal sagen, dass dem Einsatz von Suhosin erstmal nichts im Wege steht. Jedoch ist auf jeden Fall der eigene Code, und natuerlich auch Fertig-Ware, gruendlich zu testen ob denn auch alles laeuft.
In diesem Sinne gehe ich auch mal stark davon aus, dass man noch lange warten darf bis Hoster mal in Betracht ziehen den Hardening-Patch oder gar Suhosin zu nutzen da man den Kunden ja nicht durch verbesserte Sicherheit den Komfort kuerzen moechte.
Einen Vorteil koennte dies jedoch haben, dass User dazu erzogen werden den Code von Grund auf sicher zu gestalten und alle moeglichen Werte vernuenftig pruefen, zumindest halt nachdem die Website das erste Mal von Hackern zerlegt wurde und der Hoster eine boese Mail geschrieben hat. ;)

Dementsprechend moechte ich auch demnaechst mal ein wenig Zeit investieren um hier, oder einem seperaten Thread mal 2 verschiedene php.inis vorzustellen, eine mit restriktiven Einstellungen, sodass man dadurch moeglichst flexiblen und von PHP-Einstellungen unabhaengigen Code schreiben kann, und eine mit lockeren Einstellungen, welche man dann nutzen sollte um seinen Code nach Schwachstellen abzusuchen und diese zu stopfen. Denn nur so kann man auch wirklich Code schreiben der moeglichst vielen Aenderungen an irgendwelchen PHP-Einstellungen und auch diversen Attacken (Cross-Site-Scripting, SQL-Injections) gewachsen ist. Man kann sich eben nicht darauf verlassen, dass man bei jedem Hoster die gleichen Einstellungen vorfindet, und wir wollen ja auch nicht jedes Mal wenn wir den Hoster wechseln, oder der aktuelle Hoster mal ein paar Einstellungen aendert, unseren Code neu schreiben, nicht? ;)

Anregungen dazu, und natuerlich auch weitere Infos und Erfahrungen zum Hardening-Patch und zu Suhosin sind immer gern gesehen.

Nachtrag 4: Meine Website funktioniert uebrigens sowohl mit dem Suhosin-Patch als auch mit der Extension, das hatte ich beim vorherigen Nachtrag vergessen zu erwaehnen. ;)

Nachtrag 5: Die Auswahl der Datenbanken ueber die Combobox scheint irgendwie nur im Konqueror nicht zu klappen. Im Firefox hab ich keine Probleme. Moeglicherweise hat Konqueror mit irgendeinem JavaScript ein paar Probleme. Es scheint also als waere auch PHPMyAdmin nicht durch Suhosin beeintraechtigt. Lediglich den in Nachtrag 2 aufgefuehrten Punkt sollte man beachten.
 
Hallo!
Beispiel:
PHP:
$querry = "UPDATE `tabelle` SET `passwort`='".mysql_real_escape_string($_GET['passwort'])."' WHERE `id`='".mysql_real_escape_string($_GET['id'])."'";
Gruss Dr Dau

Hi,

Bei PHP.Net gibt es eine nette Funktion dazu:
PHP:
// Variablen absichern
function quote_smart($value)
{
   // Ueberfluessige Maskierungen entfernen
   if (get_magic_quotes_gpc()) {
       $value = stripslashes($value);
   }
   // In Anfuehrungszeichen setzen, sofern keine Zahl
   // oder ein numerischer String vorliegt
   if (!is_numeric($value)) {
       $value = "'" . mysql_real_escape_string($value) . "'";
   }
   return $value;
}

Ansonsten wollte ich mal fragen, wo ich bei Apache einstelle, dass ich alle Fehler ausgegeben bekomme.

Dennis hat gesagt.:
Auch hab ich bei der Entwicklung volles Error-Reporting an (beim Test uebrigens spaeter auch).
 
Bei PHP.Net gibt es eine nette Funktion dazu:
Ich stehe mit solchen Funktionen irgendwie auf dem Kriegsfuss. ;)
Ansonsten wollte ich mal fragen, wo ich bei Apache einstelle, dass ich alle Fehler ausgegeben bekomme.
Bei Apache garnicht..... sondern bei PHP..... in der php.ini:
Code:
error_reporting  =  E_ALL
Nicht vergessen, nach Änderungen an der Konfiguration den Apachen neustarten.

Alternativ kannst Du es aber auch im Script machen:
PHP:
<?php
error_reporting(E_ALL);
?>
 
Hi,

Bei PHP.Net gibt es eine nette Funktion dazu:
PHP:
// Variablen absichern
function quote_smart($value)
{
   // Ueberfluessige Maskierungen entfernen
   if (get_magic_quotes_gpc()) {
       $value = stripslashes($value);
   }
   // In Anfuehrungszeichen setzen, sofern keine Zahl
   // oder ein numerischer String vorliegt
   if (!is_numeric($value)) {
       $value = "'" . mysql_real_escape_string($value) . "'";
   }
   return $value;
}
Ich hab bei mir aehnlichen Code (inspiriert durch diesen Code hier) eingebaut, jedoch aufgeteilt in 2 Funktionen da es von Zeit zu Zeit ja auch mal noetig ist uebergebene Werte auszugeben, und dort waeren die Magic-Quotes ja doch etwas haesslich.
Meine Funktionen sehen wie folgt aus:
PHP:
function remove_magic_quotes($string)
{
	if (get_magic_quotes_gpc())
		{
			$string=stripslashes($string);
		}
	return $string;
}
function quote_string($string)
{
	global $sqldb;
	return $sqldb->escape_string(remove_magic_quotes($string));
}
$sqldb ist hierbei eine Instanz meiner MultiSQL-Klasse. Die Methode escape_string() entspricht dann eben der jeweilige Escape-Funktion des gewaehlten DBMS (bei MySQL z.B. mysql_real_escape_string()).
 
Guten Abend.

Ich muss schon sagen das dieser Thread hier eine gute und wichtige entscheidung war. Vorrausgesetzt es wird auch alles gelesen ;)

Nur denke ich das man den Feind am besten bekämpfen kann wenn man weis wie soetwas gemacht werden kann. Klar ist auch das man nicht hergehen kann und alle lücken und sicherheitsrelevante abschnitte bis ins kleinste Detail auseinander zu Pflücken denn dies könnte man dann wieder eine "Anleitung" zum ausnutzen der Lücken nennen.

Ich würde es begrüßen wenn jemand mögliche schwachstellen zeigen kann und eine Lösung dazu. Denn ich kann mir gut denken das viele lesen, hier in diesem Code sind möglichkeiten der SQLInc. usw nur wissen sie nicht wo oder verstehen nicht wie man sich dagegen schützen kann.

Mfg floHate

Nachtrag:

Ich hab noch eine lösung für eine SQL Abfrage:

PHP:
<?php
    $sql = sprintf("SELECT
                        foo
                    FROM
                        tab
                    WHERE
                        ID = '%u';", $_POST['ID']);
?>

Egal was nun in 'ID' steht müsste eig. zu einer Zahl werden. Das heist das hinzufügen von Fremdcode ist nicht mehr möglich.

Bitte klärt mich auf fals ich damit falsch liebe :) aber dürfte stimmen

Mfg floHate
 
Zuletzt bearbeitet:
Und wieder einmal ist hier von Stefan Esser die Rede.

Für alle die ihn nicht kennen, ist der Post oben wohl eine Lesung wert, für alle anderen ist die folgende Website offen:
http://www.php-security.org/

Auf dieser ist heute der The Month of PHP Bugs eröffnet worden.
 
hmm habe manche links benutzt und dass was mich eig. interessiert nicht gefunden...

bsp.

PHP:
<?php 
// Muss hier die GET Variable auf irgendeiner Art escaped werden vll mit intval?
$get = $_GET['id'];

if(empty($get) || !is_numeric($get) ) {

die('ID existiert nicht oder interner Fehler');

} else {

$db = mysql_connect('localhost', 'root', '');

$dbs = mysql_select_db('test');

$command = sprintf(SELECT * FROM users WHERE id = %s, htmlspecialchars(mysql_real_escape_string($get)));

$query = mysql_query($command);

$f = mysql_fetch_assoc($query);

?>

Würde mich auf Antworten freuen, danke ;)

MfG
KD3
 
Da es sich eindeutig um eine Zahl handelt (bzw. handeln soll) kannst du statt:

PHP:
htmlspecialchars(mysql_real_escape_string($get))

auch

PHP:
intval($get)

benutzen.

Sollten HTML Zeichen drin sein, würde ja deine erste Prüfung bereits false melden, da es dann kein numerischer String mehr ist.
 
Zurück