Re: Weird CSRF prevention behavior

2023-12-01 Thread Lasse Lindqvist
Well, one thing that could be wrong is that Log4j2 does not have FINE or
FINEST levels. It does have TRACE. If that does not fix things, you could
always  change tour log.trace to log.error if you only care about debugging
the original issue.

pe 1. jouluk. 2023 klo 22.28 Christopher Schultz (
ch...@christopherschultz.net) kirjoitti:

> All,
>
> I'm experimenting with the CsrfPreventionFilter in Tomcat 8.5. I've had
> issues with it in the past so I haven't actually enabled it in any of my
> applications, but I'm sufficiently motivated at this point to get it done.
>
> My "application" is actually split up into two applications, each
> running in a separate JVM but in the same URL space. I have a
> reverse-proxy that figures this all out and it's been working for years.
> I don't see why this wouldn't work.
>
> I have enabled CSRF prevention in Application A which is the "primary
> application" and the secondary application (Application B) is capable of
> mimicking/proxying the csrf token back to Application A.
>
> Application B has a feature where we present a web form to the user.
> It's fairly simple (paraphrasing):
>
> 
>
> 
>
> When I submit this form, I get an HTTP 403 response. Our application
> doesn't send 403 responses. When I remove the CsrfPreventionFilter from
> the configuration) by commenting-out the  in
> WEB-INF/web.xml, I do not get the 403 response and the form submission
> is successful. I'm sure that the CSRF token is *NOT* in the POST
> request: the browser shows me what is sent and it's not there. I have
> hacked the form and added the token, submitted it, and it /works/.
>
> But this is an HTTP POST and should be ignored by the filter.
>
> So I figure I'll enable logging and see what's happening. There isn't
> much logging in CsrfPreventionFilter, so I add this line to the
> beginning of the skipNonceCheck method:
>
>  log.trace("skipNonceCheck(" + request.getMethod() + " " +
> request.getRequestURI() + ")");
>
> I build-from-source and launch my custom-build Tomcat with my
> application in it. No logging. Oh, right... logging.properties. So I add
> this to my conf/logging.properties file:
>
> org.apache.catalina.filters.CsrfPreventionFilter.level = FINEST
>
> To be sure there's no funny business, I use "catalina.sh run" and wait
> for the console log to settle down. I make a few requests. No logs. Hmm.
> Oh, the ConsoleAppender is set to FINE and not FINEST.
>
> java.util.logging.ConsoleHandler.level = FINEST
>
> Done. CTRL-C, catalina.sh run. Make some requests.
>
> Nothing. Okay maybe the Filter is just ignoring these for some
> reason. So I add this line to the beginning of doFilter, before anything
> else happens:
>
>  log.trace("doFilter(" + request + ")");
>
> Re-build. CTRL-C. catalina.sh run. Make some requests.
>
> Nothing.
>
> The Filter is absolutely running. If I reload a page, the csrf tokens on
> all the links are changing. What's going on?
>
> You'd think a Tomcat committer could figure out how to make logging work.
>
> My application is using log4j2, but that library is only used by the
> application and the JAR file is in WEB-INF/lib/. I wouldn't expect that
> it would interfere with server-level logging.
>
> Any ideas? About EITHER issue? If anyone can help with logging, maybe I
> can figure out what's happening in the Filter. If you have any
> suggestions about the Filter, I'm al ears. HTTP POST should not be
> prohibited unless I'm reading both the code and the CSRF specs incorrectly.
>
> Thanks,
> -chris
>
> -
> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: users-h...@tomcat.apache.org
>
>


Tomcat returning faulty "empty" header

2023-07-12 Thread Lasse Lindqvist
Hi. Every once in a while in automatic tests I see an error

Caused by: org.apache.http.ProtocolException: Invalid header: :
at 
app//org.apache.http.impl.io.AbstractMessageParser.parseHeaders(AbstractMessageParser.java:230)
at 
app//org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:266)
at 
app//org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
at 
app//org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
at 
app//org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
at 
app//org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
at 
app//org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
at 
app//org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
at 
app//org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
at 
app//org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at 
app//org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)

Meaning that the header contents would be just ": ", suggesting that
it has an empty key and empty value.

The service being called is a Spring Boot 2.7 application that has a
simple Controller with no custom header definitions.
It does return a response with
.contentType(MediaType.APPLICATION_OCTET_STREAM)

and body of StreamingResponseBody though.

I am wondering if this is something that might be on the Tomcat side,
or Spring side. But even if on Spring side, should Tomcat perhaps
prevent  the creation of these empty headers, as at least
Apache HTTP client considers them invalid and will not choose to ignore them.

This reproduces relatively rarely, and by rerunning tests it normally
disappears, so I have not been able to catch the root issue.

Maybe it is related to
https://github.com/spring-projects/spring-security/issues/9175 and
fully a Spring issue even though my error is not exactly the same as
those in the Github issue?