Zablokuj bezpośredni dostęp do pliku dołączanego php

166

Mam plik php, którego będę używać wyłącznie jako dołączenia. Dlatego chciałbym zgłosić błąd zamiast go wykonywać, gdy jest dostępny bezpośrednio, wpisując adres URL zamiast być dołączanym.

Zasadniczo muszę sprawdzić w pliku php w następujący sposób:

if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");

Czy jest na to łatwy sposób?

Alterlife
źródło
10
zamiast die () powinieneś przetestować nagłówek '("HTTP / 1.1 404 File Not Found", 404); wyjście;'. To (przynajmniej na Apache) spowoduje, że serwer zwróci normalną stronę 404.
gnud
Oto dwie proste metody, które wyjaśniłem, aby wyłączyć bezpośredni dostęp w dołączonych plikach PHP - codespeedy.com/disable-direct-access-to-the-php-include-file
Faruque Ahamed Mollick

Odpowiedzi:

173

Najłatwiejszym sposobem dla ogólnej "aplikacji PHP uruchomionej na serwerze Apache, nad którą możesz lub nie możesz w pełni kontrolować" jest umieszczenie twoich dołączeń w katalogu i odmowa dostępu do tego katalogu w pliku .htaccess. Aby zaoszczędzić ludziom kłopotów z Googlingiem, jeśli używasz Apache, umieść to w pliku o nazwie „.htaccess” w katalogu, do którego nie chcesz mieć dostępu:

Deny from all

Jeśli faktycznie masz pełną kontrolę nad serwerem (obecnie jest to częstsze nawet w przypadku małych aplikacji niż wtedy, gdy po raz pierwszy napisałem tę odpowiedź), najlepszym podejściem jest umieszczenie plików, które chcesz chronić, poza katalogiem, z którego serwer WWW obsługuje . Jeśli więc Twoja aplikacja jest dostępna /srv/YourApp/, ustaw serwer tak, aby obsługiwał pliki z /srv/YourApp/app/i umieść w nim zawarte /srv/YourApp/includes, więc dosłownie nie ma adresu URL, który mógłby uzyskać do nich dostęp.

Głaskanie pod brodę
źródło
1
Dzięki, ponieważ mam pełną kontrolę nad serwerem, na którym uruchamiam tę aplikację, to jest odpowiedź, z którą poszedłem.
Alterlife
24
jeśli masz pełną kontrolę nad serwerem, lepiej będzie, jeśli umieścisz config w dyrektywie katalogu w pliku konfiguracyjnym wirtualnego hosta. Apache czyta go tylko raz przy starcie, .htaccess jest odczytywany przy każdym dostępie i spowalnia serwer
Eineki
22
Byłoby miło mieć przykładowy plik .htaccess jako część tej odpowiedzi.
Graham Lea
7
<Files ~ "\.inc$"> Order Allow,Deny Deny from All </Files>
Dracorat
11
@James: Poza tym nie wszyscy uważają, że Stack Overflow powinno być stroną "plz send teh codez". Jeśli jasno odpowiada na pytanie, to jest to dobra odpowiedź. Podanie przykładu, w którym żaden nie jest potrzebny, zachęca tylko do kodowania typu kopiuj i wklej.
Chuck
188

Dodaj to do strony, którą chcesz tylko uwzględnić

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

następnie na stronach, które go zawierają, dodaj

