Vererbung Sicherheitslücke? Reflection sieht members, die nicht sichtbar sein sollten?!

guni

Bekanntes Mitglied
Hallo,

folgendes Problem:
Code:
abstract class A {
  private int x;
  public int getX() { return x; }
}

class B extends A {
  private int y;
  public int getY() { return y; }
}

// main
A b = new B()
for (Field f : b.getClass().getDeclaredFields()) {
  System.out.println(f); // ZEIGT private int y an!
}
Warum sehe ich hier y?! M.M. sollten nur die Fields/Methoden der Basisklasse sichtbar sein. Was verstehe ich hier falsch?
 
Hallo Klaus,

danke für deine Antwort. Ich wollte hier aber eigentlich auf ein anderes Problem hinaus:

Mein Object (b) ist gecastet => Es sollte vom Typ A sein.
Trotzdem bin ich über Reflection in der Lage, die Fields aus Typ B zu sehen.

Das sollte m.M. nicht sein.

Meine eigentliche Frage ist wohl:

Wie kann ich sicherstellen, dass die Fields/Methods aus B unsichtbar (auch für die Reflection) sind, sobald b zum Typ A gecastet wird?

mfg, Simon
 
Garnicht; es ist technisch unmöglich. Die Zugriffsregeln in Java sind kein Sicherheitsfeature. Sie sind lediglich dazu da, interne Daten und Funktionen von globalen zu trennen.
 
mWn Gar nicht, dein Objekt ist schließlich immer noch vom Typ B, es besitzt noch die Methoden/Felder von B, also sind sie über Reflection auch noch sichtbar.
 
Die anderen haben ja schon drauf hingewiesen: getClass() liefert dir die tatsaechliche Klasse zurueck. Reflection ist ausserdem eine sehr maechtige API, du kannst darueber so ziemlich alles ueber eine Klasse herausfinden. Du kannst private Members sogar accessible machen und einen Wert reinschreiben. Du hast ausserdem getDeclaredFields verwendet, getFields hingegen wuerde dir das erwartete Resultat geben:
Code:
package info.junius.test;

import java.lang.reflect.*;

public class A
{

  private int x;

  public int getX()
  {
  return x;
  }

  public static void main(String[] args)
  {
  A b = new B();
   
  System.out.println("Klasse: " + b.getClass()); // ist typ B!
   
  System.out.println("zeige alles:");
  // zeigt dir alles an, was in B declared ist
  for (Field f : b.getClass().getDeclaredFields())
  {
  System.out.println(f); // ZEIGT private int y an!
  }

  System.out.println("zeige nur public Fields:");
  // zeigt nur public members an
  for (Field f : b.getClass().getFields())
  {
  System.out.println(f);
  }
   
  }

  static class B extends A
  {
  private int y;

  public int getY()
  {
  return y;
  }
  }

}
 
@AndyJ: danke für den Hinweis mit getFields statt getDeclaredFields. Mir ging es allerdings nicht darum, die Methode zu finden, die mir nur die "richtigen" Members zeigt; ich wollte eher ausschließen, dass es irgendeinen Weg gibt, mir die Daten anzeigen zu lassen, die an dieser Stelle nicht sichtbar sein sollten.

Noch eine Sache: du schreibst

getClass() liefert dir die tatsaechliche Klasse zurueck.

Warum ist meine __tatsächliche__ Klasse nach dem Cast nicht die, in die ich gecastet hab?

@all: vielen Dank für eure Antworten. Schade dass das nicht geht. C# scheint - was ich gehört habe - an dieser Stelle "strenger" zu sein. Fällt jemand eine andere Lösung ein das obenstehende Problem umzusetzen? So, dass nichtmal Reflection in der Lage ist auf Dinge zuzugreifen, die an dieser Stelle eigentlich nicht sichtbar sein sollten?
 
Das Objekt selber bleibt vollkommen unverändert durch einen cast. Du änderst ja nur den Typ deiner Variable.

@all: vielen Dank für eure Antworten. Schade dass das nicht geht. C# scheint - was ich gehört habe - an dieser Stelle "strenger" zu sein.
Nein, das ist bei C# genauso.
Das ist nunmal auch der Sinn von Reflection, damit können zur Laufzeit sämtliche Informationen über ein Objekt abgefragt (und geändert) werden.
 
Wir profitieren ja auch regelmäßig davon, beispielsweise wenn wir den Debugger oder ContentAssist-Funktionen der IDE nutzen. Das wäre bestimmt viel schwieriger zu programmieren, wenn man per Reflection nur begrenzten Zugriff hätte.
 
@AndyJ: danke für den Hinweis mit getFields statt getDeclaredFields. Mir ging es allerdings nicht darum, die Methode zu finden, die mir nur die "richtigen" Members zeigt; ich wollte eher ausschließen, dass es irgendeinen Weg gibt, mir die Daten anzeigen zu lassen, die an dieser Stelle nicht sichtbar sein sollten.

Was ist denn überhaupt dein Zeil? Vllt gibt es andere Wege, das zu erreichen
 

Zurück
Oben