diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9b7db7d..a802277 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
--- develop ---
+* security: Escape threshold web output and harden RLIKE filters
* issue#686: Applying a templated threshold to a graph via the wrench icon, creates a duplicate graph
* issue#707: Excessive timeout for row caching prevents data from being updated timely
* issue#710: Fixing Typo in thold_daemons.service File
diff --git a/tests/Unit/TholdRlikeClauseTest.php b/tests/Unit/TholdRlikeClauseTest.php
new file mode 100644
index 0000000..19e5f70
--- /dev/null
+++ b/tests/Unit/TholdRlikeClauseTest.php
@@ -0,0 +1,45 @@
+assertSame("RLIKE 'router'", thold_rlike_clause('router'));
+ }
+
+ /**
+ * @return void
+ */
+ public function testQuotesInTheFilterAreEscaped(): void {
+ $this->assertSame("RLIKE ''' OR 1=1 -- '", thold_rlike_clause("' OR 1=1 -- "));
+ }
+
+ /**
+ * @return void
+ */
+ public function testCoreHelperIsPreferredWhenAvailable(): void {
+ $this->assertSame(db_qstr_rlike('x'), thold_rlike_clause('x'));
+ }
+}
diff --git a/thold.php b/thold.php
index 0bf86f4..e9c491c 100644
--- a/thold.php
+++ b/thold.php
@@ -614,7 +614,7 @@ function list_tholds() {
}
if (get_request_var('rfilter') != '') {
- $sql_where .= ($sql_where == '' ? '(' : ' AND ') . " td.name_cache RLIKE '" . get_request_var('rfilter') . "'";
+ $sql_where .= ($sql_where == '' ? '(' : ' AND ') . ' td.name_cache ' . thold_rlike_clause(get_request_var('rfilter'));
}
if ($statefilter != '') {
@@ -763,18 +763,18 @@ function list_tholds() {
- '>
+ '>