Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Undertow: UnsupportedOperationException using servlet filter in SSL #43628

Closed
melloware opened this issue Oct 1, 2024 · 3 comments · Fixed by #43680
Closed

Undertow: UnsupportedOperationException using servlet filter in SSL #43628

melloware opened this issue Oct 1, 2024 · 3 comments · Fixed by #43680
Labels
area/undertow kind/bug Something isn't working
Milestone

Comments

@melloware
Copy link
Contributor

melloware commented Oct 1, 2024

Describe the bug

When using SSL with a Servlet filter its producing an UnsupportedOperationException. It works without SSL but not with SSL.

Original Quarkus Faces issue: melloware/quarkus-faces#483

Simple Servlet Filter

public class SecureServletFilter implements Filter {

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {
        final HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setHeader("X-Frame-Options", "SAMEORIGIN");
        httpResponse.setHeader("X-Content-Type-Options", "nosniff");
        httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
        httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
       chain.doFilter(request, response);
    }
}

Expected behavior

It should work without error.

Actual behavior

It fails with the stack trace below.

It looks like something is an unmodifiable list.

How to Reproduce?

Reproducer:
quarkus-filter.zip

rami@mac ~/quarkus-filter $ ls cert 
fullchain.pem privkey.pem
QUARKUS_HTTP_SSL_CERTIFICATE_FILES=./cert/fullchain.pem
QUARKUS_HTTP_SSL_CERTIFICATE_KEY_FILES=./cert/privkey.pem
QUARKUS_HTTP_HOST=0.0.0.0
QUARKUS_HTTP_PORT=9001
QUARKUS_HTTP_SSL_PORT=9002

Unzip and run the project and hit the website.

2024-10-01 14:55:15,128 DEBUG [io.net.han.ssl.BouncyCastlePemReader] (vert.x-eventloop-thread-1) Bouncy Castle provider available
2024-10-01 14:55:15,178 DEBUG [io.net.han.ssl.BouncyCastlePemReader] (vert.x-eventloop-thread-1) Parsed PEM object of type org.bouncycastle.asn1.pkcs.PrivateKeyInfo and assume key is not encrypted
2024-10-01 14:55:15,745 DEBUG [jdk.eve.security] (vert.x-eventloop-thread-1)  TLSHandshake: null:-1, TLSv1.3, TLS_AES_256_GCM_SHA384, 0
2024-10-01 14:55:15,789 DEBUG [io.net.han.ssl.SslHandler] (vert.x-eventloop-thread-1) [id: 0x516102ee, L:/127.0.0.1:9002 - R:/127.0.0.1:61919] HANDSHAKEN: protocol:TLSv1.3 cipher suite:TLS_AES_256_GCM_SHA384
2024-10-01 14:55:15,953 INFO  [com.mel.qua.SecureServletFilter] (executor-thread-1) SecureServletFilter ...
2024-10-01 14:55:15,953 INFO  [com.mel.qua.SecureServletFilter] (executor-thread-7) SecureServletFilter ...
java.lang.UnsupportedOperationException
	at java.base/java.util.AbstractList.remove(AbstractList.java:169)
	at java.base/java.util.AbstractList$Itr.remove(AbstractList.java:389)
	at io.undertow.servlet.spec.PushBuilderImpl.<init>(PushBuilderImpl.java:120)
	at io.undertow.servlet.spec.HttpServletRequestImpl.newPushBuilder(HttpServletRequestImpl.java:1184)
	at org.apache.myfaces.context.servlet.ServletExternalContextImpl.pushResource(ServletExternalContextImpl.java:402)
	at org.apache.myfaces.context.servlet.ServletExternalContextImpl.encodeResourceURL(ServletExternalContextImpl.java:383)
	at jakarta.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:107)
	at jakarta.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:107)
	at org.primefaces.renderkit.HeadRenderer.encodeCSS(HeadRenderer.java:185)
	at org.primefaces.renderkit.HeadRenderer.encodeBegin(HeadRenderer.java:105)
	at jakarta.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:561)
	at jakarta.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:495)
	at jakarta.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:519)
	at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1783)
	at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:316)
	at jakarta.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:74)
	at org.omnifaces.viewhandler.OmniViewHandler.renderView(OmniViewHandler.java:166)
	at jakarta.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:74)
	at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:122)
	at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:241)
	at jakarta.faces.webapp.FacesServlet.service(FacesServlet.java:225)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
	at org.omnifaces.filter.CacheControlFilter.doFilter(CacheControlFilter.java:239)
	at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at com.melloware.quarkus.SecureServletFilter.doFilter(SecureServletFilter.java:48)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at org.omnifaces.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:123)
	at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
	at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
	at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
	at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63)
	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:67)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:247)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:111)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:108)
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1.call(UndertowDeploymentRecorder.java:645)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:227)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:152)
	at io.undertow.server.handlers.CanonicalPathHandler.handleRequest(CanonicalPathHandler.java:49)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$1.handleRequest(UndertowDeploymentRecorder.java:126)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:284)
	at io.undertow.server.DefaultExchangeHandler.handle(DefaultExchangeHandler.java:18)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$5$2.run(UndertowDeploymentRecorder.java:445)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:635)
	at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2516)
	at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2495)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1495)
	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.base/java.lang.Thread.run(Thread.java:1583)
