Certyfikat ZendPHP

Bezpieczeństwo

Bezpieczeństwo

Bezpieczeństwo jest poważnym problemem dla aplikacji internetowych. Nawet duże organizacje, takie jak Organizacja Narodów Zjednoczonych, zostały zhakowane przy użyciu bardzo prostych wad bezpieczeństwa. Uważam, że nie ma czegoś takiego jak całkowicie bezpieczny system. Moim celem przy zabezpieczaniu aplikacji jest dwojaki. Po pierwsze, staram się, aby atakujący mógł uzyskać dostęp tak długo, jak to możliwe. Moim następnym celem jest zminimalizowanie wartości wszelkich informacji, które mogą odzyskać. Innymi słowy, nigdy nie zakładam, że mój system jest nieprzenikniony i zawsze używam dogłębnej obrony. Zmniejsza to wykonalność włamania się do mojej aplikacji dla hakera - zajmie to dużo czasu, a kiedy to zrobią, będą musieli poświęcić znaczny wysiłek, aby uzyskać wszelkie cenne informacje. Gdy ściga cię tygrys, nie musisz biec szybciej niż tygrys. Musisz tylko biegać szybciej niż facet obok ciebie.

Uwaga : Jedną z głównych wad bezpieczeństwa jest inżynieria społeczna. Dyskusja na temat inżynierii społecznej nie wchodzi w zakres egzaminu Zend, ale zawsze musisz pamiętać, że nie tylko kod i serwery są punktami wejścia do twoich danych.

Konfiguracja

Najlepszym podejściem przy konfigurowaniu PHP jest upewnienie się, że jesteś na bieżąco z wydaniami i korzystasz z wprowadzonych przez nich ulepszeń. Powinieneś mieć bardzo silny powód, jeśli nie używasz najnowszej stabilnej wersji PHP na rzecz starszej wersji. Upewnij się, że Twój system operacyjny jest załatany. Regularnie stosuj aktualizacje zabezpieczeń i bądź na bieżąco z aktualnościami dotyczącymi bezpieczeństwa. Powinieneś zastosować inne aktualizacje pakietu tylko wtedy, gdy masz szansę upewnić się, że nie wpłyną one negatywnie na twój stos lub środowiska testowe. Szanse są takie, że kuratorzy twojego repozytorium dystrybucyjnego zadbają o to, aby nie przerzucać często używanych stosów, ale jeśli używasz niezwykłego stosu lub zainstalowałeś oprogramowanie spoza repozytorium, zachowaj ostrożność podczas aktualizacji

Błędy i ostrzeżenia

Powinieneś skonfigurować PHP do ukrywania ostrzeżeń i błędów podczas produkcji. Błędy i ostrzeżenia mogą dać osobie wskazówki na temat wewnętrznych działań twojego kodu, takich jak nazwy katalogów i jakich bibliotek używasz. Tego rodzaju informacje mogą pomóc im wykorzystać luki w zabezpieczeniach. Możesz ustawić raportowanie błędów w pliku php.ini lub w czasie wykonywania za pomocą funkcji error_reporting(). Oba przyjmują argument liczbowy, zwykle w postaci wyrażenia zbudowanego ze wstępnie zdefiniowanych stałych błędów. Oto zalecane ustawienia produkcji oraz domyślne ustawienia produkcji PHP 7.1:

Ustawienie : Wartości

display_errors : Off
log_errors : On
error_reporting : E_ALL & ˜E_DEPRECATED & ˜E_STRICT

Są to również ustawienia, które możesz założyć w swoim egzaminie Zend, chyba że pytanie stanowi inaczej. W fazie projektowania ustawienie zgłaszania błędów powinno mieć wartość E_ALL, a kod musi działać bez ostrzeżeń - nie używaj przestarzałych funkcji.

Jak działają flagi

Być może zastanawiasz się, jak ustawione są flagi i dlaczego używamy na nich operatorów bitowych. Spróbuję wyjaśnić, aby ułatwić zrozumienie ustawień konfiguracji. Wyobraź liczbę w formacie binarnym jako ciąg 1 i 0. Każda pozycja w numerze binarnym jest flagą powiązaną z opcją. Jeśli liczba w tej pozycji wynosi 1, oznacza to, że flaga jest włączona i opcja jest ustawiona. Teraz E_ALL to liczba wybierana tak, aby wszystkie flagi były powiązane. Jeśli wykonasz var_ dump (E_ALL), otrzymasz wynik int (32767), czyli 0b111111111111111. Każda z opcji jest liczbą wybraną do ustawienia jednego i tylko jednego bitu. Na przykład E_NOTICE ma wartość 8, która w systemie binarnym to 0b1000, a E_DEPRECATED to 8192, która w systemie binarnym to 0b10000000000000. Pamiętaj, że możesz wstawić 8 po lewej z tyloma zerami, ile potrzebujesz, aby uzyskać tę samą długość. Bitowy operator ~ odwraca bity w liczbie, więc ˜E_NOTICE to 0b0111. Bitowy operator i porównuje pozycje bitów dwóch liczb. Jeśli obie liczby mają trochę w ustawionej pozycji, wynik jest prawdziwy. Zatem E_ALL & ˜E_NOTICE ma ustawione wszystkie bity, z wyjątkiem tego, który mówi, że E_NOTICE jest włączony. W rezultacie ustawisz raportowanie błędów na liczbę, która ma ustawione bity dla opcji, które chcesz włączyć.

Wyłączanie funkcji i klas

Możesz użyć dyrektyw disable_functions i disable_classes w pliku php.ini, aby zapobiec użyciu funkcji i klas. Te ustawienia można ustawić tylko w pliku php.ini i nie można ich zmienić w środowisku uruchomieniowym ani w plikach ini katalogu. Do typowych funkcji wyłączania należą te, które pozwalają PHP na wykonywanie poleceń systemowych: exec, passthru, shell_exec i system. DirectoryIterator i klasy Directory są również często wyłączone, ponieważ mogą być używane przez atakującego.

Wskazówka : Wyłączenie tych funkcji to podejście "czarnej listy". Pomysłowy przeciwnik postrzega to jako przeszkodę, ale nie przeszkodę nie do pokonania.

PHP jako moduł Apache

Jeśli PHP działa jako moduł Apache, zostanie uruchomiony przy użyciu tego samego użytkownika co serwer Apache. Oznacza to, że będzie miał takie same uprawnienia i dostęp jak użytkownik Apache. Najlepszą praktyką jest konfigurowanie użytkownika dla Apache zamiast uruchamiania go jako "nikt". Użytkownik Apache powinien mieć ograniczony dostęp do systemu plików i nie powinien znajdować się na liście sudoers. Powinieneś użyć ustawienia PHP open_basedir, aby ograniczyć dostęp do katalogów, do których PHP ma dostęp. Możesz to porównać z ustawieniem doc_root, które wpływa na to, z których katalogów PHP będzie obsługiwać pliki.

