[SECURITY-3501]

This commit is contained in:
Daniel Beck 2025-02-25 16:17:32 +00:00 committed by Jenkins CERT CI
parent 84ef1a4d4d
commit 4a9a3ecd08
3 changed files with 39 additions and 2 deletions

View File

@ -1651,7 +1651,7 @@ public class Util {
* @since 2.3 / 1.651.2
*/
public static boolean isSafeToRedirectTo(@NonNull String uri) {
return !isAbsoluteUri(uri) && !uri.startsWith("//");
return !isAbsoluteUri(uri) && !uri.startsWith("\\") && !uri.replace('\\', '/').startsWith("//");
}
/**

View File

@ -416,12 +416,16 @@ public class UtilTest {
}
@Test
@Issue("SECURITY-276")
@Issue({"SECURITY-276", "SECURITY-3501"})
public void testIsSafeToRedirectTo() {
assertFalse(Util.isSafeToRedirectTo("http://foobar/"));
assertFalse(Util.isSafeToRedirectTo("mailto:kk@kohsuke.org"));
assertFalse(Util.isSafeToRedirectTo("d123://test/"));
assertFalse(Util.isSafeToRedirectTo("//google.com"));
assertFalse(Util.isSafeToRedirectTo("\\\\google.com"));
assertFalse(Util.isSafeToRedirectTo("\\/google.com"));
assertFalse(Util.isSafeToRedirectTo("/\\google.com"));
assertFalse(Util.isSafeToRedirectTo("\\google.com"));
assertTrue(Util.isSafeToRedirectTo("foo/bar/abc:def"));
assertTrue(Util.isSafeToRedirectTo("foo?abc:def"));

View File

@ -0,0 +1,33 @@
package jenkins.security;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import java.util.List;
import org.htmlunit.FailingHttpStatusCodeException;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.RealJenkinsRule;
public class Security3501Test {
@Rule
public RealJenkinsRule jj = new RealJenkinsRule();
@Test
public void testRedirects() throws Throwable {
jj.then(Security3501Test::_testRedirects);
}
public static void _testRedirects(JenkinsRule j) throws Exception {
List<String> prohibitedPaths = List.of("%5C%5Cexample.org", "%5C/example.org", "/%5Cexample.org", "//example.org", "https://example.org", "\\example.org");
for (String path : prohibitedPaths) {
try (JenkinsRule.WebClient wc = j.createWebClient().withRedirectEnabled(false)) {
final FailingHttpStatusCodeException fhsce = Assert.assertThrows(FailingHttpStatusCodeException.class, () -> wc.goTo("userContent?path=" + path));
assertThat(fhsce.getStatusCode(), is(302));
assertThat(fhsce.getResponse().getResponseHeaderValue("Location"), is(j.getURL().toExternalForm() + "userContent/"));
}
}
}
}