Skip to content

Commit

Permalink
[SECURITY-3226][SECURITY-3239][SECURITY-3244]
Browse files Browse the repository at this point in the history
  • Loading branch information
TWestling authored and yaroslavafenkin committed Sep 13, 2023
1 parent 02ae0a4 commit a261229
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/
package com.sonyericsson.jenkins.plugins.bfa;

import hudson.Functions;
import java.io.Serializable;

/**
Expand All @@ -43,7 +44,9 @@ public class AnnotationHelper implements Serializable {
*/
public String getBefore() {
if (!title.isEmpty()) {
return before + "<span style=\"color:white;background:red\" title=\"" + title + "\">";
return before
+ "<span style=\"color:white;background:red\" title=\""
+ Functions.htmlAttributeEscape(title) + "\">";
} else {
return before;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.kohsuke.stapler.Stapler;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.verb.POST;
import java.io.IOException;

/**
Expand Down Expand Up @@ -220,6 +221,7 @@ public FailureCause getDynamic(String id, StaplerRequest request, StaplerRespons
* @param response the stapler response.
* @throws IOException if so during redirect.
*/
@POST
public void doRemoveConfirm(@QueryParameter String id, StaplerRequest request, StaplerResponse response)
throws IOException {
Jenkins.getInstance().checkPermission(PluginImpl.REMOVE_PERMISSION);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.verb.POST;
import org.mongojack.JacksonMongoCollection;
import org.mongojack.internal.MongoJackModule;

Expand Down Expand Up @@ -868,6 +869,7 @@ public FormValidation doCheckDbName(@QueryParameter("value") String value) {
* @return {@link FormValidation#ok() } if can be done,
* {@link FormValidation#error(java.lang.String) } otherwise.
*/
@POST
public FormValidation doTestConnection(
@QueryParameter("host") final String host,
@QueryParameter("port") final int port,
Expand All @@ -876,6 +878,7 @@ public FormValidation doTestConnection(
@QueryParameter("password") final String password,
@QueryParameter("tls") final boolean tls,
@QueryParameter("retrywrites") final boolean retryWrites) {
Jenkins.getInstance().checkPermission(Jenkins.ADMINISTER);
MongoDBKnowledgeBase base = new MongoDBKnowledgeBase(host, port, dbName, userName,
Secret.fromString(password), false, false);
base.setTls(tls);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package com.sonyericsson.jenkins.plugins.bfa;

import jenkins.model.Jenkins;
import org.htmlunit.FailingHttpStatusCodeException;
import org.htmlunit.HttpMethod;
import org.htmlunit.WebRequest;
import org.htmlunit.html.HtmlPage;
import hudson.model.Hudson;
import hudson.security.GlobalMatrixAuthorizationStrategy;
import hudson.security.SecurityRealm;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;

import javax.servlet.http.HttpServletResponse;

import java.net.URL;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
Expand All @@ -24,6 +30,10 @@
*/
public class CauseManagementPermissionTest {

private static final int EXPECTED_HTTP_NOT_FOUND_RESPONSE_CODE = 404;
private static final int EXPECTED_HTTP_FORBIDDEN_RESPONSE_CODE = 403;
private static final int EXPECTED_HTTP_SUCCESS_RESPONSE_CODE = 200;

/**
* The Jenkins Rule.
*/
Expand All @@ -44,8 +54,11 @@ public void jenkinsConfiguration() {
authorizationStrategy.add(Hudson.READ, "anonymous");
authorizationStrategy.add(PluginImpl.VIEW_PERMISSION, "view");
authorizationStrategy.add(PluginImpl.UPDATE_PERMISSION, "update");
authorizationStrategy.add(PluginImpl.REMOVE_PERMISSION, "remove");
authorizationStrategy.add(PluginImpl.VIEW_PERMISSION, "all");
authorizationStrategy.add(PluginImpl.UPDATE_PERMISSION, "all");
authorizationStrategy.add(PluginImpl.REMOVE_PERMISSION, "all");
authorizationStrategy.add(Jenkins.ADMINISTER, "admin");
j.getInstance().setAuthorizationStrategy(authorizationStrategy);
}

Expand Down Expand Up @@ -128,4 +141,54 @@ public void allowedToUpdateCausesWhenGrantedBothUpdateAndView() throws Exception
// Checks the "Create New" button is available
assertNotNull(page.getFirstByXPath("//a[.='Create new']"));
}

/**
* Tests that removeConfirm only can be used with POST, and responds with 404 otherwise.
*
* @throws java.lang.Exception If Jenkins cannot be accessed
*/
@Issue("SECURITY-3239")
@Test
public void testDoRemoveConfirmRequiresPost() throws Exception {
JenkinsRule.WebClient webClient = j.createWebClient().withThrowExceptionOnFailingStatusCode(false);
webClient.login("all");
assertEquals(
EXPECTED_HTTP_NOT_FOUND_RESPONSE_CODE,
webClient.goTo("failure-cause-management/removeConfirm").getWebResponse().getStatusCode());
WebRequest webRequest = new WebRequest(
new URL(j.jenkins.getRootUrl().toString() + "/failure-cause-management/removeConfirm"),
HttpMethod.POST);
webRequest = webClient.addCrumb(webRequest);
assertEquals(
EXPECTED_HTTP_SUCCESS_RESPONSE_CODE,
webClient.getPage(webRequest).getWebResponse().getStatusCode());
}

/**
* Test that testing mongo connection can only be accessed through a POST request from an admin.
*
* @throws Exception if Jenkins cannot be accessed
*/
@Issue("SECURITY-3226")
@Test
public void testTestMongoDBConnection() throws Exception {
JenkinsRule.WebClient webClient = j.createWebClient().withThrowExceptionOnFailingStatusCode(false);
String testUrl = "descriptorByName/com.sonyericsson.jenkins.plugins.bfa.db.MongoDBKnowledgeBase/"
+ "testConnection?port=9876&host=localhost&&dbName=Whatever\n";
assertEquals(
EXPECTED_HTTP_NOT_FOUND_RESPONSE_CODE,
webClient.goTo(testUrl).getWebResponse().getStatusCode());
webClient.login("all");
WebRequest webRequest = new WebRequest(
new URL(j.jenkins.getRootUrl().toString() + testUrl),
HttpMethod.POST);
webRequest = webClient.addCrumb(webRequest);
assertEquals(
EXPECTED_HTTP_FORBIDDEN_RESPONSE_CODE,
webClient.getPage(webRequest).getWebResponse().getStatusCode());
webClient.login("admin");
assertEquals(
EXPECTED_HTTP_SUCCESS_RESPONSE_CODE,
webClient.getPage(webRequest).getWebResponse().getStatusCode());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.sonyericsson.jenkins.plugins.bfa;

import static org.junit.Assert.assertTrue;

import com.sonyericsson.jenkins.plugins.bfa.model.FailureCause;
import com.sonyericsson.jenkins.plugins.bfa.model.FoundFailureCause;
import com.sonyericsson.jenkins.plugins.bfa.model.indication.FoundIndication;
import hudson.MarkupText;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import java.util.ArrayList;
import java.util.List;

/**
* Tests for the IndicationAnnotator.
*
* @author Tomas Westling &lt;tomas.westling@axis.com&gt;
*/
public class IndicationAnnotatorTest {

private static final String EXPECTED_ANNOTATED_TEXT = "tilt&quot; onmouseover=alert(1) foo=&quot;bar";

/**
* Tests that html is escaped correctly when annotating text.
*/
@Issue("SECURITY-3244")
@Test
public void testAnnotate() {
MarkupText text = new MarkupText("matchingString");
FoundIndication fi = new FoundIndication(
"pattern", "matchingFile", "matchingString");
List<FoundIndication> fis = new ArrayList<>();
fis.add(fi);
FoundFailureCause ffc = new FoundFailureCause(
new FailureCause("tilt\" onmouseover=alert(1) foo=\"bar", "description"), fis);
List<FoundFailureCause> foundFailureCauses = new ArrayList<>();
foundFailureCauses.add(ffc);
IndicationAnnotator ia = new IndicationAnnotator(foundFailureCauses);
ia.annotate(null, text);
assertTrue(text.toString(false).indexOf(EXPECTED_ANNOTATED_TEXT) != -1);
}
}

0 comments on commit a261229

Please sign in to comment.