java.lang.UnsupportedOperationException
	at java.base/java.util.AbstractList.remove(AbstractList.java:169)
	at java.base/java.util.AbstractList$Itr.remove(AbstractList.java:389)
	at io.undertow.servlet.spec.PushBuilderImpl.<init>(PushBuilderImpl.java:120)
	at io.undertow.servlet.spec.HttpServletRequestImpl.newPushBuilder(HttpServletRequestImpl.java:1184)
	at org.apache.myfaces.context.servlet.ServletExternalContextImpl.pushResource(ServletExternalContextImpl.java:402)
	at org.apache.myfaces.context.servlet.ServletExternalContextImpl.encodeResourceURL(ServletExternalContextImpl.java:383)
	at jakarta.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:107)
	at jakarta.faces.context.ExternalContextWrapper.encodeResourceURL(ExternalContextWrapper.java:107)
	at org.primefaces.renderkit.HeadRenderer.encodeCSS(HeadRenderer.java:185)
	at org.primefaces.renderkit.HeadRenderer.encodeBegin(HeadRenderer.java:105)
	at jakarta.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:561)
	at jakarta.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:495)
	at jakarta.faces.component.UIComponentBase.encodeAll(UIComponentBase.java:519)
	at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1783)
	at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:316)
	at jakarta.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:74)
2024-10-01 14:55:16,060 SEVERE [org.pri.app.exc.PrimeExceptionHandler] (executor-thread-7) null

Exception in SecureServletFilter.java:48
	   46          httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
	   47          httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
	-> 48         chain.doFilter(request, response);
	   49      }
	   50  }

Output of uname -a or ver

Darwin MacBook-Pro.local 22.6.0 Darwin Kernel Version 22.6.0

Output of java -version

OpenJDK Runtime Environment Temurin-17.0.11+9 (build 17.0.11+9)

Quarkus version or git rev

3.15.1

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

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)

Additional information

No response

@geoand
Copy link
Contributor

geoand commented Oct 1, 2024

I assume quarkusio/quarkus-http#166 is all that's needed to fix this

@melloware
Copy link
Contributor Author

@geoand you rock that definitely looks like it will do it!

@geoand
Copy link
Contributor

geoand commented Oct 1, 2024

🙏🏽

@gsmet gsmet closed this as completed in 2fb6844 Oct 3, 2024
gsmet added a commit that referenced this issue Oct 3, 2024
Bump to Quarkus HTTP 5.3.3
@quarkus-bot quarkus-bot bot added this to the 3.16 - main milestone Oct 3, 2024
@gsmet gsmet modified the milestones: 3.16.0.CR1, 3.15.2 Oct 18, 2024
gsmet pushed a commit to gsmet/quarkus that referenced this issue Oct 21, 2024
Fixes: quarkusio#43628
(cherry picked from commit 2fb6844)
bschuhmann pushed a commit to bschuhmann/quarkus that referenced this issue Nov 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/undertow kind/bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants