Sicheres include mit intelligenter whitelist

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

  • Sicheres include mit intelligenter whitelist

    Hi Community,

    in Sachen PHP bin ich ein totaler Neuling. Dadurch dass ich auf meiner Webseite unbedingt Strict haben wollte kam ich um PHP und include() nicht herum, da ich nicht jede Seite ändern wollte, bei z.B. neuen Links etc.

    Nun habe ich mich einige Zeit herumgetrieben und alles mögliche gelesen.
    Damit der include Befehl wirklich sicher ist, scheint es wohl mit einer whitelist am besten gelöst zu sein.

    Auf meiner Seite habe ich eine Ordnerstruktur die in etwa so aussieht.

    index.php
    home.txt
    ...
    inhalt1
    -inhalt1.txt
    -inhalt2.txt
    inhalt2
    -inhalt1.txt
    ...

    Nun geht es um folgendes.
    Mein Code momentan wäre so:
    PHP-Code:
      if(isset($_GET['site']))
        {
          
    $allowed = array('home''impressum''inhalt1''inhalt2''inhalt3''inhalt1/inhalt1''inhalt1/Inhalt2''inhalt3/inhalt1''inhalt2/inhalt1''inhalt2/inhalt1');
          
    $site=$_GET['site'];
          if( 
    in_array($_GET['site'],$allowed))
          {
            if(
    file_exists("$site.txt"))
            {
              include(
    "$site.txt");
            }
            else
            {
              include(
    "home.txt");
            }
          }
          else
          {
            echo(
    "404. Not found!!!");
          }
        }
      else
        {
          include(
    "home.txt");
        } 
    Die 1. Frage ist ob das schon sicher genug ist, oder ob es noch irgendwelche Lücken gibt.

    Die 2. Frage ist:
    Da ich ja mit der Zeit immer mehr Seiten und Ordner hinzufüge wird die whitelist in Codeansicht irgendwann sehr unübersichtlich und außerdem müsste ich das für jede neue Seite immer per Hand einfügen.

    Gibt es nicht eine Möglichkeit einen Code zu schreiben und darin einfach nur die Ordner z.B. inhalt1, inhalt2 etc. anzugeben und alle Dateien darin dann in die whitelist hinzuzufügen? Alle Dateien in diesen Ordnern sind zugänglich und sollen included werden.

    Ich freue mich auf eure Hilfe.

    Grüße
    einermeiner

  • #2
    Sollte sicher sein du schließt ja alles andere aus.

    Du kannst es auch so machen:

    PHP-Code:
    dateiarray.php
    _____________


    $dateien 
    = array();

    // fallback
    $default 'index.txt';

    // startseite
    $dateien['index'] = 'index/index.txt';

    // kontaktseite
    $dateien['kontakt'] = 'kontakt/kontakt.txt'
    PHP-Code:
    index.php
    ________


    include_once("dateiarray.php");

    // site wurde als parameter übergeben?
    if(isset($_GET['site']))
    {

        
    $site $_GET['site'];

        
    // $site ist ein array key von $dateien?
        
    if(array_key_exists($site$dateien))
        {

            
    // ist eine datei?
            
    if(is_file($dateien[$site]))
            {
                
    // ... include / weitere anweisungen
                
    include_once($dateien[$site]);
            }
            else
            {
                
    // ist keine datei also index einbinden
                
    include($default);
            }

        }
        else
        {
            
    // key existiert nicht also index einbinden
            
    include($default);
        }
    }
    else
    {
        
    // kein get['site'] parameter übergeben index einbinden
        
    include($default);

    So könntest du deinen Array übersichtlich halten und an einer Stelle zentral abändern.
    Zuletzt geändert von PitPanda; 16.10.2011, 17:03.

    Kommentar


    • #3
      @PitPanda
      Dass es sicher ist, ist schonmal gut.

      Deine Schreibweise ist auch ok, bringt mir aber wenig. Auch wenns Übersichtlicher ist, es bedeutet trotzdem, dass ich jede Seite manuell hinzufügen muss.
      Die Zentralität ist ja eh da. (Alles ist in der index.php enthalten)


      Was mir jetzt eben wichtig wäre ist, dass die Dateien der Ordner automatisch zum Array allowed hinzugefügt werden.

      Folgenden Code hätte ich z.B. schon gefunden:

      PHP-Code:
      $handle=opendir($ordner);
      while (
      $file readdir ($handle)) // while, weil nicht klar ist wieviele Dateien im Ordner sind, also werden hier die Dateien ausgelesen 

          if (
      $file != "." && $file != ".." && $file != "thumb" && $file!="Thumbs.db"
               { 
               
      $array[] = $file// Die Dateien aus dem Ordner werden in ein array gepackt 
          


      closedir($handle); // Schließt den Ordner wieder 
      Damit füge ich alle Datein des ordners $ordner in $array.
      In meinem Fall müsste man das aber irgendwie umbauen. Im Array stehen ja dann die Datein so. (inhalt1.txt, inhalt2.txt, ...). Ich muss die im Array ja aber so stehen haben (inhalt1/inhalt1, inhalt1/inhalt2, ...), dass dann natürlich auch für mehrere Ordner, auch inhalt2 etc. und dazu noch die Dateien die im Hauptverzeichnis ohne Ordner sind (home, impressum,...).

      Leider fällt mir als Neuling da keine Lösung ein.
      Zuletzt geändert von einermeiner; 16.10.2011, 17:05.

      Kommentar


      • #4
        Schau dir mal folgende Funktionen an:
        basename(),
        __FILE__,
        __DIR__,
        realpath(),
        dirname()
        und das ultimative pathinfo()

        Damit solltest du das so bearbeiten können, dass es nach deinen Wünschen in das Array geschrieben wird.

        Du solltest aber auf jedenfall bestimmte Teile sperren, also alles was unterhalb deiner Struktur ist wo die index.php liegt, da kannst du dann mit strstr() mal gucken.
        Zuletzt geändert von PitPanda; 16.10.2011, 17:21.

        Kommentar


        • #5
          Ich glaub ich habs.
          Bin mir aber nicht sicher ob das so klappt wie ich das will.
          Der folgende Code erstellt das Whitelist array $allowed. Der Rest bleibt wie in meinem Beitrag davor.

          PHP-Code:
          $ordner = array('inhalt1''inhalt2''inhalt3')
          i=0;
          while (
          != 3) {
          $handle=opendir($ordner[i]);
          $allowed[] = "$ordner[i]"//Jeder Ordner hat auch eine entsprechende .txt Datei die eingebunden werden soll
          i++;
          while (
          $file readdir ($handle)) // while, weil nicht klar ist wieviele Dateien im Ordner sind, also werden hier die Dateien ausgelesen 

              if (
          $file != "." && $file != ".." && $file != "thumb" && file!="Thumbs.db"
                   {
               
          $info pathinfo($file);
               
          $file $info['dirname']; //Umgeformt zu (inhalt1/inhalt1)
               
          $allowed[] = $file// Die Dateien aus dem Ordner werden in ein array gepackt
              


          closedir($handle); // Schließt den Ordner wieder  
          }
          $allowed[] = "home"
          Wenn das jetzt so passt, frage ich mich was ich denn sperren soll?

          Kommentar


          • #6
            Für alle die es wissen wollen.
            Habe die folgende Lösung gefunden.

            PHP-Code:
            $i=0;
                  
            $ordner = array('inhalt1''inhalt2''inhalt3');
                  while (
            $i != 3) {
                  
            $handle=opendir($ordner[$i]);
                  
            $allowed[] = "$ordner[$i]"//Jeder Ordner hat auch eine entsprechende .txt Datei die eingebunden werden soll
                  
                  
            while ($file readdir ($handle)) // while, weil nicht klar ist wieviele Dateien im Ordner sind, also werden hier die Dateien ausgelesen 
                  

                      if (
            $file != "." && $file != ".." && $file != "thumb" && file!="Thumbs.db"
                          {
                          
            $info pathinfo($file);
                          
            $file basename($file'.'.$info['extension']);
                          
            $file "$ordner[$i]/$file";
                          
            $allowed[] = $file// Die Dateien aus dem Ordner werden in ein array gepackt
                      

                  }
                  
            $i++; 
                  
            closedir($handle); // Schließt den Ordner wieder  
                  
            }
                  
            $allowed[] = "home"$allowed[] = "impressum"
            Diese Lösung funktioniert erstmal mit der momentanen Ordnerstruktur.
            Leider schienen die ganzen Befehle wie realpath(), dirname() etc. nicht zu funktionieren. Sie gaben nur ... zurück.

            Kommentar

            Lädt...
            X