This message was deleted.
# caching
s
This message was deleted.
c
A couple of points: • the nasty Log4J RCE vulnerability was in Log4j2, a separate code base from Log4. 1.x, which is what is being blocked here; what should be blocked is versions of log4j2-core from 2.0 thru 2.17.1. • It appears that the “compliance tooling” is removing the file; this will wreak havoc on solutions, such as Gradle, that expect written files to, well, be there… Nothing here that appears to be a Gradle issue/bug. Suggest working with your security folks on this.
to prevent vulnerable versions of log4j2 from leaking into code the following can be used:
Copy code
// <https://blog.gradle.org/log4j-vulnerability>
// force log4j2 to be 2.17 or higher to avoid vulnerabilities in 2.x thru 2.17.2

// for the script itself, e.g. plugins
buildscript {
    dependencies {
        constraints {
            // ensure we don't pull in a vulnerable version of log4j2
            "classpath"("org.apache.logging.log4j:log4j-core") {
                version {
                    strictly("[2.17.2,3[")
                    prefer("2.17.2")
                }
                because("CVE-2021-44228: Log4j vulnerable to remote code execution")
            }
        }
    }
}


// for any dependencies (incl. transitive) 
dependencies {
    plugins.withType<JavaPlugin> {
        constraints {
            // ensure we don't pull in a vulnerable version of log4j2
            implementation("org.apache.logging.log4j:log4j-core") {
                version {
                    strictly("[2.17.2,3[")
                    prefer("2.17.2")
                }
                because("CVE-2021-44228: Log4j vulnerable to remote code execution")
            }
        }
    }
}
a
We aren't having an issue with the vulnerable jar being used in our build. We don't even use log4J. The problem is the vulnerable Jar being pulled down with the gradle source, then the compliance tool is quarantining it, and gradle is failing to index.
We are working with our security team to get an exception, but I think in the long run gradle should update this log4J jar with one that is not subject to the vulnerability. Again - the file is located here in the gradle github source: https://github.com/gradle/gradle/blob/master/subprojects/docs/src/snippets/antMigration/fileDeps/kotlin/libs/log4j-1.2.8.jar
c
It’s not subject to that vulnerability. Your compliance tool is quarantining the wrong log4j version. Hence it’s unlikely that Gradle will change this, at least not for this erroneous reason.
a
Hmm.. I see this statement:
Copy code
Log4j 1.x has reached End of Life in 2015 and is no longer supported. Vulnerabilities reported after August 2015 against Log4j 1.x were not checked and will not be fixed. Users should upgrade to Log4j 2 to obtain security fixes.
It does appear that they have blocked all of log4j 1.x due to that.
What I don't understand is why is intellij downloading the gradle source and indexing it? I specifically asked for the binary distribution
And I don't get this error on the command line, can't find any options or configurations to make intellij stop doing that
Also it does appear there are CVE's related to log4J 1.2
c
it’s likely they’ve blocked it erroneously due to wide-spread misunderstanding of the log4j2 vulnerability. In any event, let’s see what can be done to sidestep that. IntelliJ does prompt to download Gradle source to allow click-through, auto-complete, etc - let me see if there’s any settings there…
c
this is the Very Dangerous one in log4j2: https://nvd.nist.gov/vuln/detail/CVE-2021-44228
those others are much lower severity / risk.
…and only in very specific, non-default configurations.
a
I agree with you, but my IT people probably wont.
c
agree or not, those are the facts. anyhow, back to IntelliJ - checking to see about downloading gradle sources, one sec…
This error:
Copy code
org.gradle.internal.execution.OutputSnapshotter$OutputFileSnapshottingException: Cannot snapshot output property 'outputDirectory'.
java.io.UncheckedIOException: Failed to create MD5 hash for file '/Users/spence/.gradle/caches/transforms-3/b857c89a93e3ad26d7a3a2df48b5cb23/transformed/unzipped-distribution/gradle-7.5.1/subprojects/docs/src/snippets/antMigration/fileDeps/kotlin/libs/log4j-1.2.8.jar' as it does not exist.
…when does that happen? When syncing the project w/ IntelliJ, or executing a Gradle task (if so, which one)?
a
when syncing
c
ok. there’s an issue here about a similar issue (not quite the same directory) with IntelliJ, though its marked as fixed.
a
Yep, that is the exception I'm seeing
project.logger.warn("Unexpected exception while resolving Gradle distribution sources: ${ex.message}", ex)
Though - its not coming through as a warning
c
hmmm. yea. looking at that code it should warn and eat the exception, which doesn’t appear to be the case. perhaps it’s outdated code, checking that.
could you paste the whole log output - warning, exception?
a
Copy code
> Task :prepareKotlinBuildScriptModel UP-TO-DATE
Download <https://services.gradle.org/distributions/gradle-7.5.1-src.zip>, took 938 ms (44.75 MB)
Unexpected exception while resolving Gradle distribution sources: A build operation failed.
    Cannot snapshot output property 'outputDirectory'.
