Ankündigung

Einklappen
Keine Ankündigung bisher.

Leitfaden sicherer Programmierung mit PHP und MySql!

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Leitfaden sicherer Programmierung mit PHP und MySql!

    Hallo Leute!

    Dieser Thread soll nicht als Diskussionsthread dienen,nein sondern dazu das Erfahrene User hier einfach mal Sachen rein schreiben die zum sicheren Programmieren in PHP und MySql aufschluss geben!

    Das heist zum Beispiel Code rein stellen und eine Erklärung warum diese Sicherheitsmasnahme ergriffen wurde,somit Anfänger auch damit etwas anfangen können! Es wäre gut wenn es verschiedene Beispiele und Verfahrensweisen hier mal zu sehen gibt,denn die Sicherheit ist ja meist auch untershciedlich je nach Aufgabenlage in Betracht zu ziehen!

    Darum bitte beteiligt euch mit Beiträgen die Aufschluss geben und keine Diskussion hier im Thread bieten! Eine Diskussion kann ja in einem anderen Thread gemacht werden! Vieleicht wird dieser Thread auch angepinnt als wichtig,denn was ist wichtiger als von Anfang an sicheres programmieren in Betracht zu ziehen?

    Nun ich mache mal den Anfang!

    Jeder kennt das, das über ein Formularfeld böse Links verschickt werden können oder auch SQL Injektions Einstz finden!

    So also ein kleines Beispiel!

    Wir haben zwei Variablen die in eine Tabelle geschrieben werden sollen hierzu das kleine Formular!

    PHP-Code:
    <form action="<?php echo htmlentities($_SERVER['SCRIPT_NAME']) ?>" method="post">
    <input type="text" name="name">
    <input type="text" name="icq">
    <input type="submit" name="send" value="Senden">
    </form>
    So ihr seht da das method="post" Attribut damit legen wir fest mit welcher Methode die Daten verschickt werden! So dieses Formular soll von einem Seitenbesucher abgeschickt werden. Das heist wir müssen unbedingt die Inhalte als GENERELL gefährlich und nicht Vertrauenswürdig ansehen und diese natürlich auch behandeln!
    Als erstes müssen wir auch register_globals in Betracht ziehen die meistens zum Glück auf off stehen!

    So nun zum ersten PHP Teil um die Variablen zu behandel die dann auf unsere DB losgelassen werden!

    PHP-Code:
    //Prüfen ob magic_quotes auf on stehen
    if(get_magic_quotes_gpc())
    {
          
    //wenn ja die Escapes entfernen
          
    $name stripslashes($_POST['name']);
          
    $icq stripslashes($_POST['icq']);
    }
    else
    {
         
    //wenn nein dann unbehandelt lassen
         
    $name $_POST['name'];
         
    $icq $_POST['icq'];

    So die Angaben $_POST[''] bilden sich aus dem Formular heraus nämlich aus dem method!
    Warum werden da die Escapes entfernt wenn schon welche da sind durch magic_quotes?
    Ganz einfach magic_quotes ist Müll!

    Warum überhaupt die Prüfung nach magic_quotes? Nunja tun wir das nicht und setzen einfach so mysql_real_escape_string ein dann wird doppelt escaped und es kann bzw. müsste sogar zu Fehlern kommen.

    Gut die Prüfung ist gemacht nun der nächste Schritt!
    Die Validierung der Formularfelder!

    PHP-Code:
    if(isset($_POST['send']))
    {
         
    //Variable wieder escapen bzw. überhaupt escapen
         
    $name mysql_real_escape_string($_POST['name']);
         
    //Feldvalidierung und Feldinhalt Sicherung mit Regex
         
    if(empty($_POST['name'] && !preg_match("#^([0-9a-zäöü _-]+)$#i",$name)))
         {
              echo 
    "falscher Inhalt! in Namensfeld";
         }
         
    $icq mysql_real_escape_string($_POST['icq']);
         if(!empty(
    $icq) && !preg_match("#[0-9]#",$icq))
         {
                echo 
    "Keine gültige ICQ Nummer";
         }

    In diesem Teil machen wir das entgültige escaping auf unsere Variable und behandeln unsere Textfelder je nach Bedarf und Inhaltserwartung mit einem Regex. Ich persönlich finde diese Methode am besten,auch wenn Sie von Fall zu Fall aufwendiger ist,aber ich bin der Meinung es ist die beste und sicherste Methode Feldinhalte von vornherein festzulegen! Somit ist Sichergestellt das auch nur das ankommt was Ihr erwartet und wollt! Also ist hier der Weg für Hacklinks bzw solche per Formular zu verschicken abgebrochen und funtioniert nicht!
    Bei der Validierung für das Feld name seht ihr empty stehen und bei dem für icq !empty.
    Nun das habe ich deshalb gemacht weil Name ein Pflichtfeld ist und ICQ ein Wahlfeld. Bei ICQ besteht die Möglickeit das Feld unausgefüllt zu verschicken wenn da niemand was eintragen will,jedoch wenn da jemand was rein schreibt darf auch nur das drin stehen was ihr durch das regex fordert!

    Die Daten können nun sauber in die Datenbank geschickt werden!

    Hier der komplette Code noch mal zusammen gefasst!
    PHP-Code:
    if(isset($_POST['send']))
    {
         if(
    get_magic_quotes_gpc())
         {
               
    //wenn ja die Escapes entfernen
               
    $name stripslashes($_POST['name']);
               
    $icq stripslashes($_POST['icq']);
         }
         else
         {
               
    //wenn nein dann unbehandelt lassen
               
    $name $_POST['name'];
               
    $icq $_POST['icq'];
         }      
         
    //Variable wieder escapen bzw. überhaupt escapen
         
    $name mysql_real_escape_string($_POST['name']);
         
    //Feldvalidierung und Feldinhalt Sicherung mit Regex
         
    if(empty($_POST['name'] && !preg_match("#^([0-9a-zäöü _-]+)$#i",$name)))
         {
              echo 
    "falscher Inhalt! in Namensfeld";
         }
         
    $icq mysql_real_escape_string($_POST['icq']);
         if(!empty(
    $icq) && !preg_match("#[0-9]#",$icq))
         {
                echo 
    "Keine gültige ICQ Nummer";
         }

    Ich hoffe auf mehr Beiträge zu diesem Thema die Aufschluss geben und unser aller Horizont in Sachen Sicherheit erweitern können!

    mfg der Litter!
    Aus dem Dynamo Lande kommen wir. Trinken immer reichlich kühles Bier. Und dann sind wir alle voll, die Stimmung ist so toll. Aus dem Dynamo Lande kommen wir.
    http://www.lit-web.de


  • #2
    Du solltest Deinen Code erst zur Diskussion stellen und gründlich prüfen, bevor Du ihn als allgemeingültigen Sicherheitsratschlag postest!
    Deshalb breche ich hier auch die Regel, den Thread nicht zum Antworten zu benutzen.

    Auf den ersten kurzen Blick fiel mir das ins Auge:

    PHP-Code:
    //Variable wieder escapen bzw. überhaupt escapen
         
    $name mysql_real_escape_string($_POST['name']); 
    Falsch! mysql_real_escape_string nur für Datenbankeinträge verwenden, weil die Funktion einen DB Handler nutzt (und darüber zu escapende Zeichen erfragt)!

    string mysql_real_escape_string ( string unescaped_string [, resource link_identifier] )
    [...]
    link_identifier
    The MySQL connection. If the link identifier is not specified, the last link opened by mysql_connect() is assumed. If no such link is found, it will try to create one as if mysql_connect() was called with no arguments. If by chance no connection is found or established, an E_WARNING level warning is generated.
    PHP-Code:
         if(empty($_POST['name'] && !preg_match("#^([0-9a-zäöü _-]+)$#i",$name)))
         {
              echo 
    "falscher Inhalt! in Namensfeld";
         } 
    Die Prüfung ist falsch implementiert. Hier ist der OR Operator zu verwenden, kein AND, sonst werden nur leere Eingaben abgelenht.

    Als erstes müssen wir auch register_globals in Betracht ziehen die meistens zum Glück auf off stehen!
    Woher nimmst Du diese Weisheit? Mit Rücksicht auf viele alte Scripte Ihrer Kunden haben viele Hoster eben noch nicht umgestellt. Im übrigen gehst Du auch mit keinem weiteren Wort auf Probleme oder Lösungen zu register_globals ein ?!


    //Prüfen ob magic_quotes auf on stehen
    if(get_magic_quotes_gpc())
    {
    Nicht allein magic_quotes_gpc sind hier maßgeblich.
    Note: If the directive magic_quotes_sybase is ON it will completely override magic_quotes_gpc. So even when get_magic_quotes_gpc() returns TRUE neither double quotes, backslashes or NUL's will be escaped. Only single quotes will be escaped. In this case they'll look like: ''
    PHP-Code:
    if(get_magic_quotes_gpc())
         {
               
    //wenn ja die Escapes entfernen
               
    $name stripslashes($_POST['name']);
               
    $icq stripslashes($_POST['icq']);
         }

    [...]

          
    $name mysql_real_escape_string($_POST['name']);
          if(empty(
    $_POST['name'] && !preg_match("#^([0-9a-zäöü _-]+)$#i",$name)))
    [...]
          
    $icq mysql_real_escape_string($_POST['icq']);
          if(!empty(
    $icq) && !preg_match("#[0-9]#",$icq))
    [...] 
    Leider wird Deine obige stripslashes Aktion unnütz, weil Du unten wieder mit dem original Request arbeitest...

    Nochmal sorry, dass ich hier poste. Aber das waren einfach zu viele Fehler. Und - nichts für ungut - an Deiner Rechtschreibung könntest Du auch mal 'was feilen. Gibt ja schließlich ne Edit Option hier...
    --

    „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
    Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


    --

    Kommentar


    • #3
      @litter: es stimmt nicht, dass magic_quotes meistens auf off stehen. Wenn es bei dir so ist, dann hast du einen besonderen Hoster erwischt, aber bei den meisten anderen stehen die weiterhin auf on, leider.
      Und mit den meisten meine ich wirklich die meisten, nicht nur einige. nikosch schrieb ja schon, warum das so ist.
      Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

      Kommentar


      • #4
        Jo, nachdem das Thema das letzte mal dran war, habe ich mal ein paar Provider abgeklappert und eine phpinfo Suche bei google gemacht und da waren wirklich bei 90%+ der Seiten magic_quotes auf On. Schrecklich schlecht, aber leider Realität

        Kommentar


        • #5
          macht bitte nur einen tread und was beim ersten falsch ist editieren danke...

          Kommentar


          • #6
            Ich mache mal ein wenig weiter mit zwei Sachen, die mir oft auffallen.

            Grafik-Upload:
            Eine Grafik muss auf Korrektheit geprüft werden, da anderenfalls schnell Schadcode auf das Zielsystem eingeschleust werden kann. Ein häufiger Fehler ist der:
            PHP-Code:
            if (@getimagesize($bild)) {
                echo 
            "Korrekte Bilddatei!";
            } else {
                echo 
            "Keine korrekte Bilddatei!";

            Nun komme ich als böser Cracker an und lade eine Datei virus.php mit dem folgenden Inhalt hoch:
            PHP-Code:
            GIF89a^A@^A^@~@^@^@^@^@^@^@^@^@!ù^D^A^@^@^@^@,^@^@^@^@^A^@^A^@^@^B^BD^A^@;<?php include 'config.inc.php'print_r($conf_database_access_data); ?>
            Schon habe ich die Zugangsdaten zur Datenbank.
            Also: Grafikdateien nicht nur auf Content-Type sondern auch auf Endung prüfen. Das Feld $_FILES['type'] lässt sich übrigens auf die gleiche Weise manipulieren und bietet deshalb keinen Schutz!

            $_SERVER-Array validieren
            Die Indizes des $_SERVER-Arrays gelten vielfach als sicher, was sie aber wirklich nicht sind. Ich denke, bei $_SERVER['HTTP_USER_AGENT'] leuchtet das jedem ein. Aber es gibt noch andere, so wie $_SERVER['PHP_SELF'].
            Wer das nicht glauben will, der schreibe bitte folgendes in eine PHP-Datei:
            PHP-Code:
            <?php
            echo $_SERVER['PHP_SELF'];
            ?>
            Diese Datei wird dann mit http://localhost/test.php/<script>alert('XSS!');</script> aufgerufen (Pfad evtl anpassen).
            Und schon hat man einen XSS-Angriff durchgeführt.

            Wenn das bei dir nicht klappt, so liegt es daran, dass MagicQuotes bei dir eingeschaltet sind. Das lässt sich aber auch umgehen: http://localhost/test.php/<script>alert(/XSS!/.source);</script>.
            Jetzt sagt vielleicht der eine oder andere: "damit führt der Cracker doch nur sein eigenes JavaScript aus!"
            Stimmt, aber oftmals werden z.B. Log-Dateien geschrieben oder Statistiken erstellt. Und dann führt auch jemand anderes diesen Code aus.
            Also: das $_SERVER-Array ist wie $_POST, $_GET und all die anderen zu behandeln.
            Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

            Kommentar


            • #7
              Zitat von Manko10 Beitrag anzeigen
              Schon habe ich die Zugangsdaten zur Datenbank.
              Wie und warum das denn? Ok... wenn ich so bescheuert bin und Bilddaten bei php per include oder require einbinde vielleicht.
              Zitat von Manko10 Beitrag anzeigen
              Also: Grafikdateien nicht nur auf Content-Type sondern auch auf Endung prüfen.
              Das bringt doch garnichts.

              Kommentar


              • #8
                Dann mal viel Spass beim rausfinden, wie die Variablen meiner Conf-Datei heissen. Auf jedenfall ist es nicht $conf_database_access_data.

                Kommentar


                • #9
                  Es reicht, dass die Bilddateien hochgeladen und weiterhin mit der Originalendung gespeichert sind.
                  Jetzt ein
                  PHP-Code:
                  GIF89a^A@^A^@~@^@^@^@^@^@^@^@^@!ù^D^A^@^@^@^@,^@^@^@^@^A^@^A^@^@^B^BD^A^@;<?php readfile('index.php'); ?>
                  und man hat alle Namen von weiteren Dateien, die eingebunden werden. Durch einen weiteren Upload kann man nun die so evtl. herausgefundene config.inc.php (oder wie auch immer sie heißt) mit
                  PHP-Code:
                  GIF89a^A@^A^@~@^@^@^@^@^@^@^@^@!ù^D^A^@^@^@^@,^@^@^@^@^A^@^A^@^@^B^BD^A^@;<?php readfile('config.inc.php'); ?>
                  ausgeben. Schon hat man alle Zugangsdaten. Man kann jeden nur erdenklichen PHP-Code auf dem Zielserver ausführen.

                  Dass die Überprüfung auf Dateiendungen nichts bringt, ist Quatsch. Natürlich kann die Datei weiterhin schädlichen PHP-Code enthalten, aber das kann dem Programmierer dann vollkommen egal sein, weil dieser nicht mehr zur Ausführung kommt.

                  Okay, bei reinen Up- und Download-Systemen kann man hier wenig hacken, weil die Dateien meist gar nicht mit der Original-Endung gespeichert werden und der ursprüngliche Dateiname erst beim Download wieder benutzt wird. Aber eine Avatar-Funktion kann man z.B. wunderbar dazu benutzen, eine Anwendung zu kapern.

                  Nachtrag:
                  Eine weitere Möglichkeit, sich zu schützen wäre die, dass man die Avatar-Dateien nicht direkt einbindet, sondern per readfile() ausliest und einen entsprechenden Content-Type setzt - also wie bei einem Download-Skript auch.
                  Aus Performancegründen und der Einfachheit halber würde ich die Variante mit der Dateiendungs-Prüfung aber vorziehen.
                  Refining Linux: “Performing Push Backups – Part 1: rdiff-backup

                  Kommentar


                  • #10
                    Der Beitrag von Manko ist zwar schon etwas älter, aber ich wollte doch noch mal einen Nachtrag dazu liefern.

                    Und zwar ist das weglassen der Prüfung auf die Dateiendung trotzdem gefährlich. Stell dir vor über die gleiche Funktion wird eine .htaccess hochgeladen, landet im selben Ordner wie z.B. eine Manipulierte "virus.xyz". In der htaccess wird der Server dazu aufgefordert xyz Dateien durch den PHP Interpreter zu jagen. Und dann kannst du auch wieder alle möglichen Dateien ausführen.

                    Also da sollte man doch vorsichtig sein. Ich glaube sehr viele wissen überhaupt nicht was möglich ist ... ich selbst finde auch immer wieder neue Wege wie man dann doch wieder irgendwie Schädlichen Code einbauen kann. Grad bei Fileuploads.

                    Und ganz ehrlich würde ich diesen Thread nicht als "wichtig" bzw. "Leitfaden" ins Forum stellen. Dann liest ein Anfänger nur den ersten Post und übernimmt gleich so einige Fehler! Hier sollte lieber mal eine überarbeitete Version die noch ein paar weitere Fälle abdeckt online gestellt werden.

                    Kommentar


                    • #11
                      Bin ich ganz deiner Meinung!

                      Mittlerweile weis ich wie viele Fehler ich gemacht habe auch Dank nikosch habe ich vieles überdacht und mache vieles anders!

                      Dieses Thema sollte für viele Erfahrene auch gedacht sein das sie ihre Erfahrungen hier einbringen gerade für die Anfänger,das war meine Idee für das ganze,aber leider nicht so aufgegangen! Meinen Post hätte man für die Fehler löschen können,wäre ich keinen böse gewesen.
                      Aus dem Dynamo Lande kommen wir. Trinken immer reichlich kühles Bier. Und dann sind wir alle voll, die Stimmung ist so toll. Aus dem Dynamo Lande kommen wir.
                      http://www.lit-web.de

                      Kommentar


                      • #12
                        @Flo:
                        Und ganz ehrlich würde ich diesen Thread nicht als "wichtig" bzw. "Leitfaden" ins Forum stellen. Dann liest ein Anfänger nur den ersten Post und übernimmt gleich so einige Fehler! Hier sollte lieber mal eine überarbeitete Version die noch ein paar weitere Fälle abdeckt online gestellt werden.
                        Ja. Richtig.- Mal sehen wann das Tutorials Wiki kommt. Dann kann da jeder weiter dran schrauben.

                        [edit] Ich nehm den PIN mal raus. Wer mag speichert sich den Thread als Favoriten.
                        --

                        „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                        Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                        --

                        Kommentar


                        • #13
                          Gut! Aber ich finds super dass sich Leute überhaupt die Mühe machen solche Leitfäden zu schreiben. Fürs Wiki können wir ja Litterauspirnas Beitrag nehmen und verändern damit alles wieder passt Ich werd gerne auch etwas dran arbeiten wenn die Wiki steht.

                          Kommentar


                          • #14
                            Dito. Aber gerade dieses Thema ist zu wichtig, um inkorrekte Informationen darzustellen.
                            --

                            „Emoticons machen einen Beitrag etwas freundlicher. Deine wirken zwar fachlich richtig sein, aber meist ziemlich uninteressant.
                            Wenn man nur Text sieht, haben viele junge Entwickler keine interesse, diese stumpfen Texte zu lesen.“


                            --

                            Kommentar

                            Lädt...
                            X