Uwaga : Tryb awaryjny nie ma wpływu na ustawienie parametru open_basedir, ale doc_root. Jeśli przechowujesz katalog, w którym przechowujesz pliki przesłane przez użytkowników spoza tego katalogu, możesz znacznie utrudnić atakującemu przesłanie i wykonanie pliku.

PHP jako plik binarny CGI

Nie wiem, czy ktoś nadal obsługuje PHP jako plik binarny CGI, ale temat jest nadal w sylabusie Zend. Próbowałem zrozumieć, dlaczego Zend uważał, że ważne jest, aby je zrozumieć. Myślę, że wartość zrozumienia tych problemów w starszej konfiguracji polega na tym, że we współczesnych konfiguracjach istnieją analogi. Na przykład usterka konfiguracji "Przekazywanie niekontrolowanych żądań do PHP" wydaje się bardzo podobna do omijania sprawdzania uprawnień w CGI (krótko opisane). PHP-FPM działa przy użyciu protokołu FastCGI, co stanowi ulepszenie CGI. Ta sekcja nie dotyczy PHP-FPM, ponieważ żądania są przekazywane do niej przez gniazdo i nie może mieć na nią wpływu adres URL. Do celów egzaminacyjnych musisz znać trzy parametry konfiguracyjne i ich działanie w kontekście ataków CGI. Wymieniam je tutaj, a następnie wyjaśniam bardziej szczegółowo.

Ustawienie : Funkcja

cgi.force_redirect : Zapobiega uruchamianiu PHP, chyba że serwer WWW go wywoła. Jeśli jest włączony, PHP nie będzie odpowiadać na takie żądania jak http: //yoursite.com/cgi-bin/php / …
doc_root : Ustawia katalog główny dokumentu. Jeśli masz włączony tryb bezpieczny, to PHP nie będzie obsługiwać plików spoza tego katalogu.
user_dir : Ustawia katalog domowy użytkownika sieci

Ustawienia doc_root i user_dir nie są związane wyłącznie z bezpieczeństwem CGI i powinny być ustawione jako część ogólnych ustawień bezpieczeństwa

Złośliwe parametry CGI

Zwykle informacje o zapytaniu w adresie URL po przekazaniu znaku zapytania jako argumentu wiersza polecenia do interpretera przez interfejs CGI. Dotyczy to każdego pliku binarnego używanego przez serwer WWW jako CGI. Z powodu konwencji adres URL http://my.host/cgi-bin/php?/etc/passwd będzie próbował przekazać plik / etc / passwd do pliku binarnego PHP. Zwykle interpretery CGI otwierają i wykonują plik określony jako pierwszy argument w wierszu poleceń. Jednak PHP odmawia interpretacji argumentów wiersza poleceń, gdy jest wywoływany jako plik binarny CGI. Dzięki temu jest odporny na ataki polegające na możliwości przekazania parametru do pliku binarnego.

Sprawdzanie uprawnień do obejścia

Powszechnie stosuje się "przyjazne" adresy URL, które wysyłają przyjazny dla wyszukiwarki adres URL do skryptu. Na przykład adres URL https://yourhost.com/user/nico.php może odwzorować rzeczywiste żądanie na https://yourhost.com/cgi-bin/php/user/belieber.php. Zwykle serwer internetowy sprawdza uprawnienia i sprawdza, czy użytkownik musi zrobić dostęp do katalogu / user /. Jeśli gość jest dozwolony, utworzy przekierowane żądanie. Jeśli odwiedzający uzyska dostęp do celu przekierowania, czyli pełnego adresu URL, w tym cgi-bin, serwer internetowy sprawdza uprawnienia, które musi uzyskać dostęp do katalogu / cgi-bin /, a nie rzeczywisty katalog, który będzie obsługiwany. Oznacza to, że odwiedzający może ominąć kontrolę uprawnień, która chroni katalog użytkownika, po prostu żądając pliku z PHP w cgi-bin. Złośliwy gość może uzyskać dostęp do dowolnego pliku na serwerze internetowym, który PHP może odczytać. Dyrektywy cgi.force_redirect, doc_root i user_dir służą do zapobiegania dostępowi do prywatnych dokumentów przez PHP. Ustawienie cgi.force_redirect blokuje możliwość wywoływania PHP bezpośrednio z adresu URL - zadziała tylko wtedy, gdy zostanie wywołane na przekierowaniu z serwera WWW, takiego jak Apache. Pracując z PHP jako plikiem binarnym CGI, powinieneś rozważyć przeniesienie pliku binarnego PHP poza drzewo dokumentów i oddzielenie wykonywalnych skryptów PHP od skryptów statycznych.

Uruchamianie PHP-FPM

PHP-FPM pozwala łatwo skonfigurować wiele pul, z których każda może być uruchomiona przez innego użytkownika. Jeśli hostujesz wielu klientów, upewnij się, że witryna każdego klienta działa jako własny użytkownik. Użytkownicy klienta nie powinni mieć dostępu do plików poza swoim katalogiem domowym. Oto kilka przykładowych ustawień z pliku puli:

[pool1]
user = site1
group = site1
listen = /var/run/php5-fpm-site1.sock
listen.owner = www-data
listen.group = www-data

Konfigurujemy pulę o nazwie pula1, aby działała jako witryna użytkownika 1 w witrynie grupy. Ustawiamy właściciela i grupę nasłuchującą na użytkownika serwera WWW, aby Nginx / Apache mógł czytać i zapisywać w gnieździe. Po ustawieniu użytkownika, który uruchamia pulę, skonfigurujemy uprawnienia do plików, aby ograniczyć dostęp tylko do katalogu, w którym znajduje się strona internetowa. Uniemożliwi to klientom korzystanie z funkcji odczytu plików do odczytywania zawartości innego klienta informator.

Wskazówka : niektóre pliki, takie jak wp-config.php w witrynie WordPress, mają przewidywalne nazwy i bardzo ważne jest, aby chronić katalogi użytkowników przed innymi użytkownikami.

Konfigurujemy Nginx, aby przekazywał takie żądania PHP:

location ˜\.php$ {
try_files $uri = 404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SERVER_NAME $host;
fastcgi_pass unix:/var/run/php5-fpm-pool1.sock;
}

Każda witryna przekazuje żądania do gniazda powiązanego z własną pulą. Skrypt PHP działa jako użytkownik określony w puli i jest zablokowany w ustawionych dla nich uprawnieniach do plików. Uwaga : W naszej konfiguracji Nginx uwzględniamy try_files $ uri = 404; aby zapobiec atakom wymienionym w Podręczniku Nginx.

Dodatkową warstwę bezpieczeństwa można uzyskać, zamykając każdą pulę we własnym więzieniu chroot. Pamiętaj, że musisz upewnić się, że pliki, do których PHP musi uzyskać dostęp (takie jak katalogi dziennika lub pliki binarne, takie jak ImageMagick) są dostępne w więzieniu.

Bezpieczeństwo sesji

