• Czas czytania ~8 min
  • 24.05.2023

Od początku 2022 roku spędzam czas na przeprowadzaniu audytów bezpieczeństwa i testów penetracyjnych dla aplikacji Laravel. Audytowałem aplikacje wszystkich rozmiarów, od małych aplikacji z garstką kontrolerów, aż po ogromne aplikacje z wieloma modułami i wieloma różnymi stylami kodowania i strukturami aplikacji.

Wśród tego wszystkiego pojawił się dość wyraźny trend, który dotyczy aplikacji, które skontrolowałem: Laravel jest dość bezpieczny, ale łatwo jest przeoczyć małe rzeczy, dodatkowe warstwy obrony i pozostawić gdzieś ukrytą słabość.

W rzeczywistości można śmiało powiedzieć, że zdecydowana większość problemów, które znalazłem podczas moich audytów, była albo czymś prostym, co zostało przeoczone w jednej drodze, albo są dodatkowymi warstwami zabezpieczeń, których programiści albo nie byli świadomi, albo nie czuli się komfortowo wdrażając.

Zanurzmy się więc w to i sprawdźmy 10 najczęstszych problemów z bezpieczeństwem, które odkryłem podczas audytów bezpieczeństwa.

#10 → Niewystarczająca walidacja danych wejściowych Często zdarza się, że niewystarczająca walidacja

danych wejściowych jest rozproszona po kontrolerach. Często będzie walidator sprawdzający oczekiwane klucze wejściowe (choć czasami nawet tego nie ma), a następnie request()->all() będzie używany natychmiast po tym, przesyłając dane do modeli, zdarzeń itp. Bez odpowiedniej weryfikacji łatwo jest wstrzyknąć złośliwe wartości, aby spowodować błędy, ataki iniekcyjne i inne.

Na przykład zwykła obrona masowego przypisywania jest uważana za $fillable modelową, ale jeśli $fillable zawiera flagę admin dla portalu administracyjnego, każdy może utworzyć nowego użytkownika administratora ze strony rejestracji... (I tak, to jest prawdziwy przykład.)

#9 → Missing Subresource Integrity (SRI)Subresource Integrity (SRI)

dodaje warstwę ochrony przed zainfekowanymi skryptami stron 3rd wpływającymi na twoją witrynę i moim zdaniem jest poważnie niewykorzystany. Ryzyko polega na tym, że skrypty i style stron 3rd mogą zostać zmodyfikowane w celu uwzględnienia złośliwego kodu, takiego jak Magecart, keyloggery, górnicy kryptowaluty itp. Jeśli w witrynie znajduje się skrypt, którego zabezpieczenia zostały naruszone, użytkownicy są zagrożeni, nawet jeśli Twoja aplikacja nie została naruszona.

SRI działa poprzez definiowanie skrótu integralności na każdym <script> tagu &<style>, który ładuje zasób strony 3rd, który przeglądarka weryfikuje przed załadowaniem zasobu. Jeśli skrót nie jest zgodny, zasób jest blokowany.

Większość stron, które skontrolowałem, nie ładowała zasobów od stron 3rd, a zatem i tak nie potrzebowała SRI, w przeciwnym razie spodziewałbym się, że będzie to znacznie wyżej na liście!

#8 → Niewystarczające ograniczenie

szybkości Ograniczanie szybkości jest niezbędne do ograniczania ataków botów i zapobiegania nadużyciom, a jednak często można znaleźć punkty końcowe, w których brakuje limitów szybkości. Jest to szczególnie niepokojące, jeśli chodzi o trasy takie jak uwierzytelnianie lub zapytania o poufne informacje, takie jak istnienie kont użytkowników. Na przykład odkryłem, że trasa uwierzytelniania wieloskładnikowego (MFA) oparta na SMS-ach nie miała ograniczenia szybkości - a 6-cyfrowy kod wygasł w ciągu 5 minut. To było trywialne, aby brutalnie wymusić prawidłowy kod i wcisnąć się do środka. 😈

To powiedziawszy, ograniczenie szybkości może być trudne do uzyskania - czy opierasz je na IP, nazwie użytkownika, czy na obu? A może coś innego? To zależy od trasy, ale posiadanie niektórych jest zdecydowanie lepsze niż żadne. Więc nie przeocz tego!

#7 → Cross-Site Scripting (XSS)

Jedna z najbardziej zaskakujących pozycji w Top 10, ale prawdopodobnie znacznie niższa niż się spodziewałeś! XSS zwykle pojawiał się na jednej trasie przez jedno wejście, z powodu czegoś takiego jak Markdown (który jest domyślnie niezabezpieczony) lub ograniczonego formatowania, które cierpiało z powodu subtelnego obejścia ucieczki.

