Skip to content

Commit

Permalink
[SECURITY-1097]
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-beck committed Mar 30, 2021
1 parent 42e2c74 commit 95e3a30
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 1 deletion.
2 changes: 1 addition & 1 deletion bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ THE SOFTWARE.
<properties>
<guavaVersion>11.0.1</guavaVersion>
<slf4jVersion>1.7.30</slf4jVersion>
<stapler.version>1.262</stapler.version>
<stapler.version>1.262.1</stapler.version>
<groovy.version>2.4.12</groovy.version>
</properties>

Expand Down
80 changes: 80 additions & 0 deletions test/src/test/java/org/kohsuke/stapler/Security1097Test.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package org.kohsuke.stapler;

import com.gargoylesoftware.htmlunit.FailingHttpStatusCodeException;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.Extension;
import hudson.model.InvisibleAction;
import hudson.model.RootAction;
import net.sf.json.JSONObject;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.kohsuke.stapler.json.SubmittedForm;

import javax.servlet.ServletException;
import java.lang.reflect.Field;
import java.util.Arrays;

public class Security1097Test {
@Rule
public JenkinsRule j = new JenkinsRule();

@Test
public void testPostWorks() throws Exception {
final JenkinsRule.WebClient webClient = j.createWebClient();
final HtmlPage htmlPage1 = webClient.goTo("security1097/post1");
j.submit(htmlPage1.getFormByName("config"));

final HtmlPage htmlPage2 = webClient.goTo("security1097/post2");
j.submit(htmlPage2.getFormByName("config"));
}

@Test(expected = FailingHttpStatusCodeException.class)
public void testGet1Fails() throws Exception {
final JenkinsRule.WebClient webClient = j.createWebClient();
final HtmlPage htmlPage = webClient.goTo("security1097/get1");
j.submit(htmlPage.getFormByName("config"));
}

@Test(expected = FailingHttpStatusCodeException.class)
public void testGet2Fails() throws Exception {
final JenkinsRule.WebClient webClient = j.createWebClient();
final HtmlPage htmlPage = webClient.goTo("security1097/get2");
j.submit(htmlPage.getFormByName("config"));
}

@Test
public void testGetWorksWithEscapeHatch() throws Exception {
final Field allowed_http_verbs_for_forms = RequestImpl.class.getDeclaredField("ALLOWED_HTTP_VERBS_FOR_FORMS");
allowed_http_verbs_for_forms.setAccessible(true);
try {
allowed_http_verbs_for_forms.set(null, Arrays.asList("GET", "POST"));
final JenkinsRule.WebClient webClient = j.createWebClient();
final HtmlPage htmlPage1 = webClient.goTo("security1097/get1");
j.submit(htmlPage1.getFormByName("config"));

final HtmlPage htmlPage2 = webClient.goTo("security1097/get2");
j.submit(htmlPage2.getFormByName("config"));
} finally {
allowed_http_verbs_for_forms.set(null, Arrays.asList("POST"));
}
}

@Extension
public static class RootActionImpl extends InvisibleAction implements RootAction {
@Override
public String getUrlName() {
return "security1097";
}

/* Deliberate CSRF vulnerability */
public void doConfigSubmit1(StaplerRequest req) throws ServletException {
req.getSubmittedForm();
}

/* Alternative implementation: */
public void doConfigSubmit2(@SubmittedForm JSONObject form) {
/* no-op */
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:f="/lib/form">
<l:layout title="${%Configure}">
<l:main-panel>
<h1>${%Configuration Form 1 with GET}</h1>
<f:form method="get" name="config" action="configSubmit1">
<f:block>
<f:submit value="${%Save}" />
</f:block>
</f:form>
<st:adjunct includes="lib.form.confirm" />
</l:main-panel>
</l:layout>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:f="/lib/form">
<l:layout title="${%Configure}">
<l:main-panel>
<h1>${%Configuration Form 2 with GET}</h1>
<f:form method="get" name="config" action="configSubmit2">
<f:block>
<f:submit value="${%Save}" />
</f:block>
</f:form>
<st:adjunct includes="lib.form.confirm" />
</l:main-panel>
</l:layout>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:f="/lib/form">
<l:layout title="${%Configure}">
<l:main-panel>
<h1>${%Configuration Form 1 with POST}</h1>
<f:form method="post" name="config" action="configSubmit1">
<f:block>
<f:submit value="${%Save}" />
</f:block>
</f:form>
<st:adjunct includes="lib.form.confirm" />
</l:main-panel>
</l:layout>
</j:jelly>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:l="/lib/layout" xmlns:f="/lib/form">
<l:layout title="${%Configure}">
<l:main-panel>
<h1>${%Configuration Form 2 with POST}</h1>
<f:form method="post" name="config" action="configSubmit2">
<f:block>
<f:submit value="${%Save}" />
</f:block>
</f:form>
<st:adjunct includes="lib.form.confirm" />
</l:main-panel>
</l:layout>
</j:jelly>

0 comments on commit 95e3a30

Please sign in to comment.