uniemożliwienie dostępu do pliku PHP dla zalogowanego użytkownika

0

Mam skrypt PHP, który na wywołanie ze strony JS (ajax) wystawia dane w formacie JSON. Działa, jest fajnie. Ale jeżeli użytkownik wpisze w oknie przeglądarki adres do pliku PHP, to wyświetli mu się treść JSONa. Jak mu to uniemożliwić? Zmienna sesyjna? Użytkownik nie powinien widzieć strony niezależnie od tego, czy jest zalogowany, czy nie.

3

@kosmonauta80: Ogólnie jest wiele sposobów na zabezpieczenie. Najprościej można użyć .htaccess lub "stara szkoła", dajesz takie coś na początku pliku "chronionego"

<?php
   if (!defined(YOUR_CONST)) exit;
?>

W funkcji, która pobiera dane z tego pliku dopisujesz:

define('YOUR_CONST', 'jakies_haselko');

Jeszcze inaczej, możesz sprawdzać jakimś tokenem, który generowany jest zaraz PRZED pobraniem i usuwany PO POBRANIU.

3

Nie wiem czy dobrze zrozumiałem Twoje pytanie, ale ja to rozumiem tak:

  • AJAX łączy się z jakimś adresem - http://strona.pl/zwrocDane.php, który to skrypt wypluwa jakieś dane
  • chcesz, aby te dane były przekazywane w ramach AJAX
  • jednocześnie nie chcesz, aby ktoś po wpisaniu w przeglądarce http://strona.pl/zwrocDane.php dostał na twarz tego JSON'a, którego generuje skrypt.

W takim razie spróbuj czegoś takiego:

if(!$_SERVER['HTTP_X_REQUESTED_WITH'])
{
   header("HTTP/1.0 403 Forbidden");
   exit;
}

albo zapis alternatywny

if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
    // allow access....
} else {
    // ignore....
} 

Kiedyś to działało, teraz nie mam możliwości (znaczy to taka ściema - możliwość mam, ale mi się nie chce :P ) sprawdzenia. Przy czym ważna uwaga - takie coś nie pozwala wyświetlić w przeglądarce danych zwracanych przez skrypt - jeśli ktoś wpisze w pasku adresu namiary na skrypt, ale nie powinno być to traktowanie jako zabezpieczenie. Bo nagłówek łatwo można podmienić po stronie klienta i wtedy skrypt się wykona poprawnie i pokaże wszystko co ma. Jedynie to ma zastosowanie jeśli chcesz się obronić przed sytuacją, w której ktoś w źródle strony sobie zacznie grzebać i znajdzie, że łączysz się z jakimś adresem, a potem postara się ten znaleziony adres wrzucić bezpośrednio do przeglądarki. Tutaj można to także trochę utrudnić - jakieś proste szyfrowanie, żeby adres z którym się łączysz nie był wpisany jawnie. Nawet jakiś prosty szyfr cezara zmyli większość szukaczy. Oczywiście - jak ktoś będzie chciał to sobie poradzi i nawet najbardziej zaszyfrowany adres wykopie, ale takiego przypadkowego przeglądacza powinno to powstrzymać.

2
kosmonauta80 napisał(a):

Mam skrypt PHP, który na wywołanie ze strony JS (ajax) wystawia dane w formacie JSON. Działa, jest fajnie. Ale jeżeli użytkownik wpisze w oknie przeglądarki adres do pliku PHP, to wyświetli mu się treść JSONa. Jak mu to uniemożliwić? Zmienna sesyjna? Użytkownik nie powinien widzieć strony niezależnie od tego, czy jest zalogowany, czy nie.

To zależy co chcesz przed takim użytkownikiem ukryć i dlaczego.

Inne będzie rozwiązanie, jeśli nie podoba Ci się adres, nie chcesz żeby ktoś przypadkiem wpisał ".php", żeby strona nie wyglądała na nieprofesjonalną?

Czy może masz tam jakieś dane, do których chcesz kontrolować dostęp? Może chcesz bronić samej struktury, np nie chcesz żeby ktoś widział że to JSON?

Może chcesz dostarczać coś za pieniądze, i nie chcesz żeby ktoś sobie zautomatyzował Twoją prace? Bo pod JSON łatwiej napisać bota niż pod taką stronę.

Może struktura którą zwracasz jest wątpliwego pochodzenia, i nie chcesz żeby ktoś się dowiedział co tam jest bo wyśledzi oryginalne pochodzenie?

Może Twój front jakoś ogranicza Ajax, a Twój skrypt jest "ciężki" i boisz się że jak ktoś będzie strzelał do niego zbyt często to zrobi Ci DDoS?

Może trzymasz aplikacje na jakimś serwerze, AWS lub Google Compute, gdzie płaci się za czas procesora i operacje I/O, i chcesz ograniczyć komuś niepotrzebne obliczenia, bo Twój front je cache'uje?

Przykro mi, ale na każde z tych problemów należałoby znaleźć osobne rozwiązanie, także, proszę, zamiast proponować bardzo dziwny pomysł, taki jak "blokowanie dostępu do JSON z przeglądarki", po prostu napisz dokładnie o co chodzi, a wtedy podpowiemy Ci jak to najlepiej osiągnąć.

1

