2010-11-01 15 views
7

Chciałbym być w stanie wykryć problemy z deserializacji w kodzie Java. Czego powinienem szukać? Na przykład, w jaki sposób można ustalić, czy jakiś kod Java próbuje wykorzystać "java calendar bug"? Zauważ, że nie jestem programistą javy, ale rozumiem pojęcia serializacji i grzywny OOP. Próbuję wprowadzić pewne kontrole bezpieczeństwa (coś w rodzaju narzędzia ostrzegawczego kompilatora).Jak wykryć problemy z deserializacją java?

EDIT: na podstawie uwag chciałbym zmienić Pytanie trochę: uważam cały kod analizowany „niezaufane”, czy istnieje sposób, jak ocenić potencjalne zagrożenie? Mam na myśli, czy mogę powiedzieć, że kod A jest bardziej niebezpieczny niż B w odniesieniu do błędu deserializacji? Czego powinienem szukać?

Odpowiedz

5

Po pierwsze musisz zrozumieć swój kontekst, aby określić zagrożenia bezpieczeństwa. (Kiedy mówię o "zaufaniu", robię małe skróty, mówię celowo złośliwie.)

Jeśli zserializowane dane zostały utworzone, zachowane i przeczytane z tym samym zaufaniem, to nie ma żadnych prawdziwy problem (poza zwykłymi błędami). Zauważ, że jeśli piszesz jakieś poufne informacje, to zserializowane dane są również wrażliwe (wydaje się oczywiste, ale tam jest spory margines).

Jeśli zsesekalizowane dane są niezaufane z jakiegokolwiek powodu, to jest nieco więcej do rozważenia. Wewnętrzna struktura odtworzonych obiektów może być "niezwykła". Dane mogą nie być spójne. Możliwe, że udostępniłeś zmienne obiekty, które powinny być oddzielne. Deserializacja może spowodować nieskończoną pętlę lub nieskończoną pętlę, która po prostu nie jest możliwa do wykonania przed śmiercią cieplną wszechświata. I oczywiście dane mogą być kłamstwami.

Jeśli piszesz kod biblioteki, który jest używany przez mniej zaufanego kodu, a potem robi się bardziej interesująca:

W przypadku „kalendarzowym bug” (i podobne), to jest o deserialising dowolny strumień z złośliwy dane i złośliwy kod. Wytyczne bezpiecznego kodowania Java sugerują przeprowadzanie sprawdzeń bezpieczeństwa (przy użyciu "Modelu zabezpieczeń Java2") w niestandardowych metodach readObject, co oznacza, że ​​nie należy wywoływać deserialization z większym zaufaniem niż kod i dane.

Po stronie obiektów, które można usualizować, sprawy są trudniejsze. Obiekty dostarczane przez ObjectInputStream do readObject, , , lub po prostu domyślna deserializacja mogą mieć odwołania przechwycone przez złośliwy kod lub, w przypadku klas nieostatecznych, mogą być złośliwie podklasy. Obiekt może być również używany podczas deserializacji, gdy jest częściowo zainicjowany. Deserializacja nie wywołuje "prawdziwego" konstruktora z deserializowanej klasy (readObject/readObjectNoData jest rodzajem konstruktora psuedo, który nie może ustawić wartości s final). To trochę koszmar, więc prawdopodobnie nie chcesz, aby twoje wrażliwe klasy były odtwarzane seryjnie.

Wystąpiło szereg słabych punktów w implementacji serializacji i deserializacji. Naprawdę nie musisz się tym martwić, chyba że sam je wdrożysz.

+0

+1 dokładna odpowiedź –

2

Hmm ... twoje pytanie jest trochę ogólne. Czy spojrzałeś na artykuł this? Chodzi o algorytm serializacji Java, ale z pamięci podręcznej Google, ponieważ strona główna wydaje się być w tej chwili niedostępna.

+0

Dzięki za artykuł, przejdę przez to. Wiem, że moje pytanie jest nieco zbyt ogólne, ale chcę omówić problem w sposób ogólny. – PeterK

1

Byłbym przekonany, że najlepszym sposobem na pokonanie kodu wykorzystującego znane luki w zabezpieczeniach w Javie jest uaktualnienie do wersji Java, która naprawia błąd. Kolejnym najlepszym sposobem (aby poradzić sobie z błędami związanymi z serializacją) jest traktowanie wszystkich serializowanych danych z nieznanych/niezweryfikowanych/niezabezpieczonych źródeł jako podejrzane.

Próba wykrycia problemów poprzez analizę kodu java pod kątem błędów bezpieczeństwa nie jest łatwa i wymaga dogłębnego zrozumienia mechanizmów Java, które są wykorzystywane i mogą być wykorzystywane. Próba wykrycia prób exploitów (ogólnie) byłaby jeszcze trudniejsza, szczególnie jeśli szukasz exploitów na luki w zabezpieczeniach zero-day. Pamiętaj, że istnieją inne potencjalne wektory.

(Gdyby nie było proste sposoby, aby znaleźć nieznane luki w zabezpieczeniach Javy, można założyć, że Sun i inni badacze bezpieczeństwa musiałby już korzystali z nich).

+0

Dobra uwaga! Dziękuję za odpowiedź. Zobacz edytowane pytanie, zmieniłem trochę, być może to gdzieś zaprowadzi. – PeterK

+0

@PeterK - Szczerze mówiąc, nie wiem, czego szukać. Ale po raz kolejny, gdyby istniały znane rzeczy, których należałoby szukać, można by oczekiwać, że Sun i inni już będą wyglądali. Na przykład wyobrażam sobie, że odkrycie dziury w Kalendarzu spowodowało lawinę wewnętrznych recenzji kodu. –

+0

Lepiej róbcie jedno i drugie. Uaktualnij i traktuj wszystkie zserializowane dane jako niezaufane. – Antimony

1

Jeśli serializacji swój obiekt Java, aby przenieść go do rozdzielone aplikacji, dlaczego nie rozważyć podpisania obiektu za pomocą klucza udostępnionego między aplikacjami? To powinno wystarczyć, by bronić się przed atakiem man-in-the-middle.

Wracając do sedna problemu z weryfikacją, weryfikacja jest niezwykle trudna dla języków ogólnego przeznaczenia. Powinieneś poszukać publikacji naukowych na ten temat. Myślę, że najczęściej stosowaną techniką jest sandboxing. Drugie podejście polega na ograniczeniu języka i zabronieniu wykonywania niebezpiecznych poleceń, np. Yahoo Caja library używa tej techniki.

Powiązane problemy