diff --git a/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/Log4JFilter.java b/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/Log4JFilter.java index e8344444..79d0ea8e 100644 --- a/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/Log4JFilter.java +++ b/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/Log4JFilter.java @@ -14,6 +14,15 @@ import org.apache.logging.log4j.core.Logger; import org.apache.logging.log4j.message.Message; +/** + * A Log4J implementation of the {@link LogFilter} that filters out sensitive authentication commands. + *

+ * This class extends {@link LogFilter} and implements Log4J's {@link Filter} interface to provide filtering capabilities for Log4J logging system. + *

+ * The filter is designed to prevent logging of sensitive information such as passwords and authentication tokens that might appear in certain commands. It integrates with Log4J's filtering chain and can be easily added to the root logger. + *

+ * This implementation handles various Log4J filter method overloads to ensure comprehensive coverage of all possible logging scenarios, including parameterized messages and raw objects. + */ public class Log4JFilter extends LogFilter implements Filter { @Override @@ -21,8 +30,16 @@ public void inject() { ((Logger) LogManager.getRootLogger()).addFilter(new Log4JFilter()); } - private Result checkMessageResult(String message) { - return checkMessage(message) ? Result.NEUTRAL : Result.DENY; + /** + * Converts the result of message checking into a Log4J {@link Result}. + * + * @param message The message pattern to be checked + * @param parameters The parameters associated with the message. + * @return {@link Result#NEUTRAL} if the message should be logged, {@link Result#DENY} if it should be filtered out + * @see LogFilter#checkMessage + */ + private Result checkMessageResult(String message, Object[] parameters) { + return checkMessage(message, parameters) ? Result.NEUTRAL : Result.DENY; } @Override @@ -37,72 +54,73 @@ public Result getOnMismatch() { @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object... params) { - return checkMessageResult(message); + return checkMessageResult(message, params); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2, p3}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2, p3, p4}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2, p3, p4, p5}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2, p3, p4, p5, p6}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2, p3, p4, p5, p6, p7}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2, p3, p4, p5, p6, p7, p8}); } @Override public Result filter(Logger logger, Level level, Marker marker, String message, Object p0, Object p1, Object p2, Object p3, Object p4, Object p5, Object p6, Object p7, Object p8, Object p9) { - return checkMessageResult(message); + return checkMessageResult(message, new Object[]{p0, p1, p2, p3, p4, p5, p6, p7, p8, p9}); } @Override public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) { - return checkMessageResult(msg.toString()); + return checkMessageResult(msg.toString(), null); } @Override public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) { - return checkMessageResult(msg.getFormattedMessage()); + return checkMessageResult(msg.getFormat(), msg.getParameters()); } @Override public Result filter(LogEvent event) { - return checkMessageResult(event.getMessage().getFormattedMessage()); + var message = event.getMessage(); + return checkMessageResult(message.getFormat(), message.getParameters()); } @Override @@ -126,4 +144,4 @@ public void start() { public void stop() { } -} \ No newline at end of file +} diff --git a/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/LogFilter.java b/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/LogFilter.java index 91016012..6397f5be 100644 --- a/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/LogFilter.java +++ b/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/LogFilter.java @@ -6,47 +6,67 @@ package xyz.kyngs.librelogin.common.log; -import java.util.HashSet; import java.util.Set; +/** + * A filter that prevents sensitive authentication commands from being logged. + *

+ * This abstract class provides functionality to filter out commands that might contain sensitive information such as passwords or authentication tokens. + */ public abstract class LogFilter { - private static final Set PROTECTED_COMMANDS; - - static { - PROTECTED_COMMANDS = new HashSet<>(); - - PROTECTED_COMMANDS.add("login"); - PROTECTED_COMMANDS.add("l"); - PROTECTED_COMMANDS.add("log"); - PROTECTED_COMMANDS.add("register"); - PROTECTED_COMMANDS.add("reg"); - PROTECTED_COMMANDS.add("premium"); - PROTECTED_COMMANDS.add("autologin"); - PROTECTED_COMMANDS.add("2faconfirm"); - PROTECTED_COMMANDS.add("changepassword"); - PROTECTED_COMMANDS.add("changepass"); - PROTECTED_COMMANDS.add("passch"); - PROTECTED_COMMANDS.add("passwd"); - PROTECTED_COMMANDS.add("confirmpasswordreset"); - PROTECTED_COMMANDS.add("setemail"); - PROTECTED_COMMANDS.add("librelogin user register"); - PROTECTED_COMMANDS.add("librelogin user pass-change"); - } + /** + * A set of command prefixes that should be protected from logging. + *

+ * These commands typically contain sensitive information like passwords. + */ + private static final Set PROTECTED_COMMANDS = Set.of( + "/login ", + "/l ", + "/log ", + "/register ", + "/reg ", + "/premium ", + "/autologin ", + "/2faconfirm ", + "/changepassword ", + "/changepass ", + "/passch ", + "/passwd ", + "/confirmpasswordreset ", + "/setemail ", + "/librelogin user register ", + "/librelogin user pass-change " + ); + + /** + * Checks if a log message containing a command should be filtered out. + * + * @param message The message pattern being logged + * @param parameters The parameters being used in the message. + * @return {@code true} if the message should be logged, {@code false} if it should be filtered out + */ + protected boolean checkMessage(String message, Object[] parameters) { + if (parameters == null || parameters.length <= 1 || !(parameters[1] instanceof String parameter)) return true; + + parameter = switch (message) { + case "{} issued server command: {}" -> parameter; + case "{0} executed command: /{1}", "{} -> executed command /{}" -> '/' + parameter; + default -> ""; + }; - protected boolean checkMessage(String message) { - // This sucks, but it's the only way to filter out the spam from the plugin - if (message.contains("Plugin listener xyz.kyngs.librelogin.bungeecord.BungeeCordListener took")) return false; - if (!message.contains("issued server command: /") && !message.contains("executed command /") && !message.contains("executed command: /") && !message.contains("Duplicate key name")) - return true; + if (parameter.isEmpty()) return true; for (String command : PROTECTED_COMMANDS) { - if (message.contains(command)) return false; + if (parameter.startsWith(command)) return false; } return true; } + /** + * Injects this filter into the logging system. + */ public abstract void inject(); } diff --git a/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/SimpleLogFilter.java b/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/SimpleLogFilter.java index 78b66fee..7dc1cf94 100644 --- a/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/SimpleLogFilter.java +++ b/Plugin/src/main/java/xyz/kyngs/librelogin/common/log/SimpleLogFilter.java @@ -10,9 +10,26 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; +/** + * A simple implementation of the LogFilter for Java's built-in logging system. + *

+ * This class extends {@link LogFilter} and implements {@link Filter} interface to provide filtering capabilities for the standard Java logging framework. + *

+ * This implementation preserves any existing filter that was already set on the logger by chaining it with this filter's functionality.

+ */ public class SimpleLogFilter extends LogFilter implements Filter { + /** + * The original filter that was set on the logger before this filter was applied. + *

+ * This is preserved to maintain the existing filtering chain. + */ private final Filter filter; + /** + * The logger instance that this filter is attached to. + *

+ * Used for filter injection and management. + */ private final Logger logger; public SimpleLogFilter(Logger logger) { @@ -24,7 +41,7 @@ public SimpleLogFilter(Logger logger) { public boolean isLoggable(LogRecord record) { if (filter != null && !filter.isLoggable(record)) return false; - return checkMessage(record.getMessage()); + return checkMessage(record.getMessage(), record.getParameters()); } @Override