Zabezpieczanie aplikacji internetowych - HTML i SQL
Skąd czerpać informacje o zabezpieczaniu aplikacji?
Paradoks zabezpieczania aplikacji jest taki, że w skomplikowanej aplikacji developer musi zabezpieczyć każdy potencjalny kanał dostępu do strzeżonych informacji, a atakującemu wystarczy często tylko jedna luka, żeby obejść wszystkie starania obrońcy. Dobra nowina jest taka, że istnieje organizacja, które gromadzi informacje o najlepszych praktykach bezpieczeństwa i potencjalnch niebezpieczeństwach w jednym miejscu i dba o to, aby wszystkie te informacje były aktualne i posortowane zaczynając od najistotniejszych. W przypadku aplikacji webowych tą orgaznizacją jest OWASP.
Jeżeli z tej lekcji masz wynieść cokolwiek, to niech to będzie informacja, żeby zaczynać od materiałów od OWASP kiedy przychodzi do czerpania wiedzy o bezpieczeństwie.
Są oczywiście inne organizacje i firmy zajmujące się szeroko pojętym bezpieczeństwem, w Polsce mamy chociażby grupę Sekurak czy takie organizacje informacyjne jak Niebezpiecznik czy Zaufana Trzecia Strona. Sekurak wydał nawet dość rozbudowane kompendium wiedzy na temat bezpieczeństwa aplikacji webowych w języku polskim.
Bezpieczeństwo aplikacji jest złożonym tematem, którego skomplikowanie tylko rośnie wraz z rozwojem technologii internetowych. Można powiedzieć, że bezpieczeństwo informacji to wyścig zbrojeń, w którym obrońcy starają się łatać dziury w murach, które są na bieżąco budowane. Ale dlaczego mury już na starcie są dziurawe? W momencie powstawania sieć WWW miała służyc wymianie prac naukowych pomiędzy pracownikami uniwersytetów. W tamtych czasach publiczny Internet składał się głównie z komputerów w sieciach akademickich. W tym kontekście nikt nie myślał o zabezpieczeniach, bo co zabezpieczać i przed kim? Potem dostęp do Internetu gwałtownie eksplodował, a aplikacje internetowe z czasem zaczęły dotyczyć tematów komercyjnych. Wszystko to doprowadziło do sytuacji, w której systemy komputerowe obsługujące nietrywialne tranzakcje finansowe były bardzo łatwym łupem dla kogoś z odrobiną wiedzy technicznej . Od tego czasu wiele się już zmieniło i jesteśmy w dużo lepszym miejscu, ale to nie znaczy, że wszystkie problemy są rozwiązane. Jako programiści ciągle musimy mieć się na baczności.
Dlaczego nas to dotyczy?
Już teraz nasza aplikacja korzysta z protokołu HTTP, języków HTML i CSS oraz bazy danych SQLite i w związku z tym języka SQL. To już jest spora liczba różnych technologii, gdzie możemy popełnić błąd, który będzie wpływać na bezpieczeństwo naszych aplikacji.
HTML injection
Na czym polega HTML incjection?
Zacznijmy od naszego silnika renderującego strony w języku HTML. Sam język HTML składa się z tagów, które przeglądarka przetwarza na dokument prezentowany potem użytkownikowi. Oznacza to, że jeżeli chcę umieścić w tekście tag, np. <p>, lub coś co wygląda jak tag, to na jakiej podstawie przeglądarka ma wiedzieć, że to nie jest tak naprawdę tag HTML, tylko część tekstu? HTML definiuje sekwencje znaków, które następnie przeglądarka przetwarza na odpowiednie znaki. Jeżeli chcę umieścić na swojej stronie znak ‘<’, to w kodzie HTML mogę użyć ciągu znaków <. Pełną listę takich sekwencji możesz znaleźć np. na tej stronie MDN.
Proces podmieniania znaków tak, aby składnia języka nadal pozwalała na tworzenie dowolnych treści przy zachowaniu jednoznaczności języka nazywa się character escaping, albo encoding, kiedy mówimy o przetworzeniu danych tak aby były odpowiednie do danego języka.
Ale teraz spójrzmy na to z drugiej strony. W ostatnim projekcie pozwalaliśmy użytkownikow wprowadzać do naszej aplikacji dane, które następnie wyświetlaliśmy na naszej stronie. Co jeżeli ktoś umieściłby np. w swoim przepisie na ciasto tag zamykający </body>? Albo co gorsza, gdyby postanowił w środku swojego komentarza wstawić tag <script> zawierający złośliwy kod, np. keylogger wysyłający wpisywany przez użytkownika tekst do innego serwera, albo koparkę jakiejś waluty cyfrowej?
Jako właśiciele aplikacji internetowej jesteśmy częściowo odpowiedzialni za publikowane treści. Oczywiście to nie my wysyłamy w takiej sytuacji hasła użytkowników do obcych serwerów, ale to umożliwiliśmy to innym użytkownikom naszej aplikacji. Dlatego musimy traktować zadanie zabezpieczenia naszej aplikacji z należytą powagą.
Jak zapobiegamy HTML injection?
Jeżeli dotychczas korzystaliśmy z silnika EJS tak, jak wytłumaczyliśmy to na naszych zajęciach, to nasza aplikacja powinna być bezpieczna.
Kluczowym elementem jest umieszczanie wszelkich danych pochodzących od użytkowników:
- W środku bezpiecznych tagów, takich jak
<div>,<p>, itp. Pod żadnym pozorem dane od użytkowników nie powinny trafić np. do tagu<script> - W odpowiednich tagach EJS, mianowicie
<%= %>, które przed zwróceniem zawartości na wyjście same przeprowadzają escaping danych.
Gdybyśmy zdecydowali się sami konstruować HTML na podstawie danych użytkownika, sami będziemy odpowiedzialni za escaping wprowadzonych danych. Na szczęście całe wyzwanie sprowadza się do zastąpienia zaledwie 5 znaków: <>&'".
SQL injection
Kolejnym bardzo powszechnym problemem w aplikacjach webowych jest używanie danych od użytkowników w zapytaniach do bazy SQL. Z podobnych powodów, jak przy HTML Injection, musimy uważać na sposób konstrukcji takich zapytań. Jeżeli bezkrytycznie wstawimy dane od użytkownika do zapytania SQL, to odpowiednio spreparowane dane mogłyby zmienić treść zapytania w diametralny sposób.
Rozdział niedokończonyZadanie
Wróć do swojego projektu i przeglądnij kod w poszukiwaniu miejsc, gdzie dane od użytkownika mogły wpłynąć na produkowany przez aplikację HTML lub na zapytania do bazy danych. Jeżeli znajdziesz jakieś potencjalne zagrożenie, spróbuj je wyeliminować.