Ich habe eine PHP-Datei, die ich so exklusiv als Include verwenden werde. Daher möchte ich einen Fehler auslösen, anstatt ihn auszuführen, wenn direkt darauf zugegriffen wird, indem ich die URL eingebe, anstatt eingeschlossen zu werden.
Grundsätzlich muss ich eine Überprüfung wie folgt in der PHP-Datei durchführen:
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");
Gibt es eine einfache Möglichkeit, dies zu tun?
php
include
include-guards
Alterlife
quelle
quelle
Antworten:
Der einfachste Weg für die generische Situation "PHP-App, die auf einem Apache-Server ausgeführt wird, den Sie möglicherweise vollständig steuern oder nicht", besteht darin, Ihre Includes in einem Verzeichnis abzulegen und den Zugriff auf dieses Verzeichnis in Ihrer .htaccess-Datei zu verweigern. Wenn Sie Apache verwenden, legen Sie dies in einer Datei mit dem Namen ".htaccess" in dem Verzeichnis ab, auf das Sie nicht zugreifen möchten, um den Leuten das Googeln zu ersparen:
Wenn Sie tatsächlich die volle Kontrolle über den Server haben (heutzutage sogar bei kleinen Apps häufiger als beim ersten Schreiben dieser Antwort), besteht der beste Ansatz darin, die zu schützenden Dateien außerhalb des Verzeichnisses zu speichern, von dem aus Ihr Webserver bereitgestellt wird . Wenn Ihre App aktiviert ist
/srv/YourApp/
, stellen Sie den Server so ein, dass Dateien von bereitgestellt werden,/srv/YourApp/app/
und fügen Sie die Includes ein/srv/YourApp/includes
, sodass buchstäblich keine URL darauf zugreifen kann.quelle
<Files ~ "\.inc$">
Order Allow,Deny
Deny from All
</Files>
Fügen Sie dies der Seite hinzu, die nur aufgenommen werden soll
dann auf den Seiten, die es enthalten, hinzufügen
quelle
somefile.php
auf Ihrem Server erstellt und Ihre Definition hinzugefügt haben, können sie trotzdem nicht direkt auf die Include-Datei zugreifen. Dadurch können sie Ihre Bibliotheksdateien "einschließen". Wenn sie jedoch weit genug kommen, um Dateien auf Ihrem Server zu erstellen und Ihre Definitions- / Include-Skripte zu kennen, haben Sie andere Probleme, die das Schreiben ihrer eigenen Datei mit Ihrer Definition wahrscheinlich zunächst negieren .Ich habe eine Datei, die ich anders verhalten muss, wenn sie enthalten ist, als wenn direkt darauf zugegriffen wird (hauptsächlich eine
print()
vsreturn()
). Hier ist ein modifizierter Code:Die Datei, auf die zugegriffen wird, ist immer eine enthaltene Datei, daher == 1.
quelle
Der beste Weg, um den direkten Zugriff auf Dateien zu verhindern, besteht darin, sie außerhalb des Webserver-Dokumentstamms zu platzieren (normalerweise eine Ebene darüber). Sie können sie weiterhin einschließen, es besteht jedoch keine Möglichkeit, dass jemand über eine http-Anfrage auf sie zugreift.
Normalerweise gehe ich den ganzen Weg und platziere alle meine PHP-Dateien außerhalb des Dokumentstamms neben der Bootstrap-Datei - eine einzelne index.php im Dokumentstamm, die mit dem Routing der gesamten Website / Anwendung beginnt.
quelle
1: Überprüfen der Anzahl der enthaltenen Dateien
Logik: PHP wird beendet, wenn die minimale Anzahl von Includes nicht erreicht wird. Beachten Sie, dass die Basisseite vor PHP5 nicht als Include betrachtet wird.
2: Definieren und Überprüfen einer globalen Konstante
Logik: Wenn die Konstante nicht definiert ist, wurde die Ausführung nicht von der Basisseite aus gestartet, und PHP wurde nicht mehr ausgeführt.
Beachten Sie, dass aus Gründen der Portabilität über Upgrades und zukünftige Änderungen hinweg die Modularisierung dieser Authentifizierungsmethode den Codierungsaufwand erheblich reduzieren würde, da die Änderungen nicht für jede einzelne Datei fest codiert werden müssen.
Auf diese Weise kann zusätzlicher Code für Protokollierungs- und Analysezwecke sowie zum Generieren geeigneter Antworten hinzugefügt werden
checkdefined.php
.Kredit, wo Kredit fällig ist: Die brillante Idee der Portabilität entstand aus dieser Antwort .
3: Remote-Adressautorisierung
Der Nachteil dieser Methode ist die isolierte Ausführung, es sei denn, ein Sitzungstoken wird mit der internen Anforderung bereitgestellt. Überprüfen Sie dies über die Loopback-Adresse bei einer einzelnen Serverkonfiguration oder über eine Adress-Whitelist für eine Serverinfrastruktur mit mehreren Servern oder Lastenausgleich.
4: Token-Autorisierung
Ähnlich wie bei der vorherigen Methode kann GET oder POST verwendet werden, um ein Autorisierungstoken an die Include-Datei zu übergeben:
Eine sehr unordentliche Methode, aber vielleicht auch die sicherste und vielseitigste zugleich, wenn sie richtig eingesetzt wird.
5: Webserver-spezifische Konfiguration
Auf den meisten Servern können Sie Berechtigungen für einzelne Dateien oder Verzeichnisse zuweisen. Sie können alle Ihre Includes in solchen eingeschränkten Verzeichnissen ablegen und den Server so konfigurieren, dass sie verweigert werden.
In APACHE wird die Konfiguration beispielsweise in der
.htaccess
Datei gespeichert . Tutorial hier .Beachten Sie jedoch, dass serverspezifische Konfigurationen von mir nicht empfohlen werden, da sie die Portabilität zwischen verschiedenen Webservern beeinträchtigen. In Fällen wie Content Management-Systemen, in denen der Verweigerungsalgorithmus komplex ist oder die Liste der verweigerten Verzeichnisse ziemlich groß ist, werden Rekonfigurationssitzungen möglicherweise nur ziemlich grausam. Am Ende ist es am besten, dies im Code zu behandeln.
6: Das Platzieren umfasst in einem sicheren Verzeichnis AUSSERHALB des Site-Stamms
Am wenigsten bevorzugt aufgrund von Zugriffsbeschränkungen in Serverumgebungen, aber eine ziemlich leistungsfähige Methode, wenn Sie Zugriff auf das Dateisystem haben.
Logik:
htdocs
Ordners anfordern, da die Links außerhalb des Bereichs des Adresssystems der Website liegen würden.Bitte entschuldigen Sie meine unorthodoxen Codierungskonventionen. Jedes Feedback wird geschätzt.
quelle
Eine Alternative (oder Ergänzung) zu Chucks Lösung wäre, den Zugriff auf Dateien zu verweigern, die einem bestimmten Muster entsprechen, indem Sie so etwas in Ihre .htaccess-Datei einfügen
quelle
Eigentlich ist mein Rat, all diese Best Practices zu machen.
Auf diese Weise sind die Dateien immer noch geschützt, wenn sie irgendwie verlegt werden (ein fehlerhafter FTP-Vorgang).
quelle
Ich hatte dieses Problem einmal gelöst mit:
Die ideale Lösung besteht jedoch darin, die Datei außerhalb des Webserver-Dokumentstamms zu platzieren, wie in einer anderen Antwort erwähnt.
quelle
Sie sollten eine Anwendung mit einem Einstiegspunkt erstellen, dh alle Dateien sollten über index.php erreichbar sein
Platziere dies in index.php
Diese Prüfung sollte in jeder verknüpften Datei ausgeführt werden (über require oder include).
quelle
Ich wollte den Zugriff auf die PHP- Datei direkt einschränken , aber auch über aufrufen können
jQuery $.ajax (XMLHttpRequest)
. Hier ist, was für mich funktioniert hat.quelle
Am einfachsten ist es, eine Variable in der Datei festzulegen, zu der Aufrufe gehören, z
Suchen Sie dann in der enthaltenen Datei nach der Variablen
quelle
Neben dem .htaccess-Weg habe ich ein nützliches Muster in verschiedenen Frameworks gesehen, zum Beispiel in Ruby on Rails. Sie haben ein separates pub / -Verzeichnis im Anwendungsstammverzeichnis und die Bibliotheksverzeichnisse befinden sich in Verzeichnissen auf derselben Ebene wie pub /. So etwas (nicht ideal, aber Sie haben die Idee):
Sie richten Ihren Webserver so ein, dass pub / als Dokumentenstamm verwendet wird. Dies bietet einen besseren Schutz für Ihre Skripte: Während sie vom Dokumentstamm aus greifen können, um die erforderlichen Komponenten zu laden, ist es unmöglich, über das Internet auf die Komponenten zuzugreifen. Ein weiterer Vorteil neben der Sicherheit ist, dass sich alles an einem Ort befindet.
Dieses Setup ist besser als nur das Erstellen von Überprüfungen in jeder einzelnen enthaltenen Datei, da die Meldung "Zugriff nicht zulässig" ein Hinweis für Angreifer ist, und es ist besser als die .htaccess-Konfiguration, da sie nicht auf einer weißen Liste basiert: Wenn Sie die Dateierweiterungen vermasseln Es ist in den Verzeichnissen lib /, conf / etc. nicht sichtbar.
quelle
Was für Joomla! Dabei wird eine Konstante in einer Stammdatei definiert und geprüft, ob diese in den enthaltenen Dateien definiert ist.
oder aber
Man kann alle Dateien außerhalb der Reichweite einer http-Anfrage halten, indem man sie außerhalb des Webroot-Verzeichnisses platziert, wie es die meisten Frameworks wie CodeIgniter empfehlen.
Oder indem Sie eine .htaccess-Datei in den Include-Ordner legen und Regeln schreiben, können Sie den direkten Zugriff verhindern.
quelle
quelle
Meine Antwort ist etwas anders, enthält aber viele der hier gegebenen Antworten. Ich würde einen mehrstufigen Ansatz empfehlen:
defined('_SOMECONSTANT') or die('Hackers! Be gone!');
JEDOCH das
defined or die
hat Ansatz eine Reihe von Schwächen. Erstens ist es ein echtes Problem bei den Annahmen, mit denen getestet und debuggt werden muss. Zweitens geht es um schrecklich, nervenaufreibend langweiliges Refactoring, wenn Sie Ihre Meinung ändern. "Suchen und Ersetzen!" du sagst. Ja, aber wie sicher bist du dir, dass es überall genau gleich geschrieben ist, hmmm? Multiplizieren Sie das jetzt mit Tausenden von Dateien ... oOUnd dann gibt es .htaccess. Was passiert, wenn Ihr Code auf Websites verteilt wird, auf denen der Administrator nicht so gewissenhaft ist? Wenn Sie sich nur auf .htaccess verlassen, um Ihre Dateien zu sichern, benötigen Sie außerdem a) ein Backup, b) eine Schachtel Taschentücher zum Trocknen Ihrer Tränen, c) einen Feuerlöscher, um die Flammen in der gesamten Hatemail von Personen zu löschen Verwenden Sie Ihren Code.
Ich weiß also, dass die Frage nach dem "einfachsten" fragt, aber ich denke, was dies erfordert, ist mehr "defensive Codierung".
Was ich vorschlage ist:
require('ifyoulieyougonnadie.php');
( nichtinclude()
und als Ersatz fürdefined or die
)In
ifyoulieyougonnadie.php
, einige Logik Sachen - Skript Prüfung für verschiedene Konstanten, nennen, localhost zu testen und so - und dann realisieren Ihredie(), throw new Exception, 403
etc.Ich erstelle mein eigenes Framework mit zwei möglichen Einstiegspunkten - dem Hauptindex.php (Joomla-Framework) und ajaxrouter.php (mein Framework) - also überprüfe ich je nach Einstiegspunkt nach verschiedenen Dingen. Wenn die Anfrage
ifyoulieyougonnadie.php
nicht aus einer dieser beiden Dateien stammt, weiß ich, dass Shenanigans unternommen werden!Aber was ist, wenn ich einen neuen Einstiegspunkt hinzufüge? Keine Sorge. Ich ändere mich nur
ifyoulieyougonnadie.php
und bin sortiert, plus kein "Finden und Ersetzen". Hurra!Was wäre, wenn ich mich entschließen würde, einige meiner Skripte zu verschieben, um ein anderes Framework zu erstellen, das nicht dieselben Konstanten hat
defined()
? ... Hurra! ^ _ ^Ich fand, dass diese Strategie die Entwicklung viel lustiger und viel weniger macht:
quelle
Wenn genauer, sollten Sie diese Bedingung verwenden:
get_included_files () gibt ein indiziertes Array zurück, das die Namen aller enthaltenen Dateien enthält (wenn die Datei beign ausgeführt wird, wurde sie eingeschlossen und ihr Name befindet sich im Array). Wenn also direkt auf die Datei zugegriffen wird, ist ihr Name der erste im Array, alle anderen Dateien im Array wurden eingeschlossen.
quelle
Platziere den obigen Code oben in deiner enthaltenen PHP-Datei.
Ex:
quelle
Der folgende Code wird im Flatnux CMS ( http://flatnux.altervista.org ) verwendet:
quelle
Ich habe diese reine PHP-Lösung gefunden, die sowohl mit http als auch mit cli funktioniert:
Definieren Sie eine Funktion:
Rufen Sie die Funktion in der Datei auf, auf die Sie den direkten Zugriff verhindern möchten:
Die meisten der oben angegebenen Lösungen für diese Frage funktionieren nicht im Cli-Modus.
quelle
quelle
quelle
Das Speichern Ihrer Include-Dateien außerhalb des über das Internet zugänglichen Verzeichnisses wurde bereits einige Male erwähnt und ist sicherlich eine gute Strategie, wenn dies möglich ist. Eine weitere Option, die ich noch nicht gesehen habe: Stellen Sie sicher, dass Ihre Include-Dateien keinen ausführbaren Code enthalten . Wenn Ihre Include-Dateien lediglich Funktionen und Klassen definieren und keinen anderen Code enthalten, wird beim direkten Zugriff einfach eine leere Seite erstellt.
Erlauben Sie auf jeden Fall den direkten Zugriff auf diese Datei über den Browser: Sie wird nichts tun . Es definiert einige Funktionen, aber keine von ihnen wird aufgerufen, sodass keine von ihnen ausgeführt wird.
Gleiches gilt für Dateien, die nur PHP-Klassen enthalten, und sonst nichts.
Es ist immer noch eine gute Idee, Ihre Dateien möglichst außerhalb des Webverzeichnisses zu halten.
system
, da dies mit einem für Code verwendeten Pfad in Konflikt stehen würde. Ich finde das nervig.quelle
Mach so etwas wie:
quelle
Sie können die folgende Methode verwenden, obwohl sie einen Fehler aufweist, da sie gefälscht werden kann, es sei denn, Sie können eine weitere Codezeile hinzufügen, um sicherzustellen, dass die Anforderung nur mithilfe von Javascript von Ihrem Server stammt. Sie können diesen Code im Abschnitt "Text" Ihres HTML-Codes platzieren, sodass der Fehler dort angezeigt wird.
Platzieren Sie hier Ihren anderen HTML-Code
Beenden Sie es so, damit die Ausgabe des Fehlers immer im Body-Bereich angezeigt wird, wenn Sie dies möchten.
quelle
Ich schlage vor,
$_SERVER
aus Sicherheitsgründen nicht zu verwenden.Sie können eine Variable wie
$root=true;
in der ersten Datei verwenden, die eine andere enthält.und
isset($root)
am Anfang der zweiten Datei verwenden, die enthalten sein soll.quelle
Sie können das Verzeichnis auch mit einem Kennwort schützen und alle Ihre PHP-Skripte darin aufbewahren, natürlich mit Ausnahme der Datei index.php, da zum Zeitpunkt des Einschlusskennworts kein Kennwort erforderlich ist, da es nur für den http-Zugriff erforderlich ist. Sie erhalten außerdem die Möglichkeit, auf Ihre Skripte zuzugreifen, falls Sie dies wünschen, da Sie über ein Kennwort für den Zugriff auf dieses Verzeichnis verfügen. Sie müssen eine .htaccess-Datei für das Verzeichnis und eine .htpasswd-Datei einrichten, um den Benutzer zu authentifizieren.
Nun, Sie können auch eine der oben bereitgestellten Lösungen verwenden, falls Sie der Meinung sind, dass Sie nicht normal auf diese Dateien zugreifen müssen, da Sie immer über cPanel usw. darauf zugreifen können.
Hoffe das hilft
quelle
Am einfachsten ist es, Ihre Includes außerhalb des Webverzeichnisses zu speichern. Auf diese Weise hat der Server Zugriff auf sie, jedoch keinen externen Computer. Der einzige Nachteil ist, dass Sie auf diesen Teil Ihres Servers zugreifen können müssen. Der Vorteil ist, dass keine Einrichtung, Konfiguration oder zusätzliche Code- / Serverbelastung erforderlich ist.
quelle
Ich fand die Vorschläge mit .htaccess nicht so gut, weil sie möglicherweise andere Inhalte in diesem Ordner blockieren, auf die der Benutzer möglicherweise zugreifen darf. Dies ist meine Lösung:
quelle
wird die Arbeit reibungslos erledigen
quelle
BASEPATH
const
wird in einerindex.php
Datei festgelegt, die sich am Ende der Baumstruktur befindet. CI schreibt die URLs neu, sodass ohnehin kein direkter Zugriff auf die Skripte erforderlich ist.Die zuvor erwähnte Lösung mit PHP-Versionsprüfung wurde hinzugefügt:
quelle