<?php
define('MyConst', TRUE);
?>
UnkwnTech
źródło
3
Naprawdę muszę nauczyć się pisać szybciej. To jest ten sam sposób, który proponuję, ponieważ jest bezpieczniejszy niż metoda wykorzystująca zmienną do sprawdzenia. Ponieważ w przypadku niektórych ustawień PHP może być możliwe nadpisanie tej zmiennej.
Mark Davidson,
3
W ten sposób radzi sobie z tym kilka aplikacji „głównego nurtu”. Wiem, że Joomla robi to w ten sposób i myślę, że Wiki, Wordpress i inne.
UnkwnTech
1
Może wiadomość jest zbyt pomocna dla hakera (żaden prawdziwy użytkownik nie znalazłby tych stron), możesz po prostu wysłać nagłówek przekierowania i zatrzymać przetwarzanie php.
bandi
7
Po prostu wyślij nagłówek 404 i zakończ - strona błędu będzie wyglądać identycznie jak normalne strony 404 (przynajmniej na Apache).
gnud
4
@ Smile.Hunter: chodzi o blokowanie dostępu do bezpośredniego przeglądania plików skryptów include / library, odpowiedź działa. Jeśli utworzyli somefile.phpna twoim serwerze i dodali do niego twoją definicję, nadal nie daje im to bezpośredniego dostępu do pliku dołączanego. Pozwoli im to "dołączyć" twoje pliki biblioteczne, ale jeśli zajdą wystarczająco daleko, aby tworzyć pliki na twoim serwerze i znając twoje skrypty definiujące / dołączane, masz inne problemy, które prawdopodobnie negują pisanie własnego pliku z twoją definicją w pierwszej kolejności .
James
114

Mam plik, który muszę działać inaczej, gdy jest dołączony, a gdy jest dostępny bezpośrednio (głównie a print()vs return()). Oto zmodyfikowany kod:

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

Plik, do którego uzyskiwany jest dostęp, jest zawsze plikiem dołączonym, stąd == 1.  

zero
źródło
12
To naprawdę świetny pomysł, sprawdzenie liczby dołączonych plików. Zastanawiam się, co jest lepsze: używając definicji czy używając tej metody? Wydaje się to bardziej samodzielne.
Akoi Meexx
Pierwszy raz widziałem, jak ktoś to wymyślił. Nie wiem jednak dlaczego, ponieważ wydaje się tak samoistny, jak to tylko możliwe, i bezpośrednio mierzy to, co naprawdę chcesz wiedzieć (jeśli jest uwzględniony lub nie), zamiast mierzyć coś, co przypuszczalnie jest powiązane (jak pewna stała lub pewna lokalizacja zakazana przez .htaccess). Piękny.
Jimbo Jonny
Ten jest naprawdę fajny, ponieważ użycie .htaccess do blokowania wszystkich plików .php może nie być możliwe przez cały czas, ponieważ w tym samym katalogu mogą znajdować się pliki, które muszą być wywoływane bezpośrednio lub nawet przez JavaScript. Dzięki za wspaniały pomysł!
Anuj
3
Działa to tylko w PHP5 i nowszych. Przed PHP5 chcesz ponownie porównać 0 zamiast 1.
jmucchiello
To naprawdę sprytne rozwiązanie, które pozwala kontrolować bezpośredni dostęp, a nie tylko go blokować - to mi się podoba. Zwykle umieszczam testy jednostkowe w samych plikach iw ten sposób mogę zawrzeć testy jednostkowe w tej instrukcji if. Ciekawe, jaka to wydajna ..
whiteatom
34

Najlepszym sposobem zapobieżenia bezpośredniemu dostępowi do plików jest umieszczenie ich poza katalogiem głównym dokumentów serwera WWW (zwykle o jeden poziom wyżej). Nadal możesz je dołączyć, ale nie ma możliwości uzyskania do nich dostępu przez żądanie http.

Zwykle idę na całość i umieszczam wszystkie moje pliki PHP poza katalogiem głównym dokumentu poza plikiem bootstrap - samotny plik index.php w katalogu głównym dokumentu, który rozpoczyna routing całej witryny / aplikacji.

