Skip to content
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

[JENKINS-47736] Switch Remoting/XStream blacklist to a whitelist #3120

Merged
merged 54 commits into from
Jan 12, 2018

Conversation

jglick
Copy link
Member

@jglick jglick commented Oct 30, 2017

See JENKINS-47736 and JEP 200.

Downstream of jenkinsci/remoting#208.

Proposed changelog entries

@reviewbybees @jenkinsci/code-reviewers

@jglick jglick added the work-in-progress The PR is under active development, not ready to the final review label Oct 30, 2017
@jglick jglick changed the title [JENKINS-47736] Switch Remoting/XStream blacklist to a whitelist. [JENKINS-47736] Switch Remoting/XStream blacklist to a whitelist Oct 30, 2017
@jglick
Copy link
Member Author

jglick commented Nov 28, 2017

Seems to have had some snapshot confusion with jenkins-test-harness; will simplify by just cutting a release of that.

Copy link
Member

@jtnord jtnord left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems ok - some comments left inline

LOGGER.log(Level.FINE, "permitting {0} since it is an array", name);
return false;
}
if (Throwable.class.isAssignableFrom(c)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sure throwables used to be blocked? was there not a good reason to block them - has this changed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not recall any case of Throwables being (deliberately) blocked. In fact I recall some suggestion to allow org.codehaus.groovy.runtime.powerassert.PowerAssertionError and the like through despite their whole package subtree being in the standard blacklist.

I tried for a while to whitelist individual Throwables but found it completely impractical: every miscellaneous kind of exception that might get thrown in the course of a typical Remoting call wound up having to be added. I think this was in UserResponse, despite the existence of ProxyException, though it has been a while.

Also ErrorAction tries to directly record any Throwable terminating a Pipeline step, only using ProxyException for problematic classes.

In practice Throwables tend to just have a message and stack trace and be unlikely to be a vector for exploits. We can always continue to blacklist any individual class we suspect of being problematic.

});
}

private static final Pattern CLASSES_JAR = Pattern.compile("(file:/.+/)WEB-INF/lib/classes[.]jar");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: code conventions is static fields are declared before non static fields.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wanted to keep this close to its sole usage.