Najlepszą strategią jest zwrócenie uwagi na te nieznośne tagi blade ({!! … !!}) i surowe dyrektywy HTML, takie jak v-html, i upewnienie się, że wszystkie zastosowania są prawidłowo zmienione, że funkcje bezpieczeństwa Markdown są włączone, a HTML dostarczony przez użytkownika jest oczyszczony. Zalecam unikanie tych tagów w jak największym stopniu, aby wszelkie zastosowania naprawdę się wyróżniały i można je było łatwo zidentyfikować i przejrzeć.

#6 → Przestarzałe i wrażliwe zależności

Kolejny niezaskakujący wpis... Tylko kiedy BYŁ ostatni raz, kiedy uruchomiłeś composer / npm update?

Często opóźnia się aktualizacje zależności, aby uniknąć awarii i utrzymać stabilność systemów, ale luki w zabezpieczeniach mogą narazić aplikacje na działanie bez żadnych działań. Często dołącza się również wiele zależności, ale każda zależność zwiększa potencjalne luki w zabezpieczeniach, o których musisz wiedzieć.

Zalecam aktualizowanie wszystkiego co tydzień lub co miesiąc oraz używanie narzędzi takich jak composer audit --locked i npm audit w systemie kompilacji, aby blokować wdrożenia po wykryciu luk w zabezpieczeniach. Sugeruję również ograniczenie zależności do minimum, a wszystko, co można łatwo zastąpić prostym wewnętrznym oprogramowaniem pośredniczącym lub opakowaniem, powinno być.

#5 → Niezabezpieczone Użycie

Funkcji Straciłem rachubę, ile razy widziałem md5(time()) (i md5(microtime())!) używane, odkąd zacząłem pracować w PHP - prawdopodobnie napisałem nawet kilka z nich we wczesnych latach! I rozczarowująco, jest to trend, który trwa do dziś. Co gorsza, jest często używany do generowania losowych tokenów lub unikalnych nazw plików. Tyle że nie jest ani losowy, ani wyjątkowy. Jest to niezwykle łatwe do odgadnięcia i brutalnej siły, a ataki kolizyjne mogą być również dość trywialne.

