In Java gilt der private
Zugriffsmodifikator als sicher, da er außerhalb der Klasse nicht sichtbar ist. Dann weiß die Außenwelt auch nichts über diese Methode.
Aber ich dachte, Java Reflection kann diese Regel brechen. Betrachten Sie folgenden Fall:
public class ProtectedPrivacy{
private String getInfo(){
return "confidential";
}
}
Jetzt werde ich von einer anderen Klasse Info bekommen:
public class BreakPrivacy{
public static void main(String[] args) throws Exception {
ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy();
Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null);
method.setAccessible(true);
Object result = method.invoke(protectedPrivacy);
System.out.println(result.toString());
}
}
In diesem Moment dachte ich nur, dass private Methoden noch sicher sind, da wir den Methodennamen kennen müssen, um etwas wie oben zu tun. Aber wenn Klassen, die private Methoden enthalten, die von jemand anderem geschrieben wurden, haben wir keine Sichtbarkeit dieser.
Aber mein Punkt wird ungültig, da unter der Codezeile.
Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods();
Dies method[]
enthält nun alle Dinge, die oben zu tun sind. Meine Frage ist, gibt es eine Möglichkeit, solche Dinge mit Java Reflection zu vermeiden?
Ich zitiere einen Punkt aus der Java-Dokumentation , um meine Frage zu klären.
Tipps zur Auswahl einer Zugriffsebene:
Wenn andere Programmierer Ihre Klasse verwenden, möchten Sie sicherstellen, dass keine Fehler durch Missbrauch auftreten können. Zugriffsebenen können Ihnen dabei helfen. Verwenden Sie die restriktivste Zugriffsebene, die für ein bestimmtes Mitglied sinnvoll ist. Verwenden Sie privat, es sei denn, Sie haben einen guten Grund, dies nicht zu tun.
quelle
getDeclaredMethods
Namen zurückgegeben werden, die wie Müll aussehen.Antworten:
Es kommt darauf an, was Sie unter "sicher" verstehen. Wenn Sie mit einem Sicherheitsmanager arbeiten, der solche Dinge zulässt, können Sie alle möglichen bösen Dinge mit Reflexion tun. Aber in einer solchen Umgebung kann die Bibliothek wahrscheinlich nur geändert werden, um die Methode trotzdem öffentlich zu machen.
Die Zugriffskontrolle ist in einer solchen Umgebung effektiv "beratend" - Sie vertrauen effektiv darauf, dass der Code gut funktioniert. Wenn Sie dem von Ihnen ausgeführten Code nicht vertrauen, sollten Sie einen restriktiveren Sicherheitsmanager verwenden.
quelle
check*
Grunde genommen Ausnahmen für die relevanten Aufrufe auslöst .Zugriffsmodifikatoren haben nichts mit Sicherheit zu tun. Tatsächlich können und sollten Sie Zugriffsmodifikatoren als Umkehrung der Sicherheit betrachten - es geht nicht darum, Ihre Daten oder Algorithmen zu schützen, sondern um Menschen vor der Anforderung zu schützen, über Ihre Daten und Algorithmen Bescheid zu wissen. Aus diesem Grund ist der Standardmodifikator package - wenn sie an dem Paket arbeiten, müssen sie es wahrscheinlich bereits wissen.
Zusammen mit der Kenntnis der Daten und der Methoden Ihres Codes kommt die Verantwortung, zu wissen, wann und wie Sie sie verwenden. Sie setzen Ihre inIt-Methode nicht privat, um jemanden davon abzuhalten, davon zu erfahren. Sie tun dies, weil (a) er nicht weiß, dass Sie das nur nach foo aufrufen und nur, wenn bar = 3.1415 und (b) weil es ihnen nicht gut tut, davon zu wissen.
Zugriffsmodifikatoren können in einem einfachen Satz zusammengefasst werden: "TMI, Alter, das musste ich also nicht wissen".
quelle
Wenn Sie "sicher" sagen, schützen Sie sich oder andere Entwickler, die Ihre API verwenden, um das Objekt nicht zu beschädigen, indem Sie Ihre private Methode aufrufen. Aber wenn Sie oder sie diese Methode wirklich aufrufen müssen, können sie dies mit Reflection tun.
quelle
Die Frage ist, vor wem Sie es retten wollen. Meiner Meinung nach ist ein solcher Client Ihres Codes hier derjenige, der hier ratlos ist.
Jeder Code (von Ihnen oder anderen geschrieben), der versucht, auf ein
private
Mitglied der oben genannten Klasse zuzugreifen, gräbt im Wesentlichen sein eigenes Grab.private
Mitglieder machen keinen Teil der öffentlichen API und können ohne vorherige Ankündigung geändert werden. Wenn ein Client eines dieser privaten Mitglieder auf die oben angegebene Weise verwendet, wird es unterbrochen, wenn er auf eine neuere Version der API aktualisiert, in der das private Mitglied geändert wurde.quelle
Mit der Einrichtung geht Verantwortung einher. Es gibt Dinge, die Sie nicht tun können, und Dinge, die Sie tun können, die Sie aber nicht tun sollten.
Der private Modifikator wird als / auf die am meisten eingeschränkte Weise bereitgestellt / verwendet. Mitglieder, die außerhalb der Klasse nicht sichtbar sein sollten, werden als privat definiert. Aber dies kann mit Reflection gebrochen werden, wie wir sehen. Dies bedeutet jedoch nicht, dass Sie nicht privat verwenden sollten - oder sie sind unsicher. Es geht darum, dass Sie die Dinge vernünftig oder konstruktiv einsetzen (wie Reflexion).
quelle
Angenommen, Sie vertrauen dem Client-Programmierer Ihrer API, besteht eine andere Sichtweise darin, wie sicher es für ihn ist, diese bestimmten Funktionen zu verwenden.
Ihre öffentlich verfügbaren Funktionen sollten eine klare, gut dokumentierte und sich selten ändernde Schnittstelle zu Ihrem Code bieten. Ihre privaten Funktionen können als Implementierungsdetail betrachtet werden und können sich im Laufe der Zeit ändern. Sie können daher nicht direkt verwendet werden.
Wenn ein Client-Programmierer sich Mühe gibt, diese Abstraktionen zu umgehen, erklärt er in gewisser Weise, dass er weiß, was er tut. Noch wichtiger ist, dass sie verstehen, dass es nicht unterstützt wird und möglicherweise nicht mehr mit zukünftigen Versionen Ihres Codes funktioniert.
quelle
private
dient nicht der Sicherheit, sondern dient dazu, den Code sauber zu halten und Fehler zu vermeiden. Benutzer können den Code modularisieren (und wie er entwickelt wird), ohne sich um alles kümmern zu müssen Details der anderen ModuleSobald Sie Ihren Code veröffentlicht haben, können die Benutzer herausfinden, wie er funktioniert. Es gibt keine Möglichkeit, die Logik zu "verbergen", wenn der Code schließlich auf einem Computer ausgeführt werden soll. Sogar das Kompilieren in Binärdateien ist nur eine Verschleierungsstufe.
Es gibt also keine Möglichkeit, Ihre API so einzurichten, dass bestimmte Dinge ausgeführt werden, die andere nicht aufrufen können. Im Fall einer Web-API können Sie die Methoden, über die Sie die Kontrolle haben möchten, auf die Serverseite stellen.
quelle