Anzeige
Tutorialbeschreibung

Stopp Mysql-Injections

Stopp Mysql-Injections

Eine Eingabezeile (Textareas etc.) findet man ‚an jeder Ecke’ im Internet, viele von ihnen greifen auf die Mysql-Datenbank zu, indem z.B.: Abfragen (Mysql-Queries) des Users (z.B.: in Site-Suchmaschinen, Gästebucheinträge, Forenbeiträge etc.) eingegeben werden. Natürlich müssen das nicht immer ‚harmlose’ Eingaben sein, sondern könnte (mit den ‚richtigen’ Eingaben) auch ein Hacker-Angriff auf Ihre Datenbank durchgeführt werden. Weiterführende Literatur zu solchen Hackermethoden, z.B.: http://www.php-homepage.de/manual/security.database.sql-injection.php.


Um diese Gefahr zu Minimieren gibt es mehrere Möglichkeiten: Eine Positiv- eine Negativ- formulierte und jene mit der Funktion

addslashes()

http://at.php.net/manual/de/function.addslashes.php

und/oder mysql_real_escape_string()

http://at.php.net/manual/de/function.mysqli-real-escape-string.php

Grundsätzlich sind alle Methoden gleichwertig, sie haben alle den einen oder anderen Vorteil/Nachteil. Im Ergebnis bleibt es daher eine ‚Geschmacksfrage’, welche Methode man anwendet!

Mir gefällt die Negativlistenmethode sehr gut, nach dem Code werde ich etwa sagen, warum, soweit es den Umgang mit dem folgenden Snippet berührt.

Nun zum Code, diesmal nur einer: (TIPP: fassen Sie ihn in einer Datei – z.B. checker.php – zusammen, das hat Vorteile bei der Benutzung!)

<?if(checkData($_POST, $_GET, $_COOKIE, $sonstEineVariable))

{
  echo '';
}

else
{
  die ('<body  bgcolor="#FDED7B" link="#0951FC" alink="#0951FC" vlink="#0951FC" style="color: #0951FC; font-family: Verdana"><br><br><br><br><center><b>Bitte geben Sie nur Buchstaben und Worte ein, die nicht SQL-Statements sind, Danke!</b><br>Sie haben sicher nur irrtümlich z.B.: # oder SELECT usw. eingetippt!</font><br><br><br><br><a href="javascript:history.back()"><img src="new.gif" border="0"></a></center>');
}

//und hier die funktion:

