Skip to content

Commit

Permalink
Merge back test for 2023-09-20 release (#8563)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin-CB authored Oct 5, 2023
1 parent 270062a commit a51932f
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 184 deletions.
107 changes: 0 additions & 107 deletions test/src/test/java/hudson/PluginManagerSecurity3072Test.java

This file was deleted.

62 changes: 62 additions & 0 deletions test/src/test/java/hudson/PluginManagerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,43 @@ public void noInjectionOnAvailablePluginsPage() throws Exception {
}
}

@Test
@Issue("SECURITY-3072")
public void verifyUploadedPluginFromURLPermission() throws Exception {
assumeFalse(Functions.isWindows());

HtmlPage page = r.createWebClient().goTo("pluginManager/advanced");
HtmlForm f = page.getFormByName("uploadPlugin");
f.getInputByName("pluginUrl").setValue(Jenkins.get().getRootUrl() + "pluginManagerGetPlugin/htmlpublisher.jpi");
r.submit(f);

File filesRef = Files.createTempFile("tmp", ".tmp").toFile();
File filesTmpDir = filesRef.getParentFile();
filesRef.deleteOnExit();

final Set<PosixFilePermission>[] filesPermission = new Set[]{new HashSet<>()};
await().pollInterval(250, TimeUnit.MILLISECONDS)
.atMost(10, TimeUnit.SECONDS)
.until(() -> {
Optional<File> lastUploadedPluginDir = Arrays.stream(Objects.requireNonNull(
filesTmpDir.listFiles((file, fileName) ->
fileName.startsWith("uploadDir")))).
max(Comparator.comparingLong(File::lastModified));
if (lastUploadedPluginDir.isPresent()) {
filesPermission[0] = Files.getPosixFilePermissions(lastUploadedPluginDir.get().toPath(), LinkOption.NOFOLLOW_LINKS);
Optional<File> pluginFile = Arrays.stream(Objects.requireNonNull(
lastUploadedPluginDir.get().listFiles((file, fileName) ->
fileName.startsWith("uploaded")))).
max(Comparator.comparingLong(File::lastModified));
assertTrue(pluginFile.isPresent());
return true;
} else {
return false;
}
});
assertEquals(EnumSet.of(OWNER_EXECUTE, OWNER_READ, OWNER_WRITE), filesPermission[0]);
}

static class AlertHandlerImpl implements AlertHandler {
List<String> messages = Collections.synchronizedList(new ArrayList<>());

Expand Down Expand Up @@ -838,4 +875,29 @@ public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResp
}
}

@TestExtension("verifyUploadedPluginFromURLPermission")
public static final class Security3072JpiAction implements RootAction {

@Override
public String getIconFileName() {
return "gear2.png";
}

@Override
public String getDisplayName() {
return "URL to retrieve a plugin jpi";
}

@Override
public String getUrlName() {
return "pluginManagerGetPlugin";
}

public void doDynamic(StaplerRequest staplerRequest, StaplerResponse staplerResponse) throws ServletException, IOException {
staplerResponse.setContentType("application/octet-stream");
staplerResponse.setStatus(200);
staplerResponse.serveFile(staplerRequest, PluginManagerTest.class.getClassLoader().getResource("plugins/htmlpublisher.jpi"));
}
}

}
77 changes: 0 additions & 77 deletions test/src/test/java/jenkins/model/JenkinsSecurity3073Test.java

This file was deleted.

59 changes: 59 additions & 0 deletions test/src/test/java/jenkins/model/JenkinsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@

package jenkins.model;

import static java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE;
import static java.nio.file.attribute.PosixFilePermission.OWNER_READ;
import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContaining;
import static org.hamcrest.Matchers.containsString;
Expand All @@ -38,9 +42,11 @@
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeFalse;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import hudson.ExtensionList;
import hudson.Functions;
import hudson.XmlFile;
import hudson.init.InitMilestone;
import hudson.init.Initializer;
Expand All @@ -67,27 +73,40 @@
import hudson.util.FormValidation;
import hudson.util.HttpResponses;
import hudson.util.VersionNumber;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import jenkins.AgentProtocol;
import org.apache.commons.io.FileUtils;
import org.htmlunit.FailingHttpStatusCodeException;
import org.htmlunit.HttpMethod;
import org.htmlunit.Page;
import org.htmlunit.TextPage;
import org.htmlunit.WebRequest;
import org.htmlunit.WebResponse;
import org.htmlunit.html.HtmlForm;
import org.htmlunit.html.HtmlPage;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.JenkinsRule.WebClient;
Expand All @@ -110,6 +129,46 @@ public class JenkinsTest {

@Rule public JenkinsRule j = new JenkinsRule();

@Rule
public TemporaryFolder tmp = new TemporaryFolder();

@Test
@Issue("SECURITY-3073")
public void verifyUploadedFingerprintFilePermission() throws Exception {
assumeFalse(Functions.isWindows());

HtmlPage page = j.createWebClient().goTo("fingerprintCheck");
// The form doesn't have a name, the page contain the search form and the one we're interested in
HtmlForm form = page.getForms().get(1);
File dir = tmp.newFolder();
File plugin = new File(dir, "htmlpublisher.jpi");
// We're using a plugin to have a file above DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD
FileUtils.copyURLToFile(Objects.requireNonNull(getClass().getClassLoader().getResource("plugins/htmlpublisher.jpi")), plugin);
form.getInputByName("name").setValueAttribute(plugin.getAbsolutePath());
j.submit(form);

File filesRef = Files.createTempFile("tmp", ".tmp").toFile();
File filesTmpDir = filesRef.getParentFile();
filesRef.deleteOnExit();

final Set<PosixFilePermission>[] filesPermission = new Set[]{new HashSet<>()};
await().pollInterval(250, TimeUnit.MILLISECONDS)
.atMost(10, TimeUnit.SECONDS)
.until(() -> {
Optional<File> lastUploadedPlugin = Arrays.stream(Objects.requireNonNull(
filesTmpDir.listFiles((file, fileName) ->
fileName.startsWith("jenkins-multipart-uploads")))).
max(Comparator.comparingLong(File::lastModified));
if (lastUploadedPlugin.isPresent()) {
filesPermission[0] = Files.getPosixFilePermissions(lastUploadedPlugin.get().toPath(), LinkOption.NOFOLLOW_LINKS);
return true;
} else {
return false;
}
});
assertEquals(EnumSet.of(OWNER_EXECUTE, OWNER_READ, OWNER_WRITE), filesPermission[0]);
}

@Issue("SECURITY-406")
@Test
public void testUserCreationFromUrlForAdmins() throws Exception {
Expand Down

0 comments on commit a51932f

Please sign in to comment.