Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Sicherheit – dateisystemübergreifend

PHP-Sicherheit – dateisystemübergreifend

黄舟
黄舟Original
2017-02-21 09:15:151443Durchsuche



Dateisystem übergreifend

Unabhängig davon, wie Sie die Datei verwenden, müssen Sie den Dateinamen irgendwo angeben. In vielen Fällen wird der Dateiname als Parameter der Funktion fopen() verwendet, und andere Funktionen rufen das zurückgegebene Handle auf:

<?php
 
  $handle = fopen(&#39;/path/to/myfile.txt&#39;, &#39;r&#39;);
 
  ?>


Die Sicherheitslücke entsteht, wenn Sie kontaminierte Daten als Teil des Dateinamens angeben:

  <?php
 
  $handle =
fopen("/path/to/{$_GET[&#39;filename&#39;]}.txt", &#39;r&#39;);
 
  ?>


Da in diesem Fall der Pfad sowie die führenden und nachgestellten Teile des Dateinamens vom Angreifer nicht manipuliert werden können, sind die Angriffsmöglichkeiten begrenzt. Beachten Sie jedoch, dass einige Angriffe NULL (dargestellt als %00 in der URL) zum Beenden der Zeichenfolge verwenden und so etwaige Dateierweiterungsbeschränkungen umgehen. In diesem Fall besteht die gefährlichste Angriffsmethode darin, mit mehreren ../ auf das Verzeichnis der oberen Ebene zuzugreifen und so eine Dateisystemübergreifendheit zu erreichen. Stellen Sie sich zum Beispiel vor, dass der Wert von Dateiname wie folgt angegeben wird:

http://www.php.cn/ .. . nonether/path/to/file

Wie bei vielen Angriffen bietet die Verwendung fehlerhafter Daten beim Erstellen einer Zeichenfolge einem Angreifer die Möglichkeit, die Zeichenfolge zu ändern, was dazu führt, dass sich Ihre Anwendung auf eine Weise verhält, die Sie nicht beabsichtigen. Wenn Sie es sich zur Gewohnheit machen, nur gefilterte Daten zum Erstellen dynamischer Zeichenfolgen zu verwenden, können Sie viele Arten von Schwachstellen verhindern, darunter auch viele, mit denen Sie nicht vertraut sind.

Da der führende statische Teil des von fopen() aufgerufenen Dateinamens /path/to ist, beinhaltet der obige Angriff mehr Verzeichnisübergänge nach oben als nötig. Da der Angreifer den Quellcode nicht sehen kann, bevor er den Angriff startet, besteht eine typische Strategie darin, die Zeichenfolge ../ zu oft zu wiederholen. Wenn Sie die Zeichenfolge ../ zu oft verwenden, wird der obige Angriffseffekt nicht zerstört, sodass der Angreifer nicht die Tiefe des Verzeichnisses erraten muss.

Im obigen Angriff wird der Aufruf von fopen() so ausgeführt, dass er sich auf eine Weise verhält, die Sie nicht möchten. Es wird vereinfacht und entspricht:

  <?php
 
  $handle = fopen(&#39;/another/path/to/file.txt&#39;,
&#39;r&#39;);
 
  ?>


Nachdem sie auf das Problem aufmerksam geworden sind oder einen Angriff erlebt haben, machen viele Entwickler den Fehler, potenziell schädliche Daten zu korrigieren, manchmal ohne die Daten vorher zu überprüfen. Wie in Kapitel 1 erwähnt, besteht der beste Ansatz darin, sich Filterung als einen Prüfprozess vorzustellen und Benutzer dazu zu zwingen, die von Ihnen festgelegten Regeln zu befolgen. Wenn beispielsweise legale Dateinamen nur Buchstaben enthalten, würde der folgende Code diese Einschränkung erzwingen:

<?php
 
  $clean = array();
 
  if (ctype_alpha($_GET[&#39;filename&#39;]))
  {
    $clean[&#39;filename&#39;] = $_GET[&#39;filename&#39;];
  }
  else
  {
    /* ... */
  }
 
  $handle =
fopen("/path/to/{$clean[&#39;filename&#39;]}.txt", &#39;r&#39;);
 
  ?>


Es besteht keine Notwendigkeit, den Dateinamenwert zu maskieren, da diese Daten nur in der PHP-Funktion verwendet werden und nicht an das Remote-System übertragen werden.

Die Funktion basename() ist sehr nützlich, wenn überprüft wird, ob unnötige Pfade vorhanden sind:

<?php
 
  $clean = array();
 
  if (basename($_GET[&#39;filename&#39;]) ==
$_GET[&#39;filename&#39;])
  {
    $clean[&#39;filename&#39;] = $_GET[&#39;filename&#39;];
  }
  else
  {
    /* ... */
  }
 
  $handle =
fopen("/path/to/{$clean[&#39;filename&#39;]}.txt", &#39;r&#39;);
 
  ?>


Dieser Prozess ist weniger sicher, als nur Buchstaben in Dateinamen zuzulassen, aber es ist unwahrscheinlich, dass Sie so streng vorgehen. Ein besserer und tiefgreifenderer Präventionsprozess besteht darin, die beiden oben genannten Methoden zu kombinieren, insbesondere wenn Sie reguläre Ausdrücke verwenden, um die Rechtmäßigkeit des Codes zu überprüfen (anstelle der Funktion ctype_alpha( )).

Wenn der gesamte Teil des Dateinamens aus ungefilterten Daten besteht, entsteht eine Sicherheitslücke mit hohem Risiko:

 <?php
 
  $handle = fopen("/path/to/{$_GET[&#39;filename&#39;]}",
&#39;r&#39;);
 
  ?>


Den Angreifern mehr Flexibilität zu geben, bedeutet mehr Schwachstellen. In diesem Beispiel kann ein Angreifer den Dateinamenparameter so manipulieren, dass er auf eine beliebige Datei im Dateisystem verweist, unabhängig vom Pfad und der Dateierweiterung, da die Dateierweiterung Teil von $_GET['filename'] ist. Sobald der WEB-Server die Berechtigung zum Lesen der Datei hat, wird die Verarbeitung an die vom Angreifer angegebene Datei weitergeleitet.

Wenn der führende Teil des Pfads kontaminierte Daten verwendet, wird diese Art von Schwachstelle noch größer. Dies ist auch Gegenstand des nächsten Abschnitts.

Das Obige ist der Inhalt des PHP-Sicherheitsdateisystems. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn