Skip to content

CsrfFilter called twice when CSRF token sent via HTML field, causing NullPointerException #1984

@hisashidds

Description

@hisashidds

Expected Behavior

The CsrfFilter should be called only once per request, and the request should complete successfully when a valid CSRF token is provided via HTML field.

Actual Behaviour

The CsrfFilter is called twice, causing a NullPointerException with the error message:

Cannot invoke "io.micronaut.http.filter.FilterContext.response()" because "newFilterContext" is null

Steps To Reproduce

  1. Configure Micronaut Security with CSRF protection enabled
  2. Create an HTML form that includes a CSRF token field
  3. Submit the form via POST request
  4. Observe the CsrfFilter being called twice and the subsequent NPE

The issue does not occur when the affected path is excluded from CSRF filter processing using path exclusion configuration.

DEBUG i.m.security.rules.IpPatternsRule - One or more of the IP patterns matched the host address [0:0:0:0:0:0:0:1]. Continuing request processing.
DEBUG i.m.s.rules.InterceptUrlMapRule - No url map pattern exact match found for path [/search-stock/search] and method [POST]. Searching in patterns with no defined method.
DEBUG i.m.s.rules.InterceptUrlMapRule - Url map pattern found for path [/search-stock/search]. Comparing roles.
DEBUG i.m.s.rules.AbstractSecurityRule - The given roles [[admin, isAnonymous(), isAuthenticated()]] matched one or more of the required roles [[isAuthenticated()]]. Allowing the request
DEBUG i.m.security.filters.SecurityFilter - Authorized request POST /search-stock/search. The rule provider io.micronaut.security.rules.ConfigurationInterceptUrlMapRule authorized the request.
TRACE i.m.security.csrf.filter.CsrfFilter - CSRF Token resolved
TRACE i.m.security.csrf.filter.CsrfFilter - CSRF Token resolved
ERROR i.m.http.server.RouteExecutor - Unexpected error occurred: Cannot invoke "io.micronaut.http.filter.FilterContext.response()" because "newFilterContext" is null
java.lang.NullPointerException: Cannot invoke "io.micronaut.http.filter.FilterContext.response()" because "newFilterContext" is null
        at io.micronaut.http.filter.AroundLegacyFilter$FilterChainImpl.lambda$proceed$1(AroundLegacyFilter.java:124)
        at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
        at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
        at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179)
        at io.micronaut.core.execution.ImperativeExecutionFlowImpl.completeTo(ImperativeExecutionFlowImpl.java:140)
        at io.micronaut.core.execution.DelayedExecutionFlowImpl$OnCompleteToFuture.apply(DelayedExecutionFlowImpl.java:401)
        at io.micronaut.core.execution.DelayedExecutionFlowImpl.work(DelayedExecutionFlowImpl.java:54)
        at io.micronaut.core.execution.DelayedExecutionFlowImpl.complete0(DelayedExecutionFlowImpl.java:75)
        at io.micronaut.core.execution.DelayedExecutionFlowImpl.complete(DelayedExecutionFlowImpl.java:82)
        at io.micronaut.http.body.stream.BaseSharedBuffer.complete(BaseSharedBuffer.java:417)
        at io.micronaut.http.server.netty.handler.PipeliningServerHandler$StreamingInboundHandler.read(PipeliningServerHandler.java:556)
        at io.micronaut.http.server.netty.handler.PipeliningServerHandler.channelRead(PipeliningServerHandler.java:221)

Environment Information

  • openjdk version "21.0.6" 2025-01-21 LTS

This issue appears to be related to or the same as the issue reported in micronaut-core:

micronaut-projects/micronaut-core#11341

The symptoms and stack trace patterns are very similar, suggesting this might be a broader filter chain issue affecting CSRF functionality specifically.

Example Application

https://github.com/Micronaut-TODO/micronauttodo/tree/bug

Version

4.8.2

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions