quarkus: CVE-2022-2466 - Request Context not terminated with GraphQL

Describe the bug

Upgrading from Quarkus 2.9.x to 2.10.x whenever i try to access RoutingContext request from a bean i get always the headers of the first request that have been made to the app.

This happens on both @GraphQLApi endpoints and event in any CDI bean that consumes RoutingContext or HttpServerRequest.

Also by debugging, the CurrentVertxRequest has always stale headers.

Update: The request context was not terminated. The issue is not related to the Routing Context.

My dependencies are the following:

   <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-kotlin</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-smallrye-graphql</artifactId>
    </dependency>
    <dependency>
      <groupId>io.smallrye</groupId>
      <artifactId>smallrye-jwt</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-rest-client-jackson</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-arc</artifactId>
    </dependency>
    <dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-undertow</artifactId>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlin</groupId>
      <artifactId>kotlin-stdlib-jdk8</artifactId>
    </dependency>

CDI bean:

@ApplicationScoped
class JWTAwareContext @Inject constructor(
    val routingContext: RoutingContext
): Context {
    override fun getTenant(): String {
        return parseClaims()!!.getClaimValueAsString("realm")
    }

    override fun getUser(): String {
        return parseClaims()!!.getClaimValueAsString("email")
    }

    fun parseClaims(): JwtClaims? {
        val rawToken = this.routingContext.request().headers().get("Authorization")?.replace("Bearer ", "") // --> this will always stale in 2.10.x
        if (rawToken != null) {
            val jsonClaims = String(Base64.getUrlDecoder().decode(rawToken.split(".")[1]), StandardCharsets.UTF_8)
            return JwtClaims.parse(jsonClaims)
        }
        throw PassProNextForbiddenExceptionGQL(ApiError("Missing Token", ErrorCode.FORBIDDEN))
    }
}

Graphql endpoint


@GraphQLApi
class Test {
    @Inject lateinit var routingContext: RoutingContext


    @Query
    fun test(): String {
        return  "hello";
    }
}

With 2.9.x works correctly.

Expected behavior

Everytime a new Request is performed by a client, the Request headers should be inline with the actual HTTP Request

Actual behavior

With 2.10.x the first request headers became like cached value and any subsequent request headers will contain those instead of the actual headers

How to Reproduce?

  1. create an app with Quarkus 2.10.1 - 2.10.2 and the smallrye graphql extension
  2. create an endpoint or a bean injecting RoutingContext
  3. set some HTTP headers like Authorization, MyCustomHeader etc and send the http request
  4. print RoutingContext.request().headers
  5. set others HTTP headers or remove the previous and send the new http request
  6. the second request headers will contain first request data also if you did not send them 7 ) switch to quarkus 2.9.x and will work as expected

Output of uname -a or ver

No response

Output of java -version

adopt-openjdk-11.0.8

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.10.1 - 2.10.2

Build tool (ie. output of mvnw --version or gradlew --version)

3.8.1

Additional information

No response

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 28 (19 by maintainers)

Commits related to this issue

Most upvoted comments

@Ladicek @gsmet I think I found it. the endhandler that terminates the context. Doing a PR now. I’ll add a test for this.

We have a fix that will get merged today and I will do an emergency release tomorrow.

Thanks for the report and thanks @markuseckstein for the isolated reproducer!

@Ladicek - yes I also ran the test with REST, and that worked, so it’s GraphQL specific.