mirror of
https://github.com/php/doc-de.git
synced 2026-03-24 07:12:15 +01:00
531 lines
21 KiB
XML
531 lines
21 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 7204e2dbb9b484c8b67bb5ad4a93fa1369c5b317 Maintainer: hholzgra Status: ready -->
|
|
<!-- Credits: tom -->
|
|
<chapter xml:id="security.database" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Datenbank-Sicherheit</title>
|
|
|
|
<simpara>
|
|
Heutzutage sind Datenbanken die Hauptkomponenten jeder webbasierten
|
|
Anwendung, aufgrund welcher Websites verschiedene dynamische Inhalte
|
|
anbieten können. Nachdem sensible 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 Verbindung
|
|
zur Datenbank herstellen, 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 <acronym>PHP</acronym> Ihre Datenbank nicht selbst
|
|
schützen kann. Die folgenden Abschnitte sind eine Einführung in die
|
|
Grundlagen, wie man innerhalb von <acronym>PHP</acronym>-Skripten auf
|
|
Datenbanken zugreift und diese manipuliert.
|
|
</simpara>
|
|
<simpara>
|
|
Behalten Sie diese einfache Regel im Hinterkopf: 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.
|
|
Ein gutes Design des Datenbankschemas und die Anwendung wird mit Ihren
|
|
größten Befürchtungen fertig.
|
|
</simpara>
|
|
|
|
<sect1 xml:id="security.database.design">
|
|
<title>Datenbanken entwerfen</title>
|
|
<simpara>
|
|
Der erste Schritt ist immer das Erstellen der Datenbank, außer Sie
|
|
wollen eine bereits existierende von Dritten 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>
|
|
Anwendungen sollten sich mit der Datenbank nie als deren Eigentümer oder
|
|
als ein Superuser verbinden, da diese Benutzer jede beliebige Abfrage
|
|
ausführen können, um &zb; das Schema zu modifizieren (&zb; Tabellen
|
|
löschen) oder den gesamten Inhalt löschen.
|
|
</simpara>
|
|
<simpara>
|
|
Sie können verschiedene Datenbanknutzer für jeden Aspekt Ihrer Anwendung
|
|
mit sehr limitierten Rechten auf Datenbankobjekte 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 Anwendung
|
|
kann.
|
|
</simpara>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="security.database.connection">
|
|
<title>Mit der Datenbank verbinden</title>
|
|
<simpara>
|
|
Sie sollten 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. Wird eines davon
|
|
verwendet, dann wird es für einen Angreifer schwierig, Ihre
|
|
Datenübertragung zu überwachen und Informationen über Ihre Datenbank zu
|
|
erlangen.
|
|
</simpara>
|
|
<!--simpara>
|
|
Wenn Ihr Datenbankserver über native SSL-Unterstützung verfügt, sollten
|
|
Sie die Verwendung von <link
|
|
linkend="ref.openssl">OpenSSL-Funktionen</link> bei der Kommunikation
|
|
zwischen <acronym>PHP</acronym> und Datenbank über SSL in Betracht
|
|
ziehen.
|
|
</simpara-->
|
|
</sect1>
|
|
|
|
<sect1 xml:id="security.database.storage">
|
|
<title>Verschlüsseltes Speichermodell</title>
|
|
<simpara>
|
|
SSL/SSH schützt zwar Daten, die vom Client zum Server übertragen werden,
|
|
aber SSL/SSH schützt keine dauernd in einer Datenbank gespeicherten
|
|
Daten. SSL ist ein "auf-der-Leitung"-Protokoll.
|
|
</simpara>
|
|
<simpara>
|
|
Hat ein Angreifer direkten Zugriff auf Ihre Datenbank (unter Umgehung des
|
|
Webservers), können gespeicherte sensible Daten aufgedeckt oder
|
|
zweckentfremdet werden, außer wenn die Informationen durch die Datenbank
|
|
selbst geschützt sind. Die Daten zu verschlüsseln ist eine gute Methode,
|
|
diese Gefahr zu mildern, doch bieten nur wenige Datenbanken diese Art der
|
|
Datenverschlüsselung an.
|
|
</simpara>
|
|
<simpara>
|
|
Der einfachste Weg, dieses Problem zu umgehen ist, erst einmal Ihr
|
|
eigenes Verschlüsselungspaket zu erstellen, und dieses dann in Ihren
|
|
<acronym>PHP</acronym>-Skripten zu nutzen. <acronym>PHP</acronym> kann
|
|
Ihnen in diesem Fall mit seinen verschiedenen Erweiterungen helfen, wie
|
|
&zb; <link linkend="book.openssl">OpenSSL</link> und
|
|
<link linkend="book.sodium">Sodium</link>, welche eine große Auswahl an
|
|
Verschlüsselungsalgorithmen 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 funktioniert.
|
|
</simpara>
|
|
|
|
<sect2 xml:id="security.database.storage.hashing">
|
|
<title>Hashing</title>
|
|
<simpara>
|
|
Im Fall von wirklich versteckten Daten, wenn deren unverschlüsselte
|
|
Darstellung nicht nötig ist (&dh; die nicht angezeigt werden sollen),
|
|
ist Hashing ebenfalls überlegenswert. Das bekannte Beispiel für Hashing
|
|
ist das Speichern des kryptographischen Hashes eines Passwortes in einer
|
|
Datenbank, anstatt des Passworts selbst.
|
|
</simpara>
|
|
<simpara>
|
|
Die <link linkend="ref.password">Passwort</link>-Funktionen bieten eine
|
|
bequeme Möglichkeit, sensible Daten zu hashen und mit diesen Hashes zu
|
|
arbeiten.
|
|
</simpara>
|
|
<simpara>
|
|
<function>password_hash</function> wird verwendet, um eine gegebene
|
|
Zeichenkette unter Verwendung des stärksten zurzeit verfügbaren
|
|
Algorithmus zu hashen, und <function>password_verify</function> prüft,
|
|
ob ein gegebenes Passwort mit dem Hash, der in der Datenbank gespeichert
|
|
ist, übereinstimmt.
|
|
</simpara>
|
|
<example>
|
|
<title>Hashen eines Passwortfeldes</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// Speichern des Passwort-Hashes
|
|
$query = sprintf("INSERT INTO users(name,pwd) VALUES('%s','%s');",
|
|
pg_escape_string($username),
|
|
password_hash($password, PASSWORD_DEFAULT));
|
|
$result = pg_query($connection, $query);
|
|
|
|
// Abfragen, ob der User das richtige Passwort übermittelt hat
|
|
$query = sprintf("SELECT pwd FROM users WHERE name='%s';",
|
|
pg_escape_string($username));
|
|
$row = pg_fetch_assoc(pg_query($connection, $query));
|
|
|
|
if ($row && password_verify($password, $row['pwd'])) {
|
|
echo 'Willkommen, ' . htmlspecialchars($username) . '!';
|
|
} else {
|
|
echo 'Authentifizierung für ' . htmlspecialchars($username) . 'fehlgeschlagen.';
|
|
}
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="security.database.sql-injection">
|
|
<title>SQL-Injection</title>
|
|
<simpara>
|
|
SQL-Injection ist eine Technik, bei der ein Angreifer Schwachstellen im
|
|
Anwendungscode ausnutzt, mit dem dynamische SQL-Abfragen erstellt werden.
|
|
Ein Angreifer kann sich Zugang zu besonders geschützten Bereichen der
|
|
Anwendung verschaffen, sämtliche Informationen aus der Datenbank abrufen,
|
|
vorhandene Daten manipulieren oder sogar gefährliche Befehle auf der
|
|
Systemebene des Datenbank-Hosts ausführen. Die Schwachstelle entsteht,
|
|
wenn Entwickler in ihren SQL-Anweisungen beliebige Eingaben miteinander
|
|
verknüpfen oder einfügen.
|
|
</simpara>
|
|
<para>
|
|
<example>
|
|
<title>
|
|
Die Ergebnisliste in mehrere Seiten aufsplitten ... und Superuser anlegen
|
|
(PostgreSQL)
|
|
</title>
|
|
<simpara>
|
|
Im folgenden Beispiel wird die Benutzereingabe direkt in die
|
|
SQL-Abfrage eingefügt, wodurch der Angreifer ein Superuser-Konto für
|
|
die Datenbank erlangen kann.
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$offset = $_GET['offset']; // Vorsicht, keine Validierung der Eingabe!
|
|
$query = "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
|
|
$result = pg_query($conn, $query);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Normale Benutzer klicken auf die 'nächste'- bzw. 'vorige'-Links, wo der
|
|
<varname>$offset</varname> in der <acronym>URL</acronym> enthalten ist.
|
|
Das Skript erwartet, dass der ankommende <varname>$offset</varname> eine
|
|
Zahl enthält. Was aber, wenn jemand versucht einzubrechen, indem er das
|
|
Folgende an die <acronym>URL</acronym> anhängt:
|
|
<informalexample>
|
|
<programlisting role="sql">
|
|
<![CDATA[
|
|
0;
|
|
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
|
|
select 'crack', usesysid, 't','t','crack'
|
|
from pg_shadow where usename='postgres';
|
|
--
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
In diesem Fall würde das Skript dem Angreifer einen Superuser-Zugang zur
|
|
Verfügung stellen. Beachten Sie, dass <literal>0;</literal> einen
|
|
gültigen Offset zur ursprünglichen Abfrage liefert, und sie beendet.
|
|
</para>
|
|
<note>
|
|
<para>
|
|
Es ist eine übliche Technik, den SQL-Parser mit dem SQL-Kommentarzeichen
|
|
<literal>--</literal> zu zwingen, den Rest der vom Entwickler
|
|
geschriebenen Abfrage zu ignorieren.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
Eine gangbare Methode, an Passwörter zu gelangen, ist, Ihre Seiten mit
|
|
den Suchergebnissen zu umgehen. 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
|
|
einem vorausgehenden Formular gesetzt werden, indem <literal>WHERE-,
|
|
ORDER BY-, LIMIT-</literal> und <literal>OFFSET</literal>-Klauseln in
|
|
<literal>SELECT</literal>-Statements angepasst werden. Wenn Ihre
|
|
Datenbank das <literal>UNION</literal>-Konstrukt unterstützt, kann der
|
|
Angreifer versuchen, eine komplette Abfrage an das Original anzuhängen,
|
|
um Passwörter aus einer beliebigen Tabelle aufzulisten. Es wird dringend
|
|
empfohlen, nur sichere Hashes von Passwörtern zu speichern und nicht die
|
|
Passwörter selbst.
|
|
<example>
|
|
<title>
|
|
Artikel auflisten ... und ein paar Passwörter (beliebiger Datenbankserver)
|
|
</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$query = "SELECT id, name, inserted, size FROM products
|
|
WHERE size = '$size'";
|
|
$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 role="sql">
|
|
<![CDATA[
|
|
'
|
|
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
|
|
--
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<para>
|
|
Auch <literal>UPDATE</literal>- und <literal>INSERT</literal>-Anweisungen
|
|
sind für derartige Angriffe anfällig.
|
|
<example>
|
|
<title>
|
|
Vom Zurücksetzen eines Passworts ... zum Erlangen von mehr Rechten
|
|
(beliebiger Datenbankserver)
|
|
</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$query = "UPDATE usertable SET pwd='$pwd' WHERE uid='$uid';";
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
Wenn ein böswilliger Benutzer den Wert <literal>' or uid
|
|
like'%admin%</literal> an <varname>$uid</varname> übermittelt, um das
|
|
Administrator-Passwort zu ändern, oder einfach <varname>$pwd</varname>
|
|
auf <literal>hehehe', trusted=100, admin='yes</literal> setzt, um mehr
|
|
Rechte zu erhalten, dann wird die Abfrage verdreht:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// $uid: ' or uid like '%admin%
|
|
$query = "UPDATE usertable SET pwd='...' WHERE uid='' or uid like '%admin%';";
|
|
|
|
// $pwd: hehehe', trusted=100, admin='yes
|
|
$query = "UPDATE usertable SET pwd='hehehe', trusted=100, admin='yes' WHERE
|
|
...;";
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</informalexample>
|
|
</para>
|
|
<simpara>
|
|
Obwohl es offensichtlich ist, dass ein Angreifer zumindest ein wenig
|
|
Kenntnis der genutzten Datenbankarchitektur besitzen muss, um einen
|
|
erfolgreichen Angriff durchzuführen, ist es oft sehr einfach, diese
|
|
Informationen zu erhalten. Der Code kann &zb; Teil einer
|
|
Open-Source-Software sein und öffentlich zugänglich sein. Diese
|
|
Informationen können auch durch Closed-Source-Code preisgegeben werden -
|
|
selbst wenn dieser kodiert, verschleiert oder kompiliert ist - und sogar
|
|
durch Ihren eigenen Code durch die Anzeige von Fehlermeldungen. Andere
|
|
Methoden beinhalten die Nutzung typischer Tabellen- und Spaltennamen. Ein
|
|
Login-Formular etwa, dass eine Tabelle 'users' mit den Spaltennamen 'id',
|
|
'username' und 'password' nutzt.
|
|
</simpara>
|
|
<para>
|
|
<example>
|
|
<title>Angriff auf das Betriebssystem des Datenbank-Hosts (MSSQL-Server)</title>
|
|
<simpara>
|
|
Ein erschreckendes Beispiel, wie der Zugriff auf Befehle auf
|
|
Betriebssystemebene bei manchen Datenbankservern erfolgen kann:
|
|
</simpara>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$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> auf <varname>$prod</varname>
|
|
überträgt, wird <varname>$query</varname> zu:
|
|
<informalexample>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
$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 im Batch aus, inklusive eines
|
|
Kommandos um einen neuen Benutzer zur Datenbank der lokalen Konten
|
|
hinzuzufügen. Würde diese Anwendung 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, aber das bedeutet nicht, dass ein ähnlicher Angriff auf andere
|
|
Produkte unmöglich wäre. Ihr Datenbankserver könnte auf andere Weise
|
|
genauso verwundbar sein.
|
|
</para>
|
|
</note>
|
|
<para>
|
|
<mediaobject>
|
|
<alt>Ein lustiges Beispiel für die Problematik der SQL-Injection</alt>
|
|
<imageobject>
|
|
<imagedata fileref="de/security/figures/xkcd-bobby-tables.png" format="PNG"/>
|
|
</imageobject>
|
|
<caption>
|
|
<simpara>
|
|
Bild mit freundlicher Genehmigung von
|
|
<link xlink:href="&url.xkcd;327">xkcd</link>
|
|
</simpara>
|
|
</caption>
|
|
</mediaobject>
|
|
</para>
|
|
|
|
<sect2 xml:id="security.database.avoiding">
|
|
<title>Techniken zur Vermeidung</title>
|
|
<para>
|
|
Um das Risiko einer SQL-Injection zu verringern, wird empfohlen, alle
|
|
Daten über vorbereitete Anweisungen zu binden. Die Verwendung von
|
|
parametrisierten Abfragen ist zwar nicht ausreichend, um SQL-Injections
|
|
vollständig zu verhindern, aber es ist der einfachste und sicherste Weg,
|
|
um Daten für SQL-Anweisungen bereitzustellen. Alle dynamischen
|
|
Datenliterale in <literal>WHERE</literal>-, <literal>SET</literal>- und
|
|
<literal>VALUES</literal>-Klauseln müssen durch Platzhalter ersetzt
|
|
werden. Die eigentlichen Daten werden bei der Ausführung gebunden und
|
|
getrennt vom SQL-Befehl gesendet.
|
|
</para>
|
|
<para>
|
|
Die Parameterbindung kann nur für Daten verwendet werden. Andere
|
|
dynamische Teile der SQL-Abfrage müssen gegen eine bekannte Liste
|
|
zulässiger Werte gefiltert werden.
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Ein sicherer Weg, eine Abfrage zu erstellen</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
|
|
// Der dynamische SQL-Teil wird anhand der erwarteten Werte validiert
|
|
$sortingOrder = $_GET['sortingOrder'] === 'DESC' ? 'DESC' : 'ASC';
|
|
$productId = $_GET['productId'];
|
|
// Das SQL wird mit einem Platzhalter vorbereitet
|
|
$stmt = $pdo->prepare("SELECT * FROM products WHERE id LIKE ? ORDER BY price {$sortingOrder}");
|
|
// Der Wert wird mit LIKE-Wildcards versehen
|
|
$stmt->execute(["%{$productId}%"]);
|
|
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<simpara>
|
|
Vorbereitete Anweisungen werden von
|
|
<link linkend="pdo.prepared-statements">PDO</link>,
|
|
<link linkend="mysqli.quickstart.prepared-statements">MySQLi</link> und
|
|
anderen Bibliotheken angeboten.
|
|
</simpara>
|
|
|
|
<simpara>
|
|
Angriffe durch SQL-Injection basieren hauptsächlich darauf, Code
|
|
auszunutzen, der nicht unter dem Aspekt der Sicherheit geschrieben
|
|
wurde. Vertrauen Sie niemals einer Eingabe, insbesondere nicht von der
|
|
Clientseite, selbst wenn sie von einer Auswahlbox, einem versteckten
|
|
Eingabefeld oder einem Cookie kommt. Das erste Beispiel zeigt, dass eine
|
|
so einfache Abfrage zu einer Katastrophe führen kann.
|
|
</simpara>
|
|
|
|
<para>
|
|
Eine umfassende Verteidigungsstrategie umfasst mehrere bewährte
|
|
Programmierpraktiken:
|
|
<itemizedlist>
|
|
<listitem>
|
|
<simpara>
|
|
Stellen Sie nie als Superuser oder Eigentümer 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 die gegebene Eingabe dem erwarteten Datentyp
|
|
entspricht. <acronym>PHP</acronym> bietet eine große Auswahl an
|
|
Funktionen zum Validieren der Eingaben, von den einfachsten unter
|
|
<link linkend="ref.var">Variablenfunktionen</link> und
|
|
<link linkend="ref.ctype">Character-Type-Funktionen</link> (&zb;
|
|
<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>
|
|
<simpara>
|
|
Wenn die Anwendung eine numerische Eingabe erwartet, sollten Sie die
|
|
Daten mittels <function>ctype_digit</function> überprüfen, den Typ
|
|
stillschweigend mittels <function>settype</function> ändern oder
|
|
deren numerische Darstellung mittels <function>sprintf</function>
|
|
verwenden.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Unterstützt die Datenbank-Ebene das Binden von Variablen nicht, so
|
|
maskieren Sie jede nichtnumerische Benutzereingabe, welche zur
|
|
Datenbank weitergereicht werden soll, mit der jeweiligen
|
|
datenbankspezifischen Maskierungsfunktion für Zeichenketten (&zb;
|
|
<function>mysql_real_escape_string</function>,
|
|
<function>sqlite_escape_string</function> usw.). Generische Funktionen
|
|
wie <function>addslashes</function> sind nur in einer sehr
|
|
spezifischen Umgebung nützlich (&zb; MySQL mit einem
|
|
SingleByte-Zeichensatz bei deaktiviertem
|
|
<varname>NO_BACKSLASH_ESCAPES</varname>), sodass es besser ist, diese
|
|
zu vermeiden.
|
|
</simpara>
|
|
</listitem>
|
|
<listitem>
|
|
<simpara>
|
|
Geben Sie um keinen Preis irgendwelche datenbankspezifischen
|
|
Informationen aus, speziell über das Schema. Siehe auch
|
|
<link linkend="security.errors">Fehlerbehandlung</link> und
|
|
<link linkend="ref.errorfunc">Fehlerbehandlungsfunktionen</link>.
|
|
</simpara>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</para>
|
|
|
|
<simpara>
|
|
Abgesehen davon profitieren Sie von einer Protokollierung der Abfragen
|
|
entweder in Ihrem Skript oder durch die Datenbank selbst, falls sie
|
|
Protokollierung unterstützt. Klar, die Protokollierung kann keinen
|
|
schädlichen Versuch verhindern, aber sie kann helfen herauszufinden,
|
|
welche Anwendung umgangen wurde. Das Protokoll ist nicht von sich aus
|
|
nützlich, aber durch die in ihm enthaltenen Informationen, und je mehr
|
|
Details es enthält, desto besser ist es im Allgemeinen.
|
|
</simpara>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|