Jak importować zgłoszenia z formularza publicznego do sieci prywatnej
Prześledź jedno zgłoszenie z formularza publicznego od rekordu przyjęcia do prywatnego importera i utrzymaj walidację, poświadczenia oraz obsługę ponowień po właściwej stronie.
Publiczny formularz, który nigdy nie rozmawia z siecią prywatną, i tak wytwarza dane, które sieć prywatna musi ocenić. Tunel zmienia tylko to, kto do kogo się łączy. Wszystko po pobraniu jest decyzją importową i należy do strony prywatnej. Ten przewodnik śledzi jedno zgłoszenie od przeglądarki do zapisanego rekordu wewnętrznego.
Zacznij tam, gdzie trafia zgłoszenie
Przeglądarka wysyła żądanie do publicznego punktu końcowego, który zapisuje wiersz w kontrolowanym magazynie przyjęć i zwraca nic więcej niż potwierdzenie. Ten magazyn jest punktem przekazania i powinien być jedynym miejscem, do którego warstwa publiczna może pisać. Trzymaj tam surowe dane bez zmian, wraz z czasem ich przybycia i stabilnym identyfikatorem rekordu.
Następnie prywatny robotnik pobiera oczekujące wiersze przez tunel i decyduje, co zrobić z każdym z nich. Działa pod własną tożsamością, co jest tematem następnej sekcji.
curl --silent --fail \
--cert /etc/importer/client.crt --key /etc/importer/client.key \
"https://intake.corp.internal/api/pending?limit=20" \
-o /var/lib/importer/pending.json
Daj importerowi tylko te uprawnienia, których potrzebuje
Publiczny proces sieciowy i tożsamość, która zapisuje do aplikacji wewnętrznej, powinny być dwoma różnymi podmiotami. Publiczny serwer nie potrzebuje wewnętrznej administracji tylko dlatego, że musi dostarczyć dane formularza, a jedno wspólne konto dla obu stron zamienia każdy błąd sieciowy w wewnętrzny zapis. Wydaj robotnikowi własne poświadczenia, ogranicz je do jednej operacji importu i zapisuj, który podmiot wykonał każdy import. To właśnie rozdzielenie czyni granicę tunelu sensowną, a nie dekoracyjną.
Ogranicz także, z jakiego źródła robotnik może czytać. Jeśli implementacja korzysta z kolejki lub usługi transferu, ta usługa zachowuje własne uwierzytelnianie i politykę dostępu, ponieważ VPN nie uwierzytelnia niczego wewnątrz ładunku.
Funkcja krótkotrwała nie jest zwolniona z tej samej oceny. Podczas działania jej pozycja w sieci i poświadczenia nadal dają uprawnienia, a krótszy czas życia jedynie zawęża okno. Czas życia nie zastępuje decyzji o tym, jakie operacje może wykonywać tożsamość.
Waliduj, zanim cokolwiek wewnętrznego się zmieni
Pola publicznego formularza są tekstem kontrolowanym przez atakującego, dopóki nie dowiedzie się czegoś przeciwnego, i wytyczne OWASP dotyczące walidacji danych wejściowych właśnie dlatego zaliczają strumienie zaplecza do źródeł niezaufanych. Szyfrowany transfer mówi, że bajty dotarły nietknięte, a nie że opisują dozwolone żądanie. Parsuj i waliduj przed każdym uprzywilejowanym krokiem, aby zły wiersz nigdy nie dotarł do ścieżki kodu, która może działać.
Zdefiniuj dozwolone pola, ich formaty, rozmiary i reguły biznesowe, które muszą być spełnione. Data może być poprawnie sformatowana, a mimo to błędna dla żądanej operacji, a ładunek, który wskazuje konto wewnętrzne lub status zatwierdzenia, nie może sam sobie przyznać żadnego z nich.
Odrzucone wiersze wysyłaj do wyniku przeglądu, zamiast zgadywać poprawkę albo przekazywać je do powłoki lub surowego interfejsu bazy danych. Zapisuj identyfikator rekordu i regułę, która nie przeszła, a nie każde pole wpisane przez wnioskodawcę.
Utwórz punkt ponowienia przy jednej operacji
Jeśli rekord submission-1042 zostanie pobrany dwa razy, bo pierwsze potwierdzenie zaginęło, robotnik potrzebuje trwałego sposobu rozpoznania rekordu źródłowego i jego zapisanego wyniku. Harmonogram, który uruchamia zadanie raz, nie dowodzi, że każdy wiersz został zastosowany raz. Podwójna dostawa jest normalna, więc projekt musi ją wchłonąć.
Użyj własnej transakcji i mechanizmu obsługi duplikatów aplikacji wewnętrznej i utrzymuj identyfikator źródła, wynik oraz potwierdzenie w jednej spójnej sekwencji. Potwierdzaj dopiero po zapisaniu lub trwałym przypisaniu zamierzonej operacji i nigdy nie usuwaj wiersza przyjęcia tylko dlatego, że bajty zostały pobrane.
Następnie udowodnij to trzema stałymi zestawami: poprawnym wierszem, błędnie sformatowanym wierszem i tym samym kontrolowanym identyfikatorem źródła dostarczonym dwa razy. Każdy z nich przechodzi przez ten sam punkt końcowy, którego używa robotnik.
for f in fixtures/valid-submission.json fixtures/bad-date.json; do
curl --silent --fail --cert /etc/importer/client.crt \
-X POST --data @"$f" https://intake.corp.internal/api/records
done
curl --silent --fail --cert /etc/importer/client.crt \
-X POST --data @fixtures/valid-submission.json https://intake.corp.internal/api/records
Pierwsze dwa wiersze muszą zakończyć się w różnych stanach wewnętrznych, a trzeci musi zwrócić identyfikator już zapisany dla tego rekordu źródłowego, zamiast tworzyć drugi. Cokolwiek innego oznacza, że import nie jest jeszcze powtarzalny.