org.gradle.internal.operations.MultipleBuildOperationFailures: A build operation failed.
    Cannot snapshot output property 'outputDirectory'
c
ah. that’s the warning. and then the “Cannot snapshot” message - presumably that is failing the sync?
a
Ultimately failing here I think:
Copy code
java.io.UncheckedIOException: Failed to create MD5 hash for file '/Users/spence/.gradle/caches/transforms-3/b857c89a93e3ad26d7a3a2df48b5cb23/transformed/unzipped-distribution/gradle-7.5.1/subprojects/docs/src/snippets/antMigration/fileDeps/kotlin/libs/log4j-1.2.8.jar' as it does not exist.
c
or this one where permission to access the file is denied. either way it cannot access a file it expects/needs to.
Copy code
Caused by: java.io.FileNotFoundException: /Users/spence/.gradle/caches/transforms-3/b857c89a93e3ad26d7a3a2df48b5cb23/transformed/unzipped-distribution/gradle-7.5.1/subprojects/docs/src/snippets/antMigration/fileDeps/kotlin/libs/log4j-1.2.8.jar (Operation not permitted)
	at java.base/java.io.FileInputStream.open0(Native Method)
	at java.base/java.io.FileInputStream.open(FileInputStream.java:216)
	at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
	at org.gradle.internal.hash.DefaultFileHasher.hash(DefaultFileHasher.java:36)
	... 245 more
a
Yeah - not sure how it Quarantines the file.. I can see it in the FS and delete it, but gradle can't open it
c
yea. it’s probably a FS driver / kernel hook that is denying access to the file.
trying to figure out what Gradle task is tripping into this.
v
Shouldn't be a Gradle task, but requesting build script class paths via tooling API when using Kotlin DSL build scripts, iirc.
c
agreed. Looks to be in org.gradle.kotlin.dsl.resolver.SourceDistributionResolver
huh. @Alex Spence - all that output is from the warning message. Following the code it eats the exception:
Copy code
override fun sourceDirs(): Collection<File> =
        try {
            sourceDirs
        } catch (ex: Exception) {
            project.logger.warn("Unexpected exception while resolving Gradle distribution sources: ${ex.message}", ex)
            emptyList()
        }
The log shows BUILD SUCCESSFUL. Is there actually a problem here?
a
That is interesting.. It may actually work, but every time I rebuild or refresh gradle it redownloads and indexes everything all over again
c
yea, the full code is below - it’s not getting all the way through downloading/processing before the failure, hence the repeat.
Copy code
override fun sourceDirs(): Collection<File> =
        try {
            sourceDirs
        } catch (ex: Exception) {
            project.logger.warn("Unexpected exception while resolving Gradle distribution sources: ${ex.message}", ex)
            emptyList()
        }

    private
    val sourceDirs by lazy {
        createSourceRepository()
        registerTransforms()
        transientConfigurationForSourcesDownload().files
    }
