Verhindern Sie den direkten Zugriff auf eine PHP-Include-Datei

166

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?

Alterlife
quelle
10
anstelle von die () sollten Sie den Header testen ("HTTP / 1.1 404 File Not Found", 404); Ausfahrt;'. Dadurch wird (zumindest bei Apache) der Server die normale 404-Seite zurückgeben.
Gnud
Hier sind zwei einfache Methoden, die ich erklärt habe, um den direkten Zugriff in PHP-Dateien zu deaktivieren - codespeedy.com/disable-direct-access-to-the-php-include-file
Faruque Ahamed Mollick

Antworten:

173

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:

Deny from all

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.

Futter
quelle
1
Vielen Dank, da ich die volle Kontrolle über den Server habe, auf dem ich diese App ausführe, ist dies die Antwort, mit der ich gegangen bin.
Alterlife
24
Wenn Sie die volle Kontrolle über den Server haben, ist es besser, wenn Sie die Konfiguration in eine Verzeichnisanweisung in die Konfigurationsdatei des virtuellen Hosts einfügen. Apache las es nur einmal beim Start, .htaccess wird bei jedem Zugriff gelesen und verlangsamt den Server
Eineki
22
Es wäre schön, eine Beispiel-.htaccess-Datei als Teil dieser Antwort zu haben.
Graham Lea
7
<Files ~ "\.inc$"> Order Allow,Deny Deny from All </Files>
Dracorat
11
@ James: Außerdem ist nicht jeder der Meinung, dass Stack Overflow eine "plz send the codez" -Seite sein sollte. Wenn es die Frage klar beantwortet, ist es eine gute Antwort. Wenn Sie ein Beispiel angeben, für das keines benötigt wird, wird nur das Codieren und Einfügen gefördert.
Chuck
188

Fügen Sie dies der Seite hinzu, die nur aufgenommen werden soll

<?php
if(!defined('MyConst')) {
   die('Direct access not permitted');
}
?>

dann auf den Seiten, die es enthalten, hinzufügen

<?php
define('MyConst', TRUE);
?>
UnkwnTech
quelle
3
Ich muss wirklich lernen, schneller zu tippen. Dies ist der gleiche Weg, den ich vorschlagen würde, da er sicherer ist als eine Methode, die eine Variable zum Überprüfen verwendet. Da es bei einigen PHP-Setups möglich ist, die Variable zu überschreiben.
Mark Davidson
3
So gehen einige "Mainstream" -Anwendungen damit um. Ich weiß, dass Joomla das so macht und ich denke, Wiki, Wordpress und andere auch.
UnkwnTech
1
Vielleicht ist die Nachricht für einen Hacker zu hilfreich (kein wirklicher Benutzer würde diese Seiten finden). Sie können einfach einen Weiterleitungsheader senden und die PHP-Verarbeitung stoppen.
Bandi
7
Senden Sie einfach einen 404-Header und beenden Sie ihn - die Fehlerseite sieht identisch aus mit normalen 404-Seiten (zumindest unter Apache).
Gnud
4
@ Smile.Hunter: Hier geht es darum, den Zugriff auf die direkte Anzeige Ihrer Include / Library-Skriptdateien zu blockieren. Die Antwort funktioniert. Wenn sie somefile.phpauf 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 .
James
114

Ich habe eine Datei, die ich anders verhalten muss, wenn sie enthalten ist, als wenn direkt darauf zugegriffen wird (hauptsächlich eine print()vs return()). Hier ist ein modifizierter Code:

if(count(get_included_files()) ==1) exit("Direct access not permitted.");

Die Datei, auf die zugegriffen wird, ist immer eine enthaltene Datei, daher == 1.  

