addslashes() im Vergleich zu mysql_real_escape_string()

Letzten Monat habe ich die XSS-Sicherheitslücke von Google diskutiert und ein Beispiel bereitgestellt , das dies demonstriert . Ich hatte gehofft, hervorzuheben, warum die Konsistenz der Zeichencodierung wichtig ist, aber anscheinend geht die addslashes()Versus- mysql_real_escape_string()Debatte weiter. Die XSS-Schwachstelle von Google zu demonstrieren ist ziemlich einfach. Das Demonstrieren eines SQL-Injection-Angriffs, der immun ist, addslashes()ist etwas komplizierter, aber immer noch ziemlich einfach.

In GBK , 0xbf27ist kein gültiges Multi-Byte - Zeichen, sondern 0xbf5cist. Interpretierte Zeichen als Ein-Byte, 0xbf27wird 0xbf( ¿) , gefolgt von 0x27( ') und 0xbf5cist 0xbf( ¿) , gefolgt von 0x5c( \).

Wie hilft das? Wenn ich einen SQL-Injection-Angriff auf eine MySQL-Datenbank versuchen möchte, ist es eine Schande, einfache Anführungszeichen mit einem Backslash zu maskieren. Wenn Sie addslashes()jedoch verwenden, habe ich Glück. Alles, was ich tun muss, ist etwas wie einzufügen 0xbf27und addslashes()dies zu ändern 0xbf5c27, um ein gültiges Multi-Byte-Zeichen zu werden, gefolgt von einem einfachen Anführungszeichen. Mit anderen Worten, ich kann trotz Ihrer Flucht erfolgreich ein einziges Zitat einfügen. Das liegt daran, dass 0xbf5ces als ein einzelnes Zeichen interpretiert wird, nicht als zwei. Ups, da ist der Backslash.

Ich werde MySQL 5.0 und die mysqli- Erweiterung von PHP für diese Demonstration verwenden. Wenn Sie dies selbst ausprobieren möchten, stellen Sie sicher, dass Sie GBK verwenden. Ich habe gerade geändert /etc/my.cnf, aber das liegt daran, dass ich lokal teste:

  1. [client]
  2. default-character-set=GBK

Erstellen Sie eine Tabelle mit dem Namen users:

  1. CREATE TABLE users (
  2.     username VARCHAR(32) CHARACTER SET GBK,
  3.     password VARCHAR(32) CHARACTER SET GBK,
  4.     PRIMARY KEY (username)
  5. );

Das folgende Skript ahmt eine Situation nach, in der nur addslashes()(oder magic_quotes_gpc) verwendet wird, um die in einer Abfrage verwendeten Daten zu maskieren:

  1. <?php
  2.  
  3. $mysql = array();
  4.  
  5. $db = mysqli_init();
  6. $db->real_connect('localhost', 'myuser', 'mypass', 'mydb');
  7.  
  8. /* SQL Injection Example */
  9. $_POST['username'] = chr(0xbf) .
  10.                      chr(0x27) .
  11.                      ' OR username = username /*';
  12. $_POST['password'] = 'guess';
  13.  
  14. $mysql['username'] = addslashes($_POST['username']);
  15. $mysql['password'] = addslashes($_POST['password']);
  16.  
  17. $sql = "SELECT *
  18.         FROM users
  19.         WHERE username = '{$mysql['username']}'
  20.         AND password = '{$mysql['password']}'";
  21.  
  22. $result = $db->query($sql);
  23.  
  24. if ($result->num_rows) {
  25.     /* Success */
  26. } else {
  27.     /* Failure */
  28. }
  29.  
  30. ?>

Trotz der Verwendung von addslashes()kann ich mich erfolgreich anmelden, ohne einen gültigen Benutzernamen oder ein gültiges Passwort zu kennen. Ich kann die SQL-Injection-Sicherheitslücke einfach ausnutzen.

Um diese Art von Sicherheitsanfälligkeit zu vermeiden, verwenden Sie mysql_real_escape_string(), vorbereitete Anweisungen oder eine der wichtigsten Datenbankabstraktionsbibliotheken.

Diese Art von Angriff ist mit jeder Zeichencodierung möglich, bei der ein gültiges Multibyte-Zeichen mit der Endung 0x5c, da es addslashes()dazu gebracht werden kann, ein gültiges Multibyte-Zeichen zu erstellen, anstatt das folgende einfache Anführungszeichen zu maskieren. UTF-8 passt nicht zu dieser Beschreibung.

Error: No site found with the domain 'test.basti1012.bplaced.net' (Learn more)