Dwa obszary, na które należy zwrócić uwagę, to "przejmowanie sesji" i "utrwalanie sesji". Oprócz tej części powinieneś przestudiować stronę podręcznika PHP dotyczącą bezpieczeństwa sesji.

Porwanie sesji

HTTP jest protokołem bezstanowym i można oczekiwać, że serwer sieciowy będzie obsługiwał wielu różnych użytkowników jednocześnie. Serwer musi być w stanie odróżnić klientów od siebie i robi to poprzez przypisanie każdemu klientowi identyfikatora sesji. Identyfikator sesji można pobrać, wywołując session_id(). Jest tworzony po wywołaniu funkcji session_start (). Gdy klient wysyła kolejne żądania do serwera, podaje identyfikator sesji, który pozwala serwerowi powiązać żądanie z sesją. Klienci mogą udostępnić sesji pliki cookie lub parametr adresu URL. Pliki cookie są preferowane, ale nie zawsze są dostępne. Jeśli PHP nie może użyć pliku cookie, automatycznie i transparentnie użyje adresu URL, chyba że ustawisz ustawienie session.use_only_cookies w pliku php.ini. Powinno być oczywiste, że jeśli jesteś w stanie zaprezentować komuś identyfikator sesji na serwerze, możesz maskować się jako ten użytkownik. Uzyskanie identyfikatora sesji innego użytkownika można wykonać na kilka sposobów.

•  Jeśli identyfikator sesji jest zgodny z przewidywalnym wzorcem, osoba atakująca może spróbować określić, co będzie dla użytkownika. PHP używa bardzo losowego sposobu generowania identyfikatorów sesji, więc nie musisz się tym martwić.
•  Sprawdzając ruch sieciowy między klientem a serwerem, osoba atakująca może odczytać identyfikator sesji. Możesz ustawić session.cookie_secure = On, aby sesyjne pliki cookie były dostępne tylko przez HTTPS, aby to złagodzić. HTTPS będzie również szyfrować żądany adres URL, więc jeśli identyfikator sesji zostanie przekazany jako parametr w żądaniu, zostanie zaszyfrowany.
•  Ataki na klienta, takie jak atak XSS lub trojan uruchomiony na ich komputerze, mogą również ujawnić identyfikator sesji. Można to częściowo złagodzić, ustawiając sesję. cookie_httponly dyrektywa w sprawie.
Zmuszenie PHP do używania tylko plików cookie nie ograniczy wykorzystania tego ataku. Przeciwnik może łatwo ustawić wartość cookie.

Utrwalanie sesji

Naprawa sesji wykorzystuje słabość aplikacji internetowej. Niektóre aplikacje nie generują nowego identyfikatora sesji dla użytkownika podczas ich uwierzytelniania. Zamiast tego pozwalają na użycie istniejącego identyfikatora sesji. Atak ma miejsce, gdy przeciwnik tworzy sesję na serwerze sieciowym. Znają identyfikator sesji dla tej sesji. Następnie nakłaniają użytkownika do korzystania z tej sesji i uwierzytelniania się. Osoba atakująca może wówczas użyć znanego identyfikatora sesji i ma uprawnienia uwierzytelnionego użytkownika. Istnieje kilka sposobów ustawienia identyfikatora sesji, a faktyczna zastosowana metoda będzie zależeć od tego, jak aplikacja zaakceptuje identyfikator. Najprostszym sposobem jest przekazanie identyfikatora sesji w adresie URL, w ten sposób

http://example.org/index.php?PHPSESSID=1234.

Najlepszym sposobem na ograniczenie ryzyka utrwalenia sesji jest wywołanie funkcji session_regenerate_id() za każdym razem, gdy zmienia się poziom uprawnień, na przykład po zalogowaniu. Możesz ustawić session.use_strict_mode = On w pliku konfiguracyjnym. To ustawienie zmusi PHP do używania tylko identyfikatorów sesji, które sam tworzy. Odrzuci dostarczony przez użytkownika identyfikator sesji. To ograniczy próby manipulowania plikiem cookie. Ustawienia session.use_cookies = On i session.use_only_cookies = On zapobiegną zaakceptowaniu przez PHP identyfikatora sesji z adresu URL.

Poprawa bezpieczeństwa sesji

Nie polegaj na jednej strategii łagodzenia ataków, a raczej używaj kilku warstw zabezpieczeń. Oprócz strategii łagodzenia, o których już wspomniałem, powinieneś również wykonać następujące czynności:

•  Sprawdź, czy adres IP pozostaje taki sam między połączeniami. Nie zawsze jest to możliwe w przypadku telefonów komórkowych, które przemieszczają się między wieżami, a więc zmieniają połączenia, dlatego zanim to zrobisz, sprawdź przypadki użycia.
•  Użyj wartości limitu czasu krótkiej sesji, aby zmniejszyć okno do naprawy.
•  Zapewnij użytkownikom możliwość wylogowania się z wywołania session_destroy().

Żadne z nich nie jest szczególnie skuteczne samo w sobie, ale każde z nich może przyczynić się do poprawy ogólnego bezpieczeństwa.

Cross-Site Scripting

Ataki typu cross-site scripting (XSS) to ataki, w których szkodliwy kod jest wstrzykiwany na inną, niegroźną witrynę. Zwykle złośliwy kod przeglądarki, taki jak JavaScript, jest umieszczany na stronie internetowej w celu pobrania i uruchomienia przez klientów. Atak jest skuteczny, ponieważ klient uważa, że kod pochodzi z zaufanej witryny internetowej. Kod może uzyskać dostęp do identyfikatorów sesji, plików cookie, danych do przechowywania HTML i innych informacji związanych z witryną. Istnieje kilka szerokich rodzajów ataków XSS: przechowywanych, odbijanych i DOM. W przechowywanym ataku XSS przeciwnik może umieścić dane wejściowe w zapisanej lokalizacji na serwerze. Przykładami mogą być komentarze użytkowników wyświetlane na stronie i przechowywane w bazie danych. Gdy witryna wyśle listę komentarzy użytkownika do innego użytkownika, otrzyma złośliwy kod. W odbijanym ataku XSS przeciwnik może zmusić stronę internetową do wysłania czegoś bezpośrednio. Najczęstszą formą tego ataku jest błąd wypełniania formularza, który wypełnia pola wejściowe poprzednio przesłanymi polami lub wyświetla błędną wartość pola. Wysyłając gościa pod spreparowany adres URL, który zawiera złośliwy kod jako komunikat błędu (na przykład), osoba atakująca może oszukać klienta w celu wykonania go w kontekście zaufanej strony. Atak DOM to taki, który spoczywa całkowicie na stronie. Szkodliwy kod jest odczytywany z elementu na stronie, a wywołanie kodu jest wykonywane na samej stronie. Ponadto ataki XSS można zaklasyfikować jako ataki po stronie serwera lub po stronie klienta. Atak po stronie serwera to taki, w którym serwer dostarcza złośliwy kod. Klient XSS występuje, gdy niezaufane dane dostarczone przez użytkownika są używane do aktualizacji DOM za pomocą niebezpiecznego wywołania JavaScript.

