提交 68e84726 编写于 作者: K Kohsuke Kawaguchi

[FIXED SECURITY-45]

上级 2cb3e838
...@@ -1233,6 +1233,31 @@ public class Util { ...@@ -1233,6 +1233,31 @@ public class Util {
return s==null ? s : s.intern(); return s==null ? s : s.intern();
} }
/**
* Return true if the systemId denotes an absolute URI .
*
* The same algorithm can be seen in {@link URI}, but
* implementing this by ourselves allow it to be more lenient about
* escaping of URI.
*/
public static boolean isAbsoluteUri(String uri) {
int idx = uri.indexOf(':');
if (idx<0) return false; // no ':'. can't be absolute
// #, ?, and / must not be before ':'
return idx<_indexOf(uri, '#') && idx<_indexOf(uri,'?') && idx<_indexOf(uri,'/');
}
/**
* Works like {@link String#indexOf(int)} but 'not found' is returned as s.length(), not -1.
* This enables more straight-forward comparison.
*/
private static int _indexOf(String s, char ch) {
int idx = s.indexOf(ch);
if (idx<0) return s.length();
return idx;
}
/** /**
* Loads a key/value pair string as {@link Properties} * Loads a key/value pair string as {@link Properties}
* @since 1.392 * @since 1.392
......
...@@ -137,7 +137,7 @@ public final class DirectoryBrowserSupport implements HttpResponse { ...@@ -137,7 +137,7 @@ public final class DirectoryBrowserSupport implements HttpResponse {
String pattern = req.getParameter("pattern"); String pattern = req.getParameter("pattern");
if(pattern==null) if(pattern==null)
pattern = req.getParameter("path"); // compatibility with Hudson<1.129 pattern = req.getParameter("path"); // compatibility with Hudson<1.129
if(pattern!=null) { if(pattern!=null && !Util.isAbsoluteUri(pattern)) {// avoid open redirect
rsp.sendRedirect2(pattern); rsp.sendRedirect2(pattern);
return; return;
} }
......
...@@ -31,6 +31,7 @@ import java.io.IOException; ...@@ -31,6 +31,7 @@ import java.io.IOException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import hudson.Util;
import org.acegisecurity.Authentication; import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationException; import org.acegisecurity.AuthenticationException;
import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter; import org.acegisecurity.ui.webapp.AuthenticationProcessingFilter;
...@@ -51,6 +52,9 @@ public class AuthenticationProcessingFilter2 extends AuthenticationProcessingFil ...@@ -51,6 +52,9 @@ public class AuthenticationProcessingFilter2 extends AuthenticationProcessingFil
if (targetUrl == null) if (targetUrl == null)
return getDefaultTargetUrl(); return getDefaultTargetUrl();
if (Util.isAbsoluteUri(targetUrl))
return "."; // avoid open redirect
// URL returned from determineTargetUrl() is resolved against the context path, // URL returned from determineTargetUrl() is resolved against the context path,
// whereas the "from" URL is resolved against the top of the website, so adjust this. // whereas the "from" URL is resolved against the top of the website, so adjust this.
if(targetUrl.startsWith(request.getContextPath())) if(targetUrl.startsWith(request.getContextPath()))
......
...@@ -290,4 +290,14 @@ public class UtilTest { ...@@ -290,4 +290,14 @@ public class UtilTest {
} }
} }
} }
public void testIsAbsoluteUri() {
assertTrue(Util.isAbsoluteUri("http://foobar/"));
assertTrue(Util.isAbsoluteUri("mailto:kk@kohsuke.org"));
assertTrue(Util.isAbsoluteUri("d123://test/"));
assertFalse(Util.isAbsoluteUri("foo/bar/abc:def"));
assertFalse(Util.isAbsoluteUri("foo?abc:def"));
assertFalse(Util.isAbsoluteUri("foo#abc:def"));
assertFalse(Util.isAbsoluteUri("foo/bar"));
}
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册