CVE-2026-93432

Cross-Site Scripting
Affects
Quarkus
in
Quarkus
No items found.
Versions
<3.27.5.3, >=3.28.0 <3.33.3.3, >=3.34.0 <3.39.5

Patch Available.

Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

Quarkus is a Kubernetes-native Java framework optimized for cloud-native applications, containers, and serverless workloads. It builds on standard libraries (Jakarta EE, Eclipse Vert.x, Hibernate, Netty) and compiles to both JVM and GraalVM native images for fast startup and low memory use. Qute is the templating engine shipped with Quarkus, used to render HTML, JSON, and other text responses from templates whose content type drives automatic escaping of resolved values. The issue affects versions of Quarkus that include the affected io.quarkus.qute:qute-core package.

A Cross-Site Scripting (XSS) vulnerability (CVE-2026-93432) has been identified in the Qute template engine, which allows attackers to inject markup or script into rendered responses, and to corrupt generated JSON documents, by supplying data that is rendered through a sub-template evaluated by the {#eval} section helper.

Per OWASP: Cross-Site Scripting (XSS) attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. Flaws that allow these attacks to succeed are quite widespread and occur anywhere a web application uses input from a user within the output it generates without validating or encoding it.

This issue affects applications that pass user-controlled data into a Qute {#eval} section in affected versions of Quarkus.

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in the io.quarkus.qute:qute-core package in the Qute template engine of Quarkus.

Qute decides whether resolved values must be escaped from the variant of the template being rendered. A variant carries the content type of the template, and the built-in result mappers consult it before writing a value into the output:

public boolean appliesTo(Origin origin, Object result) {
    if (result instanceof RawString) {
        return false;
    }
    Optional<Variant> variant = origin.getVariant();
    if (variant.isPresent()) {
        return requiresDefaultEscaping(variant.get());
    }
    return false;
}

When a template node has no variant, the escaper does not apply and the resolved value is written verbatim.

The {#eval} section helper parses its argument as a sub-template at render time and resolves it against the current context. It parsed that sub-template without passing the parent template's variant:

private void parseAndResolve(CompletableFuture<ResultNode> ret, String contents, ResolutionContext resolutionContext) {
    Template template;
    try {
        template = engine.parse(contents);
        template.getRootNode()
                .resolve(resolutionContext)
                .whenComplete((resultNode, t2) -> {
                    if (t2 != null) {
                        ret.completeExceptionally(t2);
                    } else {
                        ret.complete(resultNode);
                    }
                });
    } catch (TemplateException e) {
        // ...
    }
}

Because engine.parse(contents) defaults the variant to null, every node of the evaluated sub-template is created without a variant. The HTML escaper registered for text/html templates, and the corresponding mappers for other content types, therefore never apply to values resolved inside the sub-template, even though the enclosing template is rendered as HTML or JSON. Any attacker-controlled value that reaches an expression inside an evaluated sub-template, for example a stored profile field or a request parameter echoed back through a fragment that the application evaluates, is emitted raw into the response. Characters such as <, >, &, and quotes survive unescaped, which permits script injection into the rendered page and injection of structural characters into generated JSON.

The same fix also covers the str:eval namespace resolver, in the versions that provide it. The resolver passes the variant when it parses a template, but it cached templates parsed from string literals keyed only by the literal contents, so a literal first rendered in a plain-text template was later rendered unescaped in an HTML template.

Exploitation requires no privileges, only that the application pass attacker-influenced data into an {#eval} section.

Mitigation

Only recent versions of Quarkus are community-supported. The 2.16.x and 3.20.x lines were already End-of-Life when this CVE was published and will not receive public updates to address this issue. Quarkus LTS releases are maintained for 12 months from release; see the project's LTS release policy.

Users of the affected components should apply one of the following mitigations:

  • Upgrade Quarkus to a currently supported release that contains the fix.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support.

Credits

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2026-93432
PROJECT Affected
Quarkus
Versions Affected
<3.27.5.3, >=3.28.0 <3.33.3.3, >=3.34.0 <3.39.5
NES Versions Affected
Published date
October 1, 2026
≈ Fix date
October 1, 2026
Category
Cross-Site Scripting
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Quarkus
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.