Łagodzenie ataków XSS

Najważniejszą zasadą, której należy przestrzegać, jest to, że nigdy nie zezwala się na wysyłanie nieskalowanych danych do klienta. Zawsze filtruj dane i usuwaj szkodliwe tagi przed umożliwieniem ich wysłania do klienta.

Wskazówka : Zapamiętaj tę mantrę "Filtruj wejście, uciekaj z wyjściem".

Trzy przydatne do tego funkcje to htmlspecialchars(), htmlentities() i trip_tags().

Wskazówka : Najbezpieczniejszym sposobem na wyjście z wyjścia przed jego wyświetleniem jest użycie filter_var ($ string, FILTER_SANITIZE_STRING).

Ze względu na dużą różnorodność formatów, które można stosować w adresach URL i HTML do generowania danych, kody na czarnej liście nie są bezpieczne. Powinieneś raczej dodać do białej listy określone tagi, na które chcesz zezwolić. Spójrz na ściągę na temat unikania filtrów OWASP, aby zobaczyć, ile sposobów można uniknąć czarnej listy. Musisz także ograniczyć XSS w swoim JavaScript na swojej stronie HTML, ale to nie wchodzi w zakres tego podręcznika.

Fałszerstwa żądań w różnych witrynach

Ataki CSRF wykorzystują zaufanie, jakie strona internetowa ma do klienta. W tych atakach przeciwnik nakłania klienta do wykonania polecenia na stronie internetowej, która ufa temu klientowi. Najczęstszą formą byłoby wysłanie żądania POST do formularza wejściowego. Wyobraź sobie, że Alice jest zalogowana na swojej stronie internetowej banku, która ma formularz, który pozwala jej przelać pieniądze na inne konto. Chuck zna punkt końcowy tego formularza i jakie ma pola wejściowe. Jakimś sposobem udało mu się oszukać przeglądarkę internetową Alicji, aby wysłała do tego formularza żądanie POST z instrukcjami banku, aby przelał pieniądze na jego konto. Bank ufa przeglądarce internetowej Alicji, ponieważ ma prawidłową sesję i wykonuje żądanie. Jest wiele sposobów, w jakie Chuck może oszukać przeglądarkę internetową Alice, w tym użycie ramek iframe i JavaScript. Aby złagodzić te żądania, należy wygenerować unikalny i bardzo losowy token przechowywany w sesji Alice. Kiedy wysyłasz formularz, dołączasz ten token, aby Alice przesłała formularz, a ona również wysyła token. Przed przetworzeniem formularza sprawdzasz, czy przesłany token jest zgodny z tokenem przechowywanym w jej sesji. Chuck nie ma możliwości dowiedzenia się, jaki token znajduje się w sesji Alice, więc nie będzie mógł go uwzględnić w swoim POST. Twój kod odrzuci prośbę, którą oszukał Alice ponieważ nie ma prawidłowego tokena. Rzeczywiste banki często wymagają ponownej uwierzytelnienia podczas wykonywania wrażliwej operacji i często wymagają uwierzytelnienia dwuskładnikowego w ramach tego procesu.

SQL Injection

Wstrzyknięcie SQL jest najczęstszą formą ataku w Internecie i jedną z najłatwiejszych do obrony. Wstrzykiwanie SQL ma miejsce, gdy osoba atakująca może wstawić złośliwe polecenia do instrukcji SQL w celu wykonania przez bazę danych. Wiele ustawień bazy danych pozwala na zapisywanie plików na dysku. Ta funkcja umożliwia hakerom utworzenie backdoora przy użyciu bazy danych do pisania skryptów PHP w katalogu, w którym serwer internetowy będzie go obsługiwał. Oznacza to, że efekt wstrzyknięcia SQL nie ogranicza się do naruszenia bazy danych, ale może spowodować, że osoba atakująca będzie mogła wykonać dowolny kod w bazie danych. U podstaw problemu z iniekcją SQL jest fakt, że instrukcja SQL ma mieszankę danych i składni. Umożliwiając włączenie danych dostarczonych przez użytkownika do składni funkcji, stwarzamy możliwość, że złośliwe dane mogą zakłócać składnię.

Przygotowane instrukcji

Najbardziej skutecznym sposobem na rozpoczęcie ograniczania wstrzykiwania SQL w języku PHP jest używanie wyłącznie przygotowanych instrukcji do interakcji z bazą danych. Pomoże to wykluczyć większość ataków z iniekcją SQL, ale samo w sobie nie wystarczy, aby być niezawodnym. Przygotowane instrukcje są tak ważne, że sterownik PDO będzie je emulował, jeśli podstawowy sterownik ich nie obsługuje. Przygotowane wyciągi działają w trzech krokach:

1. Skonfiguruj zestawienie z symbolami zastępczymi danych.
2. Powiąż rzeczywiste dane z wyciągiem.
3. Wykonaj przygotowane polecenie.

Możliwe jest powiązanie nowych danych z instrukcją, którą już wykonałeś, a następnie ponowne uruchomienie z nową instrukcją. Aparat bazy danych nie musi ponownie analizować kodu SQL, co zapewnia poprawę wydajności oprócz korzyści bezpieczeństwa. Ten kod podaje przykład przygotowania, powiązania i wykonania instrukcji:

< ?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
$stmt->bindParam(':name', $_GET['name'], PDO::PARAM_STR, 12);
$stmt->execute();

Uwaga : Funkcja PDO :: prepar () zwraca obiekt typu PDOStatement.

Używamy bezpośrednio zmiennej GET, więc nie musimy jej uciekać, ponieważ jest ona powiązana jako zmienna za pomocą PDOStatement :: bindParam () i nie może zmienić składni SQL, który ma zostać uruchomiony. Inne sterowniki baz danych w PHP również obsługują przygotowane instrukcje. Oto przykład z podręcznika dla MySQL5:

