Ankündigung

Einklappen
Keine Ankündigung bisher.

Sicherheit meiner Scriptes

Einklappen

Neue Werbung 2019

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

  • Sicherheit meiner Scriptes

    Guten Morgen zusammen,

    ich arbeite aktuell als HiWi und mir wurde der Auftrag zugetragen eine Datenbank mit PHP und MySQL zu erstellen in der alle Vorträge und Fachartikel von unseren Mitarbeitern gespeichert werden können.

    Da ich blutiger Anfänger (noch nicht eine Zeile PHP Code geschrieben) bin musste ich mir erstmal alles selber beibringen. Das Ergebniss nach 3-4 Tagen freut mich - denn es läuft wie gewollt!

    Doch weil das Ganze nunmal online auf den Unternehmensserver soll stelle ich mir jetzt die Frage ob es so auch sicher genug ist. Schließlich möchte ich nicht schuld sein, wenn mit meinem Code nachher jemand die ganze Seite plättet.:P

    Daher wäre es nett, wenn ein Experte einen professionellen Blick in meinen Code werfen könnte um mir eventuelle Sicherheitslücken aufzuzeigen.

    Da es durch Formatierungen etc. durchaus komplex geworden ist poste ich hier mal nur ein paar Ausschnitte die ich spontan für wichtig halte. Wenn was entscheidenes fehlt, dann bitte ich um Rückmeldung.

    Dann fang ich mal an:
    Ich habe eine Seite in der die Daten eingegeben, geprüft und verarbeitet werden:
    PHP-Code:
    //Datenbankeintrag:
                
    include("mysql.php");
        
                
    $stmt $pdo->prepare('INSERT INTO `tutorial`.`vortraege` (`id`, `referent`, `titel`,...) VALUES (NULL, :referent, :titel,...)');

                
    //Verschiedenste Werte
                
    $stmt->bindParam(':referent'$_POST["referent"], PDO::PARAM_STR);
                
    $stmt->bindParam(':titel'$_POST["titel"], PDO::PARAM_STR);
                ...
                
    //Dateiupload
                
    move_uploaded_file($_FILES['datei1']['tmp_name'], $file1url);
                
    $stmt->bindParam(':file1url'$file1urlPDO::PARAM_STR);
                ...
        
                
    $stmt->execute(); 
    Die Eingabe der Werte erfolgt in der selben Seite etwa so (es wird ganz am Anfang geprüft ob dem Pflichtfeld 'Referent' ein Wert per POST übergeben wurde. Bei der überprüfung ändert sich der Wert von $errorClass['..'], sodass der User optisch per CSS auf das Fehlen des Pflichtfeldes aufmerksam gemacht werden kann):
    Code:
    <td>Referent:</td>
    <td><input class="<?PHP echo $errorClass['referent'];?>" value="<?PHP if(!empty($_POST['referent'])) echo $_POST['referent']; ?>" type="text" size="35" name="referent">*</td>
    ...
    <td>1.Datei:</td>
    <td><input name="datei1" type="file"></td>
    ...
    <td><input name="submit" type="submit" value="Vortrag eintragen!"></td>
    Inhalt der mysql.php:
    PHP-Code:
    <?php
        $dbhost 
    'localhost';
        
    $dbname 'tutorial';
        
    $dbuser 'xxx';
        
    $dbpass 'xxx';
        
        try{
            
    $pdo = new PDO('mysql:host='.$dbhost.';dbname='.$dbname$dbuser$dbpass);
        }
        catch(
    PDOException $e) {
            exit(
    'Es konnte keine Verbindung zur Datenbank hergestellt werden!');
        }
    ?>
    Und schließlich die Ausgabe der Werte auf einer anderen Seite (die Inhalte der Sortier- und Blätterfunktion sind ja unwichtig, denke ich:
    PHP-Code:
        //Datenabruf:
            
    $abfrage "SELECT * FROM vortraege $sortierfkt $blaetterfkt";
            
    $stmt $pdo->prepare($abfrage);    
            
    $stmt->execute();

        
    //Ausgabe:
            
    while($row $stmt->fetch())
            {
                ...
                echo 
    '<td class="'.$class.'">'.$row['referent'].'</td>';
                echo 
    '<td class="'.$class.'">'.$row['titel'].'</td>';
                ... 
    Reicht die Verwendung von PDO schon zur Absicherung? Oder Bedarf es da noch mehr?
    Würde mich über jeden Hinweis freuen

    Gruß
    kuchen


  • #2
    Damit verhinderst du zumindest SQL-Injection. Ich seh aber bei dir momentan keinen wirksamen Schutz gegen XSS.

    (Und Select * macht man nicht )
    Current Projects: http://www.welten-buch.de, http://neu.zooadoo.de

    Kommentar


    • #3
      - Was passiert wenn bei dir jemand eine .php-Datei hochlädt? Kann er/sie diese dann irgendwie so aufrufen, dass sie ausgeführt wird? Überprüf das mal.
      - Was passiert, wenn jemand als Titel folgendes angibt: <script>alert(123)</script>
      (Und dann dieser Datensatz aufgerufen & angezeigt wird)

      Kommentar


      • #4
        Hinweis:

        Die Verwendung von "*" in SQL-Abfragen wird im Allgemeinen als schlechter Stil angesehen. "*" kann entweder alle Felder aus einer Tabelle, oder (wenn mehrere Tabellen mit einbezogen werden) aus allen Tabellen ziehen.

        Zwei Gründe sprechen dagegen: Wenn du dein Tabellenschema anpasst, wird die Abfrage weiterhin funktionieren. Die Abfrage wird in deinem Code aber Variablen (bzw. Array-Keys) erzeugen, die von deinem Programm so nicht erwartet werden. Das kann (je nachdem, wie deine Applikation aufgebaut ist) zu schwer nachvollziehbaren Problemen führen. Würdest du die Spaltennamen direkt in deiner SQL-Abfrage angeben, würde die SQL-Abfrage direkt lautstark fehlschlagen. Dann kannst du möglicherweise einen Alias für umbenannte Tabellenspalten angeben, ohne dass du deinen Applikationscode anpassen musst.

        Außerdem kann man durch eine explizite Angabe die Reihenfolge und die Anzahl der Tabellenspalten begrenzen. Die Reihenfolge kann je nach Applikation eine Rollen spielen und je weniger Felder man einbezieht, desto schneller wird das Ergebnis zum abfragenden Client übertragen.
        Standards - Best Practices - AwesomePHP - Guideline für WebApps

        Kommentar


        • #5
          Noch Lesestoff dazu:

          http://php-de.github.io/jumpto/code-smells/#select-

          http://php-de.github.io/#security Hier findest du auch einen Artikel zu XSS
          Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
          PHP.de Wissenssammlung | Kein Support per PN

          Kommentar


          • #6
            Erstmal vielen Dank für die sehr schnellen Rückmeldungen...
            ...und offensichtlich war es gut, dass ich nachgefragt habe

            Zum XSS:
            Ich habe gerade mal gegooglet und verstehe nun das Problem. Reicht es wenn ich meinen Code beim Datenbankeintrag um strip_tags() erweitere? Also quasi so:
            PHP-Code:
            $stmt->bindParam(':referent'strip_tags($_POST["referent"]), PDO::PARAM_STR); 
            Zum SELECT *:
            Auch hier sehe ich das Problem ein. Ich sollte also besser nur die notwendigen Spalten eintragen. Bspw. so?
            PHP-Code:
            $abfrage "SELECT referent, titel FROM vortraege $sortierfkt $blaetterfkt"
            Zum Dateiupload:
            Da hatte ich bisher auch meine größte Sicherheitslücke vermutet. Ich denke es wäre möglich eine PHP datei hochzuladen und diese dann auch zu öffnen. Ich sollte also besser die möglichen Dateitypen einschränken? Da es sich um Vorträge handelt evtl. nur PDFs und PPTs? Weiß ich jetzt spontan nicht wie das geht. Aber auch das werde ich sicher durch googlen rausfinden können. Danke schonmal für den Hinweis.

            Gruß
            kuchen

            Kommentar


            • #7
              Zum XSS
              Siehe den von mir oben verlinkten Artikel. http://php-de.github.io/jumpto/cross-site-scripting/

              Sei vorsichtig beim verändern von eingehenden Daten, die kannst du dir dadurch u.U. auch kaputt machen, besser ist es bei der Ausgabe den Kontextwechsel zu beachten, der ist im Grunde die Mutter des Übels.

              EDIT:
              Hier war der Beitrag vor kurzem, das wäre so ein Beispiel wo du dir den eingehenden Text zerstören würdest - ging um htmlspecialchars() oder strip_tags() auf Eingaben, was man daher nicht machen sollte, sondern auf Ausgaben. http://www.php.de/software-design/11...tml#post809411

              LG
              Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
              PHP.de Wissenssammlung | Kein Support per PN

              Kommentar


              • #8
                Zitat von kuchen Beitrag anzeigen
                Zum Dateiupload:
                Da hatte ich bisher auch meine größte Sicherheitslücke vermutet. Ich denke es wäre möglich eine PHP datei hochzuladen und diese dann auch zu öffnen. Ich sollte also besser die möglichen Dateitypen einschränken? Da es sich um Vorträge handelt evtl. nur PDFs und PPTs? Weiß ich jetzt spontan nicht wie das geht. Aber auch das werde ich sicher durch googlen rausfinden können. Danke schonmal für den Hinweis.

                Gruß
                kuchen
                Ja wäre wohl sinnvoll dann nur Dateien mit bestimmter Endung zum Hochladen zuzulassen. Das ist auch nicht weiter schwer.

                Kommentar


                • #9
                  Zitat von hausl Beitrag anzeigen
                  Siehe den von mir oben verlinkten Artikel. http://php-de.github.io/jumpto/cross-site-scripting/

                  Sei vorsichtig beim verändern von eingehenden Daten, die kannst du dir dadurch u.U. auch kaputt machen, besser ist es bei der Ausgabe den Kontextwechsel zu beachten, der ist im Grunde die Mutter des Übels.

                  EDIT:
                  Hier war der Beitrag vor kurzem, das wäre so ein Beispiel wo du dir den eingehenden Text zerstören würdest - ging um htmlspecialchars() oder strip_tags() auf Eingaben, was man daher nicht machen sollte, sondern auf Ausgaben. http://www.php.de/software-design/11...tml#post809411

                  LG
                  Das strip_tags() evtl. Daten zerstört hatte ich auch schon gelesen. Dennoch denke ich, dass es für meine Anwendung durchaus geeignet ist, da der Anwender ja wirklich nur banale Eingaben wie eben Titel, Referent, Ort, Datum, etc eingeben soll und dort Tags generell einfach nichts zu suchen haben.
                  Das es sich um ein Ausgabeproblem handelt ist mir jetzt klar. Allerdings ist es doch nicht schlimm, dann schon direkt an der Eingabe anzusetzen. Wenn niemals was Ungewolltes in der Datenbank steht, dann kann ja auch nie was Ungewolltes ausgelesen werden (oder habe ich was übersehen?). So hätten wir auch nicht das Problem, dass evtl. bei zukünftigen Codeerweiterungen jemand die Kontrolle der Ausgabe vergisst.

                  Kommentar


                  • #10
                    Ist richtig. Ich nehme an deine Applikation ist nicht besonders groß - also mach es so und wenn es doch irgendwann zu einem Problem führt, änderst du das Prinzip notfalls. Es geht hier ja nicht darum dich zum PHP-Profi auszubilden oder die "perfekte" Applikation schreiben zu lassen.

                    Kommentar

                    Lädt...
                    X