Sub: PHP / MySQL Sicherheit

Hallo an alle Leser,

ich beschäftige mich zurzeit mit dem Thema PHP Datenbankabfragen, Datenaktualisierung etc. pp. und versuche mich mit deren Sicherheitsvorkehrungen auseinanderzusetzen.

Dass man GET / POST / REQUEST / SESSION Variablen und Werte niemals ungeprüft zur Datenbank weiterleiten soll weiß ich also bereits!
magic_quotes_gpc und register_globals sind von Strato Standardmäßig ausgeschaltet und die per POST übergebenen Variablen werden mit drei Arrays (alle die dürfen Array, Pflicht Array und Kann Array) verglichen und falls Unstimmigkeiten existieren, wird das Script sofort abgebrochen. Auch prüfe ich ob in den übergebenen Werten unerlaubte Zeilenumbrüche vorhanden sind.

Jetzt zu meinen Verständnisproblemen;

1. Da ich bei DB Abfragen nicht nur mit Zahlen (ID) arbeite sondern auch mit Buchstaben / Wörter, weiß ich nicht wie ich diese behandeln soll zwecks einer Prüfung. Für eine Prüfung auf Zahlen bietet sich ja regelrecht is_numeric an, was mache ich aber bei Wörter (Wörter mit Apostroph wie Bistro's), wäre da preg_match Sinnvoll oder habt Ihr einen besseren Vorschlag?

Beispiel:
if (preg_match('#[^a-z ßäöüÄÖÜàèòéáóúù-]#i', $_POST['koi']))
  {
    header("Location: $abbruch");
    exit();
  }

2. Aus Testzwecken frage ich die Datenbank momentan so ab:

$sich = "Op's";

$abfrage="SELECT ID,Kategorie,Sich,Event,Bild FROM 01_daten WHERE Sich LIKE BINARY'".mysql_real_escape_string($sich)."' AND Kategorie = '".mysql_real_escape_string($_POST[‘koi’])."' AND Event != '".mysql_real_escape_string($_POST[‘eve’])."' ORDER BY Event ASC";

Ist das mysql_real_escape_string so richtig gesetzt oder wäre nachfolgendes Beispiel besser:

$sich = "Op's";
$sich = mysql_real_escape_string($sich);
$kategorie = mysql_real_escape_string($_POST['koi']);
$event = mysql_real_escape_string($_POST['eve']);

$abfrage="SELECT ID,Kategorie,Sich,Event,Bild FROM 01_daten WHERE Sich LIKE BINARY'".$sich."' AND Kategorie = '".$kategorie."' AND Event != '".$event."' ORDER BY Event ASC";

Ich bedanke mich vorab für alle Antworten.

Gruß,

Sub

  1. und falls Unstimmigkeiten existieren, wird das Script sofort abgebrochen.

    Das hört sich nicht "nett" gegenüber dem Endbenutzer an.

    1. Da ich bei DB Abfragen nicht nur mit Zahlen (ID) arbeite sondern auch mit Buchstaben / Wörter, weiß ich nicht wie ich diese behandeln soll zwecks einer Prüfung.

    Kontextgerecht ;)

    Für eine Prüfung auf Zahlen bietet sich ja regelrecht is_numeric an,

    Nicht wirklich - "deadbeef" ist z.B. numeric.

    was mache ich aber bei Wörter (Wörter mit Apostroph wie Bistro's), wäre da preg_match Sinnvoll oder habt Ihr einen besseren Vorschlag?

    Entsprechend maskieren, wie schon gesagt - kontextgerecht behandeln. PHP sieht hierfür eben mysql_real_escape_string() vor.

    1. Aus Testzwecken frage ich die Datenbank momentan so ab:

    $sich = "Op's";

    $abfrage="SELECT ID,Kategorie,Sich,Event,Bild FROM 01_daten WHERE Sich LIKE BINARY'".mysql_real_escape_string($sich)."' AND Kategorie = '".mysql_real_escape_string($_POST[‘koi’])."' AND Event != '".mysql_real_escape_string($_POST[‘eve’])."' ORDER BY Event ASC";

    Was hat's mit BINARY aufsich?

    Warum $_POST[‘eve’] und nicht $_POST['eve']?

    Ist das mysql_real_escape_string so richtig gesetzt oder wäre nachfolgendes Beispiel besser:

    $sich = "Op's";
    $sich = mysql_real_escape_string($sich);
    $kategorie = mysql_real_escape_string($_POST['koi']);
    $event = mysql_real_escape_string($_POST['eve']);

    Besser nicht, aber übersichtlicher. Für das gibt es aber bereits vorgefertigtigte Funktionen (sprintf() z.B.).

    1. Hi suit,

      vielen Dank für Deine Antwort.

      Das hört sich nicht "nett" gegenüber dem Endbenutzer an.

      So verhindere ich dass das Script unerwartete Parameter erhält und auch dass Pflichtfelder fehlen. Geblockter Endbenutzer wäre in diesem fall ja eh nur derjenige (z.B. ein Bot) der mit falschen Formular versucht auf mein Script zuzugreifen! Zu solchen Endbenutzern müssen wir doch nicht nett sein, oder doch? ;-)

      Siehe hierzu bitte den Beitrag: http://forum.de.selfhtml.org/archiv/2009/5/t187309/

      Nicht wirklich - "deadbeef" ist z.B. numeric.

      Shit, Du hast recht:

      0xDEADBEEF ist numerisch, wie auch  0xFFD8FF, ich nehme an alle Magischen Zahlen zur Kennzeichnung von Dateitypen. Auch wenn man das EADBEEF wegnimmt ist es immer noch numerisch!

      Ich bin platt, das hätte ich so nicht erwartet!
      Also is_numeric scheidet für meine zwecke schon mal aus.
      Ich schaue mir aber morgen noch ctype und reguläre Ausdrücke wie preg_match an!

      Entsprechend maskieren, wie schon gesagt - kontextgerecht behandeln. PHP sieht hierfür eben mysql_real_escape_string() vor.

      Ich kann es echt nicht glauben das es nur mysql_real_escape_string() ist, und dafür schlage ich mir mehrere tage um die Ohren und wäre beinahe reif für das Irrenhaus geworden! :-)

      Was hat's mit BINARY aufsich?

      BINARY habe ich gesetzt damit auf Groß und Kleinschreibung geachtet wird!

      Warum $_POST[‘eve’] und nicht $_POST['eve']?

      Sorry, ich habe den Code vorher in MS-Word kopiert, hier wird wohl der Fehler entstanden sein!

      Besser nicht, aber übersichtlicher. Für das gibt es aber bereits vorgefertigtigte Funktionen (sprintf() z.B.).

      So zum Beispiel?

      $query = sprintf("SELECT user,password FROM users WHERE user='%s' AND password='%s'",
                 mysql_real_escape_string($user),
                 mysql_real_escape_string($password));

      Viele Grüße,

      Sub

      1. ich nehme an alle Magischen Zahlen zur Kennzeichnung von Dateitypen.

        z.B. - aber eben nicht nur - genaueres findest du in der Doku der Funktion.

        BINARY habe ich gesetzt damit auf Groß und Kleinschreibung geachtet wird!

        Dafür wäre COLLATE imho schlauer.

        So zum Beispiel?

        Ja.

        1. Hi suit,

          vielen Dank für Deine Hilfe!!!

          Grüße,

          Sub

  2. Hi Sub.

    Dass man GET / POST / REQUEST / SESSION Variablen und Werte niemals ungeprüft zur Datenbank weiterleiten soll weiß ich also bereits!

    Oje. Was meinst Du denn mit "pruefen"? Da hast Du diesen Slogan aufgeschnappt, der gut gemeint, aber Unsinn ist.

    *Dann*, wenn ein Wert in einer dieser Variablen (also ein vom Client uebergebener Wert) kein beliebiger String sein darf (also nicht alles sein darf, was er technisch sein kann), *dann* musst Du pruefen, ob das, was drin steht, etwas ist, was drinstehen darf.

    Wenn andersherum ein User einen beliebigen String angeben darf, worauf willst Du dann pruefen? Was Du lediglich tun musst, ist etwas ganz anderes:

    Du musst Dir im klaren sein, dass ein String, der in eine DB geschrieben werden soll, im dafuer verantwortlichen SQL-Statement selber (i.a.) nicht auftaucht - um aus dem String das Statement zu bilden, musst Du sein SQL-Literal bilden, d.h. eine Funktion wie mysqli_real_escape_string anwenden. Das ist alles. Pruefen tut die Funktion gar nichts.

    magic_quotes_gpc und register_globals sind von Strato Standardmäßig ausgeschaltet und die per POST übergebenen Variablen werden mit drei Arrays (alle die dürfen Array, Pflicht Array und Kann Array) verglichen und falls Unstimmigkeiten existieren, wird das Script sofort abgebrochen.

    Warum wird denn gleich das Skript abgebrochen? Das klingt nicht sehr benutzerfreundlich.

    Auch prüfe ich ob in den übergebenen Werten unerlaubte Zeilenumbrüche vorhanden sind.

    Was sind es denn eigentlich fuer Werte? Warum ist es ein Problem, wenn einer einen Zeilenumbruch eingibt?

    Jetzt zu meinen Verständnisproblemen;

    1. Da ich bei DB Abfragen nicht nur mit Zahlen (ID) arbeite sondern auch mit Buchstaben / Wörter, weiß ich nicht wie ich diese behandeln soll zwecks einer Prüfung.

    Schreibe mal auf einem Blatt Papier *exakt* auf, was Du eigentlich pruefen willst, d.h. welche Strings erlaubt und welche nicht erlaubt sind. Wenn Du das weisst, dann ist es hoechstwahrscheinlich nicht schwierig, die Pruefung zu implementieren.

    was mache ich aber bei Wörter (Wörter mit Apostroph wie Bistro's), wäre da preg_match Sinnvoll oder habt Ihr einen besseren Vorschlag?

    Warum sind denn keine Apostrophe erlaubt?

    1. Aus Testzwecken frage ich die Datenbank momentan so ab:

    $sich = "Op's";

    $abfrage="SELECT ID,Kategorie,Sich,Event,Bild FROM 01_daten WHERE Sich LIKE BINARY'".mysql_real_escape_string($sich)."' AND Kategorie = '".mysql_real_escape_string($_POST[‘koi’])."' AND Event != '".mysql_real_escape_string($_POST[‘eve’])."' ORDER BY Event ASC";

    Aber sicher nicht allzu erfolgreich, weil das so geblidete SQL-Statement Syntax-Fehler enthaelt. Vom Ansatz her ist es aber sicher der bessere Weg, als die Variablen erst noch separat umzukopieren. Dafuer gibt es keinen guten Grund.

    Viele Gruesse,
    der Bademeister

    1. Hi Bademeister,

      auch an Dir ein Dankeschön für die Stellungnahme!

      Oje. Was meinst Du denn mit "pruefen"? Da hast Du diesen Slogan aufgeschnappt, der gut gemeint, aber Unsinn ist.

      Sorry, aber wenn es so ist frage ich mich ernsthaft warum so viel Tohuwabohu um das Wörtchen Prüfungen gemacht werden! Ernsthaft, mir raucht schon der Kopf, in Abermillionen Webseiten steht prüfen, prüfen und nochmals prüfen und diese sind nicht vom 26. April 2010 sondern aus Jahren davor!

      *Dann*, wenn ein Wert in einer dieser Variablen (also ein vom Client uebergebener Wert) kein beliebiger String sein darf (also nicht alles sein darf, was er technisch sein kann), *dann* musst Du pruefen, ob das, was drin steht, etwas ist, was drinstehen darf.

      Also z.B. bei einem select Feld die Auswahl mit einem Array vergleichen.
      Sollte die Auswahl nicht im Array enthalten sein dann Abbruch, richtig?

      Wenn andersherum ein User einen beliebigen String angeben darf, worauf willst Du dann pruefen?

      Stell Dir mal vor ein User tippt anstatt Bistro's Bistros\’s ein, hier würde die mysql_real_escape_string Funktion den String ein zweites Mal maskieren! Da wäre es doch nicht falsch, bevor mysql_real_escape_string angewandt wird, auf Maskierungen zu achten und im Gegebenenfall stripslashes anzuwenden, oder täusche ich mich da?

      Warum wird denn gleich das Skript abgebrochen? Das klingt nicht sehr benutzerfreundlich.

      Da der eigentliche Benutzer davon nicht betroffen ist, hat das schon seine Berechtigung!
      Siehe hierzu bitte den Beitrag: http://forum.de.selfhtml.org/archiv/2009/5/t187309/

      Was sind es denn eigentlich fuer Werte? Warum ist es ein Problem, wenn einer einen Zeilenumbruch eingibt?

      Da bei einem Request(POST) keine Informationen über den Typ eines Formularfeldes übertragen werden, wird auch keine Information übertragen ob überhaupt das eigene Formular genutzt wurde, es sei den man benutzt eine Session für eine Formularidentifikation. Also stelle Dir auch hier einfach vor, jemand versucht mit einem fremden Formular auf Dein Script zuzugreifen und nimmt anstatt ein:

      <input type="text" name="textfield1" />

      eine

      <textarea name="textfield1">

      Resultat ist das im input type="text" kein Umbruch vorgesehen ist, aber in der textarea sind Umbrüche erlaubt. Wenn man also im eigenen Formular ein input type="text" bereitstellt ist es ja wohl logisch das man dort keine Umbrüche haben möchte.

      Schreibe mal auf einem Blatt Papier *exakt* auf, was Du eigentlich pruefen willst, d.h. welche Strings erlaubt und welche nicht erlaubt sind. Wenn Du das weisst, dann ist es hoechstwahrscheinlich nicht schwierig, die Pruefung zu implementieren.

      Wir sind uns mit Sicherheit einig dass dies nicht auf ein Blatt Papier passt! :-)
      Wenn überhaupt wäre eine Whitelist besser als eine Blacklist, aber auch für die würde ein Blatt nicht ausreichen. Ich habe eingesehen, was man vergleichen kann sollte man auch vergleichen, sprich alles wo der User nur Auswählen kann bei Auswahllisten, Checkboxen und Radioboxen.

      Warum sind denn keine Apostrophe erlaubt?

      Apostroph soll erlaubt sein, ich wusste nur noch nicht wie ich das in der preg_match unterbringe.

      Aber sicher nicht allzu erfolgreich, weil das so geblidete SQL-Statement Syntax-Fehler enthaelt. Vom Ansatz her ist es aber sicher der bessere Weg, als die Variablen erst noch separat umzukopieren. Dafuer gibt es keinen guten Grund.

      Der Fehler mit den Hochkomas ist beim kopieren aus Word passiert, Sorry!

      Viele Grüße,

      Sub

      1. Sorry, aber wenn es so ist frage ich mich ernsthaft warum so viel Tohuwabohu um das Wörtchen Prüfungen gemacht werden!

        Natürlich ist das Prüfen der Inhalte oft wichtig, aber nicht einfach um des Prüfens willen. Im Grunde ist die Aussage, die Werte dürfen nicht ungeprüft verwandt werden, völlig leer, wenn man nicht dazu sagt, was man denn eigentlich prüfen will. Sag doch mal selber: wenn ich in ein Formular einen Text schreiben soll, der dann in einer Datenbank gespeichert wird - sagen wir eine Nachricht an Dich - *was* genau willst Du da bei dem eingegebenen Text jetzt prüfen?

        Ernsthaft, mir raucht schon der Kopf, in Abermillionen Webseiten steht prüfen, prüfen

        Was denn prüfen?

        Also z.B. bei einem select Feld die Auswahl mit einem Array vergleichen.

        Zum Beispiel. Bei einem Select-Feld dürfte meistens die Situation vorliegen, dass nur wenige Werte erlaubt sind, nämlich die angebotenen. Ob Du die in einem Array stehen hast oder wie die Prüfung genau aussieht, musst Du wissen.

        Sollte die Auswahl nicht im Array enthalten sein dann Abbruch, richtig?

        Skript abbrechen? Klingt nicht gut. Vielleicht eher einen Hinweis ausgeben und dem User das Formular nochmals anbieten?

        Wenn andersherum ein User einen beliebigen String angeben darf, worauf willst Du dann pruefen?

        Stell Dir mal vor ein User tippt anstatt Bistro's Bistros\’s ein, hier würde die mysql_real_escape_string Funktion den String ein zweites Mal maskieren!

        Wenn einer in des Feld "Bistro's" eintippt, dann würde ich zunächst mal davon ausgehen, dass der String, den er eintippen wollte, eben "Bistro's" ist. Sonst hätt ers ja nicht eingetippt. Und dann speicher ich den String auch ab. Wenn Du einen guten Grund hast, dem User zu verbieten, die Zeichenfolge "'" in seinem String zu haben, dann sag mal, was Du eigentlich vorhast.

        Da wäre es doch nicht falsch, bevor mysql_real_escape_string angewandt wird, auf Maskierungen zu achten und im Gegebenenfall stripslashes anzuwenden, oder täusche ich mich da?

        Die Eingabe einfach stillschweigend zu verändern und so zu tun, als habe der Benutzer etwas anders eingegeben, als er tatsächlich hat, halte ich für so fast immer die falsche Vorgehensweise. Wenn er einen ungültigen String eingegeben hat, teile es ihm mit, und wenn nicht, dann nimm seine Eingabe.

        Was sind es denn eigentlich fuer Werte? Warum ist es ein Problem, wenn einer einen Zeilenumbruch eingibt?

        Da bei einem Request(POST) keine Informationen über den Typ eines Formularfeldes übertragen werden, wird auch keine Information übertragen ob überhaupt das eigene Formular genutzt wurde, es sei den man benutzt eine Session für eine Formularidentifikation. Also stelle Dir auch hier einfach vor, jemand versucht mit einem fremden Formular auf Dein Script zuzugreifen und nimmt anstatt ein:

        <input type="text" name="textfield1" />

        eine

        <textarea name="textfield1">

        Das ist doch *total* egal, auf welche Weise der Client den Request produziert hat. Es ist nur interessant, *welche* Werte er übergibt. Was Du für Werte erwartest, hat einzig und allein mit dem Zweck und der Logik Deines Skriptes zu tun. Diese ganzen HTMl- und SQL-Aspekte spielen dabei überhaupt keine Rolle.

        Schreibe mal auf einem Blatt Papier *exakt* auf, was Du eigentlich pruefen willst, d.h. welche Strings erlaubt und welche nicht erlaubt sind. Wenn Du das weisst, dann ist es hoechstwahrscheinlich nicht schwierig, die Pruefung zu implementieren.

        Wir sind uns mit Sicherheit einig dass dies nicht auf ein Blatt Papier passt! :-)

        Nein, sind wir bisher nicht. Ich meinte nicht, das Du alle erlaubten Strings aufschreiben sollst, sondern, dass Du exakt formulieren sollst, was die Kriterien für die Gültigkeit der Strings ist. Was hast Du denn vor?

        Viele Grü0e
        der Bademeister

        1. Hallo Bademeister,

          Sag doch mal selber: wenn ich in ein Formular einen Text schreiben soll, der dann in einer Datenbank gespeichert wird - sagen wir eine Nachricht an Dich - *was* genau willst Du da bei dem eingegebenen Text jetzt prüfen?

          Ich habe mich vielleicht nicht klar genug ausgedrückt, eigentlich wollte ich von euch wissen wie man Injections in der Eingabe verhindern kann. Daher bin ich davon ausgegangen das die mysql_real_escape_string Funktion nur einen kleinen teil dazu beiträgt aber nicht ausreichend ist und nur deswegen habe ich mich festgebissen an das Wörtchen Prüfung! Damit meinte ich ob es evtl. weitere Techniken gibt um SQL Injection zu verhindern.

          Sollte die Auswahl nicht im Array enthalten sein dann Abbruch, richtig?

          Skript abbrechen? Klingt nicht gut. Vielleicht eher einen Hinweis ausgeben und dem User das Formular nochmals anbieten?

          »»

          Ehrlich gesagt sehe ich hier keinen Sinn das Formular nochmals anzubieten.
          Wenn das Vergleichsarray den Übermittelten Wert nicht enthält kann das entweder bedeuten dass ich unaufmerksam war und vergessen habe den Wert im Array einzutragen oder, der Wert existiert in der Auswahl überhaupt nicht und soll mir untergeschoben werden. Ich würde eher das Script mit einem Hinweis beenden und zzgl. eine Nachricht mit Beschreibung an mein E-Mail Postfach senden warum das Script beendet wurde.

          Stell Dir mal vor ein User tippt anstatt Bistro's Bistros\’s ein, hier würde die mysql_real_escape_string Funktion den String ein zweites Mal maskieren!

          Wenn einer in des Feld "Bistro's" eintippt, dann würde ich zunächst mal davon ausgehen, dass der String, den er eintippen wollte, eben "Bistro's" ist. Sonst hätt ers ja nicht eingetippt. Und dann speicher ich den String auch ab. Wenn Du einen guten Grund hast, dem User zu verbieten, die Zeichenfolge "'" in seinem String zu haben, dann sag mal, was Du eigentlich vorhast.

          Versteh ich das jetzt richtig, eine zweite Maskierung wäre also nicht gravierend bezüglich der Sicherheit?

          Das ist doch *total* egal, auf welche Weise der Client den Request produziert hat. Es ist nur interessant, *welche* Werte er übergibt. Was Du für Werte erwartest, hat einzig und allein mit dem Zweck und der Logik Deines Skriptes zu tun. Diese ganzen HTMl- und SQL-Aspekte spielen dabei überhaupt keine Rolle.

          Wenn ich einen Wert ohne Zeilenumbruch erwarte dann ist das meinem Erachten nach nicht total egal ob darin nachher doch ein Wert mit Umbruch gesendet wurde!

          Nein, sind wir bisher nicht. Ich meinte nicht, das Du alle erlaubten Strings aufschreiben sollst, sondern, dass Du exakt formulieren sollst, was die Kriterien für die Gültigkeit der Strings ist. Was hast Du denn vor?

          Was ich vorhabe wurde schon erläutert, ich möchte SQL Injections weitestgehend verhindern.

          Viele Grüße,

          Sub

          1. Ich habe mich vielleicht nicht klar genug ausgedrückt, eigentlich wollte ich von euch wissen wie man Injections in der Eingabe verhindern kann. Daher bin ich davon ausgegangen das die mysql_real_escape_string Funktion nur einen kleinen teil dazu beiträgt aber nicht ausreichend ist und nur deswegen habe ich mich festgebissen an das Wörtchen Prüfung! Damit meinte ich ob es evtl. weitere Techniken gibt um SQL Injection zu verhindern.

            Nutze keine SQL ;)

            Versteh ich das jetzt richtig, eine zweite Maskierung wäre also nicht gravierend bezüglich der Sicherheit?

            Nein. Du maskierst ja nicht zwei mal sondern nur 1x ;) Dafür dass die Benutzereingabe bereits so aussieht als wäre sie maskiert, kannst du ja nichts. Du willst doch schließlich dass Bistro's in der Datenbank landet, wenn das der Benutzr eingibt und nicht Bistro's.

            Wenn ich einen Wert ohne Zeilenumbruch erwarte dann ist das meinem Erachten nach nicht total egal ob darin nachher doch ein Wert mit Umbruch gesendet wurde!

            Richtig, aber den Benuter darauf hinweisen ist immer höflicher als einfach abzuwürgen.

            Was ich vorhabe wurde schon erläutert, ich möchte SQL Injections weitestgehend verhindern.

            Dafür ist mysql_real_escape_string() vollig ausreichend.

            1. Hi suit,

              Nutze keine SQL ;)

              Ist die antwort von Dir jetzt Ironisch gemeint?

              Frage: Wie verhindere ich Bilderklau?

              Antwort: Stelle keine Bilder ins Netz! :-)

              Nein. Du maskierst ja nicht zwei mal sondern nur 1x ;) Dafür dass die Benutzereingabe bereits so aussieht als wäre sie maskiert, kannst du ja nichts. Du willst doch schließlich dass Bistro's in der Datenbank landet, wenn das der Benutzr eingibt und nicht Bistro's.

              Danke, ich bin wirklich davon ausgegangen das bei Doppelmaskierung irgendwelche Probleme in der Sicherheit entstehen könnten. Nach Deiner antwort kann ich wieder beruhigender Schlafen!

              Dafür ist mysql_real_escape_string() vollig ausreichend.

              Auch hier ein Dankeschön, genau diese kurze antwort liegt mir sehr am Herzen!

              Viele Grüße,

              Sub

              1. Dafür ist mysql_real_escape_string() vollig ausreichend.

                Auch hier ein Dankeschön, genau diese kurze antwort liegt mir sehr am Herzen!

                Dann möcht ich Dich aber ganz schnell noch mal etwas vom ruhigen Schlafen abhalten, bevor da Missverständnisse auftreten.

                mysql_real_escape_string() ist völlig ausreichend, solange Du *Strings* in die Datenbank schreibst. Bei numerischen Datentypen (und anderen, deren Literale in SQL nicht durch Anführungszeichen markiert sind) ist es das natürlich nicht! (Warum?)

                Viele Grüße,
                der Bademeister

              2. Nutze keine SQL ;)

                Ist die antwort von Dir jetzt Ironisch gemeint?

                Nein. Zudem: informiere dich, was Ironie bedeutet ;)

                Frage: Wie verhindere ich Bilderklau?

                Antwort: Stelle keine Bilder ins Netz! :-)

                Das ist bestenfalls zynisch (wenn man zwei Augen zudrückt).

          2. Hallo Bademeister,

            suit hat mich schon aufgeklärt!

            Auch an Dir nochmals ein Dankeschön für die Hilfe!

            Viele Grüße,

            Sub

          3. Hi!

            Ich habe mich vielleicht nicht klar genug ausgedrückt, eigentlich wollte ich von euch wissen wie man Injections in der Eingabe verhindern kann.

            Das zeigt, dass du das Prinzip immer noch nicht verstanden hast. Vielleicht hilft dir ja der Kontextwechsel-Artikel, besonders der Anfang. Es ist nicht die Eingabe, die problematisch ist, sondern das Zusammenbauen von Ausgabe-Code und Daten. Dabei spielt es nur eine geringe Rolle, woher die Daten stammen.

            Daher bin ich davon ausgegangen das die mysql_real_escape_string Funktion nur einen kleinen teil dazu beiträgt aber nicht ausreichend ist und nur deswegen habe ich mich festgebissen an das Wörtchen Prüfung! Damit meinte ich ob es evtl. weitere Techniken gibt um SQL Injection zu verhindern.

            Wenn du das Prinzip verstanden hast, wirst du die Rolle von Escaping und der genannten Funktion zuordnen können. Wenn von Prüfung die Rede ist, dann ist das ind er Tat missverständlich, weil nicht korrekt, oder besser: nicht für alle Anwendungsfälle korrekt. Prüfen kann man nur dann, wenn der erlaubte Wertebereich genau vorgegeben und überschaubar klein ist.

            Das ist doch *total* egal, auf welche Weise der Client den Request produziert hat. Es ist nur interessant, *welche* Werte er übergibt. Was Du für Werte erwartest, hat einzig und allein mit dem Zweck und der Logik Deines Skriptes zu tun. Diese ganzen HTMl- und SQL-Aspekte spielen dabei überhaupt keine Rolle.

            Wenn ich einen Wert ohne Zeilenumbruch erwarte dann ist das meinem Erachten nach nicht total egal ob darin nachher doch ein Wert mit Umbruch gesendet wurde!

            Es gehört zur Geschäftslogik und der Prüfung auf erlaubte Werte. Aus sicherheitstechnischer Sicht ist eine Prüfung nicht notwendig, denn da zählt nur das korrekte Escapen. Wenn deine Anwendung keinen Zeilenumbruch akzeptiert, und du außerdem die Eingabe für normale Anwender über ein einzeiliges Eingabefeld stattfindet, dann kann ein enthaltener Zeilenumbruch ein Hinweis auf Missbrauch sein. Die Sicherheit kann allerdings auch über Escaping gewährleistet sein, wenn das Ausgabemedium das vorsieht (bei E-Mail-Adressen beispielsweise nicht). Missbrauch kann man aber auch noch zur Genüge mit erlaubten Werten treiben (ungültige aber syntaktisch korrekte E-Mail, sinnloser Text als Gästebucheingabe, etc.).

            Was ich vorhabe wurde schon erläutert, ich möchte SQL Injections weitestgehend verhindern.

            Der Wunsch ist so formuliert vergleichbar mit weitestgehend nicht schwanger werden zu wollen. :-)

            Lo!

  3. was mache ich aber bei Wörter (Wörter mit Apostroph wie Bistro's)

    Da prüfst du ob es sich um ein Deppenapostroph handeln könnte und weist den Benutzer drauf hin ;-)

    1. Hallo Encoder,

      ich bin mir jetzt selbst nicht sicher ob ich nicht auch zu den Deppen gehöre! :-(

      Bistros oder Bistro’s oder einfach nur Bistro? :-|

      Eine Mehrzahl zu Bistro habe ich im Web nicht gefunden aber eine Seite die sich mit dem Apostroph beschäftigt, siehe: http://www.niederelbe.de/noranetz/apostroph.htm

      Hier ist man eher der Meinung dass es Bistro’s heißen müsste aber MS Word sagt genau das Gegenteil!

      Na ja, wie dem auch sei, die Idee den User darauf hinweisen das es sich um ein Deppenapostroph handeln könnte ist schon echt lustig aber leider wären hier sehr, sehr viele User nachher eingeschnappt und spielen beleidigte Leberwurst. :-)

      Viele Grüße,

      Sub

      1. Liebe(r) Sub,

        Bistros oder Bistro’s oder einfach nur Bistro? :-|

        Eine Mehrzahl zu Bistro habe ich im Web nicht gefunden aber eine Seite die sich mit dem Apostroph beschäftigt, siehe: http://www.niederelbe.de/noranetz/apostroph.htm

        Hier ist man eher der Meinung dass es Bistro’s heißen müsste aber MS Word sagt genau das Gegenteil!

        Du hast die Ironie nicht gesehen. Auf besagter Seite verwendet man den korrekten Plural "Bistros" und ergänzt dann, dass es im "Dummdeutsch" eben mit Apostroph geschrieben werden müsste (beachte den Konjunktiv!).

        Na ja, wie dem auch sei, die Idee den User darauf hinweisen das es sich um ein Deppenapostroph handeln könnte ist schon echt lustig aber leider wären hier sehr, sehr viele User nachher eingeschnappt und spielen beleidigte Leberwurst. :-)

        Du musst ja nicht unbedingt "Deppenapostroph" oder "Dummdeutsch" in Deinem Hinweis verwenden. Es genügt ja das Wort "Anglizismus"...

        Liebe Grüße,

        Felix Riesterer.

        --
        ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
        1. Hallo Felix,

          Du musst ja nicht unbedingt "Deppenapostroph" oder "Dummdeutsch" in Deinem Hinweis verwenden. Es genügt ja das Wort "Anglizismus"...

          ... was in diesem Fall aber völlig irreführend und IMHO falsch wäre. Denn einerseits kommt das Wort "Bistro" nicht aus dem Englischen, sondern aus dem Französischen; andererseits wird weder im Englischen, noch im Französischen das Plural-s mit einem Apostroph abgesetzt.

          Nein, das Plural-s mit Apostroph scheint mir eine deutsche Eigenentwicklung zu sein. Die einzige mir bekannte Sprache, die das regelmäßig so macht, ist Niederländisch (und da auch nur für Fremdworte, die aus anderen Sprachen entlehnt sind und mit einem Vokal enden, z.B. auto's). Und ich glaube nicht, dass Niederländisch bei uns so populär ist, dass es zum Übernehmen von Schreibgewohnheiten reicht.

          So long,
           Martin

          --
          Die letzten Worte des Hardware-Bastlers:
          Das Netzkabel lass ich wegen der Erdung lieber dran.