Initial mitigation for folks updating Dynmap but not patching MC for
some reason
This commit is contained in:
parent
66a82ceb6a
commit
4df3ce765e
3 changed files with 61 additions and 8 deletions
|
|
@ -141,6 +141,7 @@ public class DynmapCore implements DynmapCommonAPI {
|
||||||
|
|
||||||
private boolean loginRequired;
|
private boolean loginRequired;
|
||||||
|
|
||||||
|
private String hackAttemptSub = "(IaM5uchA1337Haxr-Ban Me!)";
|
||||||
// WEBP support
|
// WEBP support
|
||||||
private String cwebpPath;
|
private String cwebpPath;
|
||||||
private String dwebpPath;
|
private String dwebpPath;
|
||||||
|
|
@ -599,11 +600,13 @@ public class DynmapCore implements DynmapCommonAPI {
|
||||||
updateConfigHashcode(); /* Initialize/update config hashcode */
|
updateConfigHashcode(); /* Initialize/update config hashcode */
|
||||||
|
|
||||||
loginRequired = configuration.getBoolean("login-required", false);
|
loginRequired = configuration.getBoolean("login-required", false);
|
||||||
|
hackAttemptSub = configuration.getString("hackAttemptBlurb", "(IaM5uchA1337Haxr-Ban Me!)");
|
||||||
|
|
||||||
// If not disabled, load and initialize the internal web server
|
// If not disabled, load and initialize the internal web server
|
||||||
if (!isInternalWebServerDisabled) {
|
if (!isInternalWebServerDisabled) {
|
||||||
loadWebserver();
|
loadWebserver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enabledTriggers.clear();
|
enabledTriggers.clear();
|
||||||
List<String> triggers = configuration.getStrings("render-triggers", new ArrayList<String>());
|
List<String> triggers = configuration.getStrings("render-triggers", new ArrayList<String>());
|
||||||
|
|
@ -2297,13 +2300,60 @@ public class DynmapCore implements DynmapCommonAPI {
|
||||||
|
|
||||||
public String getDefImageFormat() { return def_image_format; }
|
public String getDefImageFormat() { return def_image_format; }
|
||||||
|
|
||||||
|
public String scanAndReplaceLog4JMacro(String msg) {
|
||||||
|
int nestcnt = 0;
|
||||||
|
int off = 0;
|
||||||
|
int firsthit = -1;
|
||||||
|
boolean done = false;
|
||||||
|
String orig = msg;
|
||||||
|
while (!done) {
|
||||||
|
int idx = msg.indexOf("${", off); // Look for next ${
|
||||||
|
if (idx >= 0) { // Hit
|
||||||
|
if (nestcnt == 0) firsthit = idx; // Record start of hit
|
||||||
|
nestcnt++;
|
||||||
|
off = idx + 2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
idx = msg.indexOf("}", off); // Next }
|
||||||
|
if (idx >= 0) {
|
||||||
|
if (nestcnt > 0) {
|
||||||
|
nestcnt--;
|
||||||
|
if ((nestcnt == 0) && (firsthit >= 0)) { // If back to zero, time to strip it
|
||||||
|
String newmsg = msg.substring(0, firsthit) + hackAttemptSub + msg.substring(idx+1);
|
||||||
|
msg = newmsg; // Switch to new version, and restart
|
||||||
|
off = 0;
|
||||||
|
firsthit = -1; // And restart scan
|
||||||
|
}
|
||||||
|
}
|
||||||
|
off = idx + 1;
|
||||||
|
}
|
||||||
|
else { // At end without a close
|
||||||
|
if (firsthit >= 0) { // Open strip?
|
||||||
|
String newmsg = msg.substring(0, firsthit) + hackAttemptSub; // Replace rest
|
||||||
|
msg = newmsg; // Switch to new version, and restart
|
||||||
|
}
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
public void webChat(final String name, final String message) {
|
public void webChat(final String name, final String message) {
|
||||||
if(mapManager == null)
|
if(mapManager == null)
|
||||||
return;
|
return;
|
||||||
|
// Check for folks trying to exploit Log4J
|
||||||
|
final String cleanname = scanAndReplaceLog4JMacro(name);
|
||||||
|
final String cleanmsg = scanAndReplaceLog4JMacro(message);
|
||||||
|
if (!cleanname.equals(name)) {
|
||||||
|
Log.severe("Possible hack attempt blocked: name contains Log4J macro - " + name.replaceAll("\\$", "_"));
|
||||||
|
}
|
||||||
|
if (!cleanmsg.equals(message)) {
|
||||||
|
Log.severe("Possible hack attempt blocked: message contains Log4J macro (from " + cleanname + ") - " + message.replaceAll("\\$", "_"));
|
||||||
|
}
|
||||||
Runnable c = new Runnable() {
|
Runnable c = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ChatEvent event = new ChatEvent("web", name, message);
|
ChatEvent event = new ChatEvent("web", cleanname, cleanmsg);
|
||||||
events.trigger("webchat", event);
|
events.trigger("webchat", event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,8 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
|
||||||
private MapStorage storage;
|
private MapStorage storage;
|
||||||
private File baseStandaloneDir;
|
private File baseStandaloneDir;
|
||||||
|
|
||||||
|
private String safeString(String s) { return s.replaceAll("\\$", "_"); }
|
||||||
|
|
||||||
private static class FileToWrite {
|
private static class FileToWrite {
|
||||||
String filename;
|
String filename;
|
||||||
byte[] content;
|
byte[] content;
|
||||||
|
|
@ -420,17 +422,17 @@ public class JsonFileClientUpdateComponent extends ClientUpdateComponent {
|
||||||
isip = false;
|
isip = false;
|
||||||
if(checkuserban) {
|
if(checkuserban) {
|
||||||
if(core.getServer().isPlayerBanned(name)) {
|
if(core.getServer().isPlayerBanned(name)) {
|
||||||
Log.info("Ignore message from '" + ip + "' - banned player (" + name + ")");
|
Log.info("Ignore message from '" + ip + "' - banned player (" + safeString(name) + ")");
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(chat_perms && !core.getServer().checkPlayerPermission(name, "webchat")) {
|
if(chat_perms && !core.getServer().checkPlayerPermission(name, "webchat")) {
|
||||||
Log.info("Rejected web chat from " + ip + ": not permitted (" + name + ")");
|
Log.info("Rejected web chat from " + ip + ": not permitted (" + safeString(name) + ")");
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(requireplayerloginip) {
|
else if(requireplayerloginip) {
|
||||||
Log.info("Ignore message from '" + name + "' - no matching player login recorded");
|
Log.info("Ignore message from '" + safeString(name) + "' - no matching player login recorded");
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ public class SendMessageServlet extends HttpServlet {
|
||||||
public DynmapCore core;
|
public DynmapCore core;
|
||||||
public HashSet<String> proxyaddress = new HashSet<String>();
|
public HashSet<String> proxyaddress = new HashSet<String>();
|
||||||
|
|
||||||
|
private String safeString(String s) { return s.replaceAll("\\$", "_"); }
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
byte[] bytes;
|
byte[] bytes;
|
||||||
|
|
@ -65,7 +66,7 @@ public class SendMessageServlet extends HttpServlet {
|
||||||
}
|
}
|
||||||
else if(chat_requires_login && (!userID.equals(LoginServlet.USERID_GUEST)) && chat_perms &&
|
else if(chat_requires_login && (!userID.equals(LoginServlet.USERID_GUEST)) && chat_perms &&
|
||||||
(!core.checkPermission(userID, "webchat"))) {
|
(!core.checkPermission(userID, "webchat"))) {
|
||||||
Log.info("Rejected web chat by " + userID + ": not permitted");
|
Log.info("Rejected web chat by " + safeString(userID) + ": not permitted");
|
||||||
error = "not-permitted";
|
error = "not-permitted";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -118,20 +119,20 @@ public class SendMessageServlet extends HttpServlet {
|
||||||
String id = ids.get(0);
|
String id = ids.get(0);
|
||||||
if (check_user_ban) {
|
if (check_user_ban) {
|
||||||
if (core.getServer().isPlayerBanned(id)) {
|
if (core.getServer().isPlayerBanned(id)) {
|
||||||
Log.info("Ignore message from '" + message.name + "' - banned player (" + id + ")");
|
Log.info("Ignore message from '" + safeString(message.name) + "' - banned player (" + id + ")");
|
||||||
error = "not-allowed";
|
error = "not-allowed";
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (chat_perms && !core.getServer().checkPlayerPermission(id, "webchat")) {
|
if (chat_perms && !core.getServer().checkPlayerPermission(id, "webchat")) {
|
||||||
Log.info("Rejected web chat from '" + message.name + "': not permitted (" + id + ")");
|
Log.info("Rejected web chat from '" + safeString(message.name) + "': not permitted (" + id + ")");
|
||||||
error = "not-allowed";
|
error = "not-allowed";
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
message.name = id;
|
message.name = id;
|
||||||
isip = false;
|
isip = false;
|
||||||
} else if (require_player_login_ip) {
|
} else if (require_player_login_ip) {
|
||||||
Log.info("Ignore message from '" + message.name + "' - no matching player login recorded");
|
Log.info("Ignore message from '" + safeString(message.name) + "' - no matching player login recorded");
|
||||||
error = "not-allowed";
|
error = "not-allowed";
|
||||||
ok = false;
|
ok = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue