Dawno się tym nie bawiłem, ale to znaczy mniej więcej
Z mojego rozkazu i dla dobra państwa zamieszczony kod zrobił to, co zrobił
.
aleosochodzi:
Mechanizm o którym niżej pisze jest nieczęsto normalnie używany. Ostatni raz się tym bawilem pewne z 8 lat temu. Mogłem coś pomieszać.
Załóżmy, że robisz np. grę dla programistów. Gra polega na tym, że trzeba napisać algorytm rozwiązujący jakies zadanie. W postaci klasy w Javie.
Czyli ludzie wysyłają kod w javie ty go kompilujesz na serwerze i uruchamiasz i sprawdzasz czy daje odpowiednie wyniki.
Fajnie.
Ale mimo, że programiście to - wiadomo - fajni ludzie - prędzej czy później ktoś, dla sportu, wrzuci taki kod:
Kopiuj
Runtime.getRuntime().exec("format.exe C:\\");
I wtedy pisząc nową wersję systemu, bo backupu wiadomo, że nie miałes,zaczniesz się zastanawiać co zrobić.
Odpowiedź -możesz "zaryzykować" java.security.manager
To taki "tryb" dzialania JVM, gdzie sprawdzane jest czy dany kod może wykonać jakąś operację. Troszkę jak uprawnienia w unix, ale nie dla plików tylko dla praktycznie wszystkich operacji ( IO).
To dość elastyczny i rozbudowany mechanizm, ale w uproszczeniu:
możesz zdefiniować np. w plikach policy (to przykład z tomcata):
Kopiuj
grant codeBase "file:${java.home}/lib/ext/-" {
permission java.security.AllPermission;
};
grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
permission java.io.FilePermission
"${java.home}${file.separator}lib${file.separator}logging.properties", "read";
permission java.io.FilePermission
"${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
permission java.io.FilePermission
"${catalina.base}${file.separator}logs", "read, write";
permission java.io.FilePermission
"${catalina.base}${file.separator}logs${file.separator}*", "read, write, delete";
permission java.lang.RuntimePermission "shutdownHooks";
permission java.lang.RuntimePermission "getClassLoader";
permission java.lang.RuntimePermission "setContextClassLoader";
permission java.util.logging.LoggingPermission "control";
permission java.util.PropertyPermission "java.util.logging.config.class", "read";
permission java.util.PropertyPermission "java.util.logging.config.file", "read";
permission java.util.PropertyPermission "org.apache.juli.ClassLoaderLogManager.debug", "read";
permission java.util.PropertyPermission "catalina.base", "read";
// Note: To enable per context logging configuration, permit read access to
// the appropriate file. Be sure that the logging configuration is
// secure before enabling such access.
// E.g. for the examples web application (uncomment and unwrap
// the following to be on a single line):
// permission java.io.FilePermission "${catalina.base}${file.separator}
// webapps${file.separator}examples${file.separator}WEB-INF
// ${file.separator}classes${file.separator}logging.properties", "read";
};
W ten sposób możesz oznaczyć, że np. tylko twoje klasy mogą coś mazac po dysku, otwierać połączneia do bazy danych itp.
No, ale co ma to wspólnego z tym doPrivileged. Otóż pytanie kto własciwie wywołał dany kod, bo jeśli np. używasz bilblioteki do obsługi bazy danych, z twojego kodu, to głupio by było,
gdyby się okazało, że nie możesz bo tylko twoja klasa ma uprawnienia.
No i tu przychodzi z pomocą doPrivileged. Mówisz security managerowi - to wszystko w tym doPrivileged to za moją wiedza i zgodą (ktokolwiek tam nie stoi). SecurityManager przy sprawdzaniu tego co się we wnętrzu dzieje traktuje to jakby to pochodziło z twojego kodu.
Tak jak podałem na poczatku w normalnym kodzie raczej się z tym nie spotkasz. Chyba, że piszesz jakieś frameworki, integrujesz frameworki, piszesz serwery gdzie można odpalac nieznany kod, albo gdy masz po prostu paranoiczne podejście do security.