function checkData()

 {
  // Werte, die überprüft werden sollen, können hier in das array $check gespeichert werden

  $check = array();
  $check[] = "SELECT";
  $check[] = "DROP";
  $check[] = "INSERT";
  $check[] = "TABLE";
  $check[] = "CREATE";
  $check[] = "DELETE";
  $check[] = "UPDATE";
  $check[] = "WHILE";
  $check[] = "#";
  $check[] = "=";
  $check[] = "BETWEEN";
  $check[] = "OR";
  $check[] = "AND";
  $check[] = ":";
  $check[] = ")";
  $check[] = "(";
  $check[] = """;
  $check[] = "//";

  // Freigabevariable, wird auf false gesetzt, wenn einer der oben genannten Begriffe im String ist

  $freigabe = true;

  if(func_num_args() == 0)

  {
   echo("Keine Daten übergeben.<br />n");
  }

  else

  {
   $i = 0;
   while($i < func_num_args())

   {
    if(is_array(func_get_arg($i)))
    {

     $array = func_get_arg($i);
     foreach($array AS $key => $wert)
     {
      $data[$i.$key] = $wert;
     }
    }

    else
    {
     $data[$i] = func_get_arg($i);
    }

    $i++;
   }

  }

  // Hier wird geprüft, ob eines der Wörter im Array String im Datastring vorhanden ist

  foreach($data AS $dataValue)

  {
   foreach($check AS $checkValue)
   {
    if(preg_match_all("/".$checkValue."/si", $dataValue, $error))
    {
     $freigabe = false;
    }

   }

  }

  // Wenn alles in ordnung ist, wird true zurückgegeben, ansonsten false

  if($freigabe)

  {
   return true;
  }

  else
  {
   return false;
  }

 }

?>

Diese Variante gefällt mir unter anderem deshalb gut, weil der Code

  1. äußerst einfach zu verwenden ist, man muss nur checker.php in jene Datei includieren, die die Mysql-Query macht (oberhalb davon) … und klappt schon, ein kleines Beispiel, wie es geht:    

<?

   include_once '../../connect.php';
   include_once 'checker.php';
   $query = mysql_query("SELECT * FROM hpx WHERE inhalt LIKE '%".$inhalt."%';");
   $ausgabe="";
   while($row = mysql_fetch_array($query)) {… ?>

  1. man beliebig den Katalog der gefährlichen Befehle verändern kann (z.B.: nur in dieser Liste $check[] = … einen neuen Begriff hinzufügen!!)

Mit diesem Code ist Ihre Datenbankapplikation sicher, soweit es überhaupt absolute Sicherheit gibt.


Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von testuserxc
  • 15.11.2010 - 21:27

hmmm, der ansatz ist gut, ausführung zu kompliziert.
ja @webmastersworld - ich habe deinen kommentar gelesen. der workshop ist halt "veraltet"

Portrait von Thore14
  • 28.05.2010 - 16:43

Also mein Server sagt:
Warning: preg_match_all() [function.preg-match-all]: Compilation failed: unmatched parentheses at offset 0 in /***ck.php on line **
Kann mir jemand Helfen?

Portrait von GrafiKman
  • 11.01.2010 - 12:45

Danke war gut!!!!!!!!!!!!!!!!!

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 22.10.2009 - 17:57

sehr gut! Hat mir schon geholfen :)
Vielen dank!

Portrait von Snaq
  • 13.07.2009 - 21:44

ein sehr gutes Tutorial

Portrait von joelschmid
  • 15.04.2009 - 23:11

Dieser Gefahr war ich mir gar nicht bewusst! :O

Portrait von mfgleo
  • 29.10.2008 - 18:02

Die Idee ist zwar gut, aber leider sehr umständlich. Versuche doch mal htmlentities().

Link: <a href="http://de3.php.net/manual/de/function.htmlentities.php"> http://de3.php.net/manual/de/function.htmlentities.php</a> [de3.php.net]

Portrait von webmastersworld
  • 16.04.2009 - 09:03

das tut stammt aus 7/2006 ==> heute gehts einfacher sql-injections abzuwehren, allerdings werden htmlentities() allein die gefahr kaum bannen. diese funktion wehrt ja nur 'html-wirksamkeit' des eingegebenen html-codes ab; das wäre zu wenig, heute müssten schon die variablen, die übergeben werden mit z.b mit (addslashes($_POST/$_GET['variable'])) geschützt werden, dann würde es das ziel der abwehr von sql-injections erreichen :-) thx für deinen kommentar :-)

Portrait von akleur
  • 19.05.2008 - 11:13

Ich muss leider sagen, ich finde diesen Umsetzungvorschlag nicht gut, eher sogar verwirrend für Laie...

- Viel zu langer Code
- Man darf noch nicht mal solche zeichen wie ) schreiben (und wo bleiben die Smilies?) oder auch englische Begriffe wie AND
- Es wurde nur die Grossgeschriebene Variante berücksichtigt (obwohl SQL-Abfrage auch klein geschrieben werden können)

addslashes() und/oder mysql_real_escape_string() ist einfach die beste Lösung!!!

Portrait von webmastersworld
  • 16.04.2009 - 09:07

lies mal meine antwort, die ich mfgleo gab, insbesondere den entstehungszeitpunkt des tut (übergang PHP3 > PHP4 in der praxis), dann wird auch klar, warum das tut ursprünglich positiv bewertet wurde und erst ab etwa 2008 schlechte kritik 'einfährt'. Aber dennoch danke für deinen kommentar, auch mal den zeitkontext eines tut zu checken, ist kein uninteressantes detail ;-)

Portrait von evolotion
  • 07.05.2008 - 14:07

1. ein # kann aus versehen mal passieren, würde mich als User nerven.
2. ist es nicht auch möglich das Select usw. auch in Hexadezimal ect. zu schreiben? (Letztens hat heise berichtet eine AJAX seite wurde mit morsecodes gehackt). Daraus würde folgen dieser Test ist leicht zu umgehen (wenn man es drauf ansetzt findet man immer eine Lücke im Server)

Portrait von webmastersworld
  • 07.05.2008 - 14:13

Du sagst es, es gibt KEINE ABSOLUTE sicherheit, insoweit wirds IMMER eine möglichkeit geben, server zu hacken; letztlich kann man immer mit einem brute-force-programm das logon eines jeden servers, bei entsprechendem zeit- und rechnereinsatz 'knacken' :-)

Portrait von hdfan
  • 07.05.2008 - 13:19

Ich habs bei mir mal eingebaut. Es zereist mir die ganze Seite und gibt Fehlermeldungen.
Sovile ich weiß muß diese Variable escapes werden.
$check[] = """;
so:
$check[] = '"';

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 31.03.2008 - 07:38

Vielen Dank, genau das was ich gesucht habe

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 12.02.2008 - 20:32

sowas hab ich schon lang gesucht *g* danke vielmals!

Portrait von Sturmrider
  • 11.02.2008 - 22:58

soweit ich das auf den ersten Blick sehe ist die obige (ziemlich langsame und rechenaufwändige) Umsetzung ziemlich überflüssig, wenn es doch bereits Funktionen wie mysql_real_escape_string() htmlentities() und Co direkt in PHP implementiert (ist schneller!) gibt. Hinzu kommt, dass sie sich nun seit mehreren PHP-Versionen halten und bisher immer sicher waren.
Hinzu kommt, dass obige Funktion ausschließt, dass jemand z.B. auch einen Text in Englisch schreibt. Dann kommt die Tatsache dazu, dass der String nur nach großgeschriebenen Worten durchsucht wird. SQL-Code lässt sich jedoch auch klein schrieben ;)
Dann wird das Zeichen ' nicht ausgeschlossen (was eines der Gefährlichsten darstellt!)
Dann wird vergessen, dass man über $_GET auch injections starten kann -> einfach leerzeichen durch %20 ersetzen und schon sieht der String ganz anders aus...ganz zu schweigen von Cross-Site-Scripting-Attacks (CSS-Attacks) die mit obiger Funktion nicht ausgeschlossen werden können...
Also alles in allem halte ich obige Funktion für absoluten Müll (sry, dass ich das so rüde ausdrücke)
angenommene $_GET, $_POST und $_COOKIE anfragen sollten IMMER mit htmlentities() -> sichert auch gegen CSS-Attacks oder zumindest mysql_real_escape_string() abgesichert sein.
Zu guter letzt wurde oben in der Funktion ein Punkt vollkommen vergessen: $_SERVER -> auch hierüber lassen sich Angriffe starten -> z.B. über einen gefälschten Referer.
Also nehmt Abstand von der obigen Funktion, sie ist gemeingefährlich!!!!

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 01.10.2007 - 09:45

Schönes Script. So ähnlich habe ich es auch umgesetzt. Nach Lesen deines Scriptes werde ich aber meines noch um die ganzen SQL-Statements ergänzen.

Thx, Headsick

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 05.03.2007 - 00:03

Sehr informativ! Verstehen tun ich es doch nicht!

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 04.02.2007 - 13:40

vielen Dank

...und wieder etwas gelernt

Portrait von the_real_didi
  • 31.01.2007 - 13:24

gutes tutotrial. scheint ganz gut zu funktionieren.

x
×
×