Before the log4j shell issue happened last month I was using 'org.springframework.boot:spring-boot-starter-logging:1.5.22.RELEASE' which has internal dependencies on
ch.qos.logback:logback-classic:1.1.11 and ch.qos.logback:logback-core:1.1.11 jars respectively.
After that log4j shell issue occurred I had upgraded both the jars to version ch.qos.logback:logback-classic:1.2.3 and ch.qos.logback:logback-core:1.2.3 with gradle v3.5 which works fine. Now when I am trying to upgrade jars to logback-classic:1.2.10 and logback-core:1.2.10, this stops me while running the application stating below error:
org.gradle.tooling.BuildException: Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-3.5-all.zip'.
Do I need to move to higher version of Grails or Gradle 3.5 have any issue with upgrade. Please any hint or guidance is most welcome.
From https://logback.qos.ch/news.html
We note that the vulnerability mentioned in CVE-2021-42550 requires
write access to logback's configuration file as a prerequisite. Please
understand that log4Shell and CVE-2021-42550 are of different severity
levels. In response to CVE-2021-42550 (aka LOGBACK-1591) we have
decided to make the following steps. 1) Hardened logback's JNDI lookup
mechanism to only honor requests in the java: namespace. All other
types of requests are ignored. Many thanks to Michael Osipov for
suggesting this change and providing the relvant PR. 2) SMTPAppender
was hardened. 3) Temporarily removed DB support for security reasons.
4) Removed Groovy configuration support. As logging is so
pervasive and configuration with Groovy is probably too powerful, this
feature is unlikely to be reinstated for security reasons. We note
that the aforementioned vulnerability requires write access to
logback's configuration file as a prerequisite. Please understand that
log4Shell/CVE-2021-44228 and CVE-2021-42550 are of different severity
levels. A successul RCE attack with CVE-2021-42550 requires all of the
following conditions to be met: write access to logback.xml use of
versions < 1.2.9 reloading of poisoned configuration data, which
implies application restart or scan="true" set prior to attack As an
additional extra precaution, in addition to upgrading to logback
version 1.2.9, we also recommend users to set their logback
configuration files as read-only
For now no support for grails so v1.2.9 onwards logback is not supported for now.
Related
We are currently facing a little conundrum with Spring Boot that's actually not a rare situation:
Spring Security OAuth2 Client has a critical vulnerability that our production systems might be vulnerable to; the vulnerability is fixed in the latest patch release of Spring Security. Naturally, we want to update our production systems ASAP, but this means we need to override the Spring Boot (Gradle) dependency management system if we don't want to wait until the next Spring Boot patch release.
I know that this can be done quite easily, in this case e.g. by setting something like this in gradle.properties:
spring-security-oauth2-client.version=5.7.5
The problem with this is that this dependency is now pinned to a specific version; I need to remember to remove this property as soon as a Spring Boot patch release is available. This means extra coordination effort because we need to document this in our backlog, and even with good documentation on our part there is a risk that we forget to do it, which means the dependency will eventually be outdated - which is the exact opposite of what we wanted to achieve in the first place.
What I'd rather do is specify a minimum version of the dependency, that gets ignored if it is older than what the Spring Boot dependency management plugin's default version.
Can this be done? Or is there a better strategy to handle a situation like this?
This is possible using gradle's dynamic versions.
For instance, you can have:
dependencies {
implementation 'org.springframework.security:spring-security-oauth2-client:5.+'
}
But keep in mind that dynamic versions add nondeterminism to your build and can introduce unexpected behaviour changes to the system.
Using dynamic versions in a build bears the risk of potentially
breaking it. As soon as a new version of the dependency is released
that contains an incompatible API change your source code might stop
compiling.
References:
Version ranges in gradle
Currently there are so many suggested steps that have been posted for excluding log4j-core library from dependency or upgrading to the latest (above version 2.15) version according to Spring Blog . Are there any recommended tools that can be used for protecting spring application deployed in Google App Engine or Pivotal Cloud Foundry(PCF) for protecting instead of patching them for redeployment?
Another necessary question is, does it make my application(microservice spring application) to be vulnerable if it uses another microservice for some of its service if it depends on another microservice and if that microservice already uses vulnerable version of log4j-core?
In regard to your first question, you can set an environment variable in order to disable the replacement lookups in log4j:
LOG4J_FORMAT_MSG_NO_LOOKUPS=true
Please note that this only works for log4j >= 2.10.
I believe you can set environment variables in PCF without having to redeploy the service (of course, a restart would be needed), so no new release would be needed. See: https://docs.pivotal.io/pivotalcf/2-3/devguide/deploy-apps/environment-variable.html and https://cli.cloudfoundry.org/en-US/v6/set-env.html
In order to see whether your spring-boot application is vulnerable to the exploit, you could use a spring-boot test I created for that purpose: https://github.com/chilit-nl/log4shell-example - You could test your application with and without the environment variable, to see if it has any effect (assuming that your application currently is vulnerable).
Short answer to your first question is may be. You can protect your application/service by using rules in WAF to discard the ${jndi://ldap pattern. However, there are so many mutations of this (base64 encoding etc.) that it will not be foolproof. If you are worried about dependencies, you should set the JVM Parameter and redeploy your app to prevent the lookup as a workaround.
Regarding your 2nd question - the answer is yes if the the 2nd micro service is being passed the same input and it's logging.
My company's Sonatype scan shows Spring-Web is vulnerable even for the latest version (currently 5.2.3.RELEASE).
It reads:
"Found security vulnerability CVE-2016-1000027 with severity 9.8".
I noticed CVE-2016-1000027 is added to the NATIONAL VULNERABILITY DATABASE
on 01/02/2020, and it is in regards to
"Spring Framework 4.1.4 suffers from a potential remote code execution
(RCE) issue if used for Java deserialization of untrusted data".
Is this an obsolete ticket or has it not be resolved after 4 years?
This issue is resolved from a Spring Framework point of view, see my latest comment summarizing the situation on that issue. Your application is only vulnerable if you're using HTTPInvokerServiceExporter or RemoteInvocationSerializingExporter and reading data from untrusted sources.
Deserializing Java code from untrusted sources is a well-known problem in Java (so, all Java applications and Frameworks!), and this feature might be removed in future Java versions.
Given the nature of this security problem (there's no way to "fix it" besides removing the classes, which will be done in the next major version of Spring Framework), contacting your vendor or your security team is the best course of action. The Spring team is happy to help the community with this matter by providing more context on that issue if needed.
I am looking at externalizing certain configuration parameters for ehcache in our Grails application and I am running into something not working that the documentation claims ought to.
Likely there is something I am missing.
I am using the grails ehcache plugin version 1.0.1 with Grails 2.4.0 and grails cache plugin 1.1.7. I am using hibernate plugin 3.6.10.16.
Here's what I have in my CacheConfig.groovy configuration...
...
cacheManagerPeerProviderFactory {
peerDiscovery 'automatic'
factoryType 'rmi'
multicastGroupAddress '${ehcacheMulticastGroupAddress}'
multicastGroupPort '${ehcacheMulticastGroupPort}'
timeToLive 'site'
}
I've turned on debug-level logging so I can see what XML it generates. Here's the relevant snippet:
<cacheManagerPeerProviderFactory class='net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory'
properties="peerDiscovery=automatic,multicastGroupAddress=${ehcacheMulticastGroupAddress},multicastGroupPort=${ehcacheMulticastGroupPort},timeToLive=32"
propertySeparator=','
/>
The grails ehcache plugin documentation has the following note, which I was hoping to "prove out"...
(note that ${ehcacheMulticastGroupAddress} and ${ehcacheMulticastGroupPort} are an Ehcache feature that lets you use system property names as variables to be resolved at runtime)
Great. Except that it doesn't work when I start the application. It fails to create CacheManagerPeerProvider due to the following
...
Caused by UnknownHostException: ${ehcacheMulticastGroupAddress}
->> 901 | lookupAllHostAddr in java.net.InetAddress$1
...
I have a myApplication-config.groovy file living in an accessible area that I point to when assigning a value to grails.config.locations in Config.groovy. But I am not sure it is making any effort to really interpolate that value at all.
I tried double quotes but they were a bad idea as well -- at the time of interpreting CacheConfig.groovy it doesn't see the configuration I put into myApplication-config.groovy. I do know it reads that file in successfully at some point because I successfully use it to drive some Quartz job logic, so the placement of that config file is probably not the issue.
The answer is that I need to set SYSTEM PROPERTIES for ehcache to find. Using Grails configuration files such as myApplication-config.groovy is completely incorrect.
The CacheConfig.groovy file is correct, as is the XML it generates. So the question becomes, how do the properties it looks for get set correctly in the first place?
I am deploying to Tomcat. For Tomcat, setting system properties makes the most sense in a setenv.bat file (or setenv.sh on *nix).
I created setenv.bat, put the following into it
set CATALINA_OPTS=%CATALINA_OPTS% -DehcacheMulticastGroupAddress=230.0.0.1 -DehcacheMulticastGroupPort=4446 -DehcachePeerListenerPort=40001
...And it worked. Ehcache was able to find the system properties and start everything appropriately.
tl;dr: system properties != grails application config
When we run a sample main program which reads a applicationContext.xml with a single bean..
how does Spring do the logging..and how can one overwrite the default logging.
I didnt see any log4j.xml in the spring dependencies as well..
Regards
This is described in the documentation:
Logging is a very important dependency for Spring because a) it is the only mandatory external dependency, b) everyone likes to see some output from the tools they are using, and c) Spring integrates with lots of other tools all of which have also made a choice of logging dependency. One of the goals of an application developer is often to have unified logging configured in a central place for the whole application, including all external components. This is more difficult than it might have been since there are so many choices of logging framework.
The mandatory logging dependency in Spring is the Jakarta Commons Logging API (JCL). We compile against JCL and we also make JCL Log objects visible for classes that extend the Spring Framework. It's important to users that all versions of Spring use the same logging library: migration is easy because backwards compatibility is preserved even with applications that extend Spring. The way we do this is to make one of the modules in Spring depend explicitly on commons-logging (the canonical implementation of JCL), and then make all the other modules depend on that at compile time. If you are using Maven for example, and wondering where you picked up the dependency on commons-logging, then it is from Spring and specifically from the central module called spring-core.
The nice thing about commons-logging is that you don't need anything else to make your application work. It has a runtime discovery algorithm that looks for other logging frameworks in well known places on the classpath and uses one that it thinks is appropriate (or you can tell it which one if you need to). If nothing else is available you get pretty nice looking logs just from the JDK (java.util.logging or JUL for short). You should find that your Spring application works and logs happily to the console out of the box in most situations, and that's important.
(emphasis mine)
Follow several sections describing how to use various logging frameworks.