mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-05 07:58:08 +01:00
Backported SQL Injection vulnerability fix and other small fixes
This commit is contained in:
parent
d34172412c
commit
65e186f15c
@ -175,6 +175,11 @@ public class ResourceSvc implements ResourceService {
|
||||
byte[] bytes = original.asBytes();
|
||||
OpenOption[] overwrite = {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE};
|
||||
Path to = resourceSettings.getCustomizationDirectory().resolve(fileName);
|
||||
if (!to.startsWith(resourceSettings.getCustomizationDirectory())) {
|
||||
throw new IllegalArgumentException(
|
||||
"Absolute path was given for writing a customized file, " +
|
||||
"writing outside customization directory is prevented for security reasons.");
|
||||
}
|
||||
Path dir = to.getParent();
|
||||
if (!Files.isSymbolicLink(dir)) Files.createDirectories(dir);
|
||||
Files.write(to, bytes, overwrite);
|
||||
|
@ -31,7 +31,11 @@ public class JoinAddress {
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address.get();
|
||||
String joinAddress = address.get();
|
||||
if (joinAddress.contains("\u0000")) {
|
||||
joinAddress = joinAddress.split("\u0000", 2)[0];
|
||||
}
|
||||
return joinAddress;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.identification.ServerUUID;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
public class QueryParameterSetter {
|
||||
@ -30,20 +31,36 @@ public class QueryParameterSetter {
|
||||
public static void setParameters(PreparedStatement statement, Object... parameters) throws SQLException {
|
||||
int index = 1;
|
||||
for (Object parameter : parameters) {
|
||||
setParameter(statement, index, parameter);
|
||||
index++;
|
||||
if (parameter instanceof Object[]) {
|
||||
for (Object arrayParameter : (Object[]) parameter) {
|
||||
setParameter(statement, index, arrayParameter);
|
||||
index++;
|
||||
}
|
||||
} else if (parameter instanceof Collection) {
|
||||
for (Object collectionParameter : (Collection<?>) parameter) {
|
||||
setParameter(statement, index, collectionParameter);
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
setParameter(statement, index, parameter);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setParameter(PreparedStatement statement, int index, Object parameter) throws SQLException {
|
||||
if (parameter == null) {
|
||||
statement.setNull(index, Types.VARCHAR);
|
||||
} else if (parameter instanceof Boolean) {
|
||||
statement.setBoolean(index, (Boolean) parameter);
|
||||
} else if (parameter instanceof Integer) {
|
||||
statement.setInt(index, (Integer) parameter);
|
||||
} else if (parameter instanceof Long) {
|
||||
statement.setLong(index, (Long) parameter);
|
||||
} else if (parameter instanceof Double) {
|
||||
statement.setDouble(index, (Double) parameter);
|
||||
} else if (parameter instanceof Character) {
|
||||
statement.setString(index, String.valueOf(parameter));
|
||||
} else if (parameter instanceof Float) {
|
||||
statement.setFloat(index, (Float) parameter);
|
||||
} else if (parameter instanceof String) {
|
||||
|
@ -21,6 +21,7 @@ import com.djrapitops.plan.identification.ServerUUID;
|
||||
import com.djrapitops.plan.storage.database.queries.Query;
|
||||
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
|
||||
import com.djrapitops.plan.storage.database.queries.RowExtractors;
|
||||
import com.djrapitops.plan.storage.database.sql.building.Sql;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
||||
@ -171,9 +172,7 @@ public class GeoInfoQueries {
|
||||
FROM + GeoInfoTable.TABLE_NAME + " g" +
|
||||
INNER_JOIN + UsersTable.TABLE_NAME + " u on u.id=g." + GeoInfoTable.USER_ID +
|
||||
WHERE + GeoInfoTable.GEOLOCATION +
|
||||
" IN ('" +
|
||||
new TextStringBuilder().appendWithSeparators(selected, "','") +
|
||||
"')";
|
||||
return db -> db.querySet(sql, RowExtractors.getInt(UsersTable.ID));
|
||||
" IN (" + Sql.nParameters(selected.size()) + ")";
|
||||
return db -> db.querySet(sql, RowExtractors.getInt(UsersTable.ID), selected);
|
||||
}
|
||||
}
|
@ -16,10 +16,13 @@
|
||||
*/
|
||||
package com.djrapitops.plan.storage.database.sql.building;
|
||||
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* Duplicate String reducing utility class for SQL language Strings.
|
||||
@ -56,6 +59,12 @@ public abstract class Sql {
|
||||
private static final String MAX = "MAX(";
|
||||
private static final String VARCHAR = "varchar(";
|
||||
|
||||
public static String nParameters(int n) {
|
||||
return new TextStringBuilder()
|
||||
.appendWithSeparators(IntStream.range(0, n).mapToObj(i -> "?").iterator(), ",")
|
||||
.toString();
|
||||
}
|
||||
|
||||
public static String varchar(int length) {
|
||||
return VARCHAR + length + ')';
|
||||
}
|
||||
|
@ -161,6 +161,9 @@ public class PlanFiles implements SubSystem {
|
||||
Path dir = config.get().getResourceSettings().getCustomizationDirectory();
|
||||
if (dir.toFile().exists() && dir.toFile().isDirectory()) {
|
||||
Path asPath = dir.resolve(resourceName);
|
||||
if (!asPath.startsWith(dir)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
File found = asPath.toFile();
|
||||
if (found.exists()) {
|
||||
return Optional.of(found);
|
||||
|
Loading…
Reference in New Issue
Block a user