Null
quelle
12
Das ist eigentlich eine verdammt gute Idee, die Anzahl der enthaltenen Dateien zu überprüfen. Ich frage mich, was besser ist: Definieren verwenden oder diese Methode verwenden? Dies scheint in sich geschlossener zu sein.
Akoi Meexx
Zum ersten Mal habe ich jemanden gesehen, der sich das ausgedacht hat. Ich weiß jedoch nicht warum, weil es so eigenständig wie möglich zu sein scheint und direkt misst, was Sie tatsächlich wissen möchten (ob es enthalten ist oder nicht), anstatt etwas zu messen, von dem angenommen wird, dass es assoziiert ist (wie eine bestimmte Konstante oder eine bestimmter Ort von .htaccess gesperrt). Wunderschönen.
Jimbo Jonny
Dieser ist wirklich cool, da die Verwendung von .htaccess zum Blockieren aller .php-Dateien möglicherweise nicht immer möglich ist, da sich einige Dateien im selben Verzeichnis befinden können, die direkt oder sogar von Javascripts aufgerufen werden müssen. Danke für diese tolle Idee!
Anuj
3
Dies funktioniert nur in PHP5 und höher. Vor PHP5 möchten Sie erneut 0 statt 1 vergleichen.
jmucchiello
Dies ist eine wirklich clevere Lösung, mit der Sie den direkten Zugriff steuern und nicht nur blockieren können - das gefällt mir. Normalerweise füge ich Unit-Tests in die Dateien selbst ein, und auf diese Weise kann ich meine Unit-Tests in diese if-Anweisung einschließen.
Ich frage
34

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.