Eran Galperin
źródło
3
To świetne rozwiązanie, jeśli możesz to zrobić. Dopiero niedawno musiałem zacząć pracować ze współdzielonymi hostami internetowymi i odkryłem, że jedną z wielu przykrości jest to, że wszystko musi znajdować się w docroot.
Beau Simensen
3
W każdym dostawcy hostingu, z którym pracowałem, zawsze miałem dostęp (dokładnie) o jeden poziom powyżej katalogu głównego dokumentu.
Eran Galperin
3
W przypadku niektórych hostów (w tym mojego obecnego) możesz skierować swoją domenę do dowolnego folderu.
Dinah
1
Jest to również dobra alternatywa ... używając preg_match -> if (preg_match ("~ globalfile \ .php ~ i", $ _SERVER ['PHP_SELF'])) {die ('<h3 style = "color: red"> Alert bezpieczeństwa urządzenia - bezpośredni dostęp niedozwolony! Twoje IP zostało zarejestrowane! <h3> '); // Zatrzymaj dalszą egzekucję}
MarcoZen
Ten adres URL devzone.zend.com/node/view/id/70 to teraz 404. Odpowiedź powinna zawierać kod, który został pierwotnie użyty z tego nieistniejącego adresu URL.
Funk Forty Niner
31

1: Sprawdzanie liczby dołączonych plików

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

Logika: PHP kończy pracę, jeśli minimalna liczba dołączeń nie zostanie osiągnięta. Zauważ, że przed PHP5, strona bazowa nie jest uwzględniana.


2: Definiowanie i weryfikacja stałej globalnej

// 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');

Logika: Jeśli stała nie jest zdefiniowana, wykonanie nie rozpoczyna się od strony bazowej, a PHP przestaje działać.

Należy pamiętać, że ze względu na przenośność w ramach uaktualnień i przyszłych zmian, uczynienie tej metody uwierzytelniania modułową znacznie zmniejszyłoby obciążenie związane z kodowaniem, ponieważ zmiany nie będą musiały być zakodowane na stałe w każdym pliku.

// 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');

W ten sposób można dodać dodatkowy kod do checkdefined.php logowania i celów analitycznych, a także do generowania odpowiednich odpowiedzi.

Kredyt jest należny: z tej odpowiedzi zrodził się genialny pomysł przenośności .


3: Zdalna autoryzacja adresu

// 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');

Wadą tej metody jest izolowane wykonywanie, chyba że token sesji jest dostarczany z wewnętrznym żądaniem. Zweryfikuj za pomocą adresu sprzężenia zwrotnego w przypadku konfiguracji z pojedynczym serwerem lub białej listy adresów dla infrastruktury wieloserwerowej lub serwera o zrównoważonym obciążeniu.


4: Autoryzacja tokena

Podobnie jak w przypadku poprzedniej metody, można użyć GET lub POST, aby przekazać token autoryzacyjny do pliku dołączanego:

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

Bardzo skomplikowana metoda, ale być może jednocześnie najbardziej bezpieczna i wszechstronna, jeśli jest używana we właściwy sposób.


5: Konfiguracja specyficzna dla serwera WWW

Większość serwerów umożliwia przypisywanie uprawnień do poszczególnych plików lub katalogów. Możesz umieścić wszystkie swoje dołączenia w takich ograniczonych katalogach i skonfigurować serwer tak, aby je odrzucał.

Na przykład w APACHE konfiguracja jest przechowywana w .htaccesspliku. Samouczek tutaj .

Zauważ jednak, że konfiguracje specyficzne dla serwera nie są przeze mnie zalecane, ponieważ są złe dla przenośności między różnymi serwerami internetowymi. W przypadkach takich jak systemy zarządzania treścią, w których algorytm odmowy jest złożony lub lista odrzuconych katalogów jest dość duża, może to tylko sprawić, że sesje rekonfiguracji będą raczej makabryczne. W końcu najlepiej załatwić to w kodzie.


6: Umieszczanie załączników w bezpiecznym katalogu POZA katalogu głównym serwisu

Najmniej preferowane ze względu na ograniczenia dostępu w środowiskach serwerowych, ale jest to dość skuteczna metoda, jeśli masz dostęp do systemu plików.

//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");

Logika:

  • Użytkownik nie może zażądać żadnego pliku spoza htdocsfolderu, ponieważ łącza znajdowałyby się poza zakresem systemu adresowego serwisu WWW.
  • Serwer php uzyskuje dostęp do systemu plików w sposób natywny, a zatem może uzyskiwać dostęp do plików na komputerze, tak jak zwykły program z wymaganymi uprawnieniami.
  • Umieszczając pliki nagłówkowe w tym katalogu, możesz zapewnić, że serwer php uzyska do nich dostęp, podczas gdy hotlinkowanie jest zabronione dla użytkownika.
  • Nawet jeśli konfiguracja dostępu do systemu plików serwera WWW nie została wykonana poprawnie, ta metoda zapobiegnie przypadkowemu upublicznieniu tych plików.

Proszę wybaczyć moje niekonwencjonalne konwencje kodowania. Wszelkie uwagi są mile widziane.

RiA
źródło
Podoba mi się numer 2
Baim Wrong
26

Alternatywą (lub uzupełnieniem) rozwiązania Chucka byłaby odmowa dostępu do plików pasujących do określonego wzorca przez umieszczenie czegoś takiego w pliku .htaccess

<FilesMatch "\.(inc)$">
    Order deny,allow
    Deny from all
</FilesMatch>
Kevin Loney
źródło
Lepiej byłoby użyć .inc.php, jak sądzę, i jest to powszechna praktyka
Lis
14

Właściwie radzę stosować wszystkie te najlepsze praktyki.

  • Umieść dokumenty poza katalogiem głównym LUB w katalogu, do którego serwer sieciowy nie ma dostępu ORAZ
  • Użyj definicji w swoich widocznych dokumentach, których szukają ukryte dokumenty:
      if (!defined(INCL_FILE_FOO)) {
          header('HTTP/1.0 403 Forbidden');
          exit;
      }

W ten sposób, jeśli pliki zostaną w jakiś sposób zagubione (błędna operacja ftp), nadal będą chronione.

jmucchiello
źródło
8

Miałem kiedyś ten problem, rozwiązany:

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

ale idealnym rozwiązaniem jest umieszczenie pliku poza głównym katalogiem serwera WWW, jak wspomniano w innym anwser.

mati
źródło
7

Lepiej zbuduj aplikację z jednym punktem wejścia, tj. Wszystkie pliki powinny być dostępne z pliku index.php

Umieść to w index.php

define(A,true);

To sprawdzenie powinno zostać uruchomione w każdym podłączonym pliku (za pośrednictwem wymagania lub dołączenia)

defined('A') or die(header('HTTP/1.0 403 Forbidden'));
user2221806
źródło
7

Chciałem ograniczyć dostęp do pliku PHP bezpośrednio, ale także móc wywołać go za pośrednictwem jQuery $.ajax (XMLHttpRequest). Oto, co zadziałało dla mnie.

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
źródło
3

Najłatwiej jest ustawić w pliku jakąś zmienną, która wywołuje include, na przykład

$including = true;

Następnie w dołączanym pliku poszukaj zmiennej

if (!$including) exit("direct access not permitted");
Kyle Cronin
źródło
2
Jest to niebezpieczne, jeśli włączone jest register_globals.
jmucchiello
25
PHP jest niebezpieczne, jeśli włączone jest register_globals.
David Precious,
3

Poza sposobem .htaccess, widziałem użyteczny wzór w różnych frameworkach, na przykład w ruby ​​on rails. Mają oddzielny katalog pub / w katalogu głównym aplikacji, a katalogi bibliotek znajdują się w katalogach na tym samym poziomie co pub /. Coś takiego (nie idealne, ale masz pomysł):

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

Skonfigurowałeś swój serwer sieciowy tak, aby używał pub / jako katalogu głównego dokumentu. Zapewnia to lepszą ochronę skryptów: podczas gdy mogą one sięgać z katalogu głównego dokumentu w celu załadowania niezbędnych komponentów, niemożliwe jest uzyskanie dostępu do komponentów z Internetu. Kolejną zaletą oprócz bezpieczeństwa jest to, że wszystko jest w jednym miejscu.

Taka konfiguracja jest lepsza niż zwykłe tworzenie sprawdzeń w każdym dołączonym pliku, ponieważ komunikat „dostęp niedozwolony” jest wskazówką dla atakujących i jest lepsza niż konfiguracja .htaccess, ponieważ nie jest oparta na białej liście: jeśli spieprzysz rozszerzenia plików nie będzie widoczny w katalogach lib /, conf / itp.

bandi
źródło
Po dłuższym czasie chcę tylko skomentować, że model, który opisujesz powyżej, nazywa się modelem MVC (Model - View - Controller). Jeśli możesz, sprawdź google i dodaj więcej informacji do swojej odpowiedzi. Również MVC obsługuje nie tylko Ruby on Rails i aplikacje ASP.NET, ale także PHP (patrz Lavarel, CakePHP).
3

Co Joomla! robi to definiowanie stałej w pliku głównym i sprawdzanie, czy taka sama jest zdefiniowana w dołączonych plikach.

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

albo

można trzymać wszystkie pliki poza zasięgiem żądania http, umieszczając je poza katalogiem webroot, jak zaleca większość frameworków, takich jak CodeIgniter.

a nawet umieszczając plik .htaccess w folderze dołączania i zapisując reguły, można uniemożliwić bezpośredni dostęp.

Pradeesh kumar
źródło
3
debug_backtrace() || die ("Direct access not permitted");
Unirgy
źródło
3

Moja odpowiedź jest nieco inna w podejściu, ale zawiera wiele odpowiedzi udzielonych tutaj. Poleciłbym podejście wielotorowe:

  1. Na pewno ograniczenia .htaccess i Apache
  2. defined('_SOMECONSTANT') or die('Hackers! Be gone!');

JEDNAKdefined or die podejście ma szereg wad. Po pierwsze, jest to prawdziwy ból w założeniach do testowania i debugowania. Po drugie, wymaga to przerażająco nudnej refaktoryzacji, jeśli zmienisz zdanie. "Znajdź i zamień!" mówisz. Tak, ale na ile jesteś pewien, że wszędzie jest napisane dokładnie tak samo, hmmm? Teraz pomnóż to przez tysiące plików ... oO

A potem jest .htaccess. Co się stanie, jeśli Twój kod zostanie rozpowszechniony w witrynach, w których administrator nie jest tak skrupulatny? Jeśli polegasz tylko na .htaccess, aby zabezpieczyć swoje pliki, będziesz również potrzebować a) kopii zapasowej, b) pudełka chusteczek do wysuszenia łez, c) gaśnicy, aby ugasić płomienie w całej ogonie od ludzi używając swojego kodu.

