diff --git a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java index e63a38b0e..fa10c4193 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/delivery/webserver/RequestHandler.java @@ -47,6 +47,7 @@ import org.apache.commons.text.TextStringBuilder; import javax.inject.Inject; import javax.inject.Singleton; import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; /** * HttpHandler for WebServer request management. @@ -68,6 +69,8 @@ public class RequestHandler implements HttpHandler { private final PassBruteForceGuard bruteForceGuard; private List ipWhitelist = null; + private final AtomicBoolean warnedAboutXForwardedSecurityIssue = new AtomicBoolean(false); + @Inject RequestHandler( Locale locale, @@ -120,7 +123,7 @@ public class RequestHandler implements HttpHandler { ? config.get(WebserverSettings.WHITELIST) : Collections.emptyList(); } - String accessor = exchange.getRemoteAddress().getAddress().getHostAddress(); + String accessor = getAccessorAddress(exchange); Request request = null; Response response; try { @@ -159,6 +162,29 @@ public class RequestHandler implements HttpHandler { return response; } + private String getAccessorAddress(HttpExchange exchange) { + if (config.isTrue(WebserverSettings.IP_WHITELIST_X_FORWARDED)) { + String header = exchange.getRequestHeaders().getFirst("X-Forwarded-For"); + if (header == null) { + warnAboutXForwardedForSecurityIssue(); + } else { + return header; + } + } + return exchange.getRemoteAddress().getAddress().getHostAddress(); + } + + private void warnAboutXForwardedForSecurityIssue() { + if (!warnedAboutXForwardedSecurityIssue.get()) { + logger.warn("Security Vulnerability due to misconfiguration: X-Forwarded-For header was not present in a request & '" + + WebserverSettings.IP_WHITELIST_X_FORWARDED.getPath() + "' is 'true'!", + "This could mean non-reverse-proxy access is not blocked & someone can use IP Spoofing to bypass security!", + "Make sure you can only access Plan panel from your reverse-proxy or disable this setting." + ); + } + warnedAboutXForwardedSecurityIssue.set(true); + } + private Request buildRequest(HttpExchange exchange) { String requestMethod = exchange.getRequestMethod(); URIPath path = new URIPath(exchange.getRequestURI().getPath()); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/paths/WebserverSettings.java b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/paths/WebserverSettings.java index c711a17d5..69da48763 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/settings/config/paths/WebserverSettings.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/settings/config/paths/WebserverSettings.java @@ -36,6 +36,7 @@ public class WebserverSettings { public static final Setting CERTIFICATE_KEYPASS = new StringSetting("Webserver.Security.SSL_certificate.Key_pass"); public static final Setting CERTIFICATE_STOREPASS = new StringSetting("Webserver.Security.SSL_certificate.Store_pass"); public static final Setting CERTIFICATE_ALIAS = new StringSetting("Webserver.Security.SSL_certificate.Alias"); + public static final Setting IP_WHITELIST_X_FORWARDED = new BooleanSetting("Webserver.Security.Use_X-Forwarded-For_Header"); public static final Setting IP_WHITELIST = new BooleanSetting("Webserver.Security.IP_whitelist"); public static final Setting> WHITELIST = new StringListSetting("Webserver.Security.IP_whitelist.Whitelist"); public static final Setting DISABLED = new BooleanSetting("Webserver.Disable_Webserver"); diff --git a/Plan/common/src/main/resources/assets/plan/bungeeconfig.yml b/Plan/common/src/main/resources/assets/plan/bungeeconfig.yml index 4d1b585d5..c3ed78f5f 100644 --- a/Plan/common/src/main/resources/assets/plan/bungeeconfig.yml +++ b/Plan/common/src/main/resources/assets/plan/bungeeconfig.yml @@ -56,6 +56,9 @@ Webserver: # https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS CORS: Allow_origin: "*" + # Allows using the whitelist & brute-force shield with a reverse-proxy. + # ! Make sure non-proxy access is not possible, it would allow IP spoofing ! + Use_X-Forwarded-For_Header: false IP_whitelist: false Whitelist: - "192.168.0.0" diff --git a/Plan/common/src/main/resources/assets/plan/config.yml b/Plan/common/src/main/resources/assets/plan/config.yml index f53915359..d78e4e98f 100644 --- a/Plan/common/src/main/resources/assets/plan/config.yml +++ b/Plan/common/src/main/resources/assets/plan/config.yml @@ -61,6 +61,9 @@ Webserver: # https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS CORS: Allow_origin: "*" + # Allows using the whitelist with a reverse-proxy. + # ! Make sure non-proxy access is not possible, it would allow IP spoofing ! + Use_X-Forwarded-For_Header: false IP_whitelist: false Whitelist: - "192.168.0.0"