OWASP_Application_Security_Verification_Standard_4.0 - scriptCode

Wywołania usług zdalnych

Wszelkie parametry wchodzące do ScriptCode'u traktuj jako niezaufane przy wysyłaniu do usług

W praktyce oznacza to, że należy ściśle przestrzegać zasad API dostarczonego klienta REST. Definiuje on między innymi sposób tworzenia ścieżki jako listę poszczególnych segmentów adresu. Taki interfejs wydaje się nieintuicyjny, ale zapewnia on większe bezpieczeństwo.

Przykładowy kod

Źle:

const url = "/api/form/" + context.getFirstParameter("form_id") + "/data";
const response = api.rest.v1.get("host", {pathParams: url.split("/")});

Dobrze:

const pathParams = ["api", "form", context.getFirstParameter("form_id"), "data"];
const response = api.rest.v1.get("host", {pathParams: pathParms});
Przed czym się chronimy?

Poprawne wykorzystanie API uchroni nas przed atakami polegającymi na modyfikacji docelowego adresu. Prześledźmy przykładowy kod, przy założeniu, że parametr form_id przychodzi z pola na formularzu. Jeżeli użytkownik wpisze w pole "abc/def" znak "/" to w pierwszym przykładzie zostanie on potraktowany jako część adresu i ostatecznie wywołamy usługę o adresie "/api/form/abc/def/data", czyli w praktyce możemy przez przypadek strzelić do innej usługi ("/api/form/{x}/{y}/data" zamiast "/api/form/{x}/data", czyli zamiast x = "abc/def", będziemy mieli x = "abc", y = "def") natomiast kod z drugiego przykładu spowoduje wyescape'owanie tego znaku i strzał pod adres "/api/form/abc%2Fdef/data" (czyli w adresie "/api/form/{x}/data" zmienna x przyjmie wartość "abc/def").

Obsługa danych autoryzacyjnych do usług

Dane autoryzacyjne nigdy nie powinny być używane bezpośrednio w ScriptCode. W przypadku wołania usług zewnętrznych (np przez api.rest.v1) to platforma jest odpowiedzialna za ustawienie odpowiednich danych autoryzacyjnych w żądaniu do usługi. Jeżeli dla danej usługi nie jest to wspierane należy zgłosić zapotrzebowanie u PO. W przypadku usług, dla których implementacja jest technicznie niemożliwa lub będzie długotrwała należy skonsultować się z developerami w jaki sposób bezpiecznie przekazać dane autoryzujące. Niezależnie od przyjętego bezwzględnie należy unikać zapisywania danych autoryzacyjnych (w kodzie, zmiennych sesyjnych, zmiennych procesowych, polach na formularzu) oraz wysyłania ich na frontend (pola formularza - również pola techniczne, zmienne sesyjne).

Jak rozpoznać problematyczne dane? Niestety ze względu różnorodność sposobów uwierzytelniania ciężko przedstawić pełną listę takich danych - należy się kierować zdrowym rozsądkiem i zwracać szczególną uwagę na dane, które dają dostęp do usług. Poniżej krótka lista terminów, która ułatwi Ci identyfikację takich danych - jeśli się z nimi spotkasz to bądź czujny:

  • login/użytkownik i hasło,

  • token,

  • klucz,

  • nagłówek Authorization,

  • API key,

  • API token,

  • bearer token,

  • token JWT.

Pobieranie zdalnych zasobów

Wszelkie używane przez nas zasoby (np: obrazki, dokumenty, wizerunki kart itd) powinny pochodzić z zaufanego źródła. Najczęściej tym źródłem jest sama platforma eximee lub jakiś zasób bankowy, natomiast nigdy nie powinien nim być internet. W większości przypadków eximee ogranicza możliwość wykorzystania zasobów wyłącznie do zaufanych (np: w kliencie usług rest można odwoływać się wyłącznie do zdefiniowanych przez administratora usług), jednak mogą istnieć miejsca, w których takie ograniczenie jest niezaimplementowane (lub niemożliwe do implementacji). Każdorazowo kiedy chcemy w aplikacji skorzystać z zewnętrznego źródła (w praktyce jakiegoś adresu URL) należy zweryfikować czy jest to źródło zaufane (pochodzi z domeny banku, przyszło do nas w wymaganiach) - jeżeli źródło nie jest zaufane należy skonsultować z PO jego użycie. Natomiast niedopuszczalnym jest korzystanie z zewnętrznych usług w celu zrealizowania funkcjonalności, której nie ma w platformie - w takich przypadkach należy zgłosić zapotrzebowanie na daną funkcjonalność.

Przykładowy problem z zewnętrznymi zasobami i jego konsekwencje

Na jednym z wydruków mieliśmy wymaganie polegające na wygenerowaniu kodu QR na podstawie danych wniosku. Ponieważ w platformie nie było takiej funkcjonalności developer podjął decyzję o skorzystaniu z zewnętrznego API https://api.qrserver.com. Podczas generowania dokumentu zaczęła być wywoływana zewnętrzna usługa https://api.qrserver.com/v1/create-qr-code/?data=${dataFormatted}&size=140x140 (dataFormatted to dane, które były zbierane na wniosku), a wynik jej wywołania był umieszczony na wydruku w formie obrazka.

Jakie są konsekwencje takiego postępowania:

  1. To jest zewnętrzna usługa, nie panujemy nad nią, nie mamy wpływu na okresy jej niedostępności, potencjalnie może zniknąć z internetu

  2. Nie został rozpoznany model licencyjny - narażamy naszego klienta i nas na konsekwencje prawne i finansowe użycia usługi niezgodnie z licencją

  3. Nie wiemy jak działa ta zewnętrzna usługa - potencjalnie może wygenerować złośliwy kod, który umieścimy na wydruku (w PDF) i zostanie wykonany u klienta

  4. W zmiennej dataFormatted były takie dane jak adres klienta czy kwota wpłaty gotówkowej w banku - są to dane chronione przez RODO i prawo bankowe, używając ich w linku przekazaliśmy je do zewnętrznego podmiotu (doprowadzamy do wycieku danych) - narażamy bank i siebie na konsekwencje prawne i finansowe

Dane wrażliwe

Używaj loggera sensytywnego do logowania danych wrażliwych

Przykładowy kod

Nowe loggery (preferowany sposób):

Nowe loggery domyślnie traktują każdy przekazany parametr jako dane wrażliwe. Żeby zmienić to zachowanie należy jawnie użyć na parametrze funkcji nonsensitive. Dodatkowo nowe loggery pozwalają na umieszczanie parametrów w szablonie tekstu (nie robimy konkatenacji tak jak w przypadku starych loggerów).

Źle:

const pesel = context.getFirstParameter("pesel");
// 1.
Logger.info("Pesel klienta wypełniony na formularzu: {}", nonsensitive(pesel));
// 2.
Logger.info("Pesel klienta wypełniony na formularzu: " + pesel);

Dobrze:

const pesel = context.getFirstParameter("pesel");
Logger.info("Pesel klienta wypełniony na formularzu: {}", pesel)

Last updated

Was this helpful?