tom Wed Feb 27 02:41:29 2002 EDT
Modified files:
/phpdoc/de/chapters security.xml
Log:
added db-sec. section, ws
Index: phpdoc/de/chapters/security.xml
diff -u phpdoc/de/chapters/security.xml:1.14 phpdoc/de/chapters/security.xml:1.15
--- phpdoc/de/chapters/security.xml:1.14 Wed Dec 12 15:46:04 2001
+++ phpdoc/de/chapters/security.xml Wed Feb 27 02:41:26 2002
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="iso-8859-1"?>
-<!-- EN-Revision: 1.31 Maintainer: tom Status: ready -->
+<!-- EN-Revision: 1.44 Maintainer: tom Status: ready -->
<chapter id="security">
<title>Sicherheit</title>
@@ -21,7 +21,7 @@
gibt es viele Konfigurationseinstellungen, die das Verhalten von
PHP beeinflussen. Eine gro�e Auswahl an Einstellungen garantiert,
dass man PHP f�r viele Zwecke einsetzen kann. Allerdings
- bedeutet das auch, dass es Kombinationen gibt, die eine Installation
+ bedeutet das auch, dass es Kombinationen gibt, die eine Installation
mit nur ungen�gender Sicherheit zur Folge haben.
</simpara>
<simpara>
@@ -30,7 +30,7 @@
mit allen M�glichkeiten eines Shell Benutzers erstellt werden, oder
auch nur einfache Server Side Includes mit einem minimalen Risiko in
einer streng kontrollierten Umgebung. Wie die Umgebung erstellt wird,
- und wie sicher diese ist, ist zu einem gro�en Teil die Sache des PHP
+ und wie sicher diese ist, ist zu einem gro�en Teil die Sache des PHP
Entwicklers.
</simpara>
<simpara>
@@ -51,7 +51,7 @@
biometrischer Pr�fung (wie z.B. ein Scan der Netzhaut und ein
Fingerabdruck) verlangen w�rde, w�re eine extrem hohe Ebene der
Verantwortlichkeit erreicht. Ein sehr komplexes Formular auszuf�llen
- w�rde auch eine halbe Stunde in Anspruch nehmen, was Benutzer dazu
+ w�rde auch eine halbe Stunde in Anspruch nehmen, die Benutzer dazu
ermuntern k�nnte, Wege zur Umgehung der Sicherheitsma�nahmen zu suchen.
</simpara>
<simpara>
@@ -63,11 +63,11 @@
f�hrt.
</simpara>
<simpara>
- Eine Phrase die es wert ist, sich an sie zu erinnern: Ein System ist
- nur so gut wie das schw�chste Glied in der Kette. Wenn alle
- Transaktionen mittels Zeit, Ort, Transaktionstyp, etc. streng gelogged
- werden, der Benutzer aber nur mittels einem einzigen Cookie verifiziert
- wird, l�sst die Zuverl�ssigkeit f�r die Bindung des Benutzers an das
+ Eine Phrase die es wert ist, sich an sie zu erinnern: Ein System ist nur
+ so gut wie das schw�chste Glied in der Kette. Wenn alle Transaktionen
+ mittels Zeit, Ort, Transaktionstyp, etc. streng mitprotokolliert werden,
+ der Benutzer aber nur mittels einem einzigen Cookie verifiziert wird,
+ l�sst die Zuverl�ssigkeit f�r die Bindung des Benutzers an das
Transaktions-Log bedrohlich nach.
</simpara>
<simpara>
@@ -81,7 +81,7 @@
wie diese modifiziert, reduziert, oder weiter ausgef�hrt werden.
</simpara>
<simpara>
- Das Internet ist voll von Leuten welche versuchen, sich durch
+ Das Internet ist voll von Leuten die versuchen, sich durch
Entschl�sseln/zerst�ren Ihres Codes, den Zusammenbruch Ihres
Systems, Einsetzen von unangebrachten Inhalten, und anderen, Ihren
Tag interessant gestaltenden Ma�nahmen, einen Namen zu machen.
@@ -191,7 +191,7 @@
noch durch einen Redirect <filename
role="php">http://my.host/dir/script.php</filename>.
</simpara>
<simpara>
- Beim Apache kann der Redirect durch den Gebrauch von
+ Beim Apache kann der Redirect durch den Gebrauch von
AddHandler und Action konfiguriert werden (siehe unten).
</simpara>
</sect2>
@@ -209,8 +209,10 @@
Normalerweise wird der Redirect in der Apache-Konfiguration mit den
folgenden Eintr�gen festgelegt:</simpara>
<programlisting role="apache-conf">
+<![CDATA[
Action php-script /cgi-bin/php
AddHandler php-script .php
+]]>
</programlisting>
<simpara>
Diese Option wurde nur mit dem Apache Webserver getestet und
@@ -245,7 +247,7 @@
von Anfragen (wie im vorangegangenen Kapitel beschrieben) nicht
verf�gbar ist, ist es notwendig, ein doc_root f�r Skripte zus�tzlich
zum Web-Dokumentenverzeichnis einzurichten.
- </simpara>
+ </simpara>
<simpara>
Sie k�nnen das PHP-Skriptverzeichnis durch die Direktive
<link linkend="ini.doc-root">doc_root</link> in der
@@ -257,7 +259,7 @@
zusammensetzen, sodass man sicher sein kann, dass au�erhalb dieses
Verzeichnisses keine Skripte ausgef�hrt werden (au�er
<parameter>user_dir</parameter>, siehe unten).
- </simpara>
+ </simpara>
<simpara>
Eine weitere hier n�tzliche Option ist <link
linkend="ini.user-dir">user_dir</link>. Wenn das
@@ -269,7 +271,7 @@
wird, sondern eine Datei namens <filename role="uri">~user/doc.php</filename>
unterhalb des doc_root (Ja, ein Verzeichnisname, der mit einer Tilde anf�ngt
[<literal>~</literal>]).
- </simpara>
+ </simpara>
<simpara>
Ist das user_dir beispielsweise auf <filename role="dir">public_php</filename>
gesetzt,
wird eine Anfrage wie <filename
role="url">http://my.host/~user/doc.php</filename>
@@ -279,14 +281,14 @@
<filename role="dir">/home/user</filename> ist, so ist die
ausgef�hrte Datei
<filename>/home/user/public_php/doc.php</filename>.
- </simpara>
+ </simpara>
<simpara>
Die <parameter>user_dir</parameter>-Expansion erfolgt ohne Ber�cksichtigung
der <parameter>doc_root</parameter> Einstellung. So k�nnen Zugriffe
auf die Dokumenten- und Benutzerverzeichnisse separat gesteuert werden.
</simpara>
</sect2>
-
+
<sect2 id="security.cgi-bin.shell">
<title>Fall 4: PHP-Parser au�erhalb des Webverzeichnisbaums</title>
<para>
@@ -296,7 +298,9 @@
Nachteil dieses Verfahrens ist, dass eine Zeile �hnlich der folgenden:
<informalexample>
<programlisting>
+<![CDATA[
#!/usr/local/bin/php
+]]>
</programlisting>
</informalexample>
als erste Zeile in jeder Datei, die PHP-Tags enth�lt, stehen muss.
@@ -395,14 +399,16 @@
<example>
<title>Schlechte Variablenpr�fung f�hrt zu....</title>
<programlisting role="php">
-<?php
+<![CDATA[
+<?php
// L�schen einer Datei aus dem Heimatverzeichnis des Users
$username = $HTTP_POST_VARS['user_submitted_name'];
$homedir = "/home/$username";
$file_to_delete = "$userfile";
unlink ($homedir/$userfile);
echo "$file_to_delete wurde gel�scht!";
-?>
+?>
+]]>
</programlisting>
</example>
Da der Benutzername �ber ein User-Formular zu posten ist, kann
@@ -414,7 +420,8 @@
<example>
<title>... Ein Angriff auf das Dateisystem</title>
<programlisting role="php">
-<?php
+<![CDATA[
+<?php
// l�scht eine Datei irgendwo auf der Festplatte, wo der
// Benutzer die n�tigen Rechte besitzt. Wenn PHP root hat:
$username = "../etc/";
@@ -422,9 +429,10 @@
$file_to_delete = "passwd";
unlink ("/home/../etc/passwd");
echo "/home/../etc/passwd wurde gel�scht!";
-?>
+?>
+]]>
</programlisting>
- </example>
+ </example>
Es gibt zwei wichtige Kriterien die Sie beachten sollten, um diese
Dinge zu vermeiden:
<itemizedlist>
@@ -443,7 +451,8 @@
<example>
<title>Etwas sicherere Pr�fung des Dateinamens</title>
<programlisting role="php">
-<?php
+<![CDATA[
+<?php
// l�scht eine Datei von der Festplatte, auf die
// der PHP user Zugriff hat.
$username = $HTTP_SERVER_VARS['REMOTE_USER']; // verwendet eine
@@ -459,7 +468,8 @@
fclose($fp);
echo "$file_to_delete wurde gel�scht!";
-?>
+?>
+]]>
</programlisting>
</example>
Auch dies nicht v�llig makellos. Wenn Ihr Authentifizierungssystem
@@ -470,20 +480,22 @@
<example>
<title>Sicherere Dateinamenspr�fung</title>
<programlisting role="php">
-<?php
+<![CDATA[
+<?php
$username = $HTTP_SERVER_VARS['REMOTE_USER']; // verwendet eine
// Authentifizierungsmethode
$homedir = "/home/$username";
if (!ereg('^[^./][^/]*$', $userfile))
die('bad filename'); // "DIE", gehen Sie nicht weiter
-
+
if (!ereg('^[^./][^/]*$', $username))
- die('bad username'); // "DIE", gehen Sie nicht weiter
+ die('bad username'); // "DIE", gehen Sie nicht weiter
//etc...
-?>
+?>
+]]>
</programlisting>
- </example>
+ </example>
</para>
<para>
Abh�ngig vom Betriebssystem gibt es eine gro�e Anzahl Dateien mit der
@@ -492,7 +504,447 @@
bekannte Verzeichnisse (/home/, My Documents), etc. Aus diesem Grund
ist es gew�hnlich einfacher eine Vorgangsweise einzuf�hren, bei der
au�er den von Ihnen explizit erlaubten Dingen alles verboten ist.
- </para>
+ </para>
+ </sect1>
+
+ <sect1 id="security.database">
+ <title>Datenbank - Sicherheit</title>
+
+ <simpara>
+ Heutzutage sind Datenbanken die Hauptkomponenten jeder Webbasierten
+ Applikation, aufgrund welcher Websites verschiedene dynamische Inhalte
+ anbieten k�nnen. Nachdem heikle oder geheime Informationen in solch einer
+ Datenbank gespeichert werden k�nnen, sollten Sie deren Schutz ernsthaft
+ bedenken.
+ </simpara>
+ <simpara>
+ Um Informationen zu bekommen oder zu speichern, m�ssen Sie eine legitime
+ Abfrage senden, das Ergebnis holen, und die Verbindung schlie�en.
+ Heutzutage ist die allgemein verwendete Abfragesprache f�r solche
+ Interaktionen die Structured Query Language (SQL). Sehen Sie, wie sich ein
+ Angreifer <link linkend="security.database.sql-injection">an einer SQL
+ Abfrage zu schaffen machen</link> kann.
+ </simpara>
+ <simpara>
+ Sie werden merken, dass PHP Ihre Datenbank alleine nicht sch�tzen kann.
+ Die folgenden Abschnitte sind eine Einf�hrung in die Grundlagen, wie man
+ innerhalb von PHP Skripten auf Datenbanken zugreift und diese manipuliert.
+ </simpara>
+ <simpara>
+ Denken Sie an diese einfache Regel: tief gestaffelte Verteidigung. Je mehr
+ Platz Sie den Ma�nahmen zum Schutz Ihrer Datenbank geben, desto geringer
+ ist die Wahrscheinlichkeit, dass ein Angreifer Erfolg hat, und gespeicherte
+ Geheiminformationen aufdeckt oder missbraucht. Gutes Design des
+ Datenbankschemas, und die Applikation wird mit Ihren gr��ten Bef�rchtungen
+ fertig.
+ </simpara>
+
+ <sect2 id="security.database.design">
+ <title>Datenbanken designen</title>
+ <simpara>
+ Der Erste Schritt liegt immer im Erstellen der Datenbank, au�er Sie wollen
+ eine bereits existierende Dritter verwenden. Ist eine Datenbank erstellt,
+ ist sie einem Eigent�mer zugewiesen, welcher das Kommando zum Erstellen
+ ausgef�hrt hat. Gew�hnlich kann nur der Eigent�mer (oder ein Superuser)
+ alles mit den Objekten in dieser Datenbank machen, und um anderen Benutzern
+ die Verwendung zu erlauben, m�ssen Rechte vergeben werden.
+ </simpara>
+ <simpara>
+ Applikationen sollten sich mit der Datenbank nie als deren Eigent�mer
+ oder als ein Superuser verbinden, da diese Benutzer jede gewollte Abfrage
+ ausf�hren k�nnen, um z.B. das Schema zu modifizieren (z.B. Tabellen
+ l�schen) oder den gesamten Inhalt l�schen.
+ </simpara>
+ <simpara>
+ Sie k�nnen verschiedene Datenbanknutzer mit sehr limitierten Rechten auf
+ Datenbankobjekte f�r jeden Aspekt Ihrer Applikation anlegen. Nur die
+ wirklich ben�tigten Rechte sollten gew�hrt werden, und vermeiden Sie, dass
+ der gleiche Benutzer in verschiedenen Anwendungsf�llen mit der Datenbank
+ interagieren kann. Das hei�t, dass Eindringlinge, welche unter Verwendung
+ einer dieser Referenzen Zugriff auf Ihre Datenbank erlangt haben, nur so
+ viele �nderungen durchf�hren k�nnen, wie es Ihre Applikation kann.
+ </simpara>
+ <simpara>
+ Implementieren Sie nicht alle Gesch�ftslogik in die Webapplikation (z.B.
+ Ihr Skript), sondern tun Sie das im Datenbankschema unter Verwendung von
+ Sichten, Triggern, oder Regeln. Wenn sich das System entwickelt, werden
+ neu zu �ffnende Ports zu der Datenbank vorgesehen, und Sie m�ssen die
+ Logik in jedem Datenbank-Client neu implementieren. �berdies k�nnen
+ Trigger verwendet werden, um transparent und automatisch mit Feldern
+ umzugehen, welche beim debuggen Ihrer Applikation oder beim
+ Zur�ckverfolgen von Transaktionen oft einen Einblick gew�hren.
+ </simpara>
+ </sect2>
+
+ <sect2 id="security.database.connection">
+ <title>Zur Datenbank verbinden</title>
+ <simpara>
+ Vielleicht wollen Sie die Verbindungen �ber SSL herstellen, um die
+ Client/Server Kommunikation f�r eine erh�hte Sicherheit zu verschl�sseln,
+ oder aber auch ssh verwenden, um die Netzwerkverbindung zwischen den
+ Clients und dem Datenbankserver zu verschl�sseln. Ist eines davon
+ realisiert, wird ein Monitoring Ihres Verkehrs und das Erlangen von
+ Informationen zu harter Arbeit.
+ </simpara>
+ <!--simpara>
+ If your database server native SSL support, consider to use <link
+ linkend="ref.openssl">OpenSSL functions</link> in communication between
+ PHP and database via SSL.
+ </simpara-->
+ </sect2>
+
+ <sect2 id="security.database.storage">
+ <title>Verschl�sseltes Speichermodell</title>
+ <simpara>
+ SSL/SSH sch�tzt zwar die gerade auf dem Weg befindlichen Daten vom Client
+ zum Server, jedoch nicht die dauernd in einer Datenbank gespeicherten
+ Daten. SSL ist ein "auf-der-Leitung" Protokoll.
+ </simpara>
+ <simpara>
+ Hat ein Angreifer direkten Zugriff auf Ihre Datenbank (den Webserver
+ umgehend), k�nnen die gespeicherten heiklen Daten aufgedeckt oder
+ zweckentfremdet werden, au�er wenn die Information von der Datenbank selbst
+ gesch�tzt ist. Die Daten zu verschl�sseln ist ein guter Weg, diese Gefahr
+ zu mildern, doch bieten nur wenige Datenbanken diese Art der
+ Verschl�sselung von Daten.
+ </simpara>
+ <simpara>
+ Der einfachste Weg, dieses Problem zu umgehen ist, erst einmal Ihr eigenes
+ Verschl�sselungspaket zu erstellen, und dieses dann in Ihren PHP Skripten
+ zu nutzen. PHP kann Ihnen in diesem Fall mit seinen verschiedenen
+ Erweiterungen helfen, wie z.B. <link linkend="ref.mcrypt">Mcrypt</link>
+ and <link linkend="ref.mhash">Mhash</link>, welche eine gro�e Auswahl an
+ Verschl�sselungsalgorhythmen abdecken. Das Skript verschl�sselt die Daten
+ vor dem Speichern, und entschl�sselt diese wieder beim Erhalt. Siehe die
+ Verweise f�r weitere Beispiele, wie Verschl�sselung arbeitet.
+ </simpara>
+ <simpara>
+ Im Fall von wirklich versteckten Daten, wenn deren unverf�lschte
+ Repr�sentation nicht n�tig ist (z.B. keine Anzeige), ist hashing ebenfalls
+ �berlegenswert. Das bekannte Beispiel f�r das Hashing ist das Speichern des
+ MD5 hash eines Passwortes in einer Datenbank, anstatt des Passwortes selbst.
+ Siehe auch <function>crypt</function> und <function>md5</function>.
+ </simpara>
+ <example>
+ <title>Verwenden eines hashed Passwortfeldes</title>
+ <programlisting role="php">
+<![CDATA[
+// Speichern des Passwort hash
+$query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
+ addslashes($username), md5($password));
+$result = pg_exec($connection, $query);
+
+// Afragen, ob der User das richtige Passwort �bermittelt hat
+$query = sprintf("SELECT 1 FROM users WHERE name='%s' AND pwd='%s';",
+ addslashes($username), md5($password));
+$result = pg_exec($connection, $query);
+
+if (pg_numrows($result) > 0) {
+ echo "Welcome, $username!";
+}
+else {
+ echo "Authentication failed for $username.";
+}
+]]>
+ </programlisting>
+ </example>
+ </sect2>
+
+ <sect2 id="security.database.sql-injection">
+ <title>SQL Injection</title>
+ <simpara>
+ Viele Entwickler sind sich nicht bewusst, wie man sich an SQL Abfragen
+ zu schaffen machen kann und nehmen an, dass eine SQL Abfrage ein
+ vertrauensw�rdiges Kommando ist. Das hei�t, dass SQL Abfragen
+ Zugriffskontrollen hinters Licht f�hren, und dadurch Standard
+ Authentifizierungs- und Authorisationschecks umgehen k�nnen, und
+ manchmal k�nnen SQL Abfragen sogar Zugriff zu Kommandos auf
+ Betriebssystemebene erlauben.
+ </simpara>
+ <simpara>
+ Direkt SQL Command Injection ist eine Technik, wo ein Angreifer SQL
+ Kommandos erstellt oder existierende ver�ndert, um versteckte Daten
+ sichtbar zu machen, wertvolle Daten zu �berschreiben, oder sogar
+ gef�hrliche Kommandos auf Systemebene des Datenbank-Hosts auszuf�hren.
+ Dies wird durch die Applikation erreicht, welche den Input des Benutzers
+ mit statischen Parametern kombiniert, um eine SQL Abfrage zu erstellen.
+ Die folgenden Beispiele basieren - leider - auf wahren Begebenheiten.
+ </simpara>
+ <para>
+ Dank dem Mangel an Input Validierungen, und dem Verbinden zum
+ Datenbankserver als ein Superuser oder jemand der Benutzer anlegen kann,
+ kann ein Angreifer einen Superuser in Ihrer Datenbank anlegen.
+ <example>
+ <title>
+ Die Ergebnisliste in mehrere Seiten aufsplitten ... und Superuser anlegen
+ (PostgreSQL and MySQL)
+ </title>
+ <programlisting role="php">
+<![CDATA[
+$offset = argv[0]; // Vorsicht, keine Validierung des Input !
+$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
+// mit PostgreSQL
+$result = pg_exec($conn, $query);
+// mit MySQL
+$result = mysql_query($query);
+]]>
+ </programlisting>
+ </example>
+ Normale Benutzer klicken auf die 'n�chste' bzw. 'vorige' Links, wo
+ <varname>$offset</varname> in der URL enthalten ist. Das Skript erwartet,
+ dass die ankommende <varname>$offset</varname> einen Dezimalwert enth�lt.
+ Ganz gleich, jemand versucht einzubrechen, indem er das folgende in einer
+ <function>urlencode</function>'d Form an die URL anh�ngt
+ <informalexample>
+ <programlisting>
+<![CDATA[
+// Im Fall von PostgreSQL
+0;
+insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
+ select 'crack', usesysid, 't','t','crack'
+ from pg_shadow where usename='postgres';
+--
+
+// Im Fall von MySQL
+0;
+UPDATE user SET Password=PASSWORD('crack') WHERE user='root';
+FLUSH PRIVILEGES;
+]]>
+ </programlisting>
+ </informalexample>
+ Wenn es passiert ist, w�rde ihm das Skript einen Zugriff als Superuser
+ pr�sentieren. Beachten Sie, dass <literal>0;</literal> ein g�ltiges
+ Offset zur urspr�nglichen Abfrage liefert, und sie beendet.
+ </para>
+ <note>
+ <para>
+ Es ist eine �bliche Technik, den SQL Parser mittels dem Kommentarzeichen
+ in SQL <literal>--</literal> zu zwingen, den Rest der vom Entwickler
+ geschriebenen Abfrage zu ignorieren.
+ </para>
+ </note>
+ <para>
+ Ein gangbarer Weg um Passw�rter zu finden ist, Ihre Seiten mit den
+ Suchergebnissen hinters Licht zu f�hren. Der Angreifer braucht nur zu
+ probieren, ob irgendeine �bertragene Variable, die in dem SQL Statement
+ verwendet wird, nicht richtig gehandhabt wird. Diese Filter k�nnen
+ gew�hnlich in einer vorausgehenden Form gesetzt werden, indem
+ <literal>WHERE, ORDER BY, LIMIT</literal> und <literal>OFFSET</literal>
+ Klauseln in <literal>SELECT</literal> Statements umgebaut werden. Wenn
+ Ihre Datenbank das <literal>UNION</literal> Konstrukt unterst�tzt, kann
+ der Angreifer versuchen, eine komplette Abfrage an das Original anzuh�ngen,
+ um Pa�w�rter aus einer willk�rlichen Tabelle aufzulisten. Die Verwendung
+ von verschl�sselten Passwortfeldern wird ausdr�cklich empfohlen.
+ <example>
+ <title>
+ Artikel auflisten ... und ein paar Passw�rter (irgendein Datenbankserver)
+ </title>
+ <programlisting role="php">
+<![CDATA[
+$query = "SELECT id, name, inserted, size FROM products
+ WHERE size = '$size'
+ ORDER BY $order LIMIT $limit, $offset;";
+$result = odbc_exec($conn, $query);
+]]>
+ </programlisting>
+ </example>
+ Der statische Teil der Abfrage kann mit einem anderen
+ <literal>SELECT</literal> Statement kombiniert werden, welches alle
+ Passw�rter preisgibt
+ <informalexample>
+ <programlisting>
+<![CDATA[
+'
+union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from
+usertable;
+--
+]]>
+ </programlisting>
+ </informalexample>
+ Wenn diese Abfrage (mit dem <literal>'</literal> und
+ <literal>--</literal>) einer der in <varname>$query</varname> verwendeten
+ Variablen zugewiesen w�rde, w�re das "Abfragebiest" erwacht.
+ </para>
+ <para>
+ SQL UPDATEs sind ebenfalls ein Anlass, Ihre Datenbank anzugreifen. Diese
+ Abfragen sind auch durch das �ndern und Anh�ngen einer komplett neuen
+ Abfrage gef�hrdet. Aber der Angreifer k�nnte auch mit der
+ <literal>SET</literal> Klausel herumspielen. In diesem Fall muss eine
+ Schemainformation vorhanden sein, um die Abfrage erfolgreich manipulieren
+ zu k�nnen. Diese kann durch Untersuchen der Variablennamen im Formular,
+ oder simpel mittels brute force gesammelt werden. Es gibt nicht so viele
+ Namenskonventionen f�r Felder, welche Passw�rter oder Benutzernamen
+ speichern.
+ <example>
+ <title>
+ Vom Zur�cksetzen eines Passwortes ... zum Erlangen von mehr Rechten
+ (irgendein Datenbankserver)
+ </title>
+ <programlisting role="php">
+<![CDATA[
+$query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
+]]>
+ </programlisting>
+ </example>
+ Aber ein b�swilliger Benutzer �bermittelt den Wert
+ <literal>' or uid like'%admin%'; --</literal> zu <varname>$uid</varname>,
+ um das Administrator Passwort zu �ndern, oder setzt einfach
+ <varname>$pwd</varname> auf <literal>"hehehe', admin='yes', trusted=100
+ "</literal> (mit dem hinteren Leerzeichen), um mehr Rechte zu erhalten.
+ Dann wird die Abfrage verdreht:
+ <informalexample>
+ <programlisting role="php">
+<![CDATA[
+// $uid == ' or uid like'%admin%'; --
+$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%'; --";
+
+// $pwd == "hehehe', admin='yes', trusted=100 "
+$query = "UPDATE usertable SET pwd='hehehe', admin='yes', trusted=100 WHERE ...;"
+]]>
+ </programlisting>
+ </informalexample>
+ </para>
+ <para>
+ Ein furchterregendes Beispiel, wie der Zugriff auf Kommandos auf
+ Betriebssystemebene bei manchen Datenbankservern erfolgen kann.
+ <example>
+ <title>Angriff auf das Betriebssystem des Datenbank Hosts (MSSQL Server)</title>
+ <programlisting role="php">
+<![CDATA[
+$query = "SELECT * FROM products WHERE id LIKE '%$prod%'";
+$result = mssql_query($query);
+]]>
+ </programlisting>
+ </example>
+ Wenn ein Angreifer den Wert
+ <literal>a%' exec master..xp_cmdshell 'net user test testpass /ADD' --</literal>
+ zu <varname>$prod</varname> �bertr�gt, wird <varname>$query</varname> zu:
+ <informalexample>
+ <programlisting role="php">
+<![CDATA[
+$query = "SELECT * FROM products
+ WHERE id LIKE '%a%'
+ exec master..xp_cmdshell 'net user test testpass /ADD'--";
+$result = mssql_query($query);
+]]>
+ </programlisting>
+ </informalexample>
+ Der MSSQL Server f�hrt die SQL Statements in dem Batch aus, inklusive einem
+ Kommando zum Anlegen eines neuen Benutzers in der Datenbank Accounts. W�rde
+ diese Applikation als <literal>sa</literal> und der MSSQLSERVER Service
+ mit gen�gend Rechten laufen, h�tte der Angreifer nun ein Konto, mit welchem
+ er Zugriff auf diese Maschine h�tte.
+ </para>
+ <note>
+ <para>
+ Manche der obigen Beispiele sind an einen spezifischen Datenbankserver
+ gebunden. Das hei�t jedoch nicht, dass nicht ein �hnlicher Angriff auf
+ andere Produkte m�glich w�re. Ihr Datenbankserver k�nnte auf andere
+ Weise genauso verwundbar sein.
+ </para>
+ </note>
+
+ <sect3 id="security.database.avoiding">
+ <title>Techniken zur Vermeidung</title>
+ <simpara>
+ Sie k�nnten sich nun darauf berufen, dass der Angreifer in den meisten
+ Beispielen ein St�ck Information �ber das Datenbankschema haben muss. Sie
+ haben recht, aber Sie wissen nie, wann und wie es genommen werden kann,
+ und wenn es passiert, kann Ihre Datenbank entbl��t werden. Wenn Sie ein
+ Open Source, oder �ffentlich verf�gbares Paket zur Handhabung von
+ Datenbanken verwenden, welches vielleicht zu einem Content Management
+ System oder Forum geh�rt, k�nnen Eindringlinge leicht eine Kopie eines
+ St�cks Ihres Codes erstellen. Es kann auch ein Sicherheitsrisiko sein,
+ wenn es sich um ein schlecht designtes Paket handelt.
+ </simpara>
+ <simpara>
+ Diese Angriffe basieren haupts�chlich auf dem Ausnutzen des Codes, welcher
+ ohne Bedenken auf die Sicherheit geschrieben wurde. Vertrauen Sie nie auf
+ irgendeine Art von Input, speziell wenn er von der Clientseite kommt,
+ selbst wenn er von einer Auswahlbox, einem versteckten Eingabefeld, oder
+ einem Cookie kommt. Das erste Beispiel zeigt, dass solch eine untadelige
+ Abfrage ein Disaster anrichten kann.
+ </simpara>
+
+ <itemizedlist>
+ <listitem>
+ <simpara>
+ Stellen Sie nie als Superuser oder Owner einer Datenbank eine Verbindung
+ zur Datenbank her. Verwenden Sie immer speziell angelegte Benutzer mit
+ sehr limitierten Rechten.
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Pr�fen Sie, ob der gegebene Input dem erwarteten Datentyp entspricht.
+ PHP bietet eine gro�e Auswahl an Funktionen zum Validieren des Input,
+ von den einfachsten unter <link
+ linkend="ref.variables">Variablenfunktionen</link> und <link
+ linkend="ref.ctype">Character Type Functions</link> (z.B.
+ <function>is_numeric</function> bzw. <function>ctype_digit</function>),
+ bis hin zu den <link linkend="ref.pcre">Perl kompatiblen Regul�ren
+ Ausdr�cken</link>.
+ </simpara>
+ </listitem>
+ <listitem>
+ <para>
+ Wenn die Applikation numerischen Input erwartet, erw�gen Sie die Pr�fung
+ der Daten mit <function>is_numeric</function>, oder die �nderung des
+ Typs mit <function>settype</function>, oder verwenden Sie die numerische
+ Repr�sentation mittels <function>sprintf</function>.
+ <example>
+ <title>Ein sicherer Weg, eine Abfrage zu erstellen</title>
+ <programlisting role="php">
+<![CDATA[
+settype($offset, 'integer');
+$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
+
+// Beachten Sie %d im Formatstring, %s zu verwenden w�re sinnlos
+$query = sprintf("SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET %d;",
+$offset);
+]]>
+ </programlisting>
+ </example>
+ </para>
+ </listitem>
+ <listitem>
+ <simpara>
+ Escapen Sie jeden nicht numerischen Input, welcher zur Datenbank
+ weitergereicht werden soll mit <function>addslashes</function>
+ oder <function>addcslashes</function>. Siehe auch <link
+ linkend="security.database.storage">das erste Beispiel</link>. Wie
+ dieses Beispiel zeigt, sind in den statischen Teil der Abfrage
+ eingebrachten Escapes nicht genug, und k�nnen leicht gehacked werden.
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Geben Sie keinerlei datenbankspezifische Informationen aus, speziell
+ �ber das Schema, egal wie (auf ehrliche oder unehrliche Weise). Siehe
+ auch <link linkend="security.errors">Fehlerbehandlung</link> und
+ <link linkend="ref.errorfunc">Error Handling and Logging
+ Functions</link>.
+ </simpara>
+ </listitem>
+ <listitem>
+ <simpara>
+ Sie k�nnen stored procedures und vorher definierte Cursor verwenden,
+ um den Datenzugriff zu abstrahieren, sodass Benutzer nicht direkt auf
+ Tabellen oder Views zugreifen, aber diese L�sung hat andere
+ Auswirkungen.
+ </simpara>
+ </listitem>
+ </itemizedlist>
+
+ <simpara>
+ Abgesehen davon profitieren Sie von einer Protokollierung der Abfragen
+ entweder in Ihrem Skript, oder durch die Datenbank selbst, wenn es hilft.
+ Klar, die Protokollierung kann nicht irgendeinen sch�dlichen Versuch
+ verhindern, aber es kann helfen herauszufinden, welche Applikation
+ umgangen wurde. Das Log ist durch die in ihm enthaltene Information
+ n�tzlich, und je mehr Details es enth�lt, desto besser ist es im
+ Allgemeinen.
+ </simpara>
+ </sect3>
+ </sect2>
</sect1>
<sect1 id="security.errors">
@@ -510,14 +962,16 @@
Seite zusammengetragen hat, kann er versuchen, Variablen zu
�berschreiben bzw. zu modifizieren:
<example>
- <title>Angreifervariablen mit einer eigenen HTML Seite</title>
+ <title>Variablen mit einer eigenen HTML Seite angreifen</title>
<programlisting role="php">
-<form method="post" action="attacktarget?username=badfoo&password=badfoo">
-<input type="hidden" name="username" value="badfoo">
-<input type="hidden" name="password" value="badfoo">
-</form>
+<![CDATA[
+<form method="post" action="attacktarget?username=badfoo&password=badfoo">
+<input type="hidden" name="username" value="badfoo">
+<input type="hidden" name="password" value="badfoo">
+</form>
+]]>
</programlisting>
- </example>
+ </example>
</para>
<para>
Die normalerweise zur�ckgegebenen PHP Fehler k�nnen f�r den Entwickler
@@ -539,13 +993,15 @@
<example>
<title>Ausnutzen von gebr�uchlichen Debugging Variablen</title>
<programlisting role="php">
-<form method="post"
action="attacktarget?errors=Y&showerrors=1"&debug=1">
-<input type="hidden" name="errors" value="Y">
-<input type="hidden" name="showerrors" value="1">
-<input type="hidden" name="debug" value="1">
-</form>
+<![CDATA[
+<form method="post" action="attacktarget?errors=Y&showerrors=1"&debug=1">
+<input type="hidden" name="errors" value="Y">
+<input type="hidden" name="showerrors" value="1">
+<input type="hidden" name="debug" value="1">
+</form>
+]]>
</programlisting>
- </example>
+ </example>
</para>
<para>
Ungeachtet der Fehlerbehandlungsmethode f�hrt die M�glichkeit ein
@@ -599,20 +1055,22 @@
<example>
<title>Gef�hrliche Variablen mit E_ALL finden</title>
<programlisting role="php">
-<?php
+<![CDATA[
+<?php
if ($username) { // Vor Verwendung nicht initialisiert oder gepr�ft
- $good_login = 1;
+ $good_login = 1;
}
if ($good_login == 1) { // Wenn der obige Test fehlschl�gt, ist vor der
// Verwendung nicht initialisiert oder gepr�ft
fpassthru ("/highly/sensitive/data/index.html");
}
-?>
+?>
+]]>
</programlisting>
</example>
</para>
</sect1>
-
+
<sect1 id="security.registerglobals">
<title>Verwendung von Register Globals</title>
<para>
@@ -631,7 +1089,8 @@
<example>
<title>Ohne register_globals=off arbeiten</title>
<programlisting role="php">
-<?php
+<![CDATA[
+<?php
if ($username) { // kann vom User mit get/post/cookies �bermittelt werden
$good_login = 1;
}
@@ -639,19 +1098,22 @@
if ($good_login == 1) { // kann vom User mit get/post/cookies �bermittelt werden
fpassthru ("/highly/sensitive/data/index.html");
}
-?>
+?>
+]]>
</programlisting>
</example>
<example>
<title>Mit register_globals = off arbeiten</title>
<programlisting role="php">
-<?php
-if($HTTP_COOKIE_VARS['username']){
+<![CDATA[
+<?php
+if($HTTP_COOKIE_VARS['username']){
// kann nur von einem Cookie kommen
$good_login = 1;
fpassthru ("/highly/sensitive/data/index.html");
}
-?>
+?>
+]]>
</programlisting>
</example>
Dies weise genutzt ist es auch m�glich, pr�ventive Messungen
@@ -664,10 +1126,11 @@
<example>
<title>Entdecken einfacher Manipulationen von Variablen</title>
<programlisting role="php">
-<?php
-if ($HTTP_COOKIE_VARS['username'] &&
- !$HTTP_POST_VARS['username'] &&
- !$HTTP_GET_VARS['username'] ) {
+<![CDATA[
+<?php
+if ($HTTP_COOKIE_VARS['username'] &&
+ !$HTTP_POST_VARS['username'] &&
+ !$HTTP_GET_VARS['username'] ) {
// Durchf�hren anderer Checks, ob der Benutzername g�ltig ist...
$good_login = 1;
fpassthru ("/highly/sensitive/data/index.html");
@@ -676,10 +1139,11 @@
echo "Security violation, admin has been alerted.";
exit;
}
-?>
+?>
+]]>
</programlisting>
</example>
- Nat�rlich bedeutet ein einfaches Dektivieren von register globals nicht,
+ Nat�rlich bedeutet ein einfaches Deaktivieren von register_globals nicht,
dass Ihr Code nun automatisch sicher ist. Jeder Teil mit Daten sollte
auch auf andere Arten gepr�ft werden.
</para>
@@ -697,7 +1161,8 @@
<example>
<title>Gef�hrliche Verwendung von Variablen</title>
<programlisting role="php">
-<?php
+<![CDATA[
+<?php
// l�sche eine Datei aus dem Benutzer-Verzeichnis...
// oder vielleicht dem eines anderen Benutzers?
unlink ($evil_var);
@@ -710,7 +1175,8 @@
system ($evil_var);
exec ($evil_var);
-?>
+?>
+]]>
</programlisting>
</example>
Sie sollten Ihren Code immer sorgf�ltig kontrollieren, um eine
@@ -737,7 +1203,7 @@
Kann dies in Verbindung mit anderen Skripten in einer negativen
Art benutzt werden?
</simpara>
- </listitem>
+ </listitem>
<listitem>
<simpara>
Werden alle Transaktionen ausreichend geloggt?
@@ -764,6 +1230,11 @@
<sect1 id="security.hiding">
<title>Verstecken von PHP</title>
<para>
+ Generell ist Sicherheit durch Unklarheit eine der schw�chsten Formen von
+ Sicherheit. Aber in manchen F�llen ist ein klein Wenig mehr an extra
+ Sicherheit w�nschenswert.
+ </para>
+ <para>
Ein paar einfache Techniken helfen PHP zu Verstecken, um einen nach
Schw�chen in Ihrem System suchenden Angreifer m�glicherweise langsamer
Wenn Sie in Ihrer php.ini expose_php = off zu machen. setzen,
@@ -776,17 +1247,21 @@
So k�nnen Sie irref�hrende Dateierweiterungen verwenden:
<example>
<title>PHP als andere Sprache ausgeben</title>
- <programlisting role="php">
+ <programlisting role="apache-conf">
+<![CDATA[
# Lasse PHP Code wie andere Arten von Code aussehen
AddType application/x-httpd-php .asp .py .pl
+]]>
</programlisting>
</example>
Oder komplett unklar machen:
<example>
<title>Verwenden von unbekannten Typen f�r PHP Dateierweiterungen</title>
- <programlisting role="php">
+ <programlisting role="apache-conf">
+<![CDATA[
# Lasse PHP Code wie unbekannte Typen aussehen
AddType application/x-httpd-php .bop .foo .133t
+]]>
</programlisting>
</example>
Oder verstecken Sie ihn als html Code, was einen leichten
@@ -794,9 +1269,11 @@
Engine geparst werden:
<example>
<title>Verwenden von html Typen f�r PHP Dateierweiterungen</title>
- <programlisting role="php">
+ <programlisting role="apache-conf">
+<![CDATA[
# Lasse PHP code wie html aussehen
AddType application/x-httpd-php .htm .html
+]]>
</programlisting>
</example>
Um dies effektiv arbeiten zu lassen, m�ssen Sie Ihre PHP Dateien