-
Notifications
You must be signed in to change notification settings - Fork 25k
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
Upgrade to OpenSAML 4.3.0 (shadowed) #98199
Upgrade to OpenSAML 4.3.0 (shadowed) #98199
Conversation
This commit upgrades to OpenSAML v4.3.0 Versions of OpenSAML ≥ 4.1 have a hard dependency on the non-FIPS release of BouncyCastle. This would prevent ES from being able to run in a JVM where BC-FIPS is configured as the security provider. In order to overcome this, we shadow OpenSAML and patch two classes to remove their dependency on BouncyCastle
@elasticsearchmachine run elasticsearch-ci/part-2 |
@tvernum This is your work passing CI 🎊 I'm going to try to reduce the surface of the changes by:
If all goes well there should be only one shadowed jar, which just removes the |
These changes effectively bypass the BC dependency. Tests do pass, but I'm not 100% that somehow, via some obscure protocal/parameter combination, our SAML SP and IDP implementations won't try to use functionality that has hence been eliminated.
|
@mark-vieira I think it is possible to put the |
Pinging @elastic/es-security (Team:Security) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I don't think we want to duplicate the property source. Sticking it in a library is probably the best way to go. It's still not clear to me that we need to repackage the dependency though.
manifest { | ||
attributes 'Automatic-Module-Name': 'org.opensaml.security' | ||
} | ||
exclude 'META-INF/services/org.opensaml.security.crypto.ec.NamedCurve' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this the only modification to this JAR we're making? Typically a "shadow" JAR is repackaging several dependencies, or relocating them under a different package, etc. Is this effectively identical to the original JAR, just excluding this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pretty much.
OpenSAML out of the box doesn't work on FIPS. My first attempt to solve it required patching 2 classes. Albert worked out that we can just avoid ever loading those classes by manipulating the set of services - one of them can be handled by stripping this service, the other by implementing our own properties resolver so that a default property can be changed.
It does seem like overkill to repackage just to drop one services
file, but I'm not aware of a simpler option.
We could just strip the file as part of the distribution, but I'm not a fan of shipping modified files JAR files that claim to be the originals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotcha, makes sense. I would suggest we go with the pattern we used for log4j though (look in libs/log4j/build.gradle
rather than use the Shadow plugin. It's not really the intended use case, and it's more complex than necessary for this, plus the log4j hack plays more nicely with IDEs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
++
The original attempt modified a couple of classes, so it was based on the approach we used for Jackson.
Now that we've settled on just stripping classes files, we can simplify it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mark-vieira I think it is possible to put the OpenSamlXpackSecurityConfigurationPropertiesSource service provider inside the shadowed jar, rather than put it in the ES code that uses the code that depends on the service. That's because the same code that uses the shadowed jar also uses the library code that depends on the service implementation.
But I'm not sure if this is better/preferable?
I think it's preferable to co-locate it with the shadowed jar. If for no other reason then it removes the existing duplication.
I've pushed 404298c and c179601 to incoporate the ConfigurationPropertiesSource
service implementation in the shadowed jar, in order to avoid having two identical such implementations in the x-pack/plugin/security
and x-pack/plugin/identity-provider
projects (it works because the same code that must not see the NamedCurve
implementations, also needs to see the new ConfigurationPropertiesSource
implementation). So now the shadowed jar effectively removes one service implementation and adds another different one (a single new class).
I think this is now a fair usage of the "shadow" plugin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When we say "pull in" what does that mean? Is it a transitive dependency or is it shadowed in the OpenSAML jar?
It is a runtime transitive dependency of OpenSAML (since version >4.1).
We manually manage transitive dependencies so we can use whatever bouncy castle jar we want, or omit it entirely.
We wish to omit it entirely because it contains crypto algorithms that are not FIPS compliant (there is a different bouncy castle with FIPS compliant algorithms), and that's a problem because we don't want the Elasticsearch FIPS distribution to ship with non-FIPS compliant crypto on the classpath (or really, no Elasticsearch distrib should have any crypto impl on the classpath. Instead we opt to delegate to the JCA API, where the JVM is configured for FIPS or not.).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, then I don't quite understand why we need this solution. We disable transitive dependencies by default in our build. The transitive BC jar shouldn't be brought in by this dependency. How does this relate to omitting that service file? From what I can tell that's part of the OpenSAML jar, not BC.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't put the BC on the classpath and we don't shadow jar the OpenSAML lib, then ES throws a class not found exception when it starts up, see this issue: #71983 .
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. So there is a runtime dependency on BC and stripping out that service avoids that issue. Understood.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, OpenSAML has had a transitive dependency on BouncyCastle for a while, but we've just avoided those parts.
In 4.1 the dependency become harder to avoid - a couple of classes that are eagerly loaded (with the the default services/properties config) have a direct dependency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
manifest { | ||
attributes 'Automatic-Module-Name': 'org.opensaml.security' | ||
} | ||
exclude 'META-INF/services/org.opensaml.security.crypto.ec.NamedCurve' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, OpenSAML has had a transitive dependency on BouncyCastle for a while, but we've just avoided those parts.
In 4.1 the dependency become harder to avoid - a couple of classes that are eagerly loaded (with the the default services/properties config) have a direct dependency.
@mark-vieira Do you want a chance to review this again before it's merged? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comment about re-enabling some of our precommit checks but otherwise LGTM.
compileOnly "org.opensaml:opensaml-core:${versions.opensaml}" | ||
} | ||
|
||
['jarHell', 'thirdPartyAudit', 'forbiddenApisMain', 'splitPackagesAudit', 'checkstyleMain', 'licenseHeaders', 'spotlessJavaCheck'].each { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can (and should) re-enable things like forbiddenApis, checkstyle and spotless here since this module actually has some code (albeit minimal) of its own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mark-vieira I see that forbiddenApisMain
fails with:
> Task :x-pack:libs:es-opensaml-security-api:forbiddenApisMain FAILED
> Task :libs:elasticsearch-core:compileJava
Note: Some input files use or override a deprecated API that is marked for removal.
Note: Recompile with -Xlint:removal for details.
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':x-pack:libs:es-opensaml-security-api:forbiddenApisMain'.
> Parsing signatures failed: Class 'org.apache.lucene.util.IOUtils' not found on classpath while parsing signature: org.apache.lucene.util.IOUtils
Is it a real problem? I suspect it's just the forbidden task itself missing a dependency classs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've only reenable checkstyle
and spotless
for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this looks to be because some of our forbidden api rules reference classes that aren't on the classpath here. We can disable this task here for now.
@tvernum @mark-vieira any objections to merging this post FF in 8.10? |
@elasticsearchmachine run elasticsearch-ci/example-plugins |
You can ignore the example-plugin build failures for now. |
None from me. It's the type of upgrade we would consider backporting to a 8.10.x patch release any way, in which case it would be acceptable to merge post FF (since FF only applies to non-patch features) |
This commit upgrades to OpenSAML v4.3.0 Versions of OpenSAML ≥ 4.1 have a hard dependency on the non-FIPS release of BouncyCastle. This would prevent ES from being able to run in a JVM where BC-FIPS is configured as the security provider. Closes: elastic#71983 Co-authored-by: Tim Vernum tim@adjective.org
This commit upgrades to OpenSAML v4.3.0 Versions of OpenSAML ≥ 4.1 have a hard dependency on the non-FIPS release of BouncyCastle. This would prevent ES from being able to run in a JVM where BC-FIPS is configured as the security provider. Backport of: #98199 Closes: #71983 Co-authored-by: Tim Vernum tim@adjective.org
apache.santuario.xmlsec version 2.1.4 is documented vulnerable. We should update to mitigate the vulnerabilities. But apache.santuario.xmlsec is a dependency of opensaml version 3.*. However, in a patch release of elasticsearch (i.e. 7.17.*) it's best we avoid updating dependencies across major versions (i.e. opensaml from version 3.* to version 4.*), particularly for such a complex dependency as opensaml (we did update the opensaml dep in this way, but in a minor elasticsearch 8.* release, i.e. #98199). The latest opensaml 3.* release (i.e. 3.4.6) still requires a vulnerable apache.santuario.xmlsec dep: https://mvnrepository.com/artifact/org.opensaml/opensaml-xmlsec-impl/3.4.6). In this case, our best hope is to find a non-vulnerable version of apache.santuario.xmlsec that is still on the same major version as the version listed in the deps of opensaml (i.e. 2.*). That's version 2.2.6: https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.2.6 , which is not vulnerable This PR updates apache.santuario.xmlsec from the existing 2.1.4 version to the 2.2.6 version. The release notes of the 2.2.0 version from https://santuario.apache.org/javareleasenotes.html look simple, and the dependencies differences (from https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.1.4) are minimal as well (hopefully optional dependencies, which we don't pull in, stay optional in the same way in the new version). So, it looks to me that the dep update is relatively safe (and it also passes CI)!
This commit upgrades to OpenSAML v4.3.0
Versions of OpenSAML ≥ 4.1 have a hard dependency on the non-FIPS release of BouncyCastle.
This would prevent ES from being able to run in a JVM where BC-FIPS is configured as the security provider.
Closes: #71983
Co-authored-by: Tim Vernum tim@adjective.org