mirror of
https://github.com/unmojang/authlib-injector.git
synced 2025-09-29 14:20:55 -04:00
Forbid multiple ALI redirects (#78)
This commit is contained in:
parent
0bd7134c81
commit
b12dd75fa5
@ -29,10 +29,8 @@ import java.io.UncheckedIOException;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.Proxy;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.Proxy.Type;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
@ -122,8 +120,6 @@ public final class AuthlibInjector {
|
||||
|
||||
public static final String PROP_DISABLE_HTTPD = "authlibinjector.httpd.disable";
|
||||
|
||||
public static final String PROP_ALI_REDIRECT_LIMIT = "authlibinjector.ali.redirectLimit";
|
||||
|
||||
// ====
|
||||
|
||||
// ==== Package filtering ====
|
||||
@ -187,8 +183,6 @@ public final class AuthlibInjector {
|
||||
}
|
||||
// ====
|
||||
|
||||
private static final int REDIRECT_LIMIT = Integer.getInteger(PROP_ALI_REDIRECT_LIMIT, 5);
|
||||
|
||||
private AuthlibInjector() {}
|
||||
|
||||
private static boolean booted = false;
|
||||
@ -242,7 +236,7 @@ public final class AuthlibInjector {
|
||||
ExecutionEnvironment side = detectSide();
|
||||
Logging.LAUNCH.fine("Detected side: " + side);
|
||||
|
||||
apiRoot = parseInputUrl(apiRoot);
|
||||
apiRoot = addHttpsIfMissing(apiRoot);
|
||||
Logging.CONFIG.info("API root: " + apiRoot);
|
||||
warnIfHttp(apiRoot);
|
||||
|
||||
@ -252,30 +246,17 @@ public final class AuthlibInjector {
|
||||
if (!prefetched.isPresent()) {
|
||||
|
||||
try {
|
||||
HttpURLConnection connection;
|
||||
boolean redirectAllowed = side == ExecutionEnvironment.SERVER;
|
||||
int redirectCount = 0;
|
||||
for (;;) {
|
||||
connection = (HttpURLConnection) new URL(apiRoot).openConnection();
|
||||
Optional<String> ali = getApiLocationIndication(connection);
|
||||
if (ali.isPresent()) {
|
||||
if (!redirectAllowed) {
|
||||
Logging.CONFIG.warning("Redirect is not allowed, ignoring ALI: " + ali.get());
|
||||
break;
|
||||
}
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(apiRoot).openConnection();
|
||||
|
||||
String ali = connection.getHeaderField("x-authlib-injector-api-location");
|
||||
if (ali != null) {
|
||||
URL absoluteAli = new URL(connection.getURL(), ali);
|
||||
if (!urlEqualsIgnoreSlash(apiRoot, absoluteAli.toString())) {
|
||||
connection.disconnect();
|
||||
|
||||
apiRoot = ali.get();
|
||||
if (redirectCount >= REDIRECT_LIMIT) {
|
||||
Logging.CONFIG.severe("Exceeded maximum number of redirects (" + REDIRECT_LIMIT + "), refusing to redirect to: " + apiRoot);
|
||||
throw new InjectorInitializationException();
|
||||
}
|
||||
redirectCount++;
|
||||
Logging.CONFIG.info("Redirect to: " + apiRoot);
|
||||
Logging.CONFIG.info("Redirect to: " + absoluteAli);
|
||||
apiRoot = absoluteAli.toString();
|
||||
warnIfHttp(apiRoot);
|
||||
} else {
|
||||
break;
|
||||
connection = (HttpURLConnection) absoluteAli.openConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,6 +284,9 @@ public final class AuthlibInjector {
|
||||
|
||||
Logging.CONFIG.fine("Metadata: " + metadataResponse);
|
||||
|
||||
if (!apiRoot.endsWith("/"))
|
||||
apiRoot += "/";
|
||||
|
||||
YggdrasilConfiguration configuration;
|
||||
try {
|
||||
configuration = YggdrasilConfiguration.parse(apiRoot, metadataResponse);
|
||||
@ -322,43 +306,20 @@ public final class AuthlibInjector {
|
||||
}
|
||||
}
|
||||
|
||||
private static String appendSuffixSlash(String url) {
|
||||
if (!url.endsWith("/")) {
|
||||
return url + "/";
|
||||
} else {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private static String parseInputUrl(String url) {
|
||||
private static String addHttpsIfMissing(String url) {
|
||||
String lowercased = url.toLowerCase();
|
||||
if (!lowercased.startsWith("http://") && !lowercased.startsWith("https://")) {
|
||||
url = "https://" + url;
|
||||
}
|
||||
|
||||
url = appendSuffixSlash(url);
|
||||
return url;
|
||||
}
|
||||
|
||||
private static Optional<String> getApiLocationIndication(URLConnection conn) {
|
||||
return Optional.ofNullable(conn.getHeaderFields().get("X-Authlib-Injector-API-Location"))
|
||||
.flatMap(list -> list.isEmpty() ? Optional.empty() : Optional.of(list.get(0)))
|
||||
.flatMap(indication -> {
|
||||
String currentUrl = appendSuffixSlash(conn.getURL().toString());
|
||||
String newUrl;
|
||||
try {
|
||||
newUrl = appendSuffixSlash(new URL(conn.getURL(), indication).toString());
|
||||
} catch (MalformedURLException e) {
|
||||
Logging.CONFIG.warning("Failed to resolve absolute ALI, the header is [" + indication + "]. Ignore it.");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (newUrl.equals(currentUrl)) {
|
||||
return Optional.empty();
|
||||
} else {
|
||||
return Optional.of(newUrl);
|
||||
}
|
||||
});
|
||||
private static boolean urlEqualsIgnoreSlash(String a, String b) {
|
||||
if (!a.endsWith("/"))
|
||||
a += "/";
|
||||
if (!b.endsWith("/"))
|
||||
b += "/";
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
private static ExecutionEnvironment detectSide() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user