=Paper= {{Paper |id=None |storemode=property |title=Sicherheitsimplikationen beim Einsatz von Test Doubles zur automatisierten Bewertung studentischer Java-Programme mit Graja und mockito |pdfUrl=https://ceur-ws.org/Vol-1067/abp2013_submission_1.pdf |volume=Vol-1067 |dblpUrl=https://dblp.org/rec/conf/abp/Garmann13 }} ==Sicherheitsimplikationen beim Einsatz von Test Doubles zur automatisierten Bewertung studentischer Java-Programme mit Graja und mockito== https://ceur-ws.org/Vol-1067/abp2013_submission_1.pdf
  Sicherheitsimplikationen beim Einsatz von Test Doubles
     zur automatisierten Bewertung studentischer Java-
             Programme mit Graja und mockito
                                                        Robert Garmann
                                                      Hochschule Hannover
                                              Fakultät IV - Wirtschaft und Informatik
                                                    Ricklinger Stadtweg 120
                                                         30459 Hannover
                                            robert.garmann@hs-hannover.de

Zusammenfassung                                                     setzt, die z. B. mittels der Bibliothek mockito [Ka13] erstellt wer-
Wir demonstrieren, dass der Einsatz von Test Doubles bei der        den. An einer Beispielaufgabe verdeutlichen wir in Abschnitt 2,
automatisierten Bewertung studentischer Java-Programme              wie der JUnit-basierte Autobewerter Graja und mockito zur Be-
besondere Sicherheitsfragen aufwirft. Wie skizzieren kurz eine      obachtung interner Programmschnittstellen genutzt werden
mögliche Antwort auf diese Fragen.                                  können.
                                                                    Das studentische Programm wird bei der dynamischen Analyse
Im ersten Teil demonstrieren wir die Erstellung eines sog.
                                                                    ausgeführt. Sicherheitsmaßnahmen auf dem Bewertungsrechner
AssignmentGraders, der in der Lage ist, interne Programm-
                                                                    sind notwendig, um ungewolltes oder böswilliges Fehlverhalten
schnittstellen eines maschinell zu bewertenden Java-Programms
                                                                    des studentischen Programms zu unterbinden. In Abschnitt 3
zu beobachten. Beispielhaft nutzen wir den Autobewerter Graja in
                                                                    stellen wir das betrachtete Modell eines Bewertungssystems vor
Verbindung mit mockito Test Doubles. Wir zeigen, wie man
                                                                    und diskutieren relevante Sicherheitsaspekte.
Leistungsaspekte einer studentischen Lösung einzeln und gezielt
automatisiert bewertet. Bei einer Beschränkung auf die              Bibliotheken wie mockito wurden nicht für die automatisierte
Beobachtung externer Programmschnittstellen würden sich diese       Programmbewertung        entworfen.    Die     Sicherheit    der
Aspekte der gezielten Bewertung entziehen. Im zweiten Teil          Testumgebung      spielt    beim    (Regressions-)Test    großer
beleuchten wir Bedrohungen des das zu bewertende Programm           Softwaresysteme meist eine untergeordnete Rolle. Im
ausführenden Systems und gewichten ausgewählte Ursachen. Wir        Bewertungsszenario jedoch wirft der Einsatz einer solchen
konzentrieren uns auf Bedrohungen, die mit Mitteln der Java-2-      Bibliothek essentielle Sicherheitsfragen auf, für die wir in
Sicherheitsarchitektur beherrschbar sind und liefern einige         Abschnitt 4 eine mögliche Lösung vorstellen.
Beispiele zur Abgrenzung. Die Eigenheiten der Java-2-
Sicherheitsarchitektur werfen im Kontext des Test Double
                                                                    2. Beobachtung programminterner
Einsatzes Fragen auf, die wir im dritten Teil erörtern. Test        Schnittstellen
Doubles sollten in einem anderen Schutzbereich der Java-2-          Die Frage, wann ein studentisches Programm gut ist, ist nicht
Sicherheitsarchitektur als der studentische Code liegen. Um eine    leicht zu beantworten. Neben dem Kriterium der funktionalen
privilegierte Ausführung der Test Doubles auch dann zu forcieren,   Korrektheit muss das Programm nichtfunktionale Kriterien
wenn der Aufruf aus studentischem Code erfolgt, schlagen wir        erfüllen (Effizienz, Änderbarkeit, …). Einige dieser Kriterien
den Einsatz von Proxy-Objekten vor. Um auch Nicht-Spezialisten      lassen sich recht gut automatisiert untersuchen. Grundsätzlich gibt
der beschriebenen Sicherheitsbelange die Autorenschaft von          es zwei Herangehensweisen bei der maschinellen Untersuchung
AssignmentGradern zu ermöglichen, entwickeln wir eine               eines Bewertungsobjektes [SL05]: die statische Code-Analyse
Wrapper-Bibliothek für mockito, deren zentrale Entwurfsideen        (bspw. in [SBG10]) und die dynamische Code-Analyse (bspw. in
wir kurz skizzieren.                                                [KSZ02], [Ed03]). In diesem Aufsatz befassen wir uns mit der
                                                                    letztgenannten Herangehensweise, der Beobachtung des
1. Einleitung                                                       Verhaltens eines studentischen Java-Programms durch Tests.
Automatisierte Bewertung studentischer Programme wird in der
Informatik-Lehre zurzeit überwiegend im formativen Assessment       Bei der dynamischen Code-Analyse beobachtet man das
eingesetzt. Zeit- und ortsunabhängiges, maschinell erstelltes,      Laufzeitverhalten des Bewertungsobjekts an beobachtbaren
quantitatives und qualitatives Feedback soll Studierende in die     Schnittstellen. Hervorragend geeignet für die Überprüfung der
Lage versetzen, ihre (Teil-)lösungen zu Programmierübungen          funktionalen Korrektheit des Bewertungsobjekts sind Ein- und
schrittweise zu verbessern.                                         Ausgabeschnittstellen des Benutzers, die auch leicht einer
                                                                    maschinellen Bedienung bzw. Abfrage zugänglich sind.
Studentische Programme müssen funktionale und nichtfunktionale      Interessante Schnittstellen für die Bewertung des studentischen
Anforderungen erfüllen, die mit statischen oder dynamischen         Programmverhaltens sind u. a.1 Tastatureingabe, Consolenaus-
Analyseverfahren untersucht werden können. Für die Analyse der      gabe, Mauseingabe, GUI-Ausgabe [TE08], Kommandozeilen-
„inneren Qualität“ des Bewertungsobjekts spielt die dynamische      argumente beim Programmstart, Dateiein-/-ausgabe. Allen
Analyse an internen Programmschnittstellen (Methodenaufruf)         genannten Schnittstellen gemein ist, dass sie prinzipiell auch vom
eine wichtige Rolle. Unittest-Frameworks wie JUnit wurden dazu
entwickelt, kleinste Einheiten eines Testobjekts durch              1
Methodenaufruf und Verifizierung des Ergebnisses dynamisch zu           Über diese nicht abschließende Aufzählung hinaus sind selbst-
untersuchen. Um die zu untersuchende Einheit für die Dauer des          verständlich viele weitere Schnittstellen denkbar (Umgebungs-
Tests vom Restsystem zu isolieren werden Test Doubles einge-            variable, Audio/Video, Netzwerk, etc.).
Benutzer des studentischen Programms bedient werden können.           Berechnen Sie die Länge der Hypotenuse eines rechtwinkligen
Um ein Bewertungsobjekt nun automatisiert mit Eingaben über           Dreiecks. Teilen Sie den Programmcode auf zwei Klassen auf:
die genannten Schnittstellen zu versorgen und die Ausgaben ma-        QuadratImpl    implementiere das folgende vorgegebene
schinell auszuwerten, werden Autobewerter wie der hier                Interface:
eingesetzte Graja [St13] verwendet.                                     package de.hsh.prog;
                                                                        public interface Quadrat {
Ein automatisiertes Bewertungsverfahren nimmt bei Nutzung der             double quadrat(double v); // berechnet v²
oben genannten Schnittstellen das Bewertungsobjekt als „black           }
box“ wahr und kann wenig über die Qualität der inneren Struktur       Schreiben Sie eine weitere Klasse Hypo mit einer statischen
des Bewertungsobjekts erfahren. Gut überprüfbar ist die               Methode hypo, die als ersten Parameter ein Quadrat-Objekt und
funktionale Korrektheit und die Überprüfung einiger                   als zwei weitere Parameter die Längen zweier Katheten erhält.
nichtfunktionaler Eigenschaften (z. B. Ressourcenverbrauch). Um       Gewünschter Rückgabewert ist die Länge der Hypotenuse.
mehr über die „innere Qualität“ des Bewertungsobjekts zu              Quadrierungen soll hypo an das Quadrat-Objekt delegieren.
erfahren, ist es hilfreich, das studentische Programm an internen
                                                                     Abbildung 1: Stark vereinfachte Beispielaufgabe
Programmschnittstellen zu beobachten. Eine geeignete
Schnittstelle ist der Methodenaufruf mit Methodenparametern als      2.3 Bewertung mit Graja
Eingabe und Methodenrückgabe als Ausgabe.                            Den Bewertungsaspekt (1) überprüft der in Abbildung 2 dar-
Im Folgenden geben wir einen kurzen Überblick über die               gestellte, mit Graja kompatible Code.
Funktionen von Graja und stellen eine Beispielaufgabe vor.           Der Aufruf der internen Programmschnittstelle des studentischen
Danach zeigen wir, wie studentische Lösungsversuche für diese        Codes ist in Programmzeile 06 zu finden. Davor wird eine Instanz
Aufgabe mit Graja unter Einsatz von Test Doubles bewertet            der studentischen Klasse erzeugt und danach das beobachtete
werden können.                                                       Ergebnis überprüft. Diese Art von Bewertungscode ist dem in der
2.1 Graja                                                            professionellen Softwareentwicklung verbreiteten Testcode für
                                                                     Modultests sehr ähnlich. Spezialitäten der hier betrachteten
Graja (“Grading Java programs”) ist i. w. ein Überbau über dem
                                                                     Programmbewertung sind die in Zeile 01 vergebenen Teilpunkte
JUnit2-Testframework und hat seine Charakterzüge von seinem
                                                                     und der in Zeile 08f zu findende ausführliche Fehlerhinweis.
Vorbild WebCAT [Ed03] geerbt. Graja bietet u. a. folgende
                                                                     Weiterhin besonders ist die von Graja angebotenen Reflection-
Funktionen:
                                                                     Bibliothek (Zeile 04f), die etwaige Exceptions in verständliche
     Extrahieren und Übersetzen von Code aus einem ZIP-Archiv,      Fehlermeldungen verwandelt.
     Umleitung von Standard-Ein/Ausgabeströmen zur Verein-
                                                                      01 @Test @ScoringWeight(35.0)
      fachung der maschinellen Steuerung des Bewertungsobjekts,       02 public void pruefeQuadratMethode() {
     intelligente Vergleiche von erwarteter und beobachteter Aus-    03   double a= 3, expected= a*a;
      gabe eines Bewertungsobjekts,                                   04   Quadrat studentImpl= ReflectionSupport.create(
                                                                      05     getSubclassForName("QuadratImpl",Quadrat.class));
     bequeme „reflection“-basierte Analyse studentischen Codes,      06   double observed= studentImpl.quadrat(a);
     Generierung formatierter, zielgruppenorientierter, und nach     07   org.junit.Assert.assertEquals(
      Kritikalität abgestufter Bewertungskommentare,                  08     "quadrat("+a+")="+observed+" (erwartet :"+expected
                                                                      09     +")", expected, observed, 1E-5);
     abgestufte Punktevergabe für verschiedene vom Dozenten          10 }
      festzulegende Bewertungsaspekte,
     Übersetzung und Ausführung von „on the fly“ generiertem        Abbildung 2: Bewertung des Aspekts (1)
      Java-Code während der Bewertung,
                                                                      11 @Test @ScoringWeight(25.0)
     Begrenzung der genutzten Systemresourcen (Laufzeit,             12 public void pruefeGesamtfunktion() {
      persistenter Speicherplatz, Hauptspeicher),                     13   double a=3, b=4, cExpected=5;
     Ausführung       des     studentischen   Codes    und    des    14   Quadrat stub= Mockito.mock(Quadrat.class);
                                                                      15   Mockito.when(stub.quadrat(a)).thenReturn(a*a);
      Bewertungscodes in verschiedenen, separat abgesicherten         16   Mockito.when(stub.quadrat(b)).thenReturn(b*b);
      Schutzbereichen.                                                17   double c= ReflectionSupport.invokeStatic(
                                                                      18    getClassForName("Hypo"),double.class,"hypo",stub,a,b);
                                                                      19   org.junit.Assert.assertEquals("hypo(q,"+a+","+b+")="+c+
2.2 Beispielaufgabe                                                   20    " (erwartet: "+cExpected+")", cExpected, c, 1E-5);
Wir betrachten eine für Zwecke der konzentrierten Darstellung         21 }
stark vereinfachte Programmieraufgabe (s. Abbildung 1).
                                                                     Abbildung 3: Bewertung des Aspekts (2)
Diese Aufgabe verlangt vom Studierenden nicht nur die
Programmierung einer einfachen mathematischen Formel,                 22 @Test @ScoringWeight(40.0)
                                                                      23 public void pruefeAufrufVonQuadrat() {
sondern die Implementierung einer vorgegebenen Schnittstelle.
                                                                      24   double a=3, b=4;
Eine korrekte Lösung kann nicht nur Hypotenusen berechnen (2);        25   Quadrat mock= Mockito.mock(Quadrat.class);
eine korrekte Lösung kann darüber hinaus Quadrate berechnen (1)       26   ReflectionSupport.invokeStatic(
und sie setzt Wiederverwendung durch Delegation ein (3). Für          27     getClassForName("Hypo"),double.class,"hypo",mock,a,b);
                                                                      28   try {
jeden der im vorstehenden Satz markierten Bewertungsaspekte           29     Mockito.verify(mock, Mockito.times(1)).quadrat(a);
möchten wir Teilpunkte vergeben.                                      30     Mockito.verify(mock, Mockito.times(1)).quadrat(b);
                                                                      31   } catch (WantedButNotInvoked e) {
                                                                      32     org.junit.Assert.fail("hypo muss die Quadrierung "+
                                                                      33       "an den Quadrat-Parameter delegieren");
                                                                      34   }
                                                                      35 }
2
    http://junit.org/                                                Abbildung 4: Bewertung des Aspekts (3)
2.4 Test Doubles: Stubs und Mocks                                              AutograderCore: Der Kern des Autobewerters, welcher eine
Ähnlich ließe sich nun der Bewertungsaspekt (2) untersuchen,                    Startroutine und eine Bibliothek mit bewertungs-
indem eine QuadratImpl-Musterlösung als Parameter an die                        unterstützenden Funktionen enthält. Ein Beispiel einer
studentische hypo-Methode übergeben wird. Die erneute                           AutograderCore-Komponente ist Graja.
Verwendung einer u. U. fehlerhaften studentischen QuadratImpl-                 AssignmentGrader: vom Dozenten erstellter, auf eine
Klasse würde die Bewertung des Aspekts (2) negativ verzerren.                   spezielle Programmieraufgabe zugeschnittener Code (kann
Der Fehler würde in zwei Bewertungsaspekten „gezählt“.                          Fremdsoftware, bspw. die mockito-Bibliothek beinhalten).
                                                                                Die Codeschnipsel der Abschnitte 2.3 und 2.4 entstammen
Als Alternative zu einer eigenen Musterlösung kann man ein Test                 dieser Komponente.
Double [Me07] einsetzen – ein Platzhalter-Objekt, mit dem ein
                                                                               Submission: vom Studenten erstellter Lösungsversuch.
untersuchter Programmteil (das sog. system under test - kurz SUT)
während des Tests interagiert. Stub-Objekte sind Test Doubles,           Jede Komponente5 stellt einen eigenen Schutzbereich (protection
die vorgefertigte Antworten an das SUT liefern.                          domain) mit jeweils eigenen Rechten (permissions) dar.
Der Code in Abbildung 3 verwendet in Zeile 14 die Bibliothek
mockito3 zur Erzeugung eines Stubs, welches das Interface
Quadrat vollständig implementiert. Die beiden folgenden Zeilen
„bestücken“ das Stub mit vorbereiteten Antworten auf erwartete
Anfragen des SUT4. In Zeile 17f kommt das SUT (hier die                              Abbildung 5: Drei geladene Komponenten
studentische Methode hypo) zur Ausführung. Als Übergabe-                 3.2 Benötigte Rechte
parameter erhält hypo das Stub-Objekt.
                                                                         Der AutograderCore benötigt für seine Funktion weitgehende
Der Bewertungsaspekt (3) lässt sich schließlich durch eine weitere       Rechte (Zugriffe auf das lokale Dateisystem, Ausführen des
Test Double Variante, die sog. Mock-Objekte realisieren (vgl.            Compilers, Verwendung eigener Klassenlader, Zugriff auf
Abbildung 4). Ein Mock-Objekt wird in Zeile 25 erstellt, welches         Reflection-Funktionen, etc.). Die Submission benötigt in der
die Quadrat-Schnittstelle implementiert. Da uns bei diesem               Regel wenige Rechte, wobei dies sicher von der Art der zu
Bewertungsaspekt das Berechnungsergebnis nicht interessiert,             lösenden Programmieraufgabe abhängt. Dazwischen im Sinne der
programmieren wir keine vorbereiteten Antworten. Stattdessen             Rechtemenge steht der AssignmentGrader, der häufig grund-
befragen wir das Mock-Objekt nach Ausführung des SUT in Zeile            legende Rechte für Dateizugriffe, manchmal auch weitergehende
29f, ob es Aufrufe mit den angegebenen Parametern erhalten hat.          Rechte besitzen muss. Eine Teilmengenbeziehung zwischen den
                                                                         benötigten Rechtemengen der drei genannten Schutzbereiche
3. Sicherheit des Bewertungssystems                                      besteht nicht notwendigerweise.
Der Ansatz, studentische Lösungen dynamisch zu analysieren,
erfordert die Ausführung des studentischen Codes. Im Unter-              3.3 Bedrohungspotential
schied zu herkömmlichen Software-Tests, wo Tester und Autor              Um das Bedrohungspotential6 der einzelnen Komponenten
einander vertrauen (bei Unit-Tests oft sogar dieselbe Person sind),      einschätzen zu können, betrachten wir zunächst die in Tabelle 1
wo also die Testumgebung vom zu testenden System kein böswil-            aufgeführten Merkmale der Komponenten-Autoren. Die beiden
liges Verhalten zu befürchten hat, ist dies beim Test von studen-        ersten Merkmale begünstigen bei hoher Ausprägung unabsichtlich
tischen Einreichungen anders. Hier muss mit Angriffen des getes-         herbeigeführte Bedrohungen, das dritte Merkmal begünstigt
teten Codes auf die Testumgebung gerechnet werden. Einige An-            absichtlich herbeigeführte Bedrohungen, das vierte Merkmal
griffsbeispiele stellt Abschnitt 3.4 vor. Dazu kommen unab-              begünstigt jede Art von Bedrohung.
sichtliche Programmierfehler in weitaus größerem Umfang als bei
                                                                         Tabelle 1: Betrachtete Merkmale der Komponenten-Autoren
Tests professioneller Software. Schutzmaßnahmen gegen solche
                                                                                                                          Ausprägungs-
Angriffe sind daher unabdingbar. In diesem Abschnitt wollen wir
                                                                                                                           grad7 für …


                                                                                                                           Assignment-
                                                                                                                           Autograder-



                                                                                                                            Submission
konkrete Bedrohungen und Gegenmaßnahmen beleuchten.




                                                                                                                              Grader
                                                                                                                               Core
3.1 Schutzbereiche
Als Bewertungssystem betrachten wir einen separaten Betriebs-            Nr. Merkmal
systemprozess. Aus konzeptioneller Sicht lädt der Prozess drei
verschiedene Komponenten und führt sie aus (vgl. Abbildung 5).           1      Geringe Programmiererfahrung                       -   -   +
Wir gehen davon aus, dass alle Komponenten aus Java Bytecode             2      Geringe Bereitschaft, Zeit für die korrekte Pro-
                                                                                                                                   -   0   +
bestehen, die von derselben JVM-Instanz geladen werden:                         grammierung der Komponente aufzuwenden
                                                                         3      „Kriminelle Energie“, d. h. Bereitschaft,
                                                                                                                                   -   -   +
3                                                                               Bedrohungen absichtlich herbei zu führen.
    http://code.google.com/p/mockito/
                                                                         4      Größe der Autorengruppe                            -   0   +
4
     Zur Funktionsweise der auf der ersten Blick verwirrenden
    Aufrufsyntax folgt eine kurze Erläuterung: Mockito.mock erzeugt      Vor diesem Hintergrund erwarten wir von der Submission-Kom-
    ein Objekt einer zur Laufzeit mit cglib (http://cglib.sourceforge.   ponente das größte Bedrohungspotential. Die AssignmentGrader-
    net/) erzeugten Subklasse von Quadrat. Das wie ein normaler
    Methodenaufruf aussehende stub.quadrat(a) führt mockito-             5
                                                                             In der Praxis entspricht jede Komponente einem jar-Archiv oder
    intern dazu, dass eine ID des aktuell ausgeführten Threads in             jeweils einer Menge von jar-Archiven. Jedem jar-Archiv wird
    einer Datenstruktur zusammen mit dem stub-Objekt und dem                  ein Satz von Rechten zugeordnet.
    Wert a abgelegt wird. Der Rückgabewert von stub.quadrat(a)           6
    wird zwar an Mockito.when weiter gereicht, dort jedoch nicht             Wir meinen hiermit das, was in etablierten Risikoschätzme-
    ausgewertet. Stattdessen weist die ID des aktuell ausführenden           thoden wie [oV13] „likelihood“ genannt wird.
                                                                         7
    Threads den Weg zum soeben abgelegten stub-Objekt.                       Legende: -=gering, 0=mittel, +=hoch
Komponente, die in der Regel von Lehrkräften oder Hilfspersonal        3.4.2.1 „rm –rf /“
erstellt wird, ist weniger kritisch, den AutograderCode erachten       Ein bösartiges Beispiel für Submission-Code, welcher versucht,
wir als Komponente mit dem geringsten Bedrohungspotential.             alle Dateien im Dateisystem zu löschen:
3.4 Bedrohungen im Einflussbereich des Java                            Runtime.getRuntime().exec("rm –rf /");

Securitymanagers                                                       Durch Gewährung selektiver Dateizugriffsrechte mittels der Java
Uns interessieren ganz allgemein alle Bedrohungen der Vertrau-         Sicherheitsarchitektur oder auch mittels der vom Betriebssystem
lichkeit und Integrität der Daten auf dem die JVM beherbergen-         verwalteten Dateirechte kann dieser Angriff gut abgewehrt wer-
den System (Dateien, Nutzerdaten, Musterlösungen, …), sowie            den.
alle Bedrohungen der Verfügbarkeit des Bewertungsdienstes. Wir         3.4.2.2 Denial of service
wollen mit der Bedrohungsanalyse dieses Kapitels keine konkret         Ein anderes Beispiel, das versucht Schaden anzurichten, in dem es
auszumerzenden Schwachstellen identifizieren, sondern es soll          die Festplatte füllt10:
hier darum gehen, einige mögliche Angriffe mit ihren
                                                                       FileOutputStream f=new FileOutputStream("x");
Auswirkungen („impacts“) zu benennen, die genügend Motivation          while (true) f.write(42);
liefern, um den Einsatz des Java Securitymanagers für sinnvoll zu
erachten. In der folgenden Darstellung nehmen wir die zu               Wenn wir davon ausgehen, dass Submission-Code in wenigstens
motivierende Maßnahme vorweg: den Einsatz des Security-                einem Verzeichnis Schreibrechte eingeräumt werden müssen, ist
managers. Die Motivation der Maßnahme durch Angriffsbeispiele          dieser denial of service Angriff mit Mitteln der Java Sicher-
folgt in Abschnitt 3.4.2.                                              heitsarchitektur unseres Wissens nicht abwehrbar. Hier müssen
                                                                       dem die JVM beherbergenden Betriebssystemprozess Ressourcen
3.4.1 Einsatz der Java Sicherheitsarchitektur                          in begrenztem Maße zugeteilt werden. Beispielsweise in Form
Konkret wollen wir dem Submission-Schutzbereich Rechte                 einer separaten Festplattenpartition oder in Form einer Datei
erteilen oder entziehen, die der Menge aller durch die Java            begrenzter Größe, die als loopback device verwendet wird.
Sicherheitsarchitektur definierten Rechte entnommen werden. Ein
                                                                       Ähnlich müssen die Ressourcen Hauptspeicher und CPU-Zeit
paar Beispiele seien hier genannt8:
                                                                       durch die Umgebung der JVM begrenzt werden, etwa über einen
      PropertyPermission: Auslesen oder Setzen von Umgebungs-         Parameter zum maximalen Speicherverbrauch beim JVM-Start
       informationen (bspw. mag eine Submission berechtigter-          bzw. mit Hilfe des Linuxkommandos timeout.
       weise das auf dem System gebräuchliche Zeichen für den
       Zeilenumbruch abfragen wollen - line.separator)                 3.4.2.3 „/etc/passwd“
      FilePermission: Dateizugriffsrechte (bspw. Einlesen und         Es folgt ein Beispiel, das versucht, die Liste der Benutzernamen
       Schreiben von Dateien im Arbeitsbereich der Submission)         des Systems auszuspähen:
      SocketPermission: Netzzugriffsrechte (bspw. soll die Sub-       System.out.println(Files.readAllLines(new File("/etc/passwd").
                                                                       toPath(), Charset.forName("UTF-8")));
       mission auf eine im Netz vorgehaltene Datenbank zugreifen)
      ReflectPermission: potentes Recht zur Überwindung der           Da die Datei /etc/passwd i. d. R. für jeden Systemnutzer lesbar ist,
       private/protected-Kapselung (wird der Submission i. d. R.       können vom Betriebssystem verwaltete Dateirechte nicht greifen.
       entzogen; Begründung am Beispiel in Abschnitt 3.4.2.5)          Dies ist eine Bedrohung, die durch selektive Rechte gemäß der
      RuntimePermission: diverse potente Rechte vom Nachladen         Java Sicherheitsarchitektur abwehrbar ist.
       weiterer Klassen bis zur Umleitung der Ein-/Ausgabe (für        3.4.2.4 Ausspähen der Musterlösung
       Submission i. d. R. nicht erforderlich und damit entziehbar)    Ist etwa der Klassenname einer Musterlösung, die häufig Teil der
                                                                       AssignmentGrader-Komponente ist, bekannt oder erraten worden,
Viele Bedrohungen können durch die Java Sicherheitsarchitektur         könnte man wie folgt versuchen, an den Bytecode der
kontrolliert werden. Insbesondere gegen unabsichtlich                  Musterlösung zu kommen:
herbeigeführte Bedrohungen ist das Sandbox-Prinzip der Java
                                                                       InputStream is= Class.forName("org.domain.sample.Solution").
Sicherheitsarchitektur ein wirksamer Mechanismus. Absichtlich          getResourceAsStream("Solution.class");
herbeigeführte Bedrohungen können nicht völlig9 durch die Java         int b; while ((b= is.read()) >= 0) System.out.print(b+" ");
Sicherheitsarchitektur unterbunden werden, wie die Beispiele des
                                                                       Die Standardausgabe wird dem Autor der Submission i. d. R. zur
folgenden Abschnitts zeigen sollen.
                                                                       Erläuterung der Bewertung angezeigt.
3.4.2 Beispiele absichtlich herbeigeführter                            Dieser    Angriff ist      leicht   mit   Mitteln    der  Java
Bedrohungen                                                            Sicherheitsarchitektur abwehrbar, indem das Recht zum Einlesen
Zur Ein- und Abgrenzung seien einige ganz konkrete Beispiele für       des AssignmentGrader-jar-Archivs nicht gewährt wird.
absichtlich herbeigeführte Bedrohungen genannt. Diese Liste ist
verständlicherweise nicht erschöpfend. Sie soll über die Liste des     3.4.2.5 Ausführen der Musterlösung
Abschnitts 3.4.1 hinaus einen Eindruck davon vermitteln, welche        Die Submission könnte versuchen, die Musterlösung einfach
Bedrohungen allein mit Mitteln der Java Sicherheitsarchitektur         auszuführen und dadurch die generierten Ausgaben als die
abwendbar sind und welche zusätzliche Maßnahmen erfordern.             eigenen zu „verkaufen“. Dieser Angriff lässt sich abwehren,
Die Beispiele geben außerdem einen Eindruck des möglichen              indem die Musterlösungsklasse als package private deklariert wird
„impact“ [oV13] erfolgreicher Angriffe.                                und indem Submission-Code das Recht zur Überwindung der
                                                                       Package-Kapselung nicht erhält.
8
    Weitere s. z. B. http://docs.oracle.com/javase/7/docs/technotes/
    guides/security/permissions.html
9                                                                      10
    Noch dazu muss immer wieder mit neu entdeckten Sicher-                   Bei diesem Beispiel kann es sich auch um eine unabsichtlich
    heitslücken in der Java Sandbox gerechnet werden.                       herbeigeführte Bedrohung handeln.
4. Test Doubles bei aktivem Securitymanager                                                               in Java den doPrivileged-Aufruf. Ein solcher Aufruf wirkt als Ab-
Das vorangegangene Kapitel hat motiviert, dass der Einsatz der                                            bruchskriterium bei der Bildung der o. g. Rechte-Schnittmenge.
Java Securitymanagers sinnvoll ist, um reale Bedrohungen                                                  Oberhalb des doPrivileged-Aufrufs am Aufrufstapel beteiligte
abzuwenden. Die durch den Einsatz des Securitymanagers                                                    Schutzbereiche werden nicht berücksichtigt.
resultierenden Auswirkungen auf den Einsatz von Test Doubles                                              Wäre etwa im Beispiel der Abbildung 6 der Aufruf der Methode d
sind Gegenstand des nun folgenden Kapitels.                                                               ein privilegierter Aufruf, würde die resultierende Schnittmenge
                                                                                                          die Rechte {2, 4} umfassen.
4.1 Wirkung der Schutzbereiche zur Laufzeit
Die drei in Abschnitt 3.1 eingeführten Schutzbereiche werden                                              4.2 Sicherheitsimplikationen durch Test
üblicherweise der Klasse der Anwendungsbereiche (application                                              Doubles
domains) zugeordnet. Ein vierter Schutzbereich mit i. d. R. unein-                                        Beim Einsatz von Test Doubles ruft Submission-Code Test
geschränkten Rechten ist der Systembereich (system domain),                                               Doubles des AssignmentGrader-Schutzbereichs auf (vgl. Aufruf
dem u. a. die Klassen der Java-Standardbibliothek angehören.                                              der Methode h in Abbildung 7). Ohne besondere Vorkehrungen
Bei eingeschaltetem Securitymanager prüft die JVM zur Laufzeit                                            würde der Code im Test Double mit den Rechten der Schnittmen-
alle an der aktuell aufzurufenden Operation beteiligten                                                   ge (AutograderCore ∩ AssignmentGrader ∩ Submission) aus-
Komponenten auf dem Aufrufstapel. Programmcode eines einge-                                               geführt, also der Rechtemenge {4}. Der von mockito erzeugte
schränkten Anwendungsbereichs darf durch Aufruf einer                                                     Bytecode eines Test Doubles ruft jedoch Methoden der mockito
Operation des Systembereichs selbstverständlich keine zu-                                                 Bibliothek auf (Methode i), die weitgehende Rechte erfordern,
sätzlichen Rechte erlangen. Die JVM ermittelt daher die                                                   u. a. das sehr potente Recht java.lang.reflect.ReflectPermission
Schnittmenge der Rechte aller am Aufrufstapel beteiligten                                                 "suppressAccessChecks", welches den Zugriff auf private und pro-
Schutzbereiche, um eine potentiell bedrohliche Operation zu                                               tected member einer Klasse erlaubt (in Abbildung 7 in der Spalte
überprüfen [Go13]. Die Aufrufreihenfolge zur Laufzeit ist in der                                          „Recht 5“ vorstellbar).
Regel11 AutograderCore → AssignmentGrader → Submission                                                    Eine Lösung kann nun nicht sein, dem Submission-Schutzbereich
(vgl. Abbildung 6). Mit zunehmender Aufruftiefe stehen geringere                                          alle Rechte zu gewähren, die das Test Double benötigt. Min-
Rechte zur Verfügung.                                                                                     destens das Beispiel in Abschnitt 3.4.2.5 spricht dagegen. Wäre
                                                                                                          der Aufruf der Methode h privilegiert, würden die Methoden h
                                                        Recht 1
                                                                  Recht 2
                                                                            Recht 3
                                                                                      Recht 4
                                                                                                Recht 5




        Komponente           Aufrufstapel
                                                                                                          und i mit der Rechtemenge {2, 4, 5} ausgeführt. Leider hat der
                                                                                                          Autor des AssignmentGraders keine Möglichkeit, den Test
         Autograder-    a                                                                                 Double-Aufruf privilegiert zu gestalten. Die Programmierschnitt-
               Code         b                                                                             stelle von mockito, wie wir sie in Abschnitt 2.4 kennen gelernt
         Assignment-
                                c                                                                         haben, ermöglicht keine privilegierten Test Doubles. Der eigent-
                                    d                                                                     liche Methodenaufruf findet im Submission-Code statt, der nicht
              Grader                    e
                                                                                                          im Einflussbereich des AssignmentGrader-Autors steht.
                                            f
          Submission                         g


            Resultierende Schnittmenge:

          Legende: Aufruf:                   Methode:               Recht:

Abbildung 6: Aufrufstapel und resultierende Rechte (Beispiel)
                                                        Recht 1
                                                                  Recht 2
                                                                            Recht 3
                                                                                      Recht 4
                                                                                                Recht 5




        Komponente           Aufrufstapel


         Autograder-    a                                                                                  Abbildung 8: Proxy-Klasse für ein Test Double von Quadrat
               Code         b                                                                             Die vorgeschlagene Lösung besteht nun darin, eine Proxy12-
                                c
         Assignment-                             i                                                        Klasse in der AssignmentGrader-Komponente zu erstellen, die ein
                                    d
              Grader                    e
                                                 h                                                        Test Double umhüllt. Beispielhaft ist in Abbildung 8 das Quadrat-
                                            f                                                             Interface und das zugehörige, mit Mockito.mock erzeugte Test
          Submission                         g                                                            Double13 zu sehen.
                                                                                                          Die Proxy-Klasse besitzt genau die gleiche Schnittstelle wie das
            Resultierende Schnittmenge:
                                                                                                          Original (Quadrat) und eine dauerhafte Referenz zum Test Double
                                                                                                          Objekt. Die Implementierung der quadrat-Methode der Proxy-
           Legende Methode d. Test Doubles:
                                                                                                          Klasse besteht nun aus einem privilegierten Aufruf von
Abbildung 7: Privilegierter Callback eines Test Doubles                                                   TestDouble.quadrat.

Damit Code des Systembereichs Rechte (bspw. Einlesen von
Font-Dateien zwecks Erzeugung einer Ausgabe) erhalten kann,
                                                                                                          12
die aufrufender Anwendungsbereichs-Code nicht besitzt, gibt es                                                    http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Pro
                                                                                                               xy.html
11                                                                                                        13
      Rückwärts gewandte Aufrufe von Methoden des Autograder-                                                   Der von mockito erzeugten Klasse haben wir hier für Darstel-
     Core aus dem AssignmentGrader heraus sind ebenfalls denkbar,                                              lungszwecke einen Namen gegeben. In Wirklichkeit ist die
     sind jedoch hier nicht Gegenstand der Betrachtung.                                                        erstellte Klasse aus Benutzersicht anonym.
Den wenigsten Autoren von AssignmentGradern wird die                     5. Fazit
Sicherheit des Autobewerters so wichtig sein, dass sie die Mühe          Wählt man wie in Graja JUnit-Tests als Werkzeug zur
auf sich nehmen und eine Klasse Proxy für jeden zu                    automatisierten Programmbewertung, ist der Einsatz einer
doublenden Typ T programmieren wollen. Es handelt sich zudem             Bibliothek zur Erzeugung von Test Doubles naheliegend.
um höchst spezialisierten Code, der ein tiefes Verständnis von           Studentischer Code und Test Doubles gehören verschiedenen
Java Reflection und Generics erfordert.                                  Schutzbereichen an. Test Doubles sind im Aufrufbaum Kinder des
Die naheliegende Idee ist nun, die Erzeugung der Proxy-Objekte           studentischen Codes, so dass tendenziell restriktive Rechte des
in eine Bibliothek auszulagern, die dem AssignmentGrader-                studentischen Codes an Test Doubles vererbt werden. Mock-
Schutzbereich angehört. Wir stellen im folgenden Abschnitt kurz          Bibliotheken benötigen für ihre Test Doubles jedoch Rechte von
die Entwurfsideen einer neuen Bibliothek MockitoWrap als Hülle           erheblichem Bedrohungspotential. Um den von der Lehrkraft
um mockito vor, die sich um die Erzeugung von Proxy-Objekten             geschriebenen Bewertungscode nicht mit sicherheitsspezifischen
kümmert, welche Aufrufe an Test Doubles delegiert, wobei jeder           Details (Proxy-Objekte mit in doPrivileged-Aufrufen gekapselten
delegierte Aufruf in ein doPrivileged-Konstrukt „verpackt“ ist.          Delegationen) zu „verschmutzen“, bietet sich die Verlagerung
                                                                         dieser Details in die Mock-Bibliothek oder in einen hierfür zu
4.3 Zentrale Entwurfsideen von Mockito-                                  schreibenden Adapter an. Die Erstellung eines solchen Adapters
Wrap                                                                     kann durch Nutzung von Java Generics und der Java-Reflection-
Die zentrale Operation (vgl. Abschnitt 2.4) bei der Nutzung von          Bibliothek kompakt gelingen.
mockito ist die generische Methode Mockito.mock(Class c)14.
Sie liefert ein Test Double vom Basistyp T, für das alle Methoden
                                                                         6. Literaturverzeichnis
                                                                         [Ed03]   Edwards, S.: Using Test-Driven Development in the
der Klasse T aufrufbar sind. Das Test Double wird im weiteren
                                                                                  Classroom: Providing Students with Automatic,
Verlauf von Methoden wie Mockito.when oder Mockito.verify
                                                                                  Concrete Feedback on Performance. In Proc. Int’l Conf.
verwendet. An dieser Art des Aufrufs von mockito soll sich durch
                                                                                  Education and Information Systems: Technologies and
die beschriebene Sicherheitsanforderung nichts ändern. Einzig der
                                                                                  Applications (EISTA ’03), Aug. 2003.
Name der Einstiegsklasse Mockito soll nun MockitoWrap heißen.
                                                                         [Go13]   Gong, L.: JavaTM SE Platform Security Architecture.
Die vollständige Beschreibung von MockitoWrap würde den
                                                                                  http://docs.oracle.com/javase/7/docs/technotes/guides/
Rahmen dieses Aufsatzes sprengen. Wir nennen nur einige
                                                                                  security/spec/security-spec.doc.html, Abruf 13.09.2013.
grundlegende Entwurfsideen, die vermutlich in ähnlicher Form
auf andere Mock-Frameworks übertragen werden können.                     [Ka13]   Kaczanowski, T.: Practical Unit Testing with JUnit and
MockitoWrap wird im Zuge der Erstellung neuer Programmier-                        Mockito. Verlag Tomasz Kaczanowski, 2013.
aufgaben sukzessive an der Hochschule Hannover weiter                    [KSZ02] Krinke J, Störzer M, Zeller A, Web-basierte
entwickelt.                                                                      Programmierpraktika mit Praktomat, Softwaretechnik-
Entwurfsidee 1: Sei Class c der Typ, für den ein Test Double                  Trends, Vol. 22, (3), October 2002.
erstellt werden soll. Statt direkt Mockito.mock(c) aufzurufen, soll      [Me07] Meszaros, G.: xUnit Test Patterns: Refactoring Test
der Wrapper genutzt werden: MockitoWrap.mock(c). Der Wrapper                    Code. Addison-Wesley Longman, Amsterdam, 2007.
delegiert den Aufruf an das Original (T td=Mockito.mock(c)) und
erstellt dann ein Proxy-Objekt für das Test Double td. Das Proxy-        [oV13]   o. V.: OWASP Risk Rating Methodology. https://www.
Objekt erhält als Konstruktorparameter ein Objekt einer neuen                     owasp.org/index.php?title=OWASP_Risk_Rating_Meth
generischen Klasse MockProxyInvocationHandler, die von                         odology&oldid=158022, Abruf 13.09.2013.
                   15
InvocationHandler     erbt. MockProxyInvocationHandler besitzt        [SBG10] Striewe, M.; Balz, M.; Goedicke, M.: Enabling Graph
als Instanzattribute Referenzen auf das Test Double td und dessen                Transformations on Program Code, In Proceedings of
Klasse c16, so dass stets vom Proxy-Objekt zum Test Double                       the Fourth International Workshop on Graph-Based
navigiert werden kann.                                                           Tools (GraBaTs 2010), Enschede, Netherlands, 2010.
Entwurfsidee 2: Die Methode MockProxyInvocationHandler.               [SL05]   Spillner, A.; Linz, T.: Basiswissen Softwaretest (3.
invoke delegiert den Methodenaufruf innerhalb einer Privileged                    Auflage). dpunkt, Heidelberg, Germany, 2005
       17
Action    an das Test Double td.                                         [St13]   Stöcker, A., Becker, S., Garmann, R., Heine, F., Kleiner,
Entwurfsidee 3: Für weitere Klassen der mockito-Bibliothek wer-                   C., Bott, O. J.: Evaluation automatisierter Programm-
den nun (einfachere) Wrapper geschrieben werden. Bspw. besitzt                    bewertung bei der Vermittlung der Sprachen Java und
OngoingStubbingWrap ein Instanzattribut vom Originaltyp                        SQL mit den Gradern „aSQLg“ und „Graja“ aus
OngoingStubbing. Methodenaufrufe wie thenReturn werden an                      studentischer Perspektive. In Proceedings DeLFI, 2013.
das Instanzattribut delegiert. Rückgabewerte werden wieder in            [TE08]   Thornton, M., Edwards, S. H., Tan, R. P., Pérez-
Objekte der …Wrap-Klasse eingehüllt.                                              Quiñones, M. A.: Supporting student-written tests of
                                                                                  GUI programs. In Proceedings of the 39th SIGCSE
14
      http://docs.mockito.googlecode.com/hg/latest/index.html?org/                Technical Symposium on Computer Science Education.
     mockito/Mockito.html                                                         ACM Press, New York, NY, 2008, pp. 537-541.
15
       http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Invo
     cationHandler.html
16
      Type erasure bei Java Generics macht den Einsatz dieses
     zweitgenannten Instanzattributs notwendig.
17
          http://docs.oracle.com/javase/7/docs/api/java/security/Privi
     legedAction.html