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

Backporting 2.462.3 LTS #9733

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,9 @@ protected void execute(TaskListener listener) throws IOException, InterruptedExc
}

public static void processJob(TaskListener listener, Job job) {
listener.getLogger().println("Processing " + job.getFullName());
GlobalBuildDiscarderConfiguration.get().getConfiguredBuildDiscarders().forEach(strategy -> {
String displayName = strategy.getDescriptor().getDisplayName();
listener.getLogger().println("Offering " + job.getFullName() + " to " + displayName);
if (strategy.isApplicable(job)) {
listener.getLogger().println(job.getFullName() + " accepted by " + displayName);
try {
strategy.apply(job);
} catch (Exception ex) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ public Object getDynamic(String id, StaplerRequest req, StaplerResponse rsp) thr
return null;
}

if (!ACL.isAnonymous2(Jenkins.getAuthentication2())) {
if (!ALLOW_AUTHENTICATED_USER && !ACL.isAnonymous2(Jenkins.getAuthentication2())) {
rsp.sendError(400);
return null;
}
Expand Down Expand Up @@ -327,4 +327,8 @@ private static Token decode(String value) {
// Not @Restricted because the entire class is
@SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console")
public static /* not final for Groovy */ int VALID_FOR_MINUTES = SystemProperties.getInteger(ResourceDomainRootAction.class.getName() + ".validForMinutes", 30);

/* Escape hatch for a security hardening preventing one of the known ways to elevate arbitrary file read to RCE */
@SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "for script console")
public static /* not final for Groovy */ boolean ALLOW_AUTHENTICATED_USER = SystemProperties.getBoolean(ResourceDomainRootAction.class.getName() + ".allowAuthenticatedUser", false);
}
10 changes: 9 additions & 1 deletion test/src/test/java/jenkins/security/ResourceDomainTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ public HttpResponse doDynamic() throws Exception {
}

@Test
public void authenticatedCannotAccessResourceDomain() throws Exception {
public void authenticatedCannotAccessResourceDomainUnlessAllowedBySystemProperty() throws Exception {
j.jenkins.setSecurityRealm(j.createDummySecurityRealm());
final MockAuthorizationStrategy authorizationStrategy = new MockAuthorizationStrategy();
authorizationStrategy.grant(Jenkins.ADMINISTER).everywhere().to("admin").grant(Jenkins.READ).everywhere().toEveryone();
Expand All @@ -416,5 +416,13 @@ public void authenticatedCannotAccessResourceDomain() throws Exception {
try (JenkinsRule.WebClient wc = j.createWebClient().withBasicCredentials("admin")) {
assertThat(assertThrows(FailingHttpStatusCodeException.class, () -> wc.getPage(new URL(resourceUrl))).getStatusCode(), is(400));
}

ResourceDomainRootAction.ALLOW_AUTHENTICATED_USER = true;
try (JenkinsRule.WebClient wc = j.createWebClient().withBasicApiToken("admin")) {
assertThat(wc.getPage(new URL(resourceUrl)).getWebResponse().getStatusCode(), is(200));
}
try (JenkinsRule.WebClient wc = j.createWebClient().withBasicCredentials("admin")) {
assertThat(wc.getPage(new URL(resourceUrl)).getWebResponse().getStatusCode(), is(200));
}
}
}
13 changes: 8 additions & 5 deletions war/src/main/scss/components/_row-selection-controller.scss
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@

.jenkins-table__checkbox-options {
height: 1.375rem;
min-height: unset;
padding: 0 0.2rem;
margin-left: 0.2rem;
min-height: unset !important;
padding: 0 0.2rem !important;
margin: 0 0 0 0.2rem !important;
border-radius: 6px;

svg {
width: 0.9rem;
height: 0.9rem;
max-width: 0.9rem;
max-height: 0.9rem;
pointer-events: none;
color: var(--input-border);
transition: var(--standard-transition);
Expand Down Expand Up @@ -185,6 +185,9 @@
justify-content: flex-start;
gap: 0.75rem;
border-radius: 10px;
margin: 0 !important;
padding: 0.5rem 0.9rem !important;
min-height: 2.25rem !important;
}

&--visible {
Expand Down
Loading