Zmien metode na POST, dodaj token, to uzytkownik nie zobaczy strony po wejsciu bo tam z adresu uzywa sie GET, ale jak sciagnie postmena czy inne cos to jedynym sposobem zeby uzytkonik nie widzial strony niezaleznie od tego czy jest zalogowany czy nie to usun plik skryptu php albo zmien jego nazwe i nikomu jej nie podawaj

0

@chomikowski: Ewentualnie trzymać te dane w bazie i w pliku WYŚWIETLAĆ je jedynie dla "zweryfikowanych" użytkowników

1
kosmonauta80 napisał(a):

Powód 1 i 2.

Czyli

TomRiddle napisał(a):

Inne będzie rozwiązanie, jeśli nie podoba Ci się adres, nie chcesz żeby ktoś przypadkiem wpisał ".php", żeby strona nie wyglądała na nieprofesjonalną?
Czy może masz tam jakieś dane, do których chcesz kontrolować dostęp? Może chcesz bronić samej struktury, np nie chcesz żeby ktoś widział że to JSON?

Tak?

Użytkownik nie powinien widzieć strony niezależnie od tego, czy jest zalogowany, czy nie.

Ale chwila. To żaden użytkownik nie powinien tych danych widzieć? Czy to chodzi o to że Twoja aplikacja pobiera jakieś dane, i użytkownik w ogóle ma nie wiedzieć że one są?

To mi wygląda jakbyś był prawdziwym haXioRem, z prawdziwego zdarzenia, i tam na tej stronie toczą się jakieś ostre machloje, i dlatego chcesz je ukryć za wszelką cene. A jeśli, tak to musisz wyciągnąć większe działa. Bo zmiana metody z GET na POST, albo zmiana nazwy pliku swojego PHP, lub sprawdzanie User-Agent, na mało się zda, bo zbyt łatwo to obejść. Rozumiem że chcesz utrudnić każdemu zobaczenie tego JSON'a, Twojego?

Bo jeśli tak, to ja się szczerze zastanawiam czy Ajax to w ogóle dobry sposób. To co opisujesz, najlepiej by się dało zrobić, gdybyś wrenderował swoje dane w kod źródłowy swojej strony, najlepiej ziminifikowane i pospisane kluczem dwustronnym.

Ale jeśli to musi koniecznie być Ajax, to najlepiej by było zrobić, także:

  • Nadaj mu dynamiczną ścieżkę, np jak teraz masz mojastrona.pl/folder/moj-plik.php, to korzystając z dostępnych narzędzi, zrób tak żeby ten zasób był dostępny pod /abc/xyz/123456/file. Bez rozszerzenia, abc/xyz to jakaś nazwa któa nie sugeruje że co tam jest, a 123456 to jest np aktualny timestamp w zaokrągleniu do godziny. Jeśli ktoś strzeli pod inny adres, zwróć zwykłą 404. Chodzi po prostu o to, żeby ścieżka nie była zawsze taka sama.
  • Przekazuj mu parametr, np ?x=43vr8w43m8348u43c8um8348, gdzie 43vr8w43m8348u43c8um8348 to jest token CSRF, który przekazałeś uprzednio, np w polu jakiegoś formularza. Poczytaj o CSRF tutaj: https://owasp.org/www-community/attacks/csrf Jeśli ktoś nie przekaże poprawnego x=, zwróć 404.
  • Noi najważniejsze, nie wysyłaj pliku jako tekst. Najlepiej by było gdybyś go zaenkodował do postaci binarnej, (np z ASCII, albo UTF-8), i wysyłał taką gołą binarkę, bez rozszerzenia w adresie, i bez Content-Typeów, bez Mime-Typeów, nic po czym można by się domyślić jaki to jest prawdziwy format. Tylko Twój zminifikowany JS wiedziałby co dostaje, i jak zdeserializować dane. (Tylko nie wsadzaj tego potem do zmiennej globalnej, bo i tak wtedy każdy to odczyta).

To jest moim zdaniem absolutne minimum.

To co dodatkowo powinieneś zrobić, i to co może być dla Ciebie trudne, to podpisać treść tej binarki kluczem dwustronnym, np 128-bitowym RSA, i potem odczytać na kliencie. To zapewni faktyczne bezpieczeństwo.

PS: Ale powtarzam, żadne z tych rzeczy, samo w sobie nie jest wystarczające:

  • Jeśli tylko zmienisz ścieżkę na dynamiczną, wystarczy parę requsstów, i sprytny użytkownik się domyśli co zrobiłeś, i po ptakach.
  • Jeśli tylko będziesz wymagał CSRF w parametrze, to samo, ktoś się łątwo domyśli, wyciągnie token z source code'a, i po ptakach.
  • Jeśli tylko zmienisz format z JSON na binarke, to ktoś zobaczy że te requesty lecą, zacznie się zastanawiać, i może wpadnie na pomysł że tak na prawdę tam jest JSON, zwłaszcza że Twój plik się nazywa tak, że boisz się że ktoś go może wpisać.
  • Jeśli tylko podpiszesz dane kluczem dwustronnym, to ktoś znajdzie klucz prywatny gdzieś w Twoim kliencie, i i tak sobie to odczyta.

Jedyną nadzieją, jest zastosować wszystkie 4, i liczyć że ktoś kto używa tej strony nawet nie wpadnie że w tym requeście jest cokolwiek.

0

Widzę, że temat jednak jest złożony. W wolnej chwili wrócę do tego. Dzięki za dotychczasowe wypowiedzi. Pomogły.

1 użytkowników online, w tym zalogowanych: 0, gości: 1