Eran Galperin
quelle
3
Dies ist eine großartige Lösung, wenn Sie dazu in der Lage sind. Ich musste erst vor kurzem anfangen, mit gemeinsam genutzten Webhosts zu arbeiten, und stellte einen der vielen Ärger fest, dass sich alles in der Docroot befinden muss.
Beau Simensen
3
Bei jedem Hosting-Anbieter, mit dem ich zusammengearbeitet habe, hatte ich immer Zugriff auf (genau) eine Ebene über dem Dokumentenstamm.
Eran Galperin
3
Bei einigen Hosts (einschließlich meines aktuellen) können Sie Ihre Domain auf einen beliebigen Ordner verweisen.
Dinah
1
Dies ist auch eine gute Alternative. Verwenden Sie preg_match -> if (preg_match ("~ globalfile \ .php ~ i", $ _SERVER ['PHP_SELF'])) {die ('<h3 style = "color: red"> Appliance-Sicherheitswarnung - Direktzugriff nicht zulässig! Ihre IP wurde protokolliert! <H3> '); // Weitere Ausführung stoppen}
MarcoZen
Diese URL devzone.zend.com/node/view/id/70 ist jetzt eine 404. Die Antwort sollte den Code enthalten, der ursprünglich von dieser nicht vorhandenen URL verwendet wurde.
Funk Forty Niner
31

1: Überprüfen der Anzahl der enthaltenen Dateien

if( count(get_included_files()) == ((version_compare(PHP_VERSION, '5.0.0', '>='))?1:0) )
{
    exit('Restricted Access');
}

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

// In the base page (directly accessed):
define('_DEFVAR', 1);

// In the include files (where direct access isn't permitted):
defined('_DEFVAR') or exit('Restricted Access');

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.

// Put the code in a separate file instead, say 'checkdefined.php':
defined('_DEFVAR') or exit('Restricted Access');

// Replace the same code in the include files with:
require_once('checkdefined.php');

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

// Call the include from the base page(directly accessed):
$includeData = file_get_contents("http://127.0.0.1/component.php?auth=token");

// In the include files (where direct access isn't permitted):
$src = $_SERVER['REMOTE_ADDR']; // Get the source address
$auth = authoriseIP($src); // Authorisation algorithm
if( !$auth ) exit('Restricted Access');

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:

if($key!="serv97602"){header("Location: ".$dart);exit();}

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 .htaccessDatei 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.

//Your secure dir path based on server file-system
$secure_dir=dirname($_SERVER['DOCUMENT_ROOT']).DIRECTORY_SEPARATOR."secure".DIRECTORY_SEPARATOR;
include($secure_dir."securepage.php");

Logik:

  • Der Benutzer kann keine Datei außerhalb des htdocsOrdners anfordern, da die Links außerhalb des Bereichs des Adresssystems der Website liegen würden.
  • Der PHP-Server greift nativ auf das Dateisystem zu und kann daher auf Dateien auf einem Computer zugreifen, genau wie es ein normales Programm mit den erforderlichen Berechtigungen kann.
  • Indem Sie die Include-Dateien in dieses Verzeichnis stellen, können Sie sicherstellen, dass der PHP-Server auf sie zugreifen kann, während dem Benutzer die Verknüpfung verweigert wird.
  • Selbst wenn die Dateisystemzugriffskonfiguration des Webservers nicht ordnungsgemäß durchgeführt wurde, würde diese Methode verhindern, dass diese Dateien versehentlich öffentlich werden.

Bitte entschuldigen Sie meine unorthodoxen Codierungskonventionen. Jedes Feedback wird geschätzt.

RiA
quelle
Ich mag die Nummer 2
Baim Wrong
26

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

<FilesMatch "\.(inc)$">
    Order deny,allow
    Deny from all
</FilesMatch>
Kevin Loney
quelle
Ich glaube, es wäre besser, .inc.php zu verwenden, und es ist eine gängige Praxis
Lis
14

Eigentlich ist mein Rat, all diese Best Practices zu machen.

  • Legen Sie die Dokumente außerhalb des Webroots ODER in ein Verzeichnis, dem der Webserver AND den Zugriff verweigert
  • Verwenden Sie in Ihren sichtbaren Dokumenten eine Definition, auf die die versteckten Dokumente prüfen:
      if (!defined(INCL_FILE_FOO)) {
          header('HTTP/1.0 403 Forbidden');
          exit;
      }

Auf diese Weise sind die Dateien immer noch geschützt, wenn sie irgendwie verlegt werden (ein fehlerhafter FTP-Vorgang).

jmucchiello
quelle
8

Ich hatte dieses Problem einmal gelöst mit:

if (strpos($_SERVER['REQUEST_URI'], basename(__FILE__)) !== false) ...

Die ideale Lösung besteht jedoch darin, die Datei außerhalb des Webserver-Dokumentstamms zu platzieren, wie in einer anderen Antwort erwähnt.

mati
quelle
7

Sie sollten eine Anwendung mit einem Einstiegspunkt erstellen, dh alle Dateien sollten über index.php erreichbar sein

Platziere dies in index.php

define(A,true);

Diese Prüfung sollte in jeder verknüpften Datei ausgeführt werden (über require oder include).

defined('A') or die(header('HTTP/1.0 403 Forbidden'));
user2221806
quelle
7

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.

if (empty($_SERVER["HTTP_X_REQUESTED_WITH"]) && $_SERVER["HTTP_X_REQUESTED_WITH"] != "XMLHttpRequest") {
    if (realpath($_SERVER["SCRIPT_FILENAME"]) == __FILE__) { // direct access denied
        header("Location: /403");
        exit;
    }
}
krasenslavov
quelle
3

Am einfachsten ist es, eine Variable in der Datei festzulegen, zu der Aufrufe gehören, z

$including = true;

Suchen Sie dann in der enthaltenen Datei nach der Variablen

if (!$including) exit("direct access not permitted");
Kyle Cronin
quelle
2
Dies ist gefährlich, wenn register_globals aktiviert ist.
jmucchiello
25
PHP ist gefährlich, wenn register_globals aktiviert ist.
David Precious
3

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):

app/
 |
 +--pub/
 |
 +--lib/
 |
 +--conf/
 |
 +--models/
 |
 +--views/
 |
 +--controllers/

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.

