Tweak DoS limits and logging; update dependencies

This commit is contained in:
Sean Owen 2021-01-15 17:03:12 -06:00
parent 6dd0776b96
commit 3374aed3fd
6 changed files with 23 additions and 11 deletions

View file

@ -442,7 +442,7 @@
<dependency> <dependency>
<groupId>com.puppycrawl.tools</groupId> <groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId> <artifactId>checkstyle</artifactId>
<version>8.38</version> <version>8.39</version>
</dependency> </dependency>
</dependencies> </dependencies>
</plugin> </plugin>

View file

@ -39,7 +39,7 @@
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>30.0-android</version> <version>30.1-android</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
@ -73,7 +73,7 @@
</parent> </parent>
<properties> <properties>
<spring.version>5.3.1</spring.version> <spring.version>5.3.2</spring.version>
</properties> </properties>
<build> <build>

View file

@ -25,7 +25,7 @@ import javax.servlet.annotation.WebInitParam;
@WebFilter(urlPatterns = {"/w/chart"}, initParams = { @WebFilter(urlPatterns = {"/w/chart"}, initParams = {
@WebInitParam(name = "maxAccessPerTime", value = "120"), @WebInitParam(name = "maxAccessPerTime", value = "120"),
@WebInitParam(name = "accessTimeSec", value = "60"), @WebInitParam(name = "accessTimeSec", value = "60"),
@WebInitParam(name = "maxEntries", value = "10000"), @WebInitParam(name = "maxEntries", value = "100000"),
@WebInitParam(name = "maxLoad", value = "0.9") @WebInitParam(name = "maxLoad", value = "0.9")
}) })
public final class ChartDoSFilter extends DoSFilter { public final class ChartDoSFilter extends DoSFilter {

View file

@ -25,7 +25,7 @@ import javax.servlet.annotation.WebInitParam;
@WebFilter(urlPatterns = {"/w/decode"}, initParams = { @WebFilter(urlPatterns = {"/w/decode"}, initParams = {
@WebInitParam(name = "maxAccessPerTime", value = "60"), @WebInitParam(name = "maxAccessPerTime", value = "60"),
@WebInitParam(name = "accessTimeSec", value = "60"), @WebInitParam(name = "accessTimeSec", value = "60"),
@WebInitParam(name = "maxEntries", value = "10000"), @WebInitParam(name = "maxEntries", value = "100000"),
@WebInitParam(name = "maxLoad", value = "0.9") @WebInitParam(name = "maxLoad", value = "0.9")
}) })
public final class DecodeDoSFilter extends DoSFilter { public final class DecodeDoSFilter extends DoSFilter {

View file

@ -91,7 +91,7 @@ import javax.servlet.http.Part;
@WebServlet(value = "/w/decode", loadOnStartup = 1, initParams = { @WebServlet(value = "/w/decode", loadOnStartup = 1, initParams = {
@WebInitParam(name = "maxAccessPerTime", value = "120"), @WebInitParam(name = "maxAccessPerTime", value = "120"),
@WebInitParam(name = "accessTimeSec", value = "120"), @WebInitParam(name = "accessTimeSec", value = "120"),
@WebInitParam(name = "maxEntries", value = "10000") @WebInitParam(name = "maxEntries", value = "100000")
}) })
public final class DecodeServlet extends HttpServlet { public final class DecodeServlet extends HttpServlet {
@ -212,7 +212,11 @@ public final class DecodeServlet extends HttpServlet {
return; return;
} }
if (destHostTracker.isBanned(imageURI.getHost())) { String host = imageURI.getHost();
// Also should parse for 172.x subnets
if (host == null || host.startsWith("10.") || host.startsWith("192.168.") ||
"127.0.0.1".equals(host) || "localhost".equals(host) ||
destHostTracker.isBanned(host)) {
errorResponse(request, response, "badurl"); errorResponse(request, response, "badurl");
return; return;
} }

View file

@ -89,7 +89,10 @@ final class DoSTracker {
// smallest count > maxAccessesPerTime // smallest count > maxAccessesPerTime
int minDisallowedCount = Integer.MAX_VALUE; int minDisallowedCount = Integer.MAX_VALUE;
int localMAPT = maxAccessesPerTime; int localMAPT = maxAccessesPerTime;
int totalEntries;
int clearedEntries = 0;
synchronized (numRecentAccesses) { synchronized (numRecentAccesses) {
totalEntries = numRecentAccesses.size();
Iterator<Map.Entry<String,AtomicInteger>> accessIt = numRecentAccesses.entrySet().iterator(); Iterator<Map.Entry<String,AtomicInteger>> accessIt = numRecentAccesses.entrySet().iterator();
while (accessIt.hasNext()) { while (accessIt.hasNext()) {
Map.Entry<String,AtomicInteger> entry = accessIt.next(); Map.Entry<String,AtomicInteger> entry = accessIt.next();
@ -99,6 +102,7 @@ final class DoSTracker {
if (count <= localMAPT) { if (count <= localMAPT) {
accessIt.remove(); accessIt.remove();
maxAllowedCount = Math.max(maxAllowedCount, count); maxAllowedCount = Math.max(maxAllowedCount, count);
clearedEntries++;
} else { } else {
// Else it exceeded the max, so log it (again) // Else it exceeded the max, so log it (again)
log.warning(name + ": Blocking " + entry.getKey() + " (" + count + " outstanding)"); log.warning(name + ": Blocking " + entry.getKey() + " (" + count + " outstanding)");
@ -108,6 +112,8 @@ final class DoSTracker {
} }
} }
} }
log.info(name + ": " + clearedEntries + " of " + totalEntries + " cleared");
if (maxLoad != null) { if (maxLoad != null) {
OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean(); OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
if (mxBean == null) { if (mxBean == null) {
@ -117,11 +123,13 @@ final class DoSTracker {
if (loadAvg >= 0.0) { if (loadAvg >= 0.0) {
int cores = mxBean.getAvailableProcessors(); int cores = mxBean.getAvailableProcessors();
double loadRatio = loadAvg / cores; double loadRatio = loadAvg / cores;
log.info(name + ": Load ratio: " + loadRatio + " (" + loadAvg + '/' + cores + ") vs " + maxLoad); int newMaxAccessesPerTime = loadRatio > maxLoad ?
maxAccessesPerTime = loadRatio > maxLoad ? Math.min(maxAllowedCount, Math.max(1, maxAccessesPerTime - 1)) :
Math.min(maxAllowedCount, maxAccessesPerTime) :
Math.max(minDisallowedCount, maxAccessesPerTime); Math.max(minDisallowedCount, maxAccessesPerTime);
log.info(name + ": New maxAccessesPerTime: " + maxAccessesPerTime); log.info(name + ": Load ratio: " + loadRatio +
" (" + loadAvg + '/' + cores + ") vs " + maxLoad +
"; new maxAccessesPerTime: " + newMaxAccessesPerTime);
maxAccessesPerTime = newMaxAccessesPerTime;
} }
} }
} }