/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) {
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
/* Prepared statement, stage 2: bind and execute */
$id = 1;
if (!$stmt->bind_param("i", $id)) {
echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

Ucieczka

Mniej skutecznym sposobem ograniczenia zastrzyku SQL jest ucieczka ze znaków specjalnych przed wysłaniem ich do bazy danych. Jest to bardziej podatne na błędy niż używanie przygotowanych instrukcji. Jeśli zamierzasz uciec od znaków specjalnych, musisz użyć funkcji specyficznej dla bazy danych (np. Mysqli_real_escape_string ()) lub PDO :: quote (), a nie funkcji ogólnej, takiej jak sumy dodatkowe ().

Ogólne zasady

Należy również zawsze łączyć się z bazą danych z użytkownikiem, który ma najmniejszą liczbę uprawnień wymaganych do działania aplikacji. Nigdy nie zezwalaj aplikacji internetowej na łączenie się z bazą danych jako użytkownik root. Jeśli hostujesz wiele baz danych na serwerze, użyj innego użytkownika dla każdej bazy danych na serwerze i upewnij się, że ich hasła są unikalne. Pomoże to zapobiec atakowi iniekcji SQL na jedną witrynę, która wpłynie na bazy danych innych witryn. Upewnij się, że korzystasz z aktualnej wersji MySQL i wymuszaj użycie zestawu znaków w DSN klienta. Istnieje bardzo subtelny sposób użycia niedopasowanych zestawów znaków w niektórych wrażliwych schematach kodowania w celu wdrożenia wstrzyknięcia SQL; zobacz drugą odpowiedź (nie zaakceptowaną) w tym artykule StackOverflow, aby uzyskać ekspozycję.

Zdalne wstrzykiwanie kodu

Zdalne wstrzykiwanie kodu to atak, w którym przeciwnik może zmusić serwer do włączenia i wykonania swojego kodu.

Funkcje, które oceniają ciągi jako kod

Niektóre funkcje, takie jak eval(), exec() i system() są podatne na exploity zdalnego wstrzykiwania kodu. Jeśli wykonujesz zmienną zawierającą dane wprowadzone przez użytkownika, będą oni mogli wstrzykiwać polecenia za pomocą znaków zmiany znaczenia. Możesz temu zaradzić, używając escapeshellargs(), aby uniknąć argumentów przekazywanych do polecenia powłoki. Funkcja escapeshellcmd() spowoduje uniknięcie samego polecenia powłoki.

Wskazówka : Jeśli nie używasz wyraźnie tych funkcji, powinieneś je wyłączyć w swoim php. ini. Nie jest niezawodny, ale może pomóc.

Funkcja assert() służy do upewnienia się, że określony warunek jest spełniony i podjęcia pewnych działań, jeśli tak nie jest. Jest przydatny do debugowania, ale należy go wyłączyć na czas produkcji. Możesz użyć funkcji assert_options(), aby skonfigurować zachowanie asert i ją wyłączyć. Jeśli przekażesz wartość ciągu do assert(), PHP oceni łańcuch tak, jakby to był kod PHP. Pozwoliłoby to atakującemu wykonać kod na twoim serwerze, gdyby mógł kontrolować, jaki argument przekazujesz do assert().

< ?php
function rce(string $a) {
assert($a);
}
rce('print("hello")'); // hello
W PHP 7.2 przekazywanie ciągu do potwierdzenia jest przestarzałe, a ten kod generuje ostrzeżenie, ale nadal analizuje parametr



Zarówno inlude() i require() pozwalają na dołączanie plików określonych przez URL, jeśli włączone jest ustawienie konfiguracyjne PHP enable_url_include. Najczęściej występuje to, gdy ludzie używają zmiennej GET w adresie URL, aby określić zawartość dynamiczną, którą należy uwzględnić. To bardzo amatorski błąd. Na przykład witryna może mieć adres URL taki jak http://example.com/index.php? sidebar = welcome, a następnie dynamicznie dołącz plik welcome.php do paska bocznego. Przeciwnik może podać adres URL zamiast ciągu "welcome" i wykonać swój kod na serwerze z takim samym poziomem uprawnień, jak użytkownik serwera WWW. Aby przeciwdziałać tego rodzaju problemowi, możesz ustawić parametr allow_url_fopen na WYŁ., Użyj funkcji basename () w stosunku do zmiennej, którą dołączasz, aby usunąć ścieżki, i uwzględniaj tylko w przypadku białej listy.

< ?php
$page = $_GET['page'];
$allowedPages = array('adverts','contacts','information');
if ( in_array($page, $allowedPages) ) {
include basename($page . '.html');
}

Zastrzyk e-mailem

Użytkownicy mogą podawać szesnastkowe znaki sterujące, które pozwalają im zmieniać treść wiadomości lub listę adresatów. Na przykład jeśli formularz umożliwia osobie wpisanie adresu e-mail jako pola "od" wiadomości e-mail, następujący ciąg spowoduje, że dodatkowi odbiorcy zostaną uwzględnieni jako odbiorcy DW i ukrytej kopii wiadomości: nadawca @ example.com% 0ACc: target@email.com%0ABcc: anotherperson @ emailexample. com, stranger @ shouldhavefiltered.com Atakujący może również podać własne ciało, a nawet zmienić typ MIME wysyłanej wiadomości. Oznacza to, że Twój formularz może być wykorzystywany przez spamerów do wysyłania poczty. Możesz się przed tym zabezpieczyć na kilka sposobów. Upewnij się, że odpowiednio filtrujesz dane wejściowe używane podczas wysyłania wiadomości e-mail. Funkcja filter_var () zapewnia szereg flag, których możesz użyć, aby upewnić się, że Twoje dane wejściowe są zgodne z pożądanym wzorcem.

< ?php
$from = $_POST["sender"];
$from = filter_var($from, FILTER_SANITIZE_EMAIL);
// wyślij wiadomość e-mail

Możesz także zainstalować rozszerzenie Suhosin PHP i korzystać z niego. Zapewnia dyrektywę suhosin. mail.protect, która będzie temu zapobiegać. Możesz wdrożyć tarpit, aby spowolnić boty lub uwięzić je w nieskończoność. Spójrz na msigley / PHP-HTTP-Tarpit na GitHub8 jako przykład tarpit. Podczas konfigurowania serwera pocztowego należy upewnić się, że nie jest skonfigurowany jako otwarty przekaźnik, który pozwala każdemu w Internecie używać go do wysyłania poczty. Należy również rozważyć zamknięcie portu 25 (SMTP) w zaporze, aby hosty zewnętrzne nie mogły uzyskać dostępu do serwera.

Filtrowanie wejścia

Zbliżając się do bezpieczeństwa, najlepiej zaplanować najgorszy scenariusz i założyć, że wszystkie dane wejściowe są skażone, a wszystkie zachowania użytkowników są złośliwe. Należy używać wyłącznie danych wejściowych, które zostały ręcznie potwierdzone jako bezpieczne. Dane wejściowe mogą mieć format, który zostanie zignorowany przez filtr, a następnie przeanalizowany przez przeglądarkę. Arkusz ściągający unikanie XSS, o którym wspomniałem wcześniej, zawiera wiele przykładów użycia znaków specjalnych do unikania wykrywania. Istnieje możliwość wprowadzenia niestandardowego zestawu znaków, który może nie być poprawnie zrozumiany przez funkcje filtrowania. Podczas pracy z filtrowaniem SQL należy używać rodzimych funkcji filtrowania bazy danych. PHP ma bardzo solidną funkcję filtrowania, filter_var(), której można używać do wykonywania wielu różnych operacji filtrowania i odkażania. Możesz znaleźć listę filtrów w Podręczniku PHP. Istnieje również kilka funkcji, za pomocą których można sprawdzić poszczególne typy ciągów. Są świadomi ustawień regionalnych, dlatego uwzględniają znaki językowe. Funkcje zwrócą wartość true, jeśli ciąg zawiera tylko znaki w filtrze, w przeciwnym razie wartość false.

Funkcyja : Filtry

ctype_alnum() : Tylko znaki alfanumeryczne
ctype_alpha() : Tylko znaki alfabetyczne
ctype_cntrl() : String to tylko znaki kontrolne
ctype_digit() : Ciąg jest tylko cyframi
ctype_graph() : Tylko znaki i spacja do wydruku
ctype_lower() : Tylko małe litery
ctype_print() : Znaki do wydruku
ctype_punct() : Dowolne do wydruku, które nie jest spacją ani alfanumerycznie
ctype_space() : Sprawdź, czy występują spacje
ctype_upper() : Tylko wielkie litery
ctype_xdigit() : Cyfry szesnastkowe

Filtrowanie po stronie klienta jest typowe, na przykład przy użyciu JavaScript w przeglądarce. Nie jest to wystarczające i należy również filtrować i sprawdzać poprawność po stronie serwera.

Unikanie wyjścia

Jedną z głównych zasad pisania bezpiecznego kodu PHP jest filtrowanie danych wejściowych i unikanie danych wyjściowych. Zanim wyślesz dane, musisz upewnić się, że są one bezpieczne dla klienta. Przypomnij sobie, jak działają ataki XSS, jako przykład, dlaczego musisz upewnić się, że to, co wysyłasz do klienta, jest odpowiednio odkażone. Jeśli dane, które wysyłasz do klienta, zawierają instrukcje wykonania kodu, zrobi to na ślepo. Musisz upewnić się, że wysyłasz tylko kod, który ma zostać wykonany przez klienta, a nie kod wprowadzony przez atakującego. Podobnie jak w przypadku filtrowania danych wejściowych, nie można polegać na kliencie, który filtruje wysyłane do niego dane wyjściowe. Nie wszyscy klienci mają włączoną obsługę JavaScript i haker może ominąć filtrowanie klientów. Najbezpieczniejszym sposobem filtrowania danych wyjściowych jest użycie filter_var() z flagą FILTER_SANITIZE_STRING. Mogą wystąpić przypadki użycia, w których jest to dla ciebie zbyt restrykcyjne, w którym to przypadku będziesz musiał spojrzeć na funkcje takie jak htmlspecialchars(), strip_tags() i htmlentities().Funkcje htmlspecialchars() i htmlentities() mają podobne efekty i upewnij się, że rozumiesz różnicę. Różnica polega na tym, że htmlentities() koduje wszystko, co ma reprezentację encji HTML, natomiast htmlspecialchars() koduje tylko znaki, które mają specjalne znaczenie w HTML . Ta tabela pokazuje znaki, które zostaną przekonwertowane przez htmlspecialchars ()

& (Ampersand) : &
" (Podwójny cudzysłów) : "
' (Pojedynczy cudysłów) : '
< (Mniejsze niż) : <
> (Większe niż) : >

Obie funkcje przyjmują flagę jako drugi parametr. Powinieneś upewnić się, że znasz przynajmniej te trzy flagi, ponieważ są one ważne dla uniknięcia kodu JavaScript, który wysyłasz:

Flaga : Opis

ENT_COMPAT : Konwertuje podwójne cudzysłowy, a nie pojedyncze cudzysłowy
ENT_QUOTES : Konwertuje podwójne cudzysłowy i pojedyncze cudzysłowy
ENT_NOQUOTES : Nie konwertuje żadnych cytatów
Podczas ucieczki ciągu JavaScript należy użyć flagi ENT_QUOTES. Kodowanie ciągu można określić w trzecim parametrze. W PHP 7.1 domyślnym kodowaniem obu funkcji jest UTF-8.

Unikaj zatrucia dzienników

Jeśli rejestrujesz komunikaty o błędach, komunikaty informacyjne itp., Musisz zachować ostrożność przy logowaniu. Oczywiście nie wolno rejestrować poufnych informacji, takich jak hasła użytkownika lub karty kredytowe. Jeśli przekazujesz to do funkcji logowania, upewnij się, że ją zaciemniłeś. Tak więc numer karty kredytowej byłby sekwencją gwiazdek w pliku dziennika, a nie rzeczywistą liczbą. Upewnij się, że odfiltrowałeś kod wykonywalny i dane osobowe przed zalogowaniem. Powinieneś także wiedzieć, jak działa atak zatrucia logów. Luka polega na niewłaściwym kodzie, w tym na plikach lokalnych. Jeśli pozwolisz, aby dane wejściowe użytkownika określiły, który plik jest dołączony, osoba atakująca może manipulować tym plikiem wejściowym, aby dołączyć plik dziennika. Jeśli plik dziennika zawiera złośliwy kod, zostanie zinterpretowany i uruchomiony. Atakujący musi jedynie pobrać swój kod do pliku dziennika, co może być bardzo łatwe. Na przykład mogą zatruć dziennik serwera WWW, tworząc zapytanie, które wstrzykuje ciąg zawierający polecenia, które chcą uruchomić w dzienniku. Innym przykładem atakującego może być SSH na serwerze i użycie złośliwego kodu jako nazwy użytkownika, aby zatruć plik dziennika uwierzytelnienia. Aby pomóc Ci zrozumieć wpływ, przejrzyjmy przykład exploita. Załóżmy, że Twój kod działa na twoim hoście lokalnym i jest podatny na dołączanie plików lokalnych i akceptuje nazwę obrazu, który musi zostać wyświetlony. Najpierw używamy polecenia nc localhost 80, aby połączyć się z serwerem WWW. Następnie wysyłamy następujące żądanie do serwera:

GET / HTTP/1.1
Host: localhost
Apache zapisze wiersz w pliku dziennika, który wygląda mniej więcej tak:
127.0.0.1 - - [08/Apr/2016:13:57:38 +0000]
"GET /
HTTP/1.1" 400 226
""
""

Podzielę mój wpis dziennika na wiele wierszy, ale oczywiście w twoim pliku dziennika wszystko będzie w tej samej linii. Następnym krokiem exploita jest wysłanie do witryny żądania zawierającego plik dziennika (wymaga to wystąpienia takiej luki w zabezpieczeniach witryny).

http: // localhost /? plik = / var / log / apache2 / access.log & cmd = ls -la

Musisz być bardzo podatny na bycie podatnym na to:

•  Użytkownik serwera WWW potrzebuje dostępu do odczytu do docelowego pliku dziennika
•  Twój kod musi umożliwiać atakującemu dołączenie pliku docelowego
•  Nie możesz wyłączyć exec, passthru i systemu w swojej konfiguracji

Algorytmy szyfrowania i mieszania

Szyfrowanie i mieszanie to różne pojęcia i powinieneś upewnić się, że rozumiesz różnicę. Szyfrowanie jest operacją dwukierunkową; możesz szyfrować i deszyfrować. Hashowanie jest operacją jednokierunkową i z założenia trudno jest lub czasochłonnie pobrać hasz i odwrócić go do pierwotnego ciągu. Hasła należy przechowywać w bazie danych jako skróty. W ten sposób, jeśli osoby atakujące otrzymają kopię bazy danych, nadal nie będą mogły uzyskać haseł użytkowników, chyba że będą w stanie odwrócić skrót. Zwykle cofnięcie skrótu zajmuje dużo czasu i mam nadzieję, że będziesz miał wystarczająco dużo czasu, aby zauważyć naruszenie bezpieczeństwa i ostrzec użytkowników, że muszą zmienić swoje hasła. Czas potrzebny na obliczenie skrótu określi, ile czasu haker będzie odgadł hasła przy użyciu brutalnej siły.

Szyfrowanie w PHP

Szyfrowanie w PHP zapewnia moduł mcrypt, który należy zainstalować i włączyć osobno. Moduł mcrypt udostępnia szeroki zakres funkcji i stałych szyfrowania. Dostępne algorytmy zależą od systemu operacyjnego, na którym zainstalowany jest PHP. Nie należy próbować pisać własnej implementacji algorytmu szyfrowania. Egzamin certyfikacyjny Zend nie kładzie dużego nacisku na szyfrowanie.

Funkcje skrótu

Starsze skróty, takie jak MD5 i SHA1, są bardzo szybkie do obliczenia, więc nie wolno ich używać w żadnym miejscu, w którym występuje bezpieczeństwo. Nadal są bardzo przydatne w innych obszarach programowania, ale nie w żadnym miejscu, w którym polegasz na tym, że są operacją jednokierunkową. PHP 5.5.0 wprowadza funkcję password_hash(), która zapewnia wygodny sposób generowania bezpiecznych skrótów. W przypadku starszych wersji PHP należy użyć funkcji crypt (). Domyślnie funkcja password_hash () używa algorytmu bcrypt do mieszania hasła. Algorytm bcrypt ma parametr określający, ile razy powinien uruchom hasło przed zwróceniem wyniku mieszania. Jest to określane jako "koszt" algorytmu. Zwiększając liczbę uruchomień algorytmu, można wydłużyć czas potrzebny do obliczenia wartości skrótu. Oznacza to, że wraz z komputerami szybciej, możesz zwiększyć liczbę iteracji w algorytmie bcrypt, aby zabezpieczyć hasła przed atakami siłowymi. Za pomocą funkcji password_info() można uzyskać informacje na temat sposobu obliczania wartości skrótu. Ta funkcja powie Ci nazwę algorytmu, koszt i sól. Funkcja password_needs_rehash() porówna skrót z opcjami określonymi przez użytkownika, aby sprawdzić, czy trzeba go ponownie przebudować. Umożliwi to zmianę algorytmu używanego do mieszania hasła, na przykład zwiększając koszty w czasie.

Zabezpiecz losowe ciągi i liczby całkowite

PHP ma dwie funkcje, które pozwalają wygodnie generować kryptograficznie bezpieczne liczby całkowite i łańcuchy. Te funkcje będą działać na dowolnej platformie, na której działa PHP.

Funkcja : Parametry : Wartość zwracana : Opis

random_bytes : Int $ length : Ciąg bajtów Generuje losowy ciąg znaków o długości $length bajtów

random_int : Int $ min, int $ max : Losowa liczba całkowita : Generuje losową liczbę całkowitą w zakresie określone przez $min i $maks

Oto przykład użycia random_bytes:

< ?php
// pobierz ciąg zawierający 8 losowych bajtów
$randomBytes = random_bytes(8);
$printableVersion = bin2hex($randomBytes);
echo $printableVersion; // d7e263202be1b99b

Ciąg, który generuje PHP, niekoniecznie będzie można go wydrukować, więc używam funkcji bin2hex (), aby przekonwertować go na ciąg szesnastkowy. Heksadecymalny wymaga dwóch znaków do wyświetlenia bajtu, więc ciąg, który wyprowadzamy na końcu, ma długość 16 znaków (dwa razy tyle, ile wygenerowaliśmy losowych bajtów).

Solenie haseł

Ciąg solny to dodatkowy ciąg dodawany do hasła. Powinien być generowany losowo dla każdego hasła. Służy do utrudniania ataków słownikowych i wstępnie obliczonych ataków tęczy. Możesz podać sól dla funkcji password_hash(), ale jeśli ją pominiesz, PHP ją utworzy. Podręcznik PHP zauważa, że zamierzonym trybem działania jest umożliwienie ci stworzenia losowej soli dla hasła. Funkcja crypt() przyjmuje łańcuch soli jako drugi parametr, ale nie wygeneruje automatycznie soli, jeśli nie podasz własnego. PHP 5.6.0+ wyda powiadomienie, jeśli nie podasz soli.

Sprawdzanie hasła

Jeśli atakujący może dokładnie zmierzyć czas potrzebny do uruchomienia procedury sprawdzania hasła, będzie on w stanie zebrać informacje, które pomogą mu złamać hasło. Ataki te są określane jako ataki na czas. Funkcja password_verify() PHP 5.5.0 jest bezpiecznym sposobem porównania w czasie skróty utworzone przez password_hash(). Jeśli nie możesz użyć tej funkcji, musisz obliczyć skrót dla hasła podanego przez użytkownika, a następnie porównać skrót z zapamiętanym. Porównywanie skrótów jest podatne na ataki czasowe. PHP 5.6.0 wprowadziło funkcję hash_equals(), która jest bezpiecznym dla czasu sposobem porównywania napisów. Powinieneś użyć tej funkcji do porównywania skrótów generowanych przez crypt().

Szybka uwaga na temat komunikatów o błędach

Nigdy nie należy potwierdzać osobie, że wprowadziła niepoprawną nazwę użytkownika. Komunikat o błędzie powinien wskazywać, że wpisali nieprawidłową nazwę użytkownika lub hasło. Im mniej informacji podasz atakującemu, tym dłużej zajmie im uzyskanie dostępu do twojego systemu

Przesyłanie plików

Przesyłanie plików stanowi poważne ryzyko dla aplikacji internetowej i musi być zabezpieczone na kilka sposobów. Przypomnij sobie, że superglobal $ _FILES [] zawiera informacje o plikach przesłanych przez klienta. Powinieneś traktować wszystko w tej tablicy jako podejrzane i upewnić się, że ręcznie potwierdzasz każdą informację. Sposób, w jaki PHP obsługuje przesyłanie plików, polega na zapisaniu ich w katalogu tymczasowym. Możesz na nich operować, a następnie przenieść je do miejsca, w którym chcesz. Powinieneś sprawdzić, czy plik, z którym pracujesz, jest prawidłowym przesłanym plikiem oraz czy klient próbował sfałszować swoją nazwę pliku i lokalizację w folderze tymczasowym. Użyj funkcji is_uploaded_file(), aby upewnić się, że plik, do którego się odwołujesz, został rzeczywiście przesłany. Użyj metody move_uploaded_file () zamiast innych metod, aby przenieść go z katalogu tymczasowego do ostatecznej lokalizacji. Odnosząc się do pliku, użyj funkcji basename(), aby usunąć ścieżki, aby uniemożliwić osobie fałszowanie nazwy pliku. Nie ufaj typowi MIME określonemu przez użytkownika. Zignoruj typ MIME dostarczony przez użytkownika i użyj finfo_file(), aby określić typ MIME, jeśli go potrzebujesz. Jeśli zezwalasz użytkownikowi na przesyłanie obrazu, powinieneś użyć na nim funkcji GD, takiej jak getimagesize(), aby potwierdzić, że jest to prawidłowy obraz. Jeśli ta funkcja zawiedzie, plik nie jest prawidłowym obrazem. Wygeneruj własną nazwę pliku, aby zapisać plik jako i nie używaj tej dostarczonej przez użytkownika. Zdecydowanie zalecane jest użycie losowego skrótu dla nazwy pliku i ręczne ustawienie rozszerzenia poprzez sprawdzenie typu MIME. Upewnij się, że folder, w którym przechowujesz pliki, umożliwia dostęp tylko do użytkownika serwera WWW. Jeśli nie musisz podawać przesłanych plików, trzymaj folder przesyłania poza katalogiem głównym dokumentu.

Przechowywanie bazy danych

Oprócz unikania wstrzykiwania SQL należy stosować pewne zasady bezpieczeństwa podczas interakcji z bazą danych. Należy oddzielić serwery bazy danych dla różnych środowisk kodu. Twoje serwery kontroli jakości, testowania, programowania i produkcji powinny używać różnych serwerów baz danych i nie powinny mieć możliwości wzajemnego dostępu do baz danych. Musisz uniemożliwić Internetowi dostęp do serwera bazy danych. Można to osiągnąć za pomocą zapory ogniowej do zamknięcia portu z ruchu zewnętrznego, przy użyciu prywatnej podsieci, która nie ma trasy do Internetu, lub skonfigurowania serwera bazy danych, aby nasłuchiwał tylko określonych hostów. Nie wystarczy zmienić port, na którym nasłuchuje baza danych. Chciałbym powiedzieć, że nie warto się tym przejmować, ponieważ nie jest to nawet wzrost prędkości atakującego i po prostu utrudnia korzystanie z środowiska serwerowego dla współpracowników. Jeśli uruchamiasz kilka aplikacji na jednym serwerze bazy danych, upewnij się, że każda z nich ma własną nazwę użytkownika i hasło na serwerze. Każdy użytkownik aplikacji powinien mieć tylko najmniejszą liczbę wymaganych uprawnień i nigdy nie powinien być w stanie czytać baz danych innych aplikacji. Unikaj używania przewidywalnych nazw użytkowników i upewnij się, że korzystasz z bezpiecznych haseł. Na przykład zwykle używam losowo generowanego UUID wersji 4 jako hasła. Szyfruj poufne dane za pomocą mcrypt () i mhash () przed umieszczeniem ich w bazie danych. Od czasu do czasu należy sprawdzać dzienniki bazy danych. Będziesz mógł dostrzec próby ataków iniekcyjnych i innych wzorów, które pozwolą ci zidentyfikować naruszenia lub zaostrzyć obszary kodu.

Unikaj publikowania swojego hasła online

Dobrą radą jest unikanie publikowania poświadczeń bazy danych lub interfejsu API w Internecie, gdzie ludzie mogą je odczytać. Okej, jestem żartobliwy, ale na poważnie, kiedy prawdopodobnie opublikowałbyś wszystkie swoje dane dostępowe dla świata i jego psa do przeczytania? Można to zrobić tylko raz, zatwierdzając repozytorium Git i przekazując je do usług takich jak GitHub lub Bitbucket. Upewnij się, że wszystkie pliki konfiguracyjne są ignorowane przez system kontroli wersji i nigdy nie są zatwierdzane ani przekazywane do repozytoriów nadrzędnych. Są roboty, które zbierają GitHub w celu uzyskania poświadczeń, które będą karać cię za te błędy. Tak na marginesie, jak ten link, nie powinieneś kodować poświadczeń Amazon w aplikacji. Zamiast tego ustaw rolę IAM, która zezwala na dostęp do usługi, z której chcesz korzystać, i zastosuj rolę na maszynie wirtualnej.


QUIZ



P1: Zalecane ustawienie produkcyjne dla ustawienia konfiguracji display_error to Włączone.

---------------------------
Prawdziwe
Fałszywe

P2: Używanie protokołu HTTPS do szyfrowania strony logowania pomoże zapobiec przejęciu sesji i naprawianiu sesji.

---------------------------
Prawdziwe
Fałszywe *

P3: Możesz wymusić umieszczanie sesji wyłącznie w plikach cookie, używając ustawienia konfiguracji _____________.

---------------------------
session.cookie_secure
session.use_cookies
session.use_trans_sid
Żadne z powyższych

P4: CSRF polega na tym, że osoba atakująca oszukuje przeglądarkę lub urządzenie użytkownika w celu złożenia żądania bez ich wiedzy. Wykorzystuje zaufanie serwera do przeglądarki. Możesz tego uniknąć, dołączając do formularza token CSRF, który zwiększa się o jeden za każdym razem, gdy odwiedzający ładuje stronę.

---------------------------
Prawdziwe
Fałszywe

P5: Zarówno funkcje crypt (), jak i password_hash () pozwalają ci określić sól, ale jeśli nie, wygenerujesz odpowiednio losową sól.

---------------------------
Prawdziwe
Fałszywe

P6: Przeglądarka określa typ pliku, wykonując wywołanie systemu operacyjnego i wysyła te informacje wraz z żądaniem. Możesz zaufać temu, aby określić rozszerzenie, które będzie używane podczas przechowywania pliku.

---------------------------
Prawdziwe
Fałszywe

P7: Ponieważ PHP usuwa plik tymczasowy po zakończeniu działania, powinieneś najpierw upewnić się, że używasz funkcji copy(), aby umieścić plik tymczasowy w stałej lokalizacji.

---------------------------
Prawdziwe
Fałszywe

P8: Domyślnie PHP jest skonfigurowane tak, aby mogło zawierać kod źródłowy przechowywany w adresie URL.

---------------------------
Prawdziwe
Fałszywe

P9: Odpowiednim środkiem zaradczym, aby zapobiec XSS, jest użycie funkcji strip_tags () przed treścią.

---------------------------
Prawdziwe
Fałszywe
P10: Ustawienie konfiguracji open_basedir nie ma żadnego efektu, chyba że włączony jest tryb bezpieczny PHP. Ogranicza katalogi, do których PHP ma dostęp.

---------------------------
Prawdziwe
Fałszywe

ODPOWIEDZI



• Fałszywe

• Fałszywe

• Żadne z powyższych

• Fałszywe

• Fałszywe

• Fałszywe

• Fałszywe

• Prawdziwe

• Fałszywe

• Fałszywe