a
so the workaround is to let it download and re-index all the time
c
yea. not seeing anything else we can tweak here.
a
And I get to ask gradle / IT really nicely to give me a real solution
and it looks like the gradles repo is hardcoded
Copy code
setUrl("<https://services.gradle.org/$repoName>")
Was thinking maybe I could host my own version of the distribution
c
you can. I’m doing that.
a
We did try to override it in the wrapper properties but that didn't work
It will use the overridden binary distribution, but then go download the src SDK from gradle
c
it should work if you use the
-all
distribution which includes the sources, hence no need for a further download.
a
Ah
so specify a distribution with -all and it will use that instead of downloading?
c
if you use ’-bin` (the default), the IDE looks to then download & index the sources for IDE reasons. With
-all
the sources are included.
a
ok I will try that
v
Yes, but will probably only work with your own where your throw out the docu snippets
a
Right
Its not ideal but better than re-indexing every time I need to refresh something
c
from my setup with a custom Gradle 7.5.1 distribution - no expanded source distribution to be found.
Copy code
➜  ~ find ~/.gradle/caches/transforms-3 -name 'log4j*'
➜  ~
a
can you default the wrapper to use that distro?
can probably set it globally in intellij
c
yes. change the distribution url to the ‘-all’ version. you don’t need a custom distribution here, just the src-included one.
v
Don't you think the compliance tool will also interfere there?
a
not if I delete the snippets from the zip
v
That's why I assume a custom distro without the snippets is necessary
a
oh
c
don’t think you need to do anything extra here. If the source isn’t available, IntelliJ downloads, expands and indexes that (this is the Bad Path). If the source is available (in the distribution) it seems to work.
…as that JAR is embedded somewhere (it isn’t directly visible in the filesystem).
v
If there wrapper downloading the distribution is not also disturbed, but well, just try it
If course it is visible in the file system
c
Copy code
➜  ~ find ~/.gradle/wrapper -name 'log4j-1*'
➜  ~
Nope.
v
The distro is downloaded and then unzipped
Hm, ok
c
yes, but that JAR either isn’t included, or is further embedded somewhere.
v
Interesting that it is different
Btw., about "agree or not, those are the facts.". While log4j1 is not vulnerable to log4shell, it still suffers from several other vulnerabilities. I don't find the quote right now, but even the main log4j maintainer said something like "if you think your safe when using log4j1, you couldn't be more wrong" or something like that.
c
it’s perhaps a transient dependency for the transformation stuff (it’s the transforms-3 cache folder)
definitely applies to vulnerable log4j2 versions, that was nasty, any user input that was logged can be turned into a remote code execution (easily). Same issue isn’t present in log4j1.
a
Yeah - the -all version of the distro is different
doesn't seem to have the snippets
still indexing things, but I don't see the log4j files in there
Yep 100% sucessful
👌 1
awesome
Thanks!!!
c
whooo!!
v
definitely applies to vulnerable log4j2 versions, that was nasty, any user input that was logged can be turned into a remote code execution (easily). Same issue isn’t present in log4j1.
Yes, that's what I said above. Log4j1 is not vulnerable to log4shell. But it has several other vulnerabilities and even the log4j main maintainer says you are doomed if you use it.
So any compliance tool forbidding it is not acting wrongly, but perfectly correct
c
perhaps. but a bit heavy-handed to blindly quarantine files - that extreme action should be reserved for critical vulnerabilities. Otherwise it’s inventory/report/remediate.
a
if intelliJ or whatever would have just downloaded the all version of the distro instead of src, this would be avoided
v
Well, everyone has different views on what is critical and what should be handled how. :-)
a
That may be actionable
c
well, there are CVE ratings for these. Tend to find this is done blindly, without context - not so much a matter of “different views” but naive, uninformed security posture.
v
But that would download much too much. The question is more why the snippets are in source, but not in all.
a
all seems to be much smaller than src
c
all includes src.
there’s only two distributions - binary and all.
a
ah
v
What your call naive, others call careful. :-D
a
but it doesn't have the docs
c
it’s possible to be “careful” by taking an informed approach, not a lazy “well, it has some random vulnerability, let’s just block it without regard to the impact on the business”. That’s naieve and irresponsible, and unfortunately happens more often than not.
all has the docs as well.
that
that’s the expanded -all.
a
Yeah - things aren't in the same place
v
Do you know the developers of that compliance tool? I mean because you seem to know exactly what their thoughts and decisions were to quarantine log4j1.
a
so all is some curated version of the source
c
Do you know the developers of that compliance tool? I mean because you seem to know exactly what their thoughts and decisions were to quarantine log4j1.
As I noted earlier, it is likely this is a corporate configuration that erroneously confuses log4j1 with log4jshell.
a
and the one downloaded by the IDE, -src.zip seems to be more of a snapshot of the git repo
v
No, that's just wild guessing. I also know several companies that have decided to get rid of log4j1 independent of log4shell because it is old and vulnerable
c
@Alex Spence what are the src snippets that are neeed?
v
Anyway, off to bed now, it's 4am, cu
c
No, that’s just wild guessing. I also know several companies that have decided to get rid of log4j1 independent of log4shell because it is old and vulnerable
lol. No guessing, unfortunantely and sadly. I’ve has CSO roles for large orgs and witnessed this at scale.
ttyl.
v
Of course this can happen, but both can be true and happens in the wild. And you cannot know which situation it is here.
c
that is true, it is indeed speculation.
👌 1
a
Company is newly public, IT ramped up real fast to get compliance going
my guess would be a third party supplying the list, but I will leave that to them now that we have a workaround that isn't going to block our whole dev org.
👌 1
I don't know to answer your question @Chris Lee - IntelliJ seems to be satisfied with the all distro, and it doesn't have the log4J file so I'm all good now.
Thanks again both for your help!
👌 1
c
good stuff. it’s what I’ve been using for quite a while, not aware of missing anything. Glad this worked out.