studyklar
IProg · Skript 8 · Abschnitt 7

JSTL statt Skriptlets, c:out gegen XSS

Java-Code in einer JSP-Seite ist schwer zu lesen. Gibt die Seite Eingaben von Benutzern roh aus, öffnet sie außerdem eine Sicherheitslücke. JSTL hilft bei beidem: fertige Tags statt Skriptlets, und c:out gibt Eingaben sicher aus. Rechts wird die Seite von Folie 31 neu geschrieben. Mit Weiter geht es voran.

Worum es geht

Nicht im Skript. Gefragt in den Klausuren:

  • Klausur 1, Aufgabe 1e (Vorteile von JSTL) und Aufgabe 8 (JSP mit JSTL, XSS).
  • Klausur 2, Aufgabe 1e (Cross-Site-Scripting) und Aufgabe 8 (JSP mit JSTL).
  • Klausur 3, Aufgabe 9 (bessere Architektur mit JSTL).

Dieser Abschnitt geht über das Skript hinaus. Skript 08 endet mit Folie 33. JSTL und Cross-Site-Scripting stehen in keinem Skript, aber in allen drei Klausuren. Darum ist er nach den Lösungen der Klausuren gebaut, mit denselben Tags und derselben Schreibweise.

Die Frage ist: Wie schreibt man die Personentabelle von Skript 08, Folie 31 ohne Java-Code in der Seite, und so, dass ein Benutzer kein Skript einschleusen kann?

„Folie N“ heißt hier immer die N-te Seite der PDF-Datei. Die kleine Zahl unten auf der Folie kann davon abweichen.

So gehen wir vor:

  1. Was an Skriptlets stört.
  2. Was Cross-Site-Scripting ist.
  3. Die JSTL einbinden und Werte mit der Expression Language holen.
  4. Schleife, Zähler, sichere Ausgabe und Meldung bei leerer Liste.
  5. Eine Klausurfrage zum Üben.

Java-Code mitten im HTML

  • Java und HTML gemischt: schwer zu lesen und zu ändern.
  • Designer müssen Java können.
  • Darstellung und Logik nicht getrennt.

Auf Folie 31 steht Java in <% … %> zwischen den HTML-Zeilen. Eine Schleife beginnt in Zeile 10 und endet erst in Zeile 14. Wer das Design ändern will, muss Java lesen können.

Schlimmer wird es, wenn in der Seite auch die Datenbank abgefragt wird. Dann sind Darstellung, Datenzugriff und Verarbeitung nicht mehr getrennt. Genau das bemängelt die Lösung von Klausur 3.

Aus Klausur 3, Aufgabe 9 („Bessere Architektur für TEST.JSP: Servlet, DB-Klasse und JSTL“): Unschön: keine Trennung von Darstellung, Datenzugriff und Verarbeitungslogik. Besser: ein Controller-Servlet und JSP-Seiten mit reiner Darstellung, mit JSTL.

Cross-Site-Scripting

      <tr><td><%= p.getVname() %></td>
<td><script>alert(1)</script></td>

Auf Folie 31 steht die Liste fest im Code. In einer echten Anwendung käme sie aus einer Datenbank, in die Besucher selbst schreiben. Angenommen, Personen tragen ihren Namen dort über ein Formular ein. Jemand gibt als Vornamen <script>alert(1)</script> ein. Zeile 12 setzt diesen Text unverändert ins HTML ein.

Der Browser jedes Besuchers liest darin ein script-Element und führt es aus. Hier öffnet es nur ein Meldungsfenster. Ein echter Angreifer könnte so aber etwa Cookies mit der Session-ID auslesen und an sich schicken.

Das heißt Cross-Site-Scripting (XSS, seitenübergreifendes Skripten): Ein Angreifer schleust über die Eingabe ein Skript in eine fremde Seite ein. Es ist eine Art der HTML-Injection, also des Einschleusens von HTML.

Aus Klausur 2, Aufgabe 1 („Grundlagen: DOM, Internet, DNS, W3C und Cross-Site-Scripting“): XSS tritt auf, wenn eine Webanwendung Daten annimmt, die von einem Nutzer stammen, und diese an anderer Stelle wieder anzeigt. Vermeiden: z. B. durch das Tag <c:out>.
Noch 8 Schritte bis zum Ergebnis
Den ganzen Lösungsweg sehen Studierende und Lehrende der HS KL. Registriere dich mit deiner Adresse @stud.hs-kl.de oder @hs-kl.de, dann geht es hier direkt weiter.

Abbildung 1Das Problem

Skriptlets und rohe Ausgabe

<%@ page contentType="text/html; charset=ISO-8859-1" %><%@ page import="java.util.List, model.CPerson" %><html>  <body>    <table>      <tr><th>Vorname</th><th>Nachname</th></tr><%   List<CPerson> pList = List.of(new CPerson("Anna", "Berg"),                                 new CPerson("Ben", "Kurz"));   for (CPerson p : pList) {%>      <tr><td><%= p.getVname() %></td>          <td><%= p.getNname() %></td></tr><% } %>    </table>  </body></html>
LegendeZeilen des SchrittsDie Seite von Folie 31: Java-Code und HTML gemischt.