Bandi
quelle
Nach langer Zeit möchte ich nur noch kommentieren, dass das oben beschriebene Modell MVC-Modell (Model - View - Controller) heißt. Wenn Sie möchten, überprüfen Sie Google und fügen Sie Ihrer Antwort weitere Informationen hinzu. MVC unterstützt nicht nur Ruby on Rails- und ASP.NET-Anwendungen, sondern auch PHP (siehe Lavarel, CakePHP).
3

Was für Joomla! Dabei wird eine Konstante in einer Stammdatei definiert und geprüft, ob diese in den enthaltenen Dateien definiert ist.

defined('_JEXEC') or die('Restricted access');

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.

Pradeesh Kumar
quelle
3
debug_backtrace() || die ("Direct access not permitted");
Unirgy
quelle
3

Meine Antwort ist etwas anders, enthält aber viele der hier gegebenen Antworten. Ich würde einen mehrstufigen Ansatz empfehlen:

  1. .htaccess- und Apache-Einschränkungen sicher
  2. defined('_SOMECONSTANT') or die('Hackers! Be gone!');

JEDOCH das defined or diehat 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 ... oO

Und 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:

  1. Vor einem Ihrer Skripte require('ifyoulieyougonnadie.php');( nicht include() und als Ersatz für defined or die)
  2. In ifyoulieyougonnadie.php, einige Logik Sachen - Skript Prüfung für verschiedene Konstanten, nennen, localhost zu testen und so - und dann realisieren Ihre die(), throw new Exception, 403etc.

    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.phpnicht 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.phpund 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:

/**
 * Hmmm... why is my netbeans debugger only showing a blank white page 
 * for this script (that is being tested outside the framework)?
 * Later... I just don't understand why my code is not working...
 * Much later... There are no error messages or anything! 
 * Why is it not working!?!
 * I HATE PHP!!!
 * 
 * Scroll back to the top of my 100s of lines of code...
 * U_U
 *
 * Sorry PHP. I didn't mean what I said. I was just upset.
 */

 // defined('_JEXEC') or die();

 class perfectlyWorkingCode {}

 perfectlyWorkingCode::nowDoingStuffBecauseIRememberedToCommentOutTheDie();
Einfach nur hoch
quelle
2

Wenn genauer, sollten Sie diese Bedingung verwenden:

if (array_search(__FILE__, get_included_files()) === 0) {
    echo 'direct access';
}
else {
    echo 'included';
}

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.

Oleg Lokshyn
quelle
1
<?php
if (eregi("YOUR_INCLUDED_PHP_FILE_NAME", $_SERVER['PHP_SELF'])) { 
 die("<h4>You don't have right permission to access this file directly.</h4>");
}
?>

Platziere den obigen Code oben in deiner enthaltenen PHP-Datei.

Ex:

<?php
if (eregi("some_functions.php", $_SERVER['PHP_SELF'])) {
    die("<h4>You don't have right permission to access this file directly.</h4>");
}

    // do something