/**
* Determine whether a class should be permitted by {@link ClassFilter#isBlacklisted(Class)} of {@link ClassFilter#DEFAULT}.
* @param c the class
* @return true to permit it when it would normally be rejected (for example due to having a custom serialization method and being from a third-party library);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Boolean.TRUE not true. etc.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, sure, but autoboxing makes that pretty transparent anyway.

org.acegisecurity.userdetails.User
org.apache.commons.fileupload.disk.DiskFileItem
org.apache.commons.fileupload.util.FileItemHeadersImpl
org.eclipse.jgit.lib.ObjectId
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this defined here and not in the git-client plugin?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be, of course; ditto a few others classes coming from job-dsl, maven-plugin, and workflow-support. Logistically I just wanted to make sure I was producing a jenkins.war that did not introduce regressions to popular plugins, without requiring people to apply recent plugin updates. TBD.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My proposal would be to exclude whitelist to a plugin and to mark it as a detached one. In such case we will be able to quickly deliver patches to whitelists if something goes south.... If XStream manages to startup from config.xml... So I am +1 for keeping what we have here

@@ -148,15 +148,15 @@ private String jsonRequest(JenkinsRule.WebClient wc, String path) throws Excepti

private static final class CustomUpdateSite extends UpdateSite {

private final TemporaryFolder tmpdir;
private final File tmpdir;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where does this now get cleaned up?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The @Rule at the top of the class.

@Test
public void whitelistSanity() throws Exception {
try (InputStream is = ClassFilterImpl.class.getResourceAsStream("whitelisted-classes.txt")) {
List<String> lines = IOUtils.readLines(is);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readLines(InputStream) uses the platform default charset and not UTF-8. so this test will be platform dependant

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, will fix.

try {
Class.forName(line);
} catch (ClassNotFoundException x) {
System.err.println("skipping checks of unknown class " + line);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code seems to be just wasting cycles - please add an assert if you expect all classes to be covered, or move this outside of a test (if you want to manually check)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole test case takes about 1s, and this line helps identify classes contributed by plugins (as in discussion above).

@@ -254,6 +254,7 @@ public void checkRoles(RoleChecker checker) throws SecurityException {
}
});
} catch (Exception ex) {
ex.printStackTrace();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like this will dump out stack traces even for a successful test (which is bad) as stack traces for OK tests look scary when running and set of triggers in human brains.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally agree. In this case it is a security test and if you are running it interactively (i.e., -Dtest=…) you should be aware that an exception is wanted here. I specifically added this line because I had trouble diagnosing a problem in the test previously, and this made things much clearer.

jglick added a commit to jglick/jenkins that referenced this pull request Dec 5, 2017
…e for purposes of whitelisting.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <manifestEntries>
        <Jenkins-ClassFilter-Whitelisted>true</Jenkins-ClassFilter-Whitelisted>
      </manifestEntries>
    </archive>
  </configuration>
</plugin>
Copy link
Member

@oleg-nenashev oleg-nenashev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I'd guess that's it for this weekly

@@ -76,6 +80,11 @@ public static void register() {
return;
}
ClassFilter.setDefault(new ClassFilterImpl());
if (SUPPRESS_ALL) {
LOGGER.warning("All class filtering suppressed. Your Jenkins installation is at risk from known attacks. See https://jenkins.io/redirect/class-filter/");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That blog post does not describe the blacklist concerns, but we can update the link later

@jglick jglick added ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback and removed needs-more-reviews Complex change, which would benefit from more eyes labels Jan 12, 2018
@jglick jglick merged commit 47be7c3 into jenkinsci:master Jan 12, 2018
@jglick jglick deleted the whitelist-JENKINS-47736 branch January 12, 2018 22:41
@allxiao
Copy link

allxiao commented Jan 15, 2018

Thanks @oleg-nenashev for mentioning us.
It looks some of the Azure plugins are affected. We're working on the migration.

To confirm, the blacklist/whitelist only applies to the following scenarios:

  1. objects that is serialized to XML using XStream(2), such as the build configuration
  2. objects returned by a Callable in a slave invocation

Right?

@oleg-nenashev
Copy link
Member

oleg-nenashev commented Jan 15, 2018

@ArieShout Yes, it's correct. You can find some guidelines here: https://jenkins.io/blog/2018/01/13/jep-200/#for-plugin-developers and https://groups.google.com/forum/#!topic/jenkinsci-dev/We-14-z_YXU. Let me know if you need any other info, we will get the guidelines extended.

@oleg-nenashev
Copy link
Member

Sorry, correct DEV ML link: https://groups.google.com/forum/#!topic/jenkinsci-dev/EALjDtS4riU

@allxiao
Copy link

allxiao commented Jan 16, 2018

We have applied the fix to the Azure plugins (azure-vm-agents specifically) and will cut new release soon.

It seems the org.jvnet.localizer.Localizable is already in the whitelist, so we're done on our side.

Thanks,

oleg-nenashev pushed a commit that referenced this pull request Feb 6, 2018
* Slave.JnlpJar.getURL did not work in some modes when core had a snapshot dependency on Remoting.

* Starting to implement Channel.Listener.read/write.

* Now obtaining response timing statistics.

* For now, avoiding timestamped snapshots, as it caused problems for #3120 which I have asked for help from @stephenc diagnosing.

* Simplified logging a bit.

* onResponse

* hudson.FilePath$Mkdirs is a lot more readable than hudson.FilePath$13.

* Specific snapshot.

* onJar

* LoggingChannelListener

* remoting.version=3.17

* Making a few test assertions more lenient to adapt to jenkinsci/remoting#247.
java.lang.reflect.Proxy
java.net.URI
java.net.URL
java.security.KeyRep
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jglick Do you remember what the use case for commit e876849 was? I'm wondering if we need to be worried about XStream trying to serialize/deserialize these types on Java 17, where it would probably fail because we haven't opened those modules.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you remember what the use case for commit e876849 was?

Sorry, no. Probably there was a test failure somewhere, in which case there is no need to worry (it would show up if this is really a problem on 17).

XStream trying to serialize/deserialize these types

More likely in Remoting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-for-merge The PR is ready to go, and it will be merged soon if there is no negative feedback
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants