Heim >Backend-Entwicklung >PHP-Tutorial >Einführung in Methoden zur Verhinderung von SQL-Injection-Angriffen in PHP

Einführung in Methoden zur Verhinderung von SQL-Injection-Angriffen in PHP

不言
不言nach vorne
2018-11-24 15:17:362376Durchsuche

Der Inhalt dieses Artikels ist eine Einführung in die Methode zum umfassenden Blockieren von SQL-Injection-Angriffen. Ich hoffe, dass er für Freunde hilfreich ist Du hast geholfen.

Es mag viele verschiedene Arten von Angriffsmotivationen geben, aber auf den ersten Blick scheint es, dass es noch mehr gibt. Dies trifft sehr zu, wenn ein böswilliger Benutzer eine Möglichkeit findet, mehrere Abfragen durchzuführen.

Wenn Ihr Skript eine SELECT-Anweisung ausführt, kann der Angreifer die Anzeige jeder Datensatzzeile in einer Tabelle erzwingen – indem er eine Bedingung wie „1=1“ in die WHERE-Klausel einfügt, wie unten gezeigt (mit dem eingefügten Teil in Fettschrift):

SELECT * FROM wines WHERE variety = 'lagrein' OR 1=1;'

Wie wir bereits erwähnt haben, kann dies an sich eine nützliche Information sein, da sie die allgemeine Struktur der Tabelle offenlegt (was mit einem normalen Datensatz nicht erreicht werden kann). und Aufzeichnungen, die möglicherweise vertrauliche Informationen zu enthalten scheinen.

Ein Update-Befehl stellt möglicherweise eine direktere Bedrohung dar. Indem ein Angreifer andere Merkmale in die SET-Klausel einfügt, kann er jedes Feld im Datensatz ändern, der aktualisiert wird, wie zum Beispiel das folgende Beispiel (in dem der injizierte Teil fett dargestellt ist):

UPDATE wines SET type='red','vintage'='9999' WHERE variety = 'lagrein'

Pass Add a Wahre Bedingung wie 1=1 für die WHERE-Klausel einer Aktualisierungsanweisung. Dieser Änderungsbereich kann auf jeden Datensatz erweitert werden, wie im folgenden Beispiel (in dem der injizierte Teil fett dargestellt ist):

UPDATE wines SET type='red','vintage'='9999 WHERE variety = 'lagrein' OR 1=1;'

Der vielleicht gefährlichste Befehl ist DELETE – das kann man sich leicht vorstellen. Die Injektionstechnik ist die gleiche wie die, die wir bereits gesehen haben – durch Modifizierung der WHERE-Klausel, um den Umfang der betroffenen Datensätze zu erweitern, wie im folgenden Beispiel (wobei der injizierte Teil fett dargestellt ist):

DELETE FROM wines WHERE variety = 'lagrein' OR 1=1;'

Mehrere Abfrageinjektionen

Mehrere Abfrageinjektionen erhöhen den potenziellen Schaden, den ein Angreifer verursachen kann – indem sie die Aufnahme mehrerer destruktiver Anweisungen in eine einzige Abfrage ermöglichen. Bei Verwendung einer MySQL-Datenbank kann ein Angreifer dies leicht erreichen, indem er ein unerwartetes Stoppzeichen in die Abfrage einfügt – nun markiert ein eingefügtes Anführungszeichen (einfaches oder doppeltes) das Ende der gewünschten Variablen. Beenden Sie dann den Befehl mit einem Semikolon. Jetzt kann am Ende des jetzt gestoppten ursprünglichen Befehls ein zusätzlicher Angriffsbefehl hinzugefügt werden. Die letzte destruktive Abfrage könnte so aussehen:

SELECT 
 FROM wines WHERE variety = 'lagrein';GRANT ALL ON 
.* TO 'BadGuy@%' IDENTIFIED BY 'gotcha';'

Diese Injektion erstellt einen neuen Benutzer BadGuy und erteilt ihm Netzwerkrechte (alle Rechte für alle Tabellen); unter anderem wird das „ominöse“ Passwort hinzugefügt zu diesem einfachen SELECT-Satz. Wenn Sie unserem Rat in einem früheren Artikel gefolgt sind und die Berechtigungen des Prozessbenutzers stark eingeschränkt haben, sollte dies nicht funktionieren, da der Webserver-Daemon nicht mehr über die von Ihnen entzogenen GRANT-Berechtigungen verfügt. Aber theoretisch könnte ein solcher Angriff BadGuy freie Hand geben, mit Ihrer Datenbank zu tun, was er will.

