22 Stimmen

Verbessert das Java-Schlüsselwort "final" tatsächlich die Sicherheit?

Es gibt zwar viele Gründe für die Verwendung des Schlüsselworts 'final' in Java Eine der Aussagen, die ich immer wieder höre, ist, dass der Code dadurch sicherer wird. Das scheint in diesem trivialen Fall zwar sinnvoll zu sein:

public class Password
{
    public final String passwordHash;
    ...
}

Mit dem letzten Schlüsselwort würde man erwarten, dass kein bösartiger Code in der Lage ist, die Variable passwordHash zu ändern. Allerdings, durch Reflexion ist es möglich, den endgültigen Modifikator für das Feld passwordHash zu ändern.

Bietet "final" also wirklich Sicherheit oder ist es nur ein Placebo?

Editar: Es gibt eine wirklich interessante Diskussion, und ich wünschte, ich könnte mehr als eine Antwort akzeptieren. Vielen Dank an alle für ihre Beiträge.

0 Stimmen

Hier ist eine Verbindung das mehrere (von Oracle geschriebene) Beispiele enthält, die zeigen, wie die endgültig Schlüsselwort kann für Sicherheitszwecke verwendet werden.

40voto

Javier Punkte 58737

Es geht nicht um "Sicherheit" im Sinne von "einem Angriff standhalten", sondern eher darum, dass es schwieriger ist, einen Fehler zu begehen.

Ich bevorzuge das Wort "Sicherheit", da ich das Gefühl habe, dass es eher darum geht, einen Unfall zu verhindern, als um Böswilligkeit.

11voto

Andrew Hare Punkte 332190

Java's final Schlüsselwort wird für diese Art von Sicherheit nicht verwendet. Es ist kein Ersatz für das, was normalerweise eine kryptographische Lösung erfordern würde.

Mit "Sicherheit" ist in diesen Diskussionen in der Regel das Konzept eines sicheren Objektmodells gemeint, d. h. eines Objektmodells, das von den Verbrauchern nicht zu Zwecken manipuliert werden kann, die vom ursprünglichen Autor der Klasse nicht beabsichtigt waren.

8voto

Uri Punkte 86472

Ich bin mir nicht sicher, ob ich mich in meinem System auf Sprachkonstrukte für zusätzliche Sicherheit verlassen würde.

Ich glaube nicht, dass die Endgültigkeit eines Feldes die Sicherheit gegen böswillige Angriffe erhöhen würde (eher gegen Fehler und natürlich Threading-Probleme). Die einzige "echte Form" von Sicherheit ist, dass ein finales konstantes Feld bei der Kompilierung eingefügt werden könnte, so dass eine Änderung des Wertes zur Laufzeit keine Auswirkungen hätte.

Ich habe von Endgültigkeit und Sicherheit eher im Zusammenhang mit Erbschaften gehört. Indem man eine Klasse endgültig macht, kann man jemanden daran hindern, sie zu unterklassifizieren und ihre geschützten Mitglieder zu berühren oder zu überschreiben, aber auch das würde ich eher zur Vermeidung von Fehlern als zur Verhinderung von Bedrohungen einsetzen.

4voto

Yishai Punkte 87548

Im Allgemeinen sollten "final", "private" und andere derartige Konstrukte eher als allgemeine Präferenzaussagen denn als streng erzwungene Sicherheit betrachtet werden.

Wenn Sie jedoch die Kontrolle über die JVM haben, auf der der Prozess läuft (z. B. wenn Sie von anderen bereitgestellten Code auf Ihrer JVM ausführen), dann bieten final und private in der Tat Sicherheit - in Verbindung mit dem SecurityManager von Java. Die Dinge, die Sie über Reflection tun können, um diese Einschränkungen zu umgehen, können verhindert werden.

Was Sie nicht tun können, ist, Code zu liefern, der auf der JVM eines anderen läuft, und zu glauben, dass Sie auf diese Weise etwas verbergen.

Edit: Tom erinnert mich daran, dass Serialisierungsangriffe (d.h. das absichtliche Bereitstellen schlechter binärer Ströme serialisierter Daten) zum Teil auch durch die korrekte Verwendung von Endfeldern verhindert werden können. Effective Java hat mehr solcher Beispiele.

4voto

Tom Hawtin - tackline Punkte 142461

Sicher gegen was?

Im Hinblick auf mobilen Code (Code, der sich zwischen Systemen bewegen kann - Applets, Midlets, WebStart, RMI/JINI usw.) ist dies sehr wichtig. Angewandt auf Klassen und in geringerem Maße auf zugängliche Methoden, verhindert sie bösartige Implementierungen. Ähnlich verhält es sich mit zugänglichen Feldern und bemerkenswerten Statiken. Wenn Sie Code schreiben, der Teil einer Bibliothek werden kann, müssen Sie sich dessen sehr bewusst sein.

Für den typischen Code von Web- oder Desktop-Anwendungen ist er weit weniger wichtig. Das Fehlen von Feldern macht den Code jedoch schwerer lesbar und deutet auf einen verwirrten Programmierer hin. Es ist unwahrscheinlich, dass solcher Code sicher ist, nur weil er schlecht geschrieben ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X