Czy odbicie jest niekorzystne, ponieważ zmiennych prywatnych nie można ograniczyć?
14
privateModyfikator jest stosowany w celu ograniczenia dostępu spoza klasy, ale przy użyciu odbicia inne klasy mogą uzyskać dostęp do metody prywatny i pola. Zastanawiam się więc, w jaki sposób możemy ograniczyć dostępność, jeśli jest to częścią wymogu.
Kod o niskim zaufaniu nie może używać prywatnej refleksji (przynajmniej nie na innych zestawach, zapomniałem szczegółów). Kod pełnego zaufania może po prostu użyć wskaźników, aby ominąć wszelkie ograniczenia w tym procesie.
Modyfikatory dostępu prywatnego istnieją głównie po to, by informować programistów, że „nie używają tego spoza klasy, a jeśli naprawdę, to nie narzekaj, jeśli następna wersja złamie kod”, a nie tak ściśle wymuszoną funkcję bezpieczeństwa.
Użytkownicy mogą również po prostu załatać twój kod, aby zrobić co tylko zechce. Z częściowym wyjątkiem dotyczącym DRM (który nie jest wystarczająco silny, aby zapewnić trwałą ochronę), każdy, kto ma dostęp do twojej aplikacji (pliki binarne lub kod źródłowy) może z tym zrobić wszystko.
Czy to nie jest pytanie specyficzne dla języka? Refleksja działa inaczej w różnych językach. Zastanawiam się, czy to pytanie powinno mieć tag Java lub coś innego.
Modyfikatory dostępu mają na celu informowanie programistów piszących kod o tym, jaki jest publiczny interfejs klasy. Nie są w żaden sposób środkiem bezpieczeństwa i nie dosłownie ukrywają ani nie zabezpieczają żadnych informacji.
To nie jest uniwersalna prawda. Cytując Erica Lipperta : „Modyfikatory dostępu w CLR są funkcjami bezpieczeństwa. Zasady dostępu są ściśle powiązane z systemami bezpieczeństwa i bezpieczeństwa typu.” W języku C # Reflection jest dostępne tylko dla kodu działającego z pełnym zaufaniem. Nie dotyczy to (i nie może) szkodliwych użytkowników systemu, którzy uruchamiają kod. Dotyczy to jednak złośliwych wtyczek.
@Brian Problem, o którym wspomina Brian, jest istotny, gdy system pozwala na uruchomienie kodu innej firmy bez pełnego zaufania. Przykłady obejmują piaskownice przeglądarki (np. Bardzo znienawidzony aplet), silnik aplikacji Google i platformę Azure . Byłoby naprawdę głupie, gdyby Azure nie pozwalał niezaufanemu kodowi na eksplorowanie szczegółów podstawowych bibliotek platformy.
@Brian To nie w 100% poprawne - istnieją pewne operacje refleksji, które można wykonać w częściowo zaufanym kodzie; po prostu nie pozwala ci robić rzeczy takich jak dostęp do prywatnych pól.
@Brian Dopóki ktoś nie znajdzie luki w zabezpieczeniach lub inżynierii społecznej, która pozwala jej ominąć ograniczenia. Nie ma sensu próbować używać ich w ten sposób. To nie jest ich głównym celem.
„Chodzi tutaj o ochronę przed Murphym vs. ochronę przed Machiavellim ... to znaczy ochronę przed przypadkowym niewłaściwym użyciem (co język robi bardzo dobrze) w porównaniu z celowym nadużyciem (co jest faktycznie niemożliwe). programista tak bardzo chce obalić system, znajdzie sposób „
Nie są czasy, gdzie trzeba do piaskownicy kod niezaufanych, ale że jest to zadanie trudne. Ochrona przed błędem (Murphy) jest znacznie bardziej powszechnym przypadkiem.
#define private public(ignorując fakt, że tak naprawdę jest to niezdefiniowane zachowanie) i voila Mam pełny dostęp z zewnątrz do ograniczonej części twoich zajęć.
Ochrona przed celowym nadużyciem może być teoretycznie niemożliwa, ale jest to faktycznie możliwe, ponieważ sprawia, że nadużycie jest wystarczająco trudne, że zdarza się bardzo rzadko. Ważne jest, aby mieć jasność na ten temat. W przeciwnym razie oprogramowanie nie byłoby w ogóle możliwe w sytuacjach takich jak krytyczne dla życia urządzenia medyczne.
@MarkJ. Uwaga Herb Suttera dotyczy umyślnego znęcania się przez programistę, który napisał klasę w pierwszej kolejności i być może jego kolegów z zespołu. Nie sądzę, że istnieje sposób, aby zapobiec tego rodzaju nadużyciom ze względu na funkcje językowe.
@bolov, że ten wyczyn zależy od języka. Podczas gdy preprocesory C / C ++ prawdopodobnie pozwoliłyby ci na ucieczkę, wszystko bez nich prawdopodobnie dałoby błąd „nie można użyć słów zastrzeżonych w #define”.
Nie, to faktycznie ważna zaleta. To, że niektórzy programiści nie uważali, że ktoś będzie potrzebował dostępu do jakiegoś stanu wewnętrznego, nie oznacza, że nigdy nie pojawi się żaden uzasadniony przypadek użycia. W takich przypadkach użycie Refleksji do wykonania operacji na obiekcie może być ostatecznością. Musiałem użyć tej techniki więcej niż raz.
Jeszcze bardziej ograniczasz dostępność, wchodząc o jeszcze jeden poziom: środowisko wykonawcze.
Nie wszystkie języki mają tę koncepcję, ale przynajmniej w Javie możesz użyć menedżera bezpieczeństwa, który zabrania udostępniania prywatnych pól. Możesz ręcznie zainstalować menedżera bezpieczeństwa w czasie wykonywania lub dodać zasadę bezpieczeństwa do pliku jar, który jest następnie zapieczętowany, aby zapobiec modyfikacji.
W Pythonie nie ma modyfikatorów dostępu. Konwencja polega na poprzedzeniu znakiem podkreślenia metod i zmiennych, do których nie oczekuje się dostępu z zewnątrz klasy. Czy to technicznie uniemożliwia ci dostęp do takiego pola z klasy innej firmy? Ani trochę; ale jeśli to zrobisz, jesteś sam i ryzykujesz zepsucie czegoś, bez możliwości obwiniania drugiej klasy.
W języku C # istnieją modyfikatory dostępu, ale są one jeszcze tylko konwencją - wymuszoną przez kompilator, ale nadal konwencją. Oznacza to, że technicznie nadal można uzyskać dostęp do zmiennych prywatnych i zmieniać je, albo poprzez odbicie, albo bezpośrednio manipulując pamięcią (jak robią to trenerzy gier ). Konsekwencja jest dokładnie taka sama: jeśli zmienne w twojej klasie zostaną zmienione przez Odbicie od innej klasy lub przez manipulowanie pamięcią przez inną aplikację, i to psuje coś w twojej klasie, to nie twoja wina.
Pamiętaj, że to oczywiście stwarza problemy bezpieczeństwa, w których strona trzecia może uzyskać dostęp do twoich danych; coś, co prowadzi do zaszyfrowanych wariantów ciągu i podobnych struktur danych. Ale ochrona twojego kodu przed takim użyciem jest bardziej związana z ograniczeniami systemu operacyjnego i dostępu na poziomie kodu i nie ma nic wspólnego z Reflection per se.
Należy pamiętać, że w języku C # tylko w pełni zaufany kod może odzwierciedlać członków prywatnych. Pisanie bezpośrednio do pamięci procesu nadal działa, ale jest trudniejsze niż w kodzie natywnym.
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.