Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,44 @@ else if (!exportUrl.endsWith("/")) // There are other non-trivial cases, admins
exportUrl += "/";
}

// Validate proxy path to prevent path traversal and URL manipulation
if (proxyPath != null && !proxyPath.isEmpty())
{
// Block path traversal attempts
if (proxyPath.contains("..") || proxyPath.contains("//") ||
proxyPath.contains("@") || proxyPath.contains("\\"))
{
throw new SecurityException("Invalid path: potential path traversal or URL manipulation detected");
}

// Block URL encoding tricks that could bypass validation
String decodedPath = java.net.URLDecoder.decode(proxyPath, "UTF-8");
if (decodedPath.contains("..") || decodedPath.contains("@") ||
decodedPath.contains("://") || decodedPath.contains("\\"))
{
throw new SecurityException("Invalid path: encoded path traversal or URL manipulation detected");
}
}

URL url = new URL(exportUrl + proxyPath + queryString);

// Validate that the final URL still points to the expected base URL (prevent SSRF)
URL baseUrl = new URL(exportUrl);
if (!url.getProtocol().equals(baseUrl.getProtocol()) ||
!url.getHost().equalsIgnoreCase(baseUrl.getHost()) ||
url.getPort() != baseUrl.getPort())
{
throw new SecurityException("Invalid URL: request redirects outside of the configured service");
}

// Additional check: ensure the path starts with the base path
String basePath = baseUrl.getPath();
String fullPath = url.getPath();
if (!fullPath.startsWith(basePath))
{
throw new SecurityException("Invalid URL: path does not start with base path");
}

HttpURLConnection con = (HttpURLConnection) url.openConnection();

con.setRequestMethod(method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ else if (Utils.sanitizeUrl(urlParam))
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");

// Re-validate immediately before connection to prevent DNS rebinding TOCTOU attacks
if (!Utils.sanitizeUrl(urlParam))
{
throw new SecurityException("URL validation failed before connection");
}

URL url = new URL(urlParam);
URLConnection connection = url.openConnection();
connection.setConnectTimeout(TIMEOUT);
Expand Down Expand Up @@ -127,6 +133,13 @@ else if (Utils.sanitizeUrl(urlParam))
break;
}


// Re-validate immediately before connection to prevent DNS rebinding TOCTOU attacks
if (!Utils.sanitizeUrl(redirectUrl))
{
log.log(Level.SEVERE, "Redirect URL validation failed before connection (possible DNS rebinding attack): " + redirectUrl);
break;
}
url = new URL(redirectUrl);
connection = url.openConnection();
((HttpURLConnection) connection)
Expand Down