Więc wiem, że pytanie brzmi „najłatwiej”, ale myślę, że to, czego wymaga, to bardziej „obronne kodowanie”.

Proponuję:

  1. Przed którymkolwiek z twoich skryptów require('ifyoulieyougonnadie.php');( nie include() i jako zamiennikdefined or die )
  2. W ifyoulieyougonnadie.php , zrób trochę logiki - sprawdź różne stałe, wywołanie skryptu, testowanie lokalnego hosta i tym podobne - a następnie zaimplementuj swoje die(), throw new Exception, 403itp.

    Tworzę własny framework z dwoma możliwymi punktami wejścia - głównym index.php (framework Joomla) i ajaxrouter.php (mój framework) - więc w zależności od punktu wejścia sprawdzam różne rzeczy. Jeśli żądanieifyoulieyougonnadie.php nie pochodzi z jednego z tych dwóch plików, wiem, że podejmowane są oszustwa!

    Ale co, jeśli dodam nowy punkt wejścia? Bez obaw. Po prostu się zmieniamifyoulieyougonnadie.php i jestem posortowany, plus nie ma opcji „znajdź i zamień”. Brawo!

    Co jeśli zdecyduję się przenieść część moich skryptów do innej platformy, która nie ma tych samych stałych defined()? ... Brawo! ^ _ ^

