Skip to content

Commit

Permalink
Add file_delete server mech, security features
Browse files Browse the repository at this point in the history
Yay for basic security
  • Loading branch information
mcmonkey4eva committed Nov 5, 2014
1 parent 83e347a commit 3035db8
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 3 deletions.
17 changes: 16 additions & 1 deletion src/main/java/net/aufdemrand/denizen/Settings.java
Expand Up @@ -30,7 +30,7 @@ public static String getAlternateScriptPath() {

public static boolean showDebug() {
return DenizenAPI.getCurrentInstance().getConfig()
.getBoolean("Debug.Show", false);
.getBoolean("Debug.Show", true);
}

public static int consoleWidth() {
Expand Down Expand Up @@ -193,6 +193,21 @@ public static int whileMaxLoops() {
.getInt("Commands.While.Max loops", 10000);
}

public static boolean allowDelete() {
return DenizenAPI.getCurrentInstance().getConfig()
.getBoolean("Commands.Delete.Allow file deletion", true);
}

public static boolean allowLogging() {
return DenizenAPI.getCurrentInstance().getConfig()
.getBoolean("Commands.log.Allow logging", true);
}

public static boolean allowStrangeYAMLSaves() {
return DenizenAPI.getCurrentInstance().getConfig()
.getBoolean("Commands.yaml.Allow saving outside folder", false);
}

public static String chatMultipleTargetsFormat() {
return DenizenAPI.getCurrentInstance().getConfig()
.getString("Commands.Chat.Options.Multiple targets format", "%target%, %target%, %target%, and others");
Expand Down
@@ -1,5 +1,6 @@
package net.aufdemrand.denizen.scripts.commands.core;

import net.aufdemrand.denizen.tags.core.UtilTags;
import net.aufdemrand.denizencore.exceptions.CommandExecutionException;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.objects.*;
Expand Down Expand Up @@ -58,6 +59,11 @@ public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
dList result = new dList();

for (String object: objects) {
if (object.equalsIgnoreCase("server")) {
UtilTags.adjustServer(new Mechanism(mechanism, value));
continue;
}

Class object_class = ObjectFetcher.getObjectClass(object.split("@")[0]);

if (object_class == null) {
Expand All @@ -75,7 +81,7 @@ public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
fetched = ObjectFetcher.getObjectFrom(object_class, object);

// Make sure this object is Adjustable
if (!(fetched instanceof Adjustable)) {
if (fetched == null || !(fetched instanceof Adjustable)) {
dB.echoError("'" + object + "' is not adjustable.");
return;
}
Expand Down
Expand Up @@ -5,6 +5,7 @@
import java.io.IOException;
import java.net.URLDecoder;

import net.aufdemrand.denizen.Settings;
import net.aufdemrand.denizencore.exceptions.CommandExecutionException;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
import net.aufdemrand.denizen.objects.Element;
Expand Down Expand Up @@ -51,6 +52,10 @@ else if (!scriptEntry.hasObject("message"))

@Override
public void execute(ScriptEntry scriptEntry) throws CommandExecutionException {
if (!Settings.allowLogging()) {
dB.echoError("Logging disabled by administrator.");
return;
}
Element message = scriptEntry.getElement("message");
Element fileName = scriptEntry.getElement("file");
Element typeElement = scriptEntry.getElement("type");
Expand Down
@@ -1,5 +1,6 @@
package net.aufdemrand.denizen.scripts.commands.core;

import net.aufdemrand.denizen.Settings;
import net.aufdemrand.denizen.events.bukkit.ReplaceableTagEvent;
import net.aufdemrand.denizencore.exceptions.CommandExecutionException;
import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException;
Expand All @@ -17,6 +18,7 @@
import org.json.JSONObject;

import java.io.*;
import java.net.URLDecoder;
import java.util.*;

public class YamlCommand extends AbstractCommand implements Listener {
Expand Down Expand Up @@ -241,6 +243,15 @@ public void execute(final ScriptEntry scriptEntry) throws CommandExecutionExcept
case SAVE:
if (yamls.containsKey(id)) {
try {
if (!Settings.allowStrangeYAMLSaves()) {
File fileObj = new File(DenizenAPI.getCurrentInstance().
getDataFolder().getAbsolutePath() + "/" + filename.asString());
String directory = URLDecoder.decode(System.getProperty("user.dir"));
if (!fileObj.getCanonicalPath().startsWith(directory)) {
dB.echoError("Outside-the-main-folder YAML saves disabled by administrator.");
return;
}
}
FileWriter fw = new FileWriter(DenizenAPI.getCurrentInstance()
.getDataFolder().getAbsolutePath() + "/" + filename.asString());
BufferedWriter writer = new BufferedWriter(fw);
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/net/aufdemrand/denizen/tags/core/UtilTags.java
Expand Up @@ -7,6 +7,7 @@

import java.sql.Connection;
import net.aufdemrand.denizen.Denizen;
import net.aufdemrand.denizen.Settings;
import net.aufdemrand.denizen.events.EventManager;
import net.aufdemrand.denizen.events.bukkit.ReplaceableTagEvent;
import net.aufdemrand.denizen.flags.FlagManager;
Expand Down Expand Up @@ -677,6 +678,38 @@ else if (player.getName().toLowerCase().contains(matchInput) && matchPlayer == n

}

public static void adjustServer(Mechanism mechanism) {
Element value = mechanism.getValue();

// <--[mechanism]
// @object server
// @name delete_file
// @input Element
// @description
// Deletes the given file from the server.
// @tags
// <server.has_file[<file>]>
// -->
if (mechanism.matches("delete_file") && mechanism.hasValue()) {
if (!Settings.allowDelete()) {
dB.echoError("File deletion disabled by administrator.");
return;
}
File file = new File(DenizenAPI.getCurrentInstance().getDataFolder(), value.asString());
try {
file.delete();
}
catch (Exception e) {
dB.echoError("Failed to delete file: " + e.getMessage());
}
}

// TODO: Properties somehow?

if (!mechanism.fulfilled())
mechanism.reportInvalid();
}


@EventHandler
public void utilTag(ReplaceableTagEvent event) {
Expand Down
18 changes: 17 additions & 1 deletion src/main/resources/config.yml
Expand Up @@ -80,8 +80,24 @@ Commands:
To target: "[<def[talker].name>] -> You: <def[message]>"
With target to bystanders: "[<def[talker].name>] -> <def[target].name>: <def[message]>"
With targets to bystanders: "[<def[talker].name>] -> [<def[targets]>]: <def[message]>"
Delete:
# Whether scripts are allowed to delete files from your server
# This is mostly to clean up saves, but could potentially be abused.
# Set to 'false' if you're worried about security.
Allow file deletion: true
log:
# The log command writes to file, which is potentially dangerous
# Set to 'false' if you're worried about security.
Allow logging: true
yaml:
# Whether the YAML command is allowed to save outside the minecraft folder.
# Set to 'false' if you're worried about security.
Allow saving outside folder: false
# GENERAL SECURITY NOTE: Always run your server on a user with access to nothing but the minecraft folder
# Otherwise, a bad script or plugin could potentially damage things
# ALSO: Always read scripts you download for anything suspicious looking, EG the log command, the file_delete mechanism, ...

# The version of this configuration file, used to check if your
# configuration file is outdated or too new
Config:
Version: 7
Version: 8

0 comments on commit 3035db8

Please sign in to comment.