From 84adff610cfb55a404ab5f20053ebdbbea17216f Mon Sep 17 00:00:00 2001 From: Maciej Sobaczewski Date: Sun, 27 Oct 2024 10:29:47 +0100 Subject: [PATCH] Translate the entire security/ section --- security/apache.xml | 66 ++++++ security/cgi-bin.xml | 246 ++++++++++++++++++++ security/current.xml | 40 ++++ security/database.xml | 487 ++++++++++++++++++++++++++++++++++++++++ security/errors.xml | 147 ++++++++++++ security/filesystem.xml | 236 +++++++++++++++++++ security/general.xml | 71 ++++++ security/hiding.xml | 77 +++++++ security/intro.xml | 61 +++++ security/sessions.xml | 34 +++ security/variables.xml | 103 +++++++++ 11 files changed, 1568 insertions(+) create mode 100644 security/apache.xml create mode 100644 security/cgi-bin.xml create mode 100644 security/current.xml create mode 100644 security/database.xml create mode 100644 security/errors.xml create mode 100644 security/filesystem.xml create mode 100644 security/general.xml create mode 100644 security/hiding.xml create mode 100644 security/intro.xml create mode 100644 security/sessions.xml create mode 100644 security/variables.xml diff --git a/security/apache.xml b/security/apache.xml new file mode 100644 index 00000000..86b1e7dd --- /dev/null +++ b/security/apache.xml @@ -0,0 +1,66 @@ + + + + + Zainstalowane jako moduł Apache + + Kiedy PHP jest używane jako moduł Apache, dziedziczy uprawnienia + użytkownika Apache (zazwyczaj te użytkownika "nobody"). Wpływa to na kilka + rzeczy w kwestii bezpieczeństwa i autoryzacji. Na przykład, jeśli używasz + PHP do dostępu do bazy danych, o ile ta baza nie ma wbudowanej kontroli + dostępu, będziesz musiał sprawić, aby baza danych była dostępna dla + użytkownika "nobody". Oznacza to, że złośliwy skrypt może uzyskać dostęp i modyfikować + dane w bazie, nawet bez nazwy użytkownika i hasła. Jest zupełnie + możliwe, żeby robot sieciowy natknął się na stronę administracyjną + bazy danych i skasował wszystkie twoje bazy danych. Możesz się + przed tym zabezpieczyć, używając autoryzacji Apache lub stworzyć + własny model dostępu używając LDAP, plików &htaccess; itd. + + + Często, po ustawieniu zabezpieczeń do tego stopnia, że użytkownik PHP + (w tym wypadku użytkownik Apache) nie stanowi już dużego zagrożenia, + odkrywa się, że PHP nie jest już w stanie zapisać żadnych plików + do katalogu użytkownika. Lub że nie może uzyskać dostępu do + ani modyfikować baz danych. Zabezpieczenia powstrzymują przed zapisywaniem + tych dobrych i tych złych plików lub wprowadzaniem dobrych i złych danych do bazy. + + + Częstą pomyłką bezpieczeństwa czynioną w tym momencie jest pozwolenie Apache + na działanie z uprawnieniami roota albo zwiększenie uprawnień Apache w inny + sposób. + + + Zwiększanie uprawnień użytkownika Apache do roota jest skrajnie + niebezpieczne i może narazić cały system, więc użycie sudo, + chroot lub uruchamianie jako root w inny sposób nie powinno być nawet rozważane, + o ile nie jesteś specjalistą z zakresu bezpieczeństwa. + + + Istnieją pewne prostsze sposoby. Używając + open_basedir możesz kontrolować i ograniczać + katalogi, które mogą być używane przez PHP. Możesz także ustawić + obszary tylko dla Apache, aby zabronić aktywności pochodzącej z sieci dla katalogów + innych niż danego użytkownika. + + + + diff --git a/security/cgi-bin.xml b/security/cgi-bin.xml new file mode 100644 index 00000000..a4df8295 --- /dev/null +++ b/security/cgi-bin.xml @@ -0,0 +1,246 @@ + + + + + Zainstalowane jako program CGI + + + Możliwe ataki + + Użycie PHP jako program CGI jest opcją dla + osób, które z jakiegoś powodu nie chcą integrować PHP jako + moduł do ich serwera WWW (np. Apache), lub które będą używać PHP + z innymi rodzajami wrapperów CGI aby stworzyć bezpieczne + środowiska dla skryptów używając + chroot i setuid. Takie środowisko zazwyczaj opiera się o zainstalowanie + programu wykonywalnego php do katalogu cgi-bin serwera WWW. + Rekomendacja CERT CA-96.11 zaleca + nie umieszczać żadnych interpreterów w cgi-bin. + Nawet jeśli plik binarny php może być użyty jako samodzielny interpreter, + PHP jest zaprojektowane tak, aby zapobiegać atakom, które są możliwe przy takim środowisku: + + + + + Dostęp do plików systemowych: http://my.host/cgi-bin/php?/etc/passwd + + + Informacje o zapytaniu w adresie URL (tzw. query string) po znaku zapytania (?) są + przekazywane jako argumenty wiersza poleceń do interpretera przez interfejs + CGI. Zazwyczaj interpretery otwierają i wykonują plik + podany jako pierwszy argument w wierszu poleceń. + + + Kiedy wywoływany jest jako program CGI, php odmówi zinterpretowania + argumentów wiersza poleceń. + + + + + Dostęp do dowolnego dokumentu na serwerze: http://my.host/cgi-bin/php/secret/doc.html + + + Część adresu URL będąca ścieżką po nazwie pliku binarnego PHP, + /secret/doc.html jest + zgodnie z konwencją używana do określenia nazwy pliku do + otwarcia i zinterpretowania przez program CGI. + Zazwyczaj używane są pewne dyrektywy konfiguracyjne serwera WWW (Apache: + Action) są używane do przekierowania żądań o dokumenty jak + http://my.host/secret/script.php do + interpretera PHP. Przy takim ustawieniu, serwer WWW najpierw sprawdza + uprawnienia dostępu do katalogu /secret, a potem tworzy + przekierowane żądanie http://my.host/cgi-bin/php/secret/script.php. + Niestety, jeśli żądanie jest od razu przekazane w tej postaci, + serwer nie wykonuje żadnych sprawdzeń dostępu dla pliku /secret/script.php, lecz tylko dla pliku + /cgi-bin/php. W ten sposób + każdy użytkownik, który ma dostęp do /cgi-bin/php jest w stanie uzyskać dostęp do dowolnego + chronionego dokumentu na serwerze WWW. + + + W PHP dyrektywy konfiguracyjne cgi.force_redirect, doc_root oraz user_dir mogą zostać wykorzystane do zapobieżenia + temu atakowi, jeśli struktura katalogów na serwerze ma jakieś katalogi + z ograniczeniami dostępu. Zobacz poniżej, żeby zapoznać się z pełnym objaśnieniem + różnych ich kombinacji. + + + + + + + Przypadek 1: obsługiwane są tylko publiczne pliki + + + Jeżeli Twój serwer nie ma żadnej zawartości, która nie jest zastrzeżona + przez kontrolę dostępu opartą o hasło lub adres IP, nie ma potrzeby użycia + tych opcji konfiguracyjnych. Jeśli Twój serwer nie pozwala + wykonywać przekierowań lub jeśli serwer nie ma sposobu, aby + zakomunikować plikowi binarnemu PHP, że żądanie jest bezpiecznie + przekierowanym żądaniem, możesz włączyć dyrektywę INI + cgi.force_redirect. + Wciąż musisz się upewnić, że Twoje skrypty PHP + nie zależą od konkretnej metody wywoływania skryptu, + czy to bezpośrednio przez http://my.host/cgi-bin/php/dir/script.php, + czy przez przekierowanie: http://my.host/dir/script.php. + + + Przekierowanie może być ustawione w Apache używając dyrektyw AddHandler i + Action (patrz poniżej). + + + + + Przypadek 2: użycie <literal>cgi.force_redirect</literal> + + Dyrektywa konfiguracyjna cgi.force_redirect + zapobiega wywołaniu php + bezpośrednio w adresie URL, np. http://my.host/cgi-bin/php/secretdir/script.php. + PHP będzie parsowało pliki w tym trybie tylko jeśli przekierowanie + pochodzi z reguły serwera WWW. + + + Zazwyczaj przekierowanie jest wykonywane w konfiguracji Apache w + następujący sposób: + + + + + + Ta opcja została przetestowana tylko z serwerem Apache i + opiera się o ustawienie niestandardowej zmiennej środowiskowej CGI + REDIRECT_STATUS przez Apache dla przekierowanych żądań. Jeśli Twój + serwer WWW nie wspiera żadnego sposobu zakomunikowania czy żądanie jest + bezpośrednie czy przekierowane, nie możesz użyć tej opcji i musisz + użyć jednej z innych metod uruchamiania CGI opisanych + w tym dokumencie. + + + + + Przypadek 3: ustawienie doc_root lub user_dir + + Umieszczanie aktywnej zawartości jak skrypty i pliki wykonywalne w + katalogu dokumentów serwera WWW jest czasem uznawane za niebezpieczną + praktykę. Jeśli na skutek mylnej konfiguracji skrypty + nie zostaną wykonane a wyświetlone jak zwykłe dokumenty HTML, to + skutkiem może być wyciek własności intelektualnej lub informacji + bezpieczeństwa, takich jak hasła. W związku z tym wielu administratorów preferuje + stworzenie innej struktury katalogów dla skryptów, które są + dostępne tylko przez PHP CGI i w związku z tym zawsze są + interpretowane, a nigdy nie wyświetlane bezpośrednio. + + + Ponadto, jeśli metoda upewnienia się, że żądania nie są + przekierowane (jak opisano w poprzedniej sekcji) nie jest + dostępna, konieczne jest ustawienie + opcji doc_root dla skryptu, + której wartość będzie inna niż ścieżka katalogu dokumentów serwera WWW. + + + Katalog główny skryptów PHP można ustawić dyrektywą + konfiguracyjną doc_root w + pliku konfiguracyjnym lub + ustawiając zmienną środowiskową + PHP_DOCUMENT_ROOT. Gdy ta opcja jest ustawiona PHP w + wersji CGI zawsze skonstruuje nazwę pliku do otwarcia z + użyciem doc_root i informacji o ścieżce w + żądaniu. Dzięki temu możesz mieć pewność, że żaden skrypt nie zostanie + wykonany poza tym katalogiem (poza user_dir, + patrz niżej). + + + Inną opcją której można użyć jest user_dir. Gdy user_dir nie + jest ustawiona, jedynym ustawieniem wpływającym na nazwę otwieranego pliku jest + doc_root. Otwarcie adresu URL jak np. http://my.host/~user/doc.php nie + skutkuje otwarciem pliku w katalogu domowym użytkownika, lecz pliku + nazywającego się ~user/doc.php w katalogu + doc_root (tak, katalogu zaczynającego się od tyldy + [~]). + + + Jeśli user_dir jest ustawiona przykładowo na public_php, żądanie takie jak http://my.host/~user/doc.php otworzy + plik doc.php w katalogu + nazwanym public_php w katalogu + domowym użytkownika. Jeśli katalog domowy użytkownika to /home/user, to wykonanym plikiem będzie + /home/user/public_php/doc.php. + + + Opcja user_dir działa niezależnie od + ustawienia doc_root, tak więc możesz kontrolować + dostęp do katalogu głównego dokumentów i katalogu użytkownika + osobno. + + + + + Przypadek 4: parser PHP poza drzewem dokumentów serwera WWW + + Bardzo bezpiecznym rozwiązaniem jest umieszczenie parsera PHP gdzieś + poza drzewem dokumentów webowych. Na przykład w /usr/local/bin. Jedyną faktyczną + wadą takiego rozwiązania jest konieczność umieszczenia linii + podobnej do: + + + + + + jako pierwszej linii w dowolnym pliku zawierającym tagi PHP. Będziesz też + musiał uczynić plik wykonywalnym. To znaczy traktować go tak, jak + traktowałbyś dowolny inny skrypt CGI napisany w Perlu, sh lub dowolnym + innym powszechnym języku skryptowym, który używa + mechanizmu powłoki #! do uruchomienia samego + siebie. + + + Aby PHP obsługiwało poprawnie informacje PATH_INFO i + PATH_TRANSLATED przy tym ustawieniu, musisz włączyć + dyrektywę INI cgi.discard_path. + + + + + + diff --git a/security/current.xml b/security/current.xml new file mode 100644 index 00000000..0169157b --- /dev/null +++ b/security/current.xml @@ -0,0 +1,40 @@ + + + + + Pozostawanie na bieżąco + + PHP, tak jak każdy inny wielki system, jest stale kontrolowany + i ulepszany. Nowa wersje często zawierają mniejsze i + większe zmiany mające na celu poprawę bezpieczeństwa i usunięcie luk, błędnej + konfiguracji i innych problemów, które wpływają na ogólny + poziom zabezpieczeń i stabilność Twojego systemu. + + + Tak jak i przy innych językach i programach skryptowych działających na poziomie systemu, najlepszym + sposobem jest częste pobieranie aktualizacji i pozostawanie na bieżąco z najnowszymi + wydaniami oraz zmianami w nich. + + + + + diff --git a/security/database.xml b/security/database.xml new file mode 100644 index 00000000..a4d8a58b --- /dev/null +++ b/security/database.xml @@ -0,0 +1,487 @@ + + + + Bezpieczeństwo baz danych + + + W dzisiejszych czasach bazy danych są kluczowymi komponentami każdej aplikacji internetowej, + umożliwiającymi stronom internetowym dostarczanie różnych dynamicznych treści. Ponieważ w bazie danych + mogą być przechowywane bardzo wrażliwe lub tajne informacje, należy poważnie podejść + do kwestii ochrony swoich baz danych. + + + Aby pobrać lub zapisać jakiekolwiek informacje, należy się połączyć do bazy danych, + wysłać poprawne zapytanie, pobrać wynik i zamknąć połączenie. + W obecnych czasach powszechnie stosowanym w tym celu językiem zapytań jest + SQL (Structured Query Language). Zobacz, w jaki sposób atakujący może manipulować zapytaniami SQL. + + + Jak możesz przypuszczać, PHP nie może ochronić Twojej bazy danych samej w sobie. + Kolejne sekcje są wprowadzeniem do podstaw tego, jak + uzyskiwać dostęp i zmieniać informacje w bazach danych z poziomu skryptów PHP. + + + Pamiętaj o prostej zasadzie: głęboka ochrona. W im większej ilości miejsc + zadbasz o zwiększenie ochrony swojej bazy danych, tym mniejsze + prawdopodobieństwo, że atakujący da radę wykraść lub wykorzystać przechowywane + w niej informacje. Dobry projekt schematu bazy danych oraz aplikacji + poradzi sobie z większością problemów. + + + + Projektowanie baz danych + + Pierwszym krokiem jest zawsze stworzenie bazy danych, chyba że chcesz + użyć bazy danych od strony trzeciej. Gdy baza danych jest tworzona, + przypisywany jest jej właściciel, który wykonał żądanie tworzące bazę. Zazwyczaj tylko + właściciel (lub superużytkownik) może operować na obiektach w tej + bazie danych, a inni użytkownicy muszą otrzymać uprawnienia, + aby mogli ich używać. + + + Aplikacja nigdy nie powinna łączyć się do bazy danych jako jej właściciel lub + superużytkownik, ponieważ ci użytkownicy mogą wykonać dowolne zapytania, na + przykład zmieniające strukturę bazy danych (np. usuwające tabele) lub + usuwające całą jej zawartość. + + + Możesz stworzyć różnych użytkowników bazy danych dla każdego z zastosowań + Twojej aplikacji z bardzo ograniczonymi uprawnieniami do obiektów w bazie danych. + Powinieneś nadawać tylko niezbędne uprawnienia i unikać tego, by ten sam użytkownik + mógł używać bazy danych w innych celach. Oznacza to, że jeśli + atakujący zdobędą dostęp do Twojej bazy danych używając poświadczeń aplikacji, + mogą wykonać tylko takie zmiany, które może wykonać Twoja aplikacja. + + + + + Łączenie z bazą danych + + Możesz ustanowić połączenie z wykorzystaniem SSL aby zaszyfrować + komunikację między klientem a serwerem i zwiększyć bezpieczeństwo, lub użyć ssh, + aby zaszyfrować połączenie sieciowe między klientami a serwerem bazy danych. + Przy zastosowaniu któregoś z tych rozwiązań monitorowanie ruchu i zdobycie + informacji o Twojej bazie danych będzie utrudnione dla potencjalnego atakującego. + + + + + + Szyfrowany model zapisu + + SSL lub SSH chroni dane płynące z klienta do serwera, ale + nie chroni danych już zapisanych w bazie. SSL jest + protokołem szyfrującym transfer danych. + + + Kiedy atakujący uzyska bezpośredni dostęp do Twojej bazy danych (omijając + serwer WWW), przechowywane wrażliwe informacje mogą być ujawnione, chyba że + informacja jest chroniona przez samą bazę danych. Szyfrowanie danych + jest dobrym sposobem, aby zapobiec temu zagrożeniu, ale bardzo niewiele + baz danych oferuje ten typ szyfrowania danych. + + + Najprostszym sposobem obejścia tego problemu jest stworzenie + swojej własnej paczki szyfrującej i wykorzystanie jej z poziomu skryptów PHP. PHP + może Ci w tym pomóc dostarczając kilka rozszerzeń, takich jak OpenSSL i Sodium, które oferują szeroką gamę algorytmów + szyfrujących. Skrypt może szyfrować dane przed ich umieszczeniem w bazie danych i odszyfrować + je w chwili odczytu. Zobacz odniesienia, żeby zobaczyć dalsze przykłady tego, + jak działa szyfrowanie. + + + + Haszowanie + + W wypadku naprawdę ukrytych danych, jeśli ich surowa reprezentacja nie jest potrzebna + (tj. dane nie będą wyświetlane), można rozważyć ich haszowanie. + Powszechnie znanym przykładem haszowania jest zapisywanie haszu kryptograficznego + haseł w bazie danych, zamiast trzymania samych haseł. + + + Funkcje modułu password + oferują wygodny sposób haszowania wrażliwych danych i pracy z tymi haszami. + + + Funkcja password_hash jest używana do haszowania podanego ciągu znaków używając + najmocniejszego obecnie dostępnego algorytmu, a password_verify + sprawdza czy podane hasło pasuje do haszu zapisanego w bazie danych. + + + Haszowanie pola z hasłem + + +]]> + + + + + + + SQL Injection (wstrzyknięcie SQL) + + SQL injection (wstrzyknięcie SQL) jest techniką, w której atakujący wykorzystuje luki + w kodzie aplikacji odpowiedzialnym za budowanie dynamicznych zapytań SQL. + Atakujący może zyskać dostęp do chronionych części aplikacji, + pobrać wszystkie informacje z bazy danych, manipulować istniejącymi danymi + lub nawet wykonywać niebezpieczne komendy systemowe na maszynie bazy + danych. Podatność występuje, gdy programista łączy lub wplata + dane wejściowe od użytkownika do zapytań SQL. + + + + + Dzielenie wyników na strony... i tworzenie superużytkowników + (PostgreSQL) + + + W następującym przykładzie dane wejściowe od użytkownika są bezpośrednio wplatane + w zapytanie SQL, pozwalając atakującemu na zdobycie konta superużytkownika w bazie danych. + + + +]]> + + + Normalni użytkownicy klikają na linki 'następna'/'poprzednia', które kodują wartość + zmiennej $offset w adresie URL. Skrypt spodziewa się, że + dane przychodzące w zmiennej $offset są liczbą. Jednak co jeśli ktoś spróbuje + włamać się doklejając następującą rzecz do adresu URL? + + + + + + Jeśli tak się stanie, skrypt utworzyłby atakującemu konto superużytkownika. + Zauważ, że 0; zostało podane aby dostarczyć poprawny offset + do oryginalnego zapytania i je zakończyć. + + + + Częstą techniką wymuszenia na parserze SQL aby zignorował resztę + zapytania napisanego przez programistę jest podanie --, czyli + znaków rozpoczynających komentarz w SQL. + + + + Możliwym sposobem na uzyskanie haseł jest obejście stron wyników wyszukiwania. + Jedynym co musi zrobić atakujący jest zobaczenie czy istnieją jakieś wysyłane zmienne + używane w zapytaniu SQL, które nie są obsługiwane poprawnie. Takie filtry mogą być + często ustawiane w poprzedzającym formularzu, aby dostosować klauzule WHERE, ORDER BY, + LIMIT and OFFSET w zapytaniu SELECT. + Jeśli Twoja baza danych wspiera konstrukcję UNION, + atakujący może spróbować dokleić całe zapytanie do oryginalnego, aby otrzymać + listę haseł z określonej tabeli. Jest zdecydowanie zalecane aby przetrzymywać jedynie + bezpieczne hasze haseł zamiast samych haseł. + + + Pobieranie listy artykułów... i haseł (dowolna baza danych) + + + +]]> + + + Statyczna część zapytania może zostać połączona z innym + wyrażeniem SELECT, które ujawnia wszystkie hasła: + + + + + + + + Zapytania UPDATE i INSERT również są + podatne na takie ataki. + + + Formularz resetujący hasło... aby uzyskać więcej uprawnień (dowolna baza danych) + + + +]]> + + + Jeżeli złośliwy użytkownik wyśle wartość + ' or uid like'%admin% jako zmienną $uid, aby + zmienić hasło administratora lub po prostu ustawi $pwd na + hehehe', trusted=100, admin='yes aby uzyskać więcej + uprawnień, to zapytanie zostanie zmienione: + + + +]]> + + + + + Mimo, że jest oczywiste, że atakujący musi posiąść jakąś + wiedzę na temat architektury bazy danych, aby przeprowadzić udany + atak, to zdobycie tej informacji jest często bardzo proste. Przykładowo + kod może być częścią otwartoźródłowego oprogramowania i być publicznie dostępny. + Informacje te mogą również zostać ujawnione + przez zamknięty kod źródłowy - nawet jeśli jest on zakodowany, zaciemniony lub skompilowany - + a nawet przez Twój własny kod, poprzez wyświetlanie wiadomości błędów. + Inne metody to np. użycie typowych nazw tabel i kolumn Na + przykład formularz logowania, który używa taeli 'users' z kolumnami nazwanymi + 'id', 'username', and 'password'. + + + + Atak na system operacyjny serwera baz danych (MSSQL Server) + + Przerażający przykład tego, jak na niektórych maszynach baz danych można + uzyskać dostęp do komend systemowych. + + + +]]> + + + Jeśli atakujący wyśle wartość + a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- + jako zmienną $prod, to wartością $query będzie: + + + +]]> + + + MSSQL Server wykonuje zapytania SQL w grupach, w tym komendę + dodającą nowego użytkownika do lokalnych kont bazy danych. Jeśli ta aplikacja + była uruchomiona jako sa i usługa MSSQLSERVER została + uruchomiona z wystarczającymi uprawnieniami, to atakujący miałby teraz + konto z dostępem do tej maszyny. + + + + Niektóre przykłady powyżej są powiązane z konkretnym serwerem baz danych, ale + nie oznacza to, że podobne ataki są niemożliwe względem innych produktów. + Twój serwer baz danych może mieć podobną podatność wykorzystywaną w inny sposób. + + + + + Zabawny przykład problemów związanych z SQL injection + + + + + + Obrazek dzięki uprzejmości xkcd + + + + + + + Techniki unikania + + Rekomendowanym sposobem unikania SQL injection jest przypisanie wszystkich danych + za pomocą przygotowanych instrukcji (ang. prepared statements). Użycie parametryzowanych zapytań + nie jest wystarczające aby zupełnie uniknąć SQL injection, ale jest najbezpieczniejszym sposobem dostarczenia + danych wejściowych od użytkownika do zapytań SQL. Wszystkie dynamiczne dane w zapytaniach WHERE, + SET i VALUES muszą być + zastąpione symbolami zastępczymi (placeholderami). Rzeczywiste dane zostaną podstawione podczas + wykonywania i zostaną wysłane osobno od zapytania SQL. + + + Podstawianie parametrów może być wykorzystane tylko dla danych. Inne dynamiczne części + zapytań SQL muszą być filtrowane tak, aby pozwolić tylko na znaną listę dozwolonych wartości. + + + + Unikanie SQL injection przy użyciu przygotowanych instrukcji PDO + +prepare("SELECT * FROM products WHERE id LIKE ? ORDER BY price {$sortingOrder}"); +// Wartość jest dostarczana z symbolami wieloznacznymi LIKE +$stmt->execute(["%{$productId}%"]); + +?> +]]> + + + + + + Przygotowane instrukcje są obsługiwane + przez PDO, + przez MySQLi + i inne biblioteki baz danych. + + + + Ataki SQL injection są oparte głównie na wykorzystywaniu kodu, który nie został stworzony + z myślą o bezpieczeństwie. Nigdy nie ufaj żadnym danym wejściowym, szczególnie + pochodzącym od użytkownika, nawet jeśli pochodzi z listy wyboru, + ukrytego pola formularza lub ciasteczka. Pierwszy przykład pokazuje, że takie + proste zapytanie może spowodować prawdziwy chaos. + + + + Strategia głębokiej ochrony opiera się na kilku dobrych praktykach kodowania: + + + + Nigdy nie łącz się do bazy danych jako superużytkownik lub właściciel bazy danych. + Zawsze używaj dostosowanych użytkowników z minimalnymi uprawnieniami. + + + + + Sprawdzaj czy otrzymane dane wejściowe mają oczekiwany typ danych. PHP ma + szeroki zakres funkcji sprawdzających dane, od najprostszych, które + można znaleźć w funkcjach zmiennych i + w funkcjach typu znaków + (np. is_numeric czy ctype_digit) + aż po wsparcie + wyrażeń regularnych kompatybilnych z Perlem. + + + + + Jeżeli aplikacja oczekuje danych numerycznych, rozważ ich weryfikację + funkcją ctype_digit, po cichu zmień ich typ + używając settype lub użyj reprezentacji numerycznej + dzięki sprintf. + + + + + Jeżeli warstwa bazy danych nie wspiera podstawiania parametrów, to + ujmij w apostrofy każdą nienumeryczną wartość przekazaną przez użytkownika, która jest + przekazywana do bazy danych. Zrób to za pomocą funkcji dodającej znaki ucieczki dla Twojej bazy danych (np. + mysql_real_escape_string, + sqlite_escape_string, itd.). + Ogólne funkcje takie jak addslashes są przydatne tylko + w bardzo określonych zastosowaniach (np. MySQL w jednobajtowym zestawie znaków + z wyłączonym NO_BACKSLASH_ESCAPES), więc + lepiej ich unikać. + + + + + Nie wyświetlaj żadnych informacji o bazie danych, szczególnie + jej strukturze — czy to umyślnie, czy przypadkiem. Zobacz też sekcje raportowanie błędów and funkcje raportowania i logowania błędów. + + + + + + + Poza tym, warto też skorzystać z logowania zapytań w kodzie Twojej aplikacji + lub przez samą bazę danych, jeśli wspiera ona takie logi. Oczywiście logowanie danych nie + jest w stanie zapobiec szkodliwym sytuacjom, ale może być pomocne w wyśledzeniu, która + aplikacja została zaatakowana. Log nie jest przydatny sam w sobie, lecz + dzięki informacjom które zawiera. Ogólnie rzecz biorąc, im więcej szczegółów tym lepiej. + + + + + + diff --git a/security/errors.xml b/security/errors.xml new file mode 100644 index 00000000..bd4b3b3c --- /dev/null +++ b/security/errors.xml @@ -0,0 +1,147 @@ + + + + + Raportowanie błędów + + W kwestii bezpieczeństwa PHP, są dwie strony raportowania błędów. Z jednej + strony jest to przydatne, aby zwiększyć bezpieczeństwo, a z drugiej może być szkodliwe. + + + Standardowa taktyka ataku zakłada profilowanie systemu dostarczając + mu niepoprawnych danych i sprawdzanie rodzaju i kontekstu zwracanych + błędów. To pozwala atakującemu na sprawdzenie + informacji o serwerze i określenie potencjalnych słabości systemu. + Na przykład, jeśli atakujący pozyskał informacje o stronie + na podstawie wcześniej wysłanego formularza, to może spróbować nadpisać + zmienne lub je zmodyfikować: + + Atak na zmienne przy użyciu własnego formularza HTML + + + + + +]]> + + + + + Zwracane błędy PHP zazwyczaj mogą być całkiem przydatne + dla programisty, który próbuje znaleźć błąd w skrypcie, wskazując na rzeczy + jak funkcja lub plik, który zawiódł, w którym pliku PHP nastąpił błąd, + numer linii z błędem. Te wszystkie informacje + mogą zostać wykorzystane. Zdarza się, że programiści PHP + wykorzystują funkcje show_source, + highlight_string lub + highlight_file jako narzędzia znajdowania błędów, ale w + przypadku działającej już strony, mogą one ujawnić ukryte zmienne, niesprawdzoną składnię + i inne niebezpieczne sytuacje. Szczególnie niebezpieczne jest uruchamianie + kodu z nieznanych źródeł z użyciem wbudowanych narzędzi debugujących lub używając + powszechnych technik debugowania. Jeśli atakujący może określić + jakiej techniki używasz, mogą spróbować zastosować atak brute-force na stronę, + wysyłając powszechnie znane ciągi znaków związane z debugowaniem: + + Wykorzystanie powszechnych zmiennych debugujących + + + + + + +]]> + + + + + Niezależnie od metody obsługi błędów, możliwość sprawdzenia + systemu pod kątem błędów prowadzi do uzbrojenia atakującego + w więcej informacji. + + + Na przykład sam styl ogólnego błędu w PHP daje informacje, że system + używa PHP. Jeśli atakujący patrzył na stronę .html i + chciał sprawdzić jej backend (szukając znanych luk w + systemie), wysyłając złe dane mogą być w stanie odkryć, + że system został zbudowany przy użyciu PHP. + + + Błąd funkcji może oznaczać, że system używa + konkretnego silnika baz danych lub dać poszlaki odnośnie tego jak strona + została zaprogramowana lub zaprojektowana. To pozwala na głębsze zbadanie + otwartych portów bazy danych lub sprawdzenie konkretnych błędów i podatności + na stronie. Dostarczając różne próbki błędnych danych atakujący + może na przykład określić kolejność autoryzacji w skrypcie + (w oparciu o numer linii w błędach) lub szukać podatności, które + mogą byc wykorzystane w różnych miejscach skryptu. + + + Błąd systemu plików lub ogólny błąd PHP mogą dać informacje jakie uprawnienia + ma serwer WWW oraz o strukturze i organizacji + plików na serwerze. Kod obsługi błędów napisany przez programistę może + pogorszyć ten problem, prowadząc do prostego wykorzystania wcześniej "ukrytych" + informacji. + + + Istnieją trzy główne rozwiązania tego problemu. Pierwsze to + sprawdzenie wszystkich funkcji i próba zapobieżenia większości + błędów. Drugie to całkowite wyłączenie raportowania błędów + dla działającego już kodu. Trzecie to wykorzystanie własnych + funkcji obsługi błędów w PHP. Zależnie od + Twojej polityki bezpieczeństwa, możesz uznać, że wszystkie trzy metody mają zastosowanie + w Twojej sytuacji. + + + Jednym ze sposobów wyłapania tej sytuacji przed czasem jest wykorzystanie + dyrektywy error_reporting w PHP, aby pomóc sobie + w zabezpieczeniu kodu i odkryciu użycia zmiennych, które może być niebezpieczne. + Testując swój kod przed wdrożeniem używając poziomu E_ALL + możesz szybko znaleźć obszary, w których zmienne są podatne na zatrucie + lub ich modyfikację w inny sposób. Gdy jesteś gotowy na wdrożenie, + powinieneś albo zupełnie wyłączyć raportowanie błędów, ustawiając + error_reporting na 0, albo wyłączyć pokazywanie + błędów używając opcji display_errors w &php.ini;, + aby zabezpieczyć swój kod przed sprawdzaniem go przed atakującego. Jeśli zdecydowałeś się + na drugą opcję, powinieneś też określić ścieżkę do swojego pliku logów używając + dyrektywy error_log i włączyć opcję + log_errors. + + Znajdowanie niebezpiecznych zmiennych dzięki E_ALL + + +]]> + + + + + + diff --git a/security/filesystem.xml b/security/filesystem.xml new file mode 100644 index 00000000..460adced --- /dev/null +++ b/security/filesystem.xml @@ -0,0 +1,236 @@ + + + + + Bezpieczeństwo systemu plików + + PHP podlega zabezpieczeniom wbudowanym w większość systemów serwerowych, + jeśli chodzi o uprawnienia do plików i katalogów. To pozwala + na kontrolę, które pliki w systemie plików mogą być odczytywane. Powinno + się zwracać uwagę na wszelkie pliki odczytywalne dla wszystkich, aby upewnić się, + że mogą one być bezpiecznie odczytane przez wszystkich użytkowników, którzy mają dostęp do tego + systemu plików. + + + Jako iż PHP został zaprojektowany, aby pozwolić na dostęp na poziomie użytkownika do systemu plików, + jest absolutnie możliwe, by napisać skrypt PHP, który pozwoli Ci na + odczytanie plików systemowych takich jak /etc/passwd, modyfikację połączeń + ethernet, wysłanie zadań do drukarki itd. Ma to pewne + oczywiste implikacje — musisz się upewnić, że pozwalasz + na odczyt i zapis właściwych plików. + + + Przeanalizuj poniższy skrypt, w którym użytkownik decyduje, że chciałby + usunąć plik w swoim katalogu domowym. Zakłada on + sytuację, w której interfejs webowy PHP jest często używany do + zarządzania plikami, więc użytkownik Apache ma uprawnienia do usuwania plików + w katalogu domowym użytkownika. + + + + Złe sprawdzanie zmiennych prowadzi do... + + +]]> + + + Ponieważ nazwa użytkownika i nazwa pliku pochodzą z formularza, + użytkownik może wysłać nazwę użytkownika i pliku należące do kogoś innego, + i skasować ich pliki nawet jeśli nie powinni mieć do tego uprawnień. + W tym wypadku powinno się użyć jakiejś innej formy autentykacji. + Zastanów się, co mogłoby się wydarzyć, jeśli przekazano by zmienne + "../etc/" i "passwd". + Kod mówiłby wtedy: + + ...ataku na system plików + + +]]> + + + Istnieją dwie konkretne akcje, które powinieneś podjąć aby zapobiec + tym problemom. + + + + Plik binarny PHP wykorzystywany przez strony internetowe powinien mieć ogranicozne uprawnienia, + + + + + Sprawdzaj wszystkie przesyłane zmienne. + + + + Oto poprawiony skrypt: + + Bardziej bezpieczne sprawdzanie nazwy pliku + + +]]> + + + Jednakże nawet ten skrypt nie jest pozbawiony wad. Jeżeli Twój system + autentykacji pozwala użytkownikom stworzyć ich własne loginy i użytkownik + wybrał login "../etc/", to system jest ponownie w niebezpieczeństwie. Z + tego powodu możesz preferować bardziej dostosowane sprawdzenie: + + Bardziej bezpieczne sprawdzanie nazwy pliku + + +]]> + + + + + W zależności od systemu operacyjnego, istnieją różne pliki, o których + ochronę powinieneś się zatroszczyć, w tym wpisy urządzeń (/dev/ + lub COM1), pliki konfiguracyjne (pliki w /etc/ oraz + pliki .ini), powszechnie znane miejsca przechowywania plików (/home/, + Moje Dokumenty) itd. Z tego + powodu zazwyczaj łatwiej jest stworzyć politykę, w której zabraniasz + wszystko poza wprost dozwolonymi plikami. + + + Problemy związane z pustym bajtem + + Jako iż PHP wykorzystuje pod maską funkcje C do obsługi operacji na + systemie plików, puste bajty mogą być obsługiwane w nieco zaskakujący sposób. + Jako że puste bajty oznaczają koniec ciągu znaków w C, ciągi znaków zawierające je + nie będą interpretowane w całości a jedynie do wystąpienia pustego bajtu. + + Następujący przykład pokazuje podatny kod, który demonstruje ten problem: + + + Skrypt podatny na puste bajty + + +]]> + + + + Z tego powodu każdy skrypt, który wykonuje operacje na systemie plików powinien być zawsze + dokładnie sprawdzony. Oto lepsza wersja poprzedniego przykładu: + + + Poprawne sprawdzanie danych wejściowych + + +]]> + + + + + + + diff --git a/security/general.xml b/security/general.xml new file mode 100644 index 00000000..f0d4933a --- /dev/null +++ b/security/general.xml @@ -0,0 +1,71 @@ + + + + + Uwagi ogólne + + Stworzenie w pełni bezpiecznego systemu jest zasadniczo niemożliwe, więc + często stosowanym podejściem w dziedzinie bezpieczeństwa jest balansowanie + między ryzykiem a użytecznością. Jeżeli każda zmienna wysyłana przez użytkownika + wymagałaby dwóch sposobów weryfikacji biometrycznej (jak np. skan siatkówki oraz + odcisk palca), osiągnęlibyśmy bardzo wysoki poziom + bezpieczeństwa. Oznaczałoby to też, że wypełnienie średnio + skomplikowanego formularza zajmowałoby 30 minut, a to z kolei powodowałoby, że + użytkownicy szukaliby sposobu na obejście wymogów bezpieczeństwa. + + + Najlepsze zabezpieczenia są często wystarczająco nieprzeszkadzające aby + spełniły wymagania bez powstrzymywania użytkowników od wykonania + ich zadań oraz bez zmuszania twórcy kodu do przesadnej + złożoności. W rzeczywistości niektóre z ataków wykorzystują właśnie + te przesadnie rozbudowane zabezpieczenia, która często z czasem zaczynają się rozpadać. + + + Stwierdzeniem wartym zapamiętania jest: system jest tak bezpieczny + jak jego najsłabszy element. Jeżeli wszystkie transakcje są dokładnie logowane + w oparciu o czas, lokalizację, typ transakcji itd., ale użytkownik jest + weryfikowany tylko w oparciu o pojedyncze ciasteczko, to poprawność przypisywania + użytkowników do logu transakcji jest bardzo wątpliwa. + + + Podczas testowania pamiętaj, że nie będziesz w stanie przetestować wszystkich + możliwości nawet dla najprostszych stron. Dane wejściowe, + których się spodziewasz, mogą być kompletnie inne niż te + podane przez zniechęconego pracownika, hackera przygotowującego się + miesiącami lub kota, który przeszedł po klawiaturze. Dlatego + najlepiej patrzeć na kod z logicznego punktu widzenia, aby określić + gdzie mogą się pojawić nieoczekiwane dane, a potem ustalić + jak zmienić lub wzmocnić to miejsce. + + + Internet jest pełen ludzi, którzy próbują wyrobić sobie markę łamiąc + Twoje zabezpieczenia, psując Twoją stronę, publikując nieodpowiednie + treści lub w inny sposób sprawiając, że Twój dzień stanie się bardzo interesujący. + Nie ma znaczenia czy Twoja strona jest duża czy mała, jesteś + celem tylko dlatego, że jesteś online, ponieważ masz serwer, do + którego można się podłączyć. Wiele programów do łamania zabezpieczeń nie patrzy + na rozmiar witryny, po prostu przeszukują ogromne blok adresów IP w poszukiwaniu ofiar. + Spróbuj nie stać się jedną z nich. + + + + diff --git a/security/hiding.xml b/security/hiding.xml new file mode 100644 index 00000000..488b1599 --- /dev/null +++ b/security/hiding.xml @@ -0,0 +1,77 @@ + + + + + Hiding PHP + + Ogólnie rzecz biorąc, bezpieczeństwo przez ukrywanie jest jedną z najsłabszych form bezpieczeństwa. + Jednak w pewnych wypadkach każda odrobina dodatkowego bezpieczeństwa jest pożądana. + + + Kilka prostych technik pozwala na ukrycie PHP, potencjalnie spowalniając + atakujących, którzy próbują znaleźć luki w Twoim + systemie. Ustawiając expose_php na off w Twoim + pliku &php.ini; zmniejszasz ilość dostępnych dla nich informacji. + + + Inną taktyką jest skonfigurowanie serwerów WWW (takich jak Apache) aby + parsowały różne typy plików z wykorzystaniem PHP, używając + dyrektyw &htaccess; lub w samych plikach konfiguracyjnych Apache. Możesz + wtedy użyć mylących rozszerzeń plików: + + Ukrywanie PHP jako innego języka + + + + + Lub ukryć go zupełnie: + + Użycie nieznanych rozszerzeń dla plików PHP + + + + + Możesz go też ukryć jako kod HTML, choć skutkuje to delikatnym pogorszeniem + wydajności jako, że wszystkie pliki HTML będą parsowane przez silnik PHP: + + Użycie <acronym>HTML</acronym> jako rozszerzenia dla PHP + + + + + Aby działało to poprawnie musisz zmienić nazwy swoich plików PHP + na takie z rozszerzeniami powyżej. Mimo że jest to forma bezpieczeństwa przez + ukrywanie, to jest to niewielki element utrudniający, kosztem niewielu wad. + + + + + diff --git a/security/intro.xml b/security/intro.xml new file mode 100644 index 00000000..c07edba5 --- /dev/null +++ b/security/intro.xml @@ -0,0 +1,61 @@ + + + + + Wprowadzenie + + PHP jest potężnym językiem i interpreterem, niezależnie czy jest dołączony + do serwera WWW jako moduł, czy wykonywany jako osobny program + CGI, ma dostęp do plików, możliwość wykonywania + komend i otwierania połączeń sieciowych na serwerze. Te + cechy powodują, że wszystko uruchamiane na serwerze jest z definicji niebezpieczne. + PHP został zaprojektowany w taki sposób, aby był bardziej bezpiecznym językiem do + tworzenia programów CGI niż Perl lub C i przy wybraniu odpowiednich + opcji konfiguracyjnych podczas konfiguracji i w czasie działania oraz przy zastosowaniu + poprawnych praktyk pisania kodu, może Ci zaoferować dokładnie taką kombinację wolności + i bezpieczeństwa, jakiej potrzebujesz. + + + Jako że istnieje wiele sposobów wykorzystania PHP, istnieje też wiele + opcji konfiguracyjnych kontrolujących jego zachowanie. Szeroki + wybór opcji pozwala na zastosowanie PHP w wielu + celach, ale oznacza też, że istnieją kombinacje tych + opcji i konfiguracji serwera, które skutkują niebezpiecznymi + ustawieniami. + + + Elastyczność konfiguracji PHP jest równie duża co elastyczność + tworzonego w nim kodu. PHP może być wykorzystane do stworzenia kompletnych + aplikacji serwerowych z całą potęgą użytkownika powłoki, bądź może być wykorzystane + dla prostych skryptów po stronie serwera z niewielkim ryzykiem, uruchamianych + w ściśle kontrolowanym środowisku. To jak zbudowane jest to środowisko + i jak bardzo jest bezpieczne, zależy w dużej części od programisty PHP. + + + Ten rozdział rozpoczyna się od ogólnych porad bezpieczeństwa, tłumaczy + różne kombinacje opcji konfiguracyjnych i sytuacje, + w których mogą być bezpiecznie użyte. Opisuje też różne uwagi odnośnie + pisania kodu, aby osiągnąć różne poziomy bezpieczeństwa. + + + + diff --git a/security/sessions.xml b/security/sessions.xml new file mode 100644 index 00000000..f5412943 --- /dev/null +++ b/security/sessions.xml @@ -0,0 +1,34 @@ + + + + Bezpieczeństwo sesji + + + Ważne jest, aby zarządzanie sesjami HTTP odbywało się bezpiecznie. + Zagadnienia związane z bezpieczeństwem sesji są opisane w sekcji + Bezpieczeństwo sesji w + części poświęconej modułowi sesji. + + + + + diff --git a/security/variables.xml b/security/variables.xml new file mode 100644 index 00000000..77e1feea --- /dev/null +++ b/security/variables.xml @@ -0,0 +1,103 @@ + + + + + Dane przesyłane przez użytkownika + + Największą słabością w wielu programach PHP jest nie słabość + samego języka, a zwyczajny problem w kodzie, który nie został napisany + z myślą o bezpieczeństwie. Z tego powodu, powinno się zawsze poświęcić czas, + aby przeanalizować skutki danego fragmentu kodu, rozważyć + potencjalne straty, jeżeli przekazana do niego zostanie nieoczekiwana zmienna. + + Niebezpieczne wykorzystanie zmiennych + + +]]> + + + + + Powinno się zawsze dokładnie sprawdzić kod, aby upewnić się, że + wszystkie zmienne wysyłane przez przeglądarkę są poprawnie + sprawdzone. Zadaj sobie następujące pytania: + + + + Czy ten skrypt wpłynie tylko na zamierzone pliki? + + + + + Czy może reagować na nietypowe lub niepożądane dane? + + + + + Czy ten skrypt może być użyty w niezamierzony sposób? + + + + + Czy ten skrypt w połączeniu z innymi skryptami może być użyty w zły + sposób? + + + + + Czy wszystkie działania są poprawnie logowane? + + + + + + Odpowiednio zadając sobie te pytania w trakcie pisania kodu, + a nie później, możesz zapobiec niefortunnej konieczności przepisania kodu, gdy + musisz zwiększyć bezpieczeństwo. Zaczynając z tymi zasadami w głowie, + nie zagwarantujesz pełnego bezpieczeństwa sytemu, ale pomoże Ci to + je poprawić. + + + Możesz też rozważyć wyłączenie register_globals, + magic_quotes lub innych wygodnych ustawień, które mogą wprowadzić zamieszanie + co do poprawności, źródła i wartości danej zmiennej. + Używanie PHP z trybem error_reporting(E_ALL) także może ostrzec + Cię przed zmiennymi, które są użyte przed sprawdzeniem lub + inicjalizacją (więc możesz zapobiec operowaniu na nietpowych + danych). + + + +