Skip to content

Commit 7c7605d

Browse files
committed
KNOX-3132: Improve URL checks for originalUrl
1 parent 8445d1c commit 7c7605d

File tree

5 files changed

+50
-3
lines changed

5 files changed

+50
-3
lines changed

gateway-applications/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@
5858
<groupId>org.apache.knox</groupId>
5959
<artifactId>knox-webshell-ui</artifactId>
6060
</dependency>
61+
<dependency>
62+
<groupId>org.apache.commons</groupId>
63+
<artifactId>commons-text</artifactId>
64+
</dependency>
6165
</dependencies>
6266

6367
<build>

gateway-applications/src/main/resources/applications/knoxauth/app/logout.jsp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<%@ page import="org.apache.knox.gateway.config.GatewayConfig" %>
2222
<%@ page import="java.net.MalformedURLException" %>
2323
<%@ page import="org.apache.knox.gateway.util.Urls" %>
24+
<%@ page import="org.apache.commons.text.StringEscapeUtils" %>
2425

2526
<!DOCTYPE html>
2627
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]-->
@@ -93,6 +94,9 @@
9394
if (origUrl != null) {
9495
validRedirect = RegExUtils.checkWhitelist(whitelist, origUrl);
9596
}
97+
if (validRedirect) {
98+
validRedirect = Urls.isValidURL(originalUrl);
99+
}
96100
if (("1".equals(request.getParameter("returnToApp")))) {
97101
if (validRedirect) {
98102
response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY);
@@ -178,7 +182,7 @@
178182
the application. If your previously established SSO session is still valid then
179183
you will likely be automatically logged into your application. Otherwise, you
180184
will be required to login again.
181-
<a href="?returnToApp=1&originalUrl=<%= originalUrl %>" >Return to Application</a>
185+
<a href="?returnToApp=1&originalUrl=<%= StringEscapeUtils.escapeHtml4(originalUrl) %>" >Return to Application</a>
182186
</p>
183187
<%
184188
if (globalLogoutPageURL != null && !globalLogoutPageURL.isEmpty()) {

gateway-applications/src/main/resources/applications/knoxauth/app/redirecting.jsp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<%@ page import="org.apache.knox.gateway.util.RegExUtils" %>
2121
<%@ page import="org.apache.knox.gateway.util.Urls" %>
2222
<%@ page import="org.apache.knox.gateway.util.WhitelistUtils" %>
23+
<%@ page import="org.apache.commons.text.StringEscapeUtils" %>
2324

2425
<!DOCTYPE html>
2526
<!--[if lt IE 7]><html class="no-js lt-ie9 lt-ie8 lt-ie7"><![endif]-->
@@ -57,6 +58,9 @@
5758
// if not a well formed URL then not a valid redirect
5859
validRedirect = false;
5960
}
61+
if (validRedirect) {
62+
validRedirect = Urls.isValidURL(originalUrl);
63+
}
6064
if (validRedirect) {
6165
Topology topology = (Topology)request.getSession().getServletContext().getAttribute("org.apache.knox.gateway.topology");
6266
String whitelist = null;
@@ -82,7 +86,7 @@
8286
document.addEventListener("load", redirectOnLoad());
8387
8488
function redirectOnLoad() {
85-
var originalUrl = "<%= originalUrl %>";
89+
var originalUrl = "<%= StringEscapeUtils.escapeEcmaScript(originalUrl) %>";
8690
if (originalUrl != null) {
8791
redirect(originalUrl);
8892
}
@@ -103,7 +107,7 @@
103107
<div style="background: white;" class="l-logo">
104108
<img src="images/loading.gif" alt="Knox logo" style="text-align:center;width: 2%; height: 2%">
105109
</div>
106-
<p style="color: white;display: block">Loading should complete in few a seconds. If not, click <a href="<%= originalUrl %>">here</a></p>
110+
<p style="color: white;display: block">Loading should complete in few a seconds. If not, click <a href="<%= StringEscapeUtils.escapeHtml4(originalUrl) %>">here</a></p>
107111
<%
108112
} else {
109113
%>

gateway-util-common/src/main/java/org/apache/knox/gateway/util/Urls.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import java.io.UnsupportedEncodingException;
2121
import java.net.MalformedURLException;
22+
import java.net.URISyntaxException;
2223
import java.net.URL;
2324
import java.nio.charset.StandardCharsets;
2425
import java.util.regex.Matcher;
@@ -81,6 +82,20 @@ public static boolean containsUserInfo(String url) throws MalformedURLException
8182
return (new URL(url).getUserInfo() != null);
8283
}
8384

85+
/**
86+
* Checks if a given URL is valid according to RFC2396.
87+
* @param url a URL
88+
* @return true if URL conforms to RFC2396, false otherwise.
89+
*/
90+
public static boolean isValidURL(String url) {
91+
try {
92+
new URL(url).toURI();
93+
return true;
94+
} catch (MalformedURLException | URISyntaxException e) {
95+
return false;
96+
}
97+
}
98+
8499
/**
85100
* Compute the domain name from an URL.
86101
*

gateway-util-common/src/test/java/org/apache/knox/gateway/util/UrlsTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626

2727
public class UrlsTest {
2828

29+
private static final String INVALID_ORIGINAL_URL = "https://localhost:8443/gateway/homepage/homeisyr\">";
30+
private static final String VALID_LOCAL_ORIGINAL_URL = "https://localhost:8443/gateway/homepage/home";
31+
private static final String VALID_ORIGINAL_URL = "https://knoxhost.site:8443/gateway/homepage/home";
32+
private static final String VALID_ORIGINAL_URL_SOLR = "https://knoxhost.site:8443/gateway/cdp-proxy/solr/";
33+
private static final String LOGOUT_LOCAL_ORIGINAL_URL = "https://localhost:8443/gateway/homepage/home?profile=token";
34+
private static final String LOGOUT_ORIGINAL_URL_WITH_PARAMETERS = "https://knoxhost.site:8443/gateway/homepage/session/api/v1/sessioninfo?logoutPageProfile=token&logoutPageTopologies=cdp-proxy-token";
35+
private static final String LOGOUT_ORIGINAL_URL_WITH_PARAMETERS_ENCODED = "https://knoxhost.site:8443/gateway/homepage/session/api/v1/sessioninfo%3FlogoutPageProfile=token%26logoutPageTopologies=cdp-proxy-token";
36+
2937
/*
3038
* Domain name creation follows the following algorithm:
3139
* 1. if the incoming request hostname endsWith a configured domain suffix return the suffix - with prefixed dot
@@ -101,4 +109,16 @@ public void testContainsUserInfo() throws Exception {
101109
assertTrue(Urls.containsUserInfo( "https://www.local.com:[email protected]"));
102110
assertFalse(Urls.containsUserInfo( "https://www.local.com:8443/google.com"));
103111
}
112+
113+
@Test
114+
public void testValidUrl() throws Exception {
115+
assertFalse(Urls.isValidURL(INVALID_ORIGINAL_URL));
116+
assertTrue(Urls.isValidURL(VALID_LOCAL_ORIGINAL_URL));
117+
assertTrue(Urls.isValidURL(VALID_ORIGINAL_URL));
118+
assertTrue(Urls.isValidURL(VALID_ORIGINAL_URL_SOLR));
119+
assertTrue(Urls.isValidURL(LOGOUT_LOCAL_ORIGINAL_URL));
120+
assertTrue(Urls.isValidURL(LOGOUT_ORIGINAL_URL_WITH_PARAMETERS));
121+
assertTrue(Urls.isValidURL(LOGOUT_ORIGINAL_URL_WITH_PARAMETERS_ENCODED));
122+
}
123+
104124
}

0 commit comments

Comments
 (0)