Heim > Artikel > Backend-Entwicklung > Mögliche Angriffe und Lösungen bei der Installation von PHP im CGI-Modus
Wenn Sie PHP nicht in serverseitige Software (wie Apache) einbetten und als Modul installieren möchten, können Sie es im CGI-Modus installieren. Oder verwenden Sie PHP mit verschiedenen CGI-Wrappern, um sichere Chroot- und Setuid-Umgebungen für Ihren Code zu erstellen. Diese Installationsmethode installiert normalerweise die ausführbare PHP-Datei im cgi-bin-Verzeichnis des Webservers. Obwohl PHP als eigenständiger Interpreter verwendet werden kann, ist es aufgrund seines Designs resistent gegen die folgenden Arten von Angriffen:
Zugriff auf Systemdateien: http://my.host/cgi-bin/php?/etc/ passwd Die Informationen nach dem Fragezeichen (?) in der URL-Anfrage werden als Parameter der benannten Zeile an die CGI-Schnittstelle übergeben. Andere Interpreter öffnen die durch das erste Argument in der Befehlszeile angegebene Datei und führen sie aus. Beim Aufruf des im CGI-Modus installierten PHP-Interpreters verweigert dieser jedoch die Interpretation dieser Parameter.
Greifen Sie auf ein beliebiges Verzeichnis auf dem Server zu: http://my.host/cgi-bin/php/secret/doc.html Im obigen Fall befinden sich die URL-Informationen hinter dem Verzeichnis, in dem sich der PHP-Interpreter befindet /secret/ doc.html wird routinemäßig an das CGI-Programm übergeben und interpretiert. Normalerweise leitet ein Webserver es auf eine Seite wie http://my.host/secret/script.php um. Wenn dies der Fall ist, prüfen einige Server die Berechtigung des Benutzers, auf das Verzeichnis /secret zuzugreifen, bevor sie eine Weiterleitung zur Seite unter http://my.host/cgi-bin/php/secret/script.php erstellen. Leider überprüfen viele Server nicht die Berechtigung des Benutzers, auf /secret/script.php zuzugreifen, sondern nur die Berechtigung von /cgi-bin/php, sodass jeder Benutzer, der auf /cgi-bin/php zugreifen kann, auf das Webverzeichnis zugreifen kann einer beliebigen Datei. In PHP können die Konfigurationsoption --enable-force-cgi-redirect zur Kompilierungszeit und die Laufzeitkonfigurationsanweisungen doc_root und user_dir Einschränkungen für Dateien und Verzeichnisse auf dem Server hinzufügen, um solche Angriffe zu verhindern. Die Einstellungen der einzelnen Optionen werden im Folgenden ausführlich erläutert.
Fall 1: Nur öffentliche Dateien ausführen
Wenn alle Inhalte auf dem Webserver durch Passwort oder IP-Adresse eingeschränkt sind, müssen diese Optionen nicht festgelegt werden. Wenn der Webserver keine Umleitung unterstützt oder der Webserver nicht mit PHP kommunizieren kann, um Zugriffsanfragen sicherer zu machen, können Sie die Option --enable-force-cgi-redirect im Konfigurationsskript angeben. Darüber hinaus muss auch bestätigt werden, dass das PHP-Programm nicht auf andere Aufrufmethoden angewiesen ist, wie z. B. den direkten Zugriff auf http://my.host/cgi-bin/php/dir/script.php oder den Zugriff über Umleitung zu http://mein .host/dir/script.php.
In Apache können Umleitungen mithilfe von AddHandler- und Action-Anweisungen eingerichtet werden.
Fall 2: Verwenden Sie die Option --enable-force-cgi-redirect
Diese Kompilierungsoption verhindert, dass jemand auf http://my.host/cgi-bin/php/secretdir A zugreift Eine URL wie /script.php ruft PHP direkt auf. PHP analysiert in diesem Modus nur URLs, die die Umleitungsregeln des Webservers bestanden haben.
Normalerweise können Umleitungseinstellungen in Apache mit dem folgenden Befehl abgeschlossen werden:
Action php-script /cgi-bin/php AddHandler php-script .php
Diese Option wurde nur unter Apache getestet und hängt davon ab, was Apache im Umleitungsvorgang festlegt. Standard-CGI-Umgebungsvariable REDIRECT_STATUS. Wenn der Webserver keine Möglichkeit unterstützt, festzustellen, ob eine Anfrage direkt oder umgeleitet ist, kann diese Option nicht verwendet werden und es sollten andere Methoden verwendet werden.
Szenario 3: Festlegen von doc_root oder user_dir
Das Einfügen dynamischer Inhalte wie Skripts und ausführbarer Programme in das Hauptdokumentverzeichnis eines Webservers wird manchmal als unsichere Vorgehensweise angesehen. Wenn das Skript aufgrund eines Konfigurationsfehlers nicht ausgeführt werden kann und als normales HTML-Dokument angezeigt wird, kann dies zum Verlust von geistigem Eigentum oder Passwortinformationen führen. Daher richten viele Systemadministratoren speziell ein Verzeichnis ein, auf das nur über PHP CGI zugegriffen werden kann, sodass der Inhalt des Verzeichnisses nur analysiert und nicht so angezeigt wird, wie er ist.
Für die oben genannte Situation, in der es unmöglich ist, zu bestimmen, ob eine Umleitung erfolgen soll, ist es notwendig, ein doc_root-Verzeichnis für Skripte außerhalb des Hauptdokumentverzeichnisses zu erstellen.
Sie können das Home-Verzeichnis des PHP-Skripts über doc_root in der Konfigurationsdatei oder durch Festlegen der Umgebungsvariablen PHP_DOCUMENT_ROOT definieren. Wenn diese Option gesetzt ist, interpretiert PHP nur Dateien im Verzeichnis doc_root und stellt sicher, dass Skripte außerhalb des Verzeichnisses nicht vom PHP-Interpreter ausgeführt werden (mit Ausnahme des unten erwähnten Benutzerverzeichnisses).
Eine weitere verfügbare Option ist user_dir. Wenn user_dir nicht festgelegt ist, ist doc_root die einzige Option, die steuert, wo die Datei geöffnet wird. Beim Zugriff auf eine URL wie http://my.host/~user/doc.php wird die Datei im Home-Verzeichnis des Benutzers nicht geöffnet, sondern nur ~user/doc.php im Verzeichnis doc_root ausgeführt (dies Unterverzeichnis beginnt mit [ ~] als Anfang).
Wenn user_dir festgelegt ist, z. B. public_php, führt eine Anfrage wie http://my.host/~user/doc.php die Datei doc.php im Unterverzeichnis public_php im Home-Verzeichnis des Benutzers aus. Unter der Annahme, dass der absolute Pfad des Home-Verzeichnisses des Benutzers /home/user ist, lautet die ausgeführte Datei /home/user/public_php/doc.php.
user_dir 的设置与 doc_root 无关,所以可以分别控制 PHP 脚本的主目录和用户目录。
情形四:PHP 解释器放在 web 目录以外
一个非常安全的做法就是把 PHP 解释器放在 web 目录外的地方,比如说 /usr/local/bin。这样做唯一不便的地方就是必须在每一个包含 PHP 代码的文件的第一行加入如下语句:
#!/usr/local/bin/php
还要将这些文件的属性改成可执行。也就是说,要像处理用 Perl 或 sh 或其它任何脚本语言写的 CGI 脚本一样,使用以 #! 开头的 shell-escape 机制来启动它们。
在这种情况下,要使 PHP 能正确处理 PATH_INFO 和 PATH_TRANSLATED 等变量的话,在编译 PHP 解释器时必须加入 --enable-discard-path 参数。