There is a newer version of the announcement for Jenkins administrators. Please see this blogpost. |
Overview
JEP-200 has been integrated into Jenkins weekly builds and (if all goes well) will be a part of the next LTS line. In a nutshell, this change is a security hardening measure to be less permissive about deserializing Java classes defined in the Java Platform or libraries bundled with Jenkins. For several years now, Jenkins has specifically blacklisted certain classes and packages according to known or suspected exploits; now it will reject all classes not explicitly mentioned in a whitelist, or defined in Jenkins core or plugins.
For Jenkins administrators
Before upgrade
Back up your Jenkins instance prior to upgrade so you have any easy way of rolling back. If you are running any of the plugins listed inPlugins affected by fix for JEP-200, update them after taking the backup but before upgrading Jenkins core.
If you have a way of testing the upgrade in an isolated environment before applying it to production, do so now.
Using backups and a staging server is good advice before any upgrade but especially this one, with a relatively high risk of regression.
After upgrade
To the extent that advance testing of the impact of this change on popular plugins has been completed,
most users (and even plugin developers) should not notice any difference.
If you do encounter a java.lang.SecurityException: Rejected: some.pkg.and.ClassName
in the Jenkins UI or logs,
you may have found a case where an unusual plugin, or an unusual usage mode of a common plugin,
violates the existing whitelist.
This will be visible in the Jenkins system log as a message from jenkins.security.ClassFilterImpl
like the following:
some.pkg.and.ClassName in file:/var/lib/jenkins/plugins/some-plugin-name/WEB-INF/lib/some-library-1.2.jar might be dangerous, so rejecting; see https://jenkins.io/redirect/class-filter/
where the link would direct you here.
If you find such a case, please report it in the Jenkins issue tracker, under the appropriate plugin component.
Link it to JENKINS-47736 and add the JEP-200
label.
If at all possible, include complete steps to reproduce the problem from scratch.
Jenkins developers will strive to evaluate the reason for the violation and offer a fix in the form of a core and/or plugin update.
For more details and current status, seePlugins affected by fix for JEP-200.
Assuming you see no particular reason to think that the class in question has dangerous deserialization semantics, which is rare, it is possible to work around the problem in your own installation as a temporary expedient. Simply make note of any class name(s) mentioned in such log messages, and run Jenkins with this startup option (details will depend on your installation method):
-Dhudson.remoting.ClassFilter=some.pkg.and.ClassName,some.pkg.and.OtherClassName
For plugin developers
Testing plugins against Jenkins 2.102 and above
As a plugin developer encountering this kind of error,
your first task is to ensure that it is reproducible in a functional (JenkinsRule
) test
when running Jenkins 2.102 or newer to reproduce the error.
mvn test -Djenkins.version=2.102 -Denforcer.skip=true
The above assumes you are using a recent 2.x or 3.x parent Plugin POM. For certain cases you may need to use Plugin Compat Tester (PCT) to run tests against Jenkins core versions newer than your baseline.
Running PCT against the latest Jenkins core:
java -jar pct-cli.jar -reportFile $(pwd)/out/pct-report.xml \
-workDirectory $(pwd)/work -skipTestCache true -mvn $(which mvn) \
-includePlugins ${ARTIFACT_ID} -localCheckoutDir ${YOUR_PLUGIN_REPO}
You may need to run tests using an agent (e.g., JenkinsRule.createSlave
) or force saves of plugin settings.
For maven plugins you can also specify custom Jenkins versions in Jenkinsfile
to run tests against JEP-200:
buildPlugin(jenkinsVersions: [null, '2.102'])
(again picking whatever version you need to test against) so that the test is included during CI builds, even while your minimum core baseline predates JEP-200.
If your plugins are built with Gradle, your mileage may vary.
Making plugins compatible with Jenkins 2.102 or above
If you discover a compatibility issue in your plugin, you then have several choices for fixing the problem:
Ideally, simplify your code so that the mentioned class is not deserialized via Jenkins Remoting or XStream to begin with:
If the problem occurred when receiving a response from an agent, change your
Callable
(orFileCallable
) to return a plainer type.If the problem occurred when saving an XML file (such as a
config.xml
orbuild.xml
), use a plainer type in non-transient
fields in your persistable plugin classes.
If the class(es) are defined in the Java Platform or some library bundled in Jenkins core, propose a pull request adding it to
core/src/main/resources/jenkins/security/whitelisted-classes.txt
injenkinsci/jenkins
.If the class(es) are defined in a third-party library bundled in your plugin, create a resource file
META-INF/hudson.remoting.ClassFilter
listing them. (example)You may also do this for Java or Jenkins core library classes, as a hotfix until your core baseline includes the whitelist entry proposed above.
If the class(es) are defined in a JAR you build and then bundle in your plugin’s
*.jpi
, add aJenkins-ClassFilter-Whitelisted: true
manifest entry. This whitelists every class in the JAR. (example)