You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ma...@apache.org on 2022/10/11 09:17:40 UTC
[iotdb] 01/01: fix dos attack
This is an automated email from the ASF dual-hosted git repository.
marklau99 pushed a commit to branch fix-regex
in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 1bf41662bbd9543afdbe34de676889a666bc12e7
Author: Liu Xuxin <li...@outlook.com>
AuthorDate: Tue Oct 11 17:17:22 2022 +0800
fix dos attack
---
.../resources/conf/iotdb-engine.properties | 4 ++
.../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 10 +++++
.../org/apache/iotdb/db/conf/IoTDBDescriptor.java | 7 ++++
.../iotdb/tsfile/common/conf/TSFileConfig.java | 10 +++++
.../iotdb/tsfile/read/filter/operator/Regexp.java | 48 +++++++++++++++++++++-
5 files changed, 78 insertions(+), 1 deletion(-)
diff --git a/server/src/assembly/resources/conf/iotdb-engine.properties b/server/src/assembly/resources/conf/iotdb-engine.properties
index 8991b9933a..f8267b9c38 100644
--- a/server/src/assembly/resources/conf/iotdb-engine.properties
+++ b/server/src/assembly/resources/conf/iotdb-engine.properties
@@ -741,6 +741,10 @@ timestamp_precision=ms
# Datatype: long
# slow_query_threshold=5000
+# max pattern access time in regex filter
+# Datatype: int
+# pattern_matching_threshold=1000000
+
####################
### MQTT Broker Configuration
####################
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index d92bd997e9..f4517811da 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -792,6 +792,8 @@ public class IoTDBConfig {
/** time cost(ms) threshold for slow query. Unit: millisecond */
private long slowQueryThreshold = 5000;
+ private int patternMatchingThreshold = 1000000;
+
/**
* whether enable the rpc service. This parameter has no a corresponding field in the
* iotdb-engine.properties
@@ -2796,4 +2798,12 @@ public class IoTDBConfig {
public void setChunkMetadataMemorySizeProportion(double chunkMetadataMemorySizeProportion) {
this.chunkMetadataMemorySizeProportion = chunkMetadataMemorySizeProportion;
}
+
+ public int getPatternMatchingThreshold() {
+ return patternMatchingThreshold;
+ }
+
+ public void setPatternMatchingThreshold(int patternMatchingThreshold) {
+ this.patternMatchingThreshold = patternMatchingThreshold;
+ }
}
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
index 7516081328..fadf77ccf0 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
@@ -928,6 +928,13 @@ public class IoTDBDescriptor {
.setDfsClientFailoverProxyProvider(
properties.getProperty(
"dfs_client_failover_proxy_provider", conf.getDfsClientFailoverProxyProvider()));
+ TSFileDescriptor.getInstance()
+ .getConfig()
+ .setPatternMatchingThreshold(
+ Integer.parseInt(
+ properties.getProperty(
+ "pattern_matching_threshold",
+ String.valueOf(conf.getPatternMatchingThreshold()))));
TSFileDescriptor.getInstance()
.getConfig()
.setUseKerberos(
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java
index df5df28446..0fd1bdcaa6 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/common/conf/TSFileConfig.java
@@ -146,6 +146,8 @@ public class TSFileConfig implements Serializable {
private double bloomFilterErrorRate = 0.05;
/** The amount of data iterate each time */
private int batchSize = 1000;
+
+ private int patternMatchingThreshold = 1000000;
/** customizedProperties, this should be empty by default. */
private Properties customizedProperties = new Properties();
@@ -422,4 +424,12 @@ public class TSFileConfig implements Serializable {
public void setCustomizedProperties(Properties customizedProperties) {
this.customizedProperties = customizedProperties;
}
+
+ public int getPatternMatchingThreshold() {
+ return patternMatchingThreshold;
+ }
+
+ public void setPatternMatchingThreshold(int patternMatchingThreshold) {
+ this.patternMatchingThreshold = patternMatchingThreshold;
+ }
}
diff --git a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Regexp.java b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Regexp.java
index 646b51ba57..31e7260469 100644
--- a/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Regexp.java
+++ b/tsfile/src/main/java/org/apache/iotdb/tsfile/read/filter/operator/Regexp.java
@@ -18,6 +18,7 @@
*/
package org.apache.iotdb.tsfile.read.filter.operator;
+import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
import org.apache.iotdb.tsfile.file.metadata.statistics.Statistics;
import org.apache.iotdb.tsfile.read.filter.basic.Filter;
import org.apache.iotdb.tsfile.read.filter.factory.FilterSerializeId;
@@ -66,7 +67,7 @@ public class Regexp<T extends Comparable<T>> implements Filter {
if (filterType != FilterType.VALUE_FILTER) {
return false;
}
- return pattern.matcher(value.toString()).find();
+ return pattern.matcher(new MatcherInput(value.toString(), new AccessCount())).find();
}
@Override
@@ -124,4 +125,49 @@ public class Regexp<T extends Comparable<T>> implements Filter {
public FilterSerializeId getSerializeId() {
return FilterSerializeId.REGEXP;
}
+
+ private static class AccessCount {
+ private int count;
+ private final int accessThreshold =
+ TSFileDescriptor.getInstance().getConfig().getPatternMatchingThreshold();
+
+ public void check() throws IllegalStateException {
+ if (this.count++ > accessThreshold) {
+ throw new IllegalStateException("Pattern access threshold exceeded");
+ }
+ }
+ }
+
+ private static class MatcherInput implements CharSequence {
+
+ private final CharSequence value;
+
+ private final AccessCount access;
+
+ public MatcherInput(CharSequence value, AccessCount access) {
+ this.value = value;
+ this.access = access;
+ }
+
+ @Override
+ public char charAt(int index) {
+ this.access.check();
+ return this.value.charAt(index);
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return new MatcherInput(this.value.subSequence(start, end), this.access);
+ }
+
+ @Override
+ public int length() {
+ return this.value.length();
+ }
+
+ @Override
+ public String toString() {
+ return this.value.toString();
+ }
+ }
}