Założę się, że jeśli wejdziesz teraz do swojej bazy kodu i poszukasz md5(, znajdziesz go gdzieś niebezpiecznie ... Poważnie, mam traumę z tego powodu!

To nie tylko md5(time()) konkretnie, ale także inne funkcje, takie jak rand() i które nie są kryptograficznie bezpieczne i array_rand() nie należy ufać w niczym, co wymaga bezpieczeństwa.

Zawsze używaj odpowiednich bezpiecznych generatorów liczb losowych random_int() i Str::random(), aby bezpiecznie generować wartości losowe.

#4 → Brakujące

nagłówki bezpieczeństwa Teraz przechodzimy do dodatkowych warstw ochrony, które nie są dobrze rozumiane. Przeglądarki internetowe zawierają kilka naprawdę niesamowitych funkcji bezpieczeństwa, wystarczy włączyć je w swojej witrynie za pomocą nagłówków odpowiedzi. Chociaż ich brak nie otwiera bezpośrednio Twojej witryny na zhakowanie, pomagają zapobiegać takim rzeczom, jak clickjacking, wyciek informacji o stronie odsyłającej, ataki XSS i inne ataki iniekcyjne, ataki obniżające HTTPS itp. Włączenie wielu z tych nagłówków bezpieczeństwa jest trywialne, ale większość witryn nie włącza nawet łatwych ... 😭

Najlepszą sugestią, jaką mogę ci dać, jest udanie się do securityheaders.com i zeskanowanie witryny. Zostanie wyświetlona lista wszystkich brakujących nagłówków i łącza do zasobów, aby dowiedzieć się więcej o ich dodawaniu.

#3 → Brakujące zasady bezpieczeństwa treści (CSP)Zasady bezpieczeństwa treści są tak ważne,

że dałem im własne miejsce w Top 10. Dostawcy CSP stanowią drugorzędną linię obrony przed XSS i clickjackingiem oraz zapewniają wgląd w skrypty, style, czcionki, formularze, ramki itp. CSP informuje przeglądarkę, jakie zasoby mogą być używane na stronie, i blokuje i / lub zgłasza wszelkie naruszenia zasad - zapobiegając atakom XSS i zapewniając widoczność tego, co dzieje się w Twojej witrynie.

Często są one odrzucane jako zbyt trudne lub "psują rzeczy", jednak wdrożenie zasad tylko do raportów zapewnia pełną widoczność bez uszkadzania czegokolwiek. Więc jest to zdecydowanie droga, którą należy iść, gdy zaczynasz! Najprostszym sposobem skonfigurowania go jest użycie Kreatora CSP w identyfikatorze URI raportu.

Opublikowałem moje oprogramowanie pośredniczące CSP jako prosty sposób na rozpoczęcie pracy z dostawcami usług kryptograficznych: https://gist.github.com/valorin/d4cb9daa190fdee90603efaa8cbc5886

#2 → Brak autoryzacji O rany, ten obejmuje kilka rzeczy związanych z autoryzacją

(i uwierzytelnianiem w pewnym sensie). Widziałem: Insecure Direct Object References (IDOR), brakujące, auth i policy middleware, zapomniane signedauthorize() wywołania, webhooki bez walidacji itp. Ostatecznie kod nie sprawdzał, czy żądający może zrobić to, co chciał.

Byłem zaskoczony, widząc to tak wysoko na liście, ale okazuje się, że dość często zdarza się, że większość projektów ukrywa się gdzieś i czeka na wykorzystanie. Zwykle jest to prosty przypadek, w którym programista zapomina dodać linię, ale potencjalnie pozostawia ogromną dziurę.

Moim najlepszym zaleceniem jest uwzględnienie testów uwierzytelniania i autoryzacji na każdej trasie, obok innych testów. W ten sposób sprawdzasz prawidłowe i nieprawidłowe uprawnienia w ramach standardowego procesu testowania, a zauważysz, że brakuje autoryzacji, ponieważ test zakończy się pomyślnie, gdy powinien zakończyć się niepowodzeniem.

#1 → Ujawnione klucze API i hasła

Ile razy muszę to mówić? Nie wprowadzaj sekretów do Git! 😡

To nie był zaskakujący mistrz listy: klucze API i hasła zatwierdzone do kontroli wersji i rozproszone po bazach kodu. Jest to tak absurdalnie powszechne, że jestem szczerze zaskoczony, gdy nie natknąłem się na to podczas audytu.

Zastanów się, dokąd trafia Twój kod... Jest na wszystkich komputerach programistów, udostępnianych kontrahentom, na GitHub, Bitbucket, GitLab itp., W usługach i narzędziach do budowania stron 3rd. Jest rozproszony w wielu różnych miejscach. Podczas gdy klucze API odblokowują rozliczenia, przechowywanie plików, dane osobowe, kopie zapasowe, infrastrukturę itp. Tak wiele poufnych informacji i dostępu, a jeśli wpadną w niepowołane ręce, twoja reputacja zniknie.

Wiem, że istnieją samouczki, które zalecają popełnienie tych rzeczy, więc widzę, dlaczego tak się dzieje. Ale jest to coś, nad czym musimy ciężko pracować, aby zatrzymać się jako społeczność.

Jeśli przypadkowo zatwierdzisz poświadczenia, upewnij się, że zostały odwołane u źródła. Uniemożliwi to komukolwiek korzystanie z niego, jeśli go znajdzie. Sugeruję również użycie narzędzi takich jak Gitleaks i TruffleHog, aby znaleźć sekrety w swoich bazach kodów.

BONUS → Brak bezpieczeństwa.txt plik!

Nie jest to kwestia bezpieczeństwa jako taka, więc uwzględniłem ją jako bonus, ale dodanie security.txt pliku do aplikacji jest jedną z najprostszych i najlepszych rzeczy, które możesz zrobić dla swojego bezpieczeństwa.

security.txt is a text file that you put at /.well-known/security.txt, which provides your (security) contact details in case someone finds a security issue with your site. This makes it super easy for security folks to contact you, reducing the time and effort it takes to report issues so you can get them fixed faster.

Wygeneruj jeden tutaj: https://securitytxt.org

Podsumowanie

Ok, moi przyjaciele, to moje 10 najlepszych! Czy były jakieś niespodzianki? Rzeczy, które musisz sprawdzić we własnych aplikacjach? Może było coś, z czym się nie zgadzasz? Przejdź do wątku na Twitterze, Fediverse lub Substack Notes, aby dołączyć do dyskusji!

Kluczowym wnioskiem dla mnie jest to, że chociaż Laravel jest bezpieczny, to wszystkie małe rzeczy są pomijane i pomijane. Łatwo jest założyć, że sprawdziłeś autoryzację na każdej trasie, a dane wyjściowe są całkowicie uniknięte, ale może być to jedno wystąpienie, które przegapiłeś. Jest to korzyść z audytów bezpieczeństwa - nakłonienie kogoś, kto nie przyjmuje założeń, do przejrzenia kodu. Jest to również to, czego uczę na moim praktycznym kursie Laravel Security.

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297