Die Schlussfolgerung, ob eine solche Mehrfachabfrage vom MySQL-Server verarbeitet wird, ist nicht eindeutig. Einige der Gründe können auf unterschiedliche Versionen von MySQL zurückzuführen sein, die meisten liegen jedoch in der Art und Weise, wie mehrere Abfragen vorhanden sind. Das Überwachungsprogramm von MySQL lässt eine solche Abfrage vollständig zu. Die häufig verwendete MySQL-GUI-phpMyAdmin kopiert alle vorherigen Inhalte vor der endgültigen Abfrage und führt nur dies aus.

Die meisten Mehrfachabfragen innerhalb eines Injektionskontexts werden jedoch von der MySQL-Erweiterung von PHP verwaltet. Glücklicherweise ist die Ausführung mehrerer Anweisungen in einer Abfrage standardmäßig nicht möglich; der Versuch, zwei Anweisungen auszuführen (wie die oben gezeigte Injektion), führt lediglich zu einem Fehler – es werden keine Fehler gesetzt und es werden keine Ausgabeinformationen generiert. Obwohl PHP in diesem Fall sein Standardverhalten nur „regelmäßig“ implementiert, kann es Sie tatsächlich vor den meisten einfachen Injektionsangriffen schützen.

Die neue MySQLi-Erweiterung in PHP5 (siehe http://php.net/mysqli) unterstützt wie MySQL nicht von Natur aus mehrere Abfragen, bietet jedoch eine mysqli_multi_query()-Funktion, die Sie bei der Durchführung mehrerer Abfragen unterstützt - wenn Sie das wirklich wollen.
Allerdings ist die Situation mit SQLite – der einbettbaren SQL-Datenbank-Engine, die mit PHP5 gebündelt ist (siehe http://sqlite.org/ und http://php.net/sqlite) aufgrund seiner Benutzerfreundlichkeit noch schlimmer Die Anwendung hat die Aufmerksamkeit vieler Benutzer auf sich gezogen. In einigen Fällen lässt SQLite solche Abfragen mit mehreren Anweisungen standardmäßig zu, da die Datenbank Batch-Abfragen optimieren kann, insbesondere die Batch-INSERT-Anweisungsverarbeitung, was sehr effizient ist.

Wenn die Abfrageergebnisse jedoch von Ihrem Skript verwendet werden (z. B. wenn Sie einen SELECT-Satz zum Abrufen von Datensätzen verwenden), lässt die Funktion sqlite_query() nicht die Ausführung mehrerer Abfragen zu.

3. SQL-Injection-Schwachstelle im INVISION Power BOARD

Invision Power Board ist ein bekanntes Forensystem. Am 6. Mai 2005 wurde im Anmeldecode eine SQL-Injection-Sicherheitslücke entdeckt. Es wurde von James Bercegay von GulfTech Security Research entdeckt.

Diese Anmeldeabfrage sieht so aus:

$DB->query("SELECT * FROM ibf_members WHERE id=$mid AND password='$pid'");

Mitglieds-ID-Variable $mid und Passwort-ID-Variable $pid werden von der Funktion my_cookie() mithilfe der folgenden zwei Codezeilen abgerufen:

$mid = intval($std->my_getcookie('member_id'));$pid = $std->my_getcookie('pass_hash');

Hier ruft die Funktion my_cookie() die angeforderten Variablen aus dem Cookie mithilfe des folgenden Satzes ab:

return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]);

【留意】从该cookie回来的值底子没有被处理。虽然$mid在运用于查询之前被强制转换成一个整数,可是$pid却保持不变。因而,它很容易遭受咱们前面所评论的注入类型的进犯。

因而,经过以如下方法修正my_cookie()函数,这种软弱性就会露出出来:

if ( ! in_array( $name,array('topicsread', 'forum_read','collapseprefs') ) )
{
return $this->
clean_value(urldecode($_cookie[$ibforums->vars['cookie_id'].$name]));
}
else
{
return urldecode($_cookie[$ibforums->vars['cookie_id'].$name]);
}

经过这样的改正之后,其间的要害变量在"经过"全局clean_value()函数后被回来,而其它变量却未进行检查。
现在,已然咱们大致了解了什么是SQL注入,它的注入原理以及这种注入的软弱程度,那么接下来,让咱们探讨如何有用地防备它。幸亏,PHP为咱们供给了丰厚的资源,因而咱们有充沛的信心预言,一个经细心地彻底地运用咱们所引荐的技能构建的应用程序将会从你的脚本中底子上消除任何或许性的SQL注入-经过在它或许形成任何损坏之前"整理"你的用户的数据来完成。

Das obige ist der detaillierte Inhalt vonEinführung in Methoden zur Verhinderung von SQL-Injection-Angriffen in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:segmentfault.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen