Frage von netcube, 4

PHP - Sicherheitslücke - Wie fixen und überhaupt relevant in diesem Fall?

Hi, Community. Ich arbeite an einer Website. Das Menü funktioniert folgendermaßen. Wenn ich ein Button anklicke wird am "index.php" ein "?site=Seiten Name" hinzugefügt (über eine normalen Link). und jetzt wird die Seite durch ein "include" angezeigt.

 include("site/$site");

Ganzer Script:

$site = $_GET["site"];
        if($site == ""){
        header("location:index.php?site=home");
        exit;
        }
        else{
             if(file_exists("site/$site")){
            include("site/$site");
             }else{
                 echo "Der Script wurde gestoppt!";
                 exit;
             }
        }

Vor kurzem hab ich versucht die "Notice" Meldungen zu unterdrücken (Wegen undefinierten Variablen). Ich hab gelesen das undefinierte Variablen eine Sicherheitslücke sind. Wäre das hier bei diesem Script ein Problem wen eine Variable undefiniert ist oder nicht? Wäre das Problem so gefixt (Mit der Umleitung und wenn es die Datei nicht gibt das der Script gestoppt wird?)

Danke im voraus für eine Antwort.

Antwort
von FaronWeissAlles, 2

Das was du da vorhast ist ein absolutes No-Go und eine der größten Sicherheitslücken die man überhaupt konstruieren kann! Dein Code erlaubt einem potenziellen Angreifer unkontrolliert Zugriff auf jede Datei auf deinem kompletten Server. Und durch die URL kann man das direkt sehen, weil du einen Dateinamen übergibst. Was man damit machen kann ist z.B. auf die passwd-Datei des Webservers zuzugreifen, Skripte in nicht festgelegter Reihenfolge aufrufen (was eine potenzielle Sicherheitslücke ist) oder gar andere Webseiten aufrufen (je nach Konfiguration). Niemals Variablen in include/require verwenden, es sei denn dass du dessen Inhalt genau überprüfst (Whitelist).

Wenn du´s schon dirty machst, dann bitte so:

$sites = array( "home" => "home.php", "about" => "impressum.php"); 
include "/site/". $sites[array_key_exists($_GET["site"],$sites) ? $_GET["site"] : exit() ];

Die Verwendung von nicht-existenten Variablen ist keine Sicherheitslücke, kann aber eine werden wenn der verwendende Befehl dadurch ein ungewolltes Verhalten an den Tag legt und somit eine potenzielle Lücke darstellt.

Um dein Skript abzusichern solltest du

  • absolut jede Eingabe auf Inhalt prüfen. Wenn´s irgendwie möglich ist mit einer Whitelist, ansonsten (z.B. bei Nachrichten-Text) wenigstens gefährliche Zeichen escapen. Jeder Angriff auf dein Skript (ausgenommen sind DoS-Angriffe, die richten sich auf den Server) läuft über die Eingaben (GET, POST, COOKIE). Daher solltest du dort nur das zulassen was du auch erwartest.
  • Variablen die Zugangsdaten beinhalten direkt nach dem Aufbau der Verbindung leeren (unset)
  • Sicherstellen dass man include-Skripte nicht einfach so aufrufen kann, sondern nur die von dir gewollten (mithilfe einer Konstanten)
  • Gib dem Angreifer keine Information. Im Produktivbetrieb schalte "display errors" aus und verrate auch nichts über den Server (Servername, Version, PHP-Version, etc). Tarne deine *.php-Dateien als *htm-Dateien mit mod_rewrite
Kommentar von netcube ,

Interessant. Frage, was ist genau eine Konstante? Wäre eine bessere Lösung einfach eine Datei zu erstellen und einfach eine Datei namens Top.php für das Menü und so und eine Bottom.php für das Ende der Seite zu includen? Danke für den Script, danke für die Aufklärung (Ich bin leider noch in keiner Ausbildung, darf noch in die Schule).

Kommentar von FaronWeissAlles ,

Eine Konstate ist sowas wie eine unveränderliche Variable (ok, "unveränderliche Variable" schließt sich gegenseitig aus so wie "glutenfreies Saitan", aber ich weiß grad nicht wie ich Konstate anders beschreiben soll ^^). Du definierst sie, nennen wir sie "RUN", in php-Skripten die aufgerufen werden dürfen (so wie die index.php oder impressum.php). php-Skripte die nicht direkt aufgerufen werden dürfen (z.B. die top.php oder bottom.php in dem nur Teile deiner Seite liegen - gute Idee übrigens!) fragst du ab ob sie definiert wurde. Falls nicht, terminiert das Skript. Damit funktioniert dann die top.php nur wenn sie von der index.php und anderen "Hauptseiten" included wurde. Beispiel:

index.php (oder eine andere direkt aufrufbare Seite):

define("RUN",1);
//danach deine includes und der ganze Rest

top.php (oder eine andere nicht direkt aufrufbare Seite):

if(!defined("RUN"))
    exit;

//danach dein Code

Einer der großen Vorteile von PHP gegenüber statischen HTML-Seiten ist dass du Code wiederverwenden kannst und ihn so nur einmal schreiben musst. Das Grundgerüst der Seite, Menüs, etc. kannst du in eigene Dateien auslagern und sie dann nach Bedarf einfach an die richtige Stelle includen und musst nicht x Kopien eines Menüs erstellen (was äußerst nervig wird wenn du mal was ändern willst, dann darfst du in jeder Datei das ganze anpassen)

Keine passende Antwort gefunden?

Fragen Sie die Community