Zauważyłem, że ta strategia sprawia, że ​​programowanie jest o wiele przyjemniejsze i dużo mniej:

/**
 * 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();
Just Plain High
źródło
2

Jeśli dokładniej, powinieneś użyć tego warunku:

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

get_included_files () zwraca tablicę indeksowaną zawierającą nazwy wszystkich włączonych plików (jeśli plik jest wykonywany, to został dołączony, a jego nazwa znajduje się w tablicy). Tak więc, gdy plik jest dostępny bezpośrednio, jego nazwa jest pierwszą w tablicy, wszystkie inne pliki w tablicy zostały uwzględnione.

Oleg Lokshyn
źródło
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>");
}
?>

umieść powyższy kod na górze dołączonego pliku php.

dawny:

<?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
?>
Porady dotyczące blogowania
źródło
if (preg_match ("~ globalfile \ .php ~ i", $ _SERVER ['PHP_SELF'])) {die ('<h3 style = "color: red"> Alert bezpieczeństwa urządzenia - dostęp bezpośredni niedozwolony! Twoje IP zostało zarejestrowane ! <h3> '); // Zatrzymaj dalsze wykonywanie} gdzie ~ jest ogranicznikiem
MarcoZen
1

Poniższy kod jest używany w CMS Flatnux ( http://flatnux.altervista.org ):

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

Znalazłem to niezmienne rozwiązanie tylko dla php, które działa zarówno z http, jak i cli:

Zdefiniuj funkcję:

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

Wywołaj funkcję w pliku, do którego chcesz uniemożliwić bezpośredni dostęp:

forbidDirectAccess(__FILE__);

Większość podanych powyżej rozwiązań tego pytania nie działa w trybie Cli.

Ka.
źródło
gdzie ma wpisać adres URL w trybie CLI?
Twój zdrowy rozsądek
Ma to na celu zapobieżenie uruchomieniu skryptu php / inlude w trybie cli. Może być przydatne w projekcie z wieloma programistami.
Ka.
1
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { die('Access denied'); };
andy
źródło
1
<?php       
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
  if (false !== strpos($url,'.php')) {
      die ("Direct access not premitted");
  }
?>
Matt Bettiol
źródło
1

Przechowywanie plików dołączanych poza katalogiem dostępnym w Internecie było wspominane kilka razy i jest z pewnością dobrą strategią, jeśli to możliwe. Jednak wspomniano o innej opcji, której jeszcze nie widziałem: upewnij się, że pliki dołączane nie zawierają żadnego kodu do uruchomienia . Jeśli twoje pliki dołączane tylko definiują funkcje i klasy i nie mają innego kodu, po prostu utworzą pustą stronę przy bezpośrednim dostępie.

W każdym razie zezwalaj na bezpośredni dostęp do tego pliku z przeglądarki: nic nie da . Definiuje niektóre funkcje, ale żadna z nich nie jest wywoływana, więc żadna z nich nie działa.

<?php

function a() {
    // function body
}

function b() {
    // function body
}

To samo dotyczy plików, które zawierają tylko klasy PHP i nic więcej.


W miarę możliwości dobrym pomysłem jest przechowywanie plików poza katalogiem WWW.

  • Możesz przypadkowo dezaktywować PHP, w takim przypadku twój serwer może wysłać zawartość plików PHP do przeglądarki, zamiast uruchamiać PHP i wysyłać wynik. Może to spowodować wyciek kodu (w tym haseł do bazy danych, kluczy API itp.).
  • Pliki w katalogu internetowym znajdują się pod adresami URL, których możesz chcieć użyć w swojej aplikacji. Pracuję z systemem CMS, który nie może mieć wywoływanej strony system, ponieważ powodowałoby to konflikt ze ścieżką używaną do kodu. Uważam to za denerwujące.
Wymuskany
źródło
0

Zrób coś takiego:

<?php
if ($_SERVER['SCRIPT_FILENAME'] == '<path to php include file>') {
    header('HTTP/1.0 403 Forbidden');
    exit('Forbidden');
}
?>
kmkaplan
źródło
Nie zapobiegnie to załadowaniu go do przeglądarki.
UnkwnTech
0

Możesz użyć poniższej metody, chociaż ma ona wadę, ponieważ można ją sfałszować, z wyjątkiem sytuacji, gdy możesz dodać kolejną linię kodu, aby upewnić się, że żądanie pochodzi tylko z twojego serwera, albo przy użyciu JavaScript. Możesz umieścić ten kod w sekcji Body kodu HTML, aby błąd był tam wyświetlany.

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

Umieść tutaj swój drugi kod HTML

<? } ?>

Zakończ to w ten sposób, aby wynik błędu zawsze był wyświetlany w sekcji treści, jeśli tak chcesz.

Czarujący Książę
źródło
Rozumiem, że nie należy ufać wszystkim nagłówkom serwera HTTP_ *, więc lepiej nie używać tej metody.
andreszs
0

Sugeruję, aby nie używać go ze $_SERVERwzględów bezpieczeństwa.
Możesz użyć zmiennej, takiej jak $root=true;w pierwszym pliku, który zawierał inny.
i użyj isset($root)na początku drugiego dołączonego pliku.

M Rostami
źródło
0

Możesz również zabezpieczyć katalog hasłem i przechowywać w nim wszystkie skrypty php, oczywiście z wyjątkiem pliku index.php, ponieważ w momencie dołączania hasło nie będzie wymagane, ponieważ będzie wymagane tylko do dostępu http. to, co zrobi, to również opcja dostępu do skryptów na wypadek, gdybyś chciał, ponieważ będziesz mieć hasło dostępu do tego katalogu. będziesz musiał skonfigurować plik .htaccess dla katalogu i plik .htpasswd, aby uwierzytelnić użytkownika.

cóż, możesz również użyć dowolnego z rozwiązań przedstawionych powyżej, jeśli uważasz, że nie musisz normalnie uzyskiwać dostępu do tych plików, ponieważ zawsze możesz uzyskać do nich dostęp przez cPanel itp.

Mam nadzieję że to pomoże

RohitG
źródło
0

Najłatwiejszym sposobem jest przechowywanie dołączonych plików poza katalogiem internetowym. W ten sposób serwer ma do nich dostęp, ale nie ma maszyny zewnętrznej. Jedyną wadą jest to, że musisz mieć dostęp do tej części serwera. Zaletą jest to, że nie wymaga instalacji, konfiguracji ani dodatkowego obciążenia kodu / serwera.


źródło
0

Nie znalazłem sugestii z .htaccess tak dobrych, ponieważ może blokować inną zawartość w tym folderze, do której możesz chcieć zezwolić użytkownikowi, oto moje rozwiązanie:

$currentFileInfo = pathinfo(__FILE__);
$requestInfo = pathinfo($_SERVER['REQUEST_URI']);
if($currentFileInfo['basename'] == $requestInfo['basename']){
    // direct access to file
}
talsibony
źródło
0
if ( ! defined('BASEPATH')) exit('No direct script access allowed');

wykona pracę płynnie

Varshaan
źródło
2
Skopiuj wklej z CodeIgnitor. To fajne, ale w rzeczywistości sam nic nie robi. BASEPATH const Znajduje się w index.phppliku, który kładzie się na dole struktury drzewa. CI przepisuje adresy URL, więc i tak nie ma potrzeby bezpośredniego dostępu do skryptów.
jimasun
wiem, że nie ma takiej potrzeby, ale jeśli ktoś spróbuje to zrobić
Varshaan
0

Wcześniej wspomniane rozwiązanie z dodanym sprawdzaniem wersji PHP:

    $max_includes = version_compare(PHP_VERSION, '5', '<') ? 0 : 1;
    if (count(get_included_files()) <= $max_includes)
    {
        exit('Direct access is not allowed.');
    }
Milo Wanrooij
źródło
2
Naprawdę nie rozumiem, jak to może uniemożliwić bezpośredni dostęp
Adam Lindsay,