?>
Blogging-Tipps
quelle
if (preg_match ("~ globalfile \ .php ~ i", $ _SERVER ['PHP_SELF'])) {die ('<h3 style = "color: red"> Appliance-Sicherheitswarnung - Direktzugriff nicht zulässig! Ihre IP wurde protokolliert ! <h3> '); // Weitere Ausführung stoppen} whre ~ ist das Trennzeichen
MarcoZen
1

Der folgende Code wird im Flatnux CMS ( http://flatnux.altervista.org ) verwendet:

if ( strpos(strtolower($_SERVER['SCRIPT_NAME']),strtolower(basename(__FILE__))) )
{
    header("Location: ../../index.php");
    die("...");
}
JohnRDOrazio
quelle
1

Ich habe diese reine PHP-Lösung gefunden, die sowohl mit http als auch mit cli funktioniert:

Definieren Sie eine Funktion:

function forbidDirectAccess($file) {
    $self = getcwd()."/".trim($_SERVER["PHP_SELF"], "/");
    (substr_compare($file, $self, -strlen($self)) != 0) or die('Restricted access');
}

Rufen Sie die Funktion in der Datei auf, auf die Sie den direkten Zugriff verhindern möchten:

forbidDirectAccess(__FILE__);

Die meisten der oben angegebenen Lösungen für diese Frage funktionieren nicht im Cli-Modus.

Ka.
quelle
Wo soll die URL im CLI-Modus eingegeben werden?
Ihr gesunder Menschenverstand
Es dient nur dazu, den Start von PHP-Skript / Inlude im CLI-Modus zu verhindern. Kann in einem Projekt mit mehreren Entwicklern nützlich sein.
Ka.
1
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { die('Access denied'); };
Andy
quelle
1
<?php       
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
  if (false !== strpos($url,'.php')) {
      die ("Direct access not premitted");
  }
?>
Matt Bettiol
quelle
1

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.

<?php

function a() {
    // function body
}

function b() {
    // function body
}

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.

  • Sie können PHP versehentlich deaktivieren. In diesem Fall sendet Ihr Server möglicherweise Inhalte der PHP-Dateien an den Browser, anstatt PHP auszuführen und das Ergebnis zu senden. Dies kann dazu führen, dass Ihr Code (einschließlich Datenbankkennwörtern, API-Schlüsseln usw.) verloren geht.
  • Dateien im Webverzeichnis hocken auf URLs, die Sie möglicherweise für Ihre App verwenden möchten. Ich arbeite mit einem CMS, auf dem keine Seite aufgerufen werden kann system, da dies mit einem für Code verwendeten Pfad in Konflikt stehen würde. Ich finde das nervig.
TRiG
quelle
0

Mach so etwas wie:

<?php
if ($_SERVER['SCRIPT_FILENAME'] == '<path to php include file>') {
    header('HTTP/1.0 403 Forbidden');
    exit('Forbidden');
}
?>
kmkaplan
quelle
Dies verhindert nicht, dass es in den Browser geladen wird.
UnkwnTech
0

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.

<?
if(!isset($_SERVER['HTTP_REQUEST'])) { include ('error_file.php'); }
else { ?>

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.

Charmanter Prinz
quelle
Ich verstehe, dass nicht alle HTTP_ * -Server-Header vertrauenswürdig sind, daher sollten Sie diese Methode besser nicht verwenden.
andreszs
0

Ich schlage vor, $_SERVERaus 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.

M Rostami
quelle
0

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

RohitG
quelle
0

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
0

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:

$currentFileInfo = pathinfo(__FILE__);
$requestInfo = pathinfo($_SERVER['REQUEST_URI']);
if($currentFileInfo['basename'] == $requestInfo['basename']){
    // direct access to file
}
Talsibony
quelle
0
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

wird die Arbeit reibungslos erledigen

Varshaan
quelle
2
Kopieren und Einfügen aus CodeIgnitor. Das ist cool, aber es macht eigentlich nichts für sich. Das BASEPATH const wird in einer index.phpDatei festgelegt, die sich am Ende der Baumstruktur befindet. CI schreibt die URLs neu, sodass ohnehin kein direkter Zugriff auf die Skripte erforderlich ist.
Jimasun
Ich weiß, es gibt keine Notwendigkeit, aber wenn jemand versucht, dies zu tun
Varshaan
0

Die zuvor erwähnte Lösung mit PHP-Versionsprüfung wurde hinzugefügt:

    $max_includes = version_compare(PHP_VERSION, '5', '<') ? 0 : 1;
    if (count(get_included_files()) <= $max_includes)
    {
        exit('Direct access is not allowed.');
    }
Milo Wanrooij
quelle
2
Ich verstehe nicht wirklich, wie dies einen direkten Zugriff verhindern kann
Adam Lindsay