diff --git a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp index dbb1f4c37f59..5a56343420a0 100644 --- a/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp +++ b/java/ql/src/Security/CWE/CWE-730/PolynomialReDoS.qhelp @@ -15,8 +15,7 @@

- Pattern.compile("^\\s+|\\s+$").matcher(text).replaceAll("") // BAD - +Pattern.compile("^\\s+|\\s+$").matcher(text).replaceAll("") // BAD

@@ -71,8 +70,7 @@

- "^0\\.\\d+E?\\d+$"" - +"^0\\.\\d+E?\\d+$""

@@ -103,6 +101,33 @@ + +

+ Sometimes it is unclear how a regular expression can be rewritten to + avoid the problem. In such cases, it often suffices to limit the + length of the input string. For instance, the following + regular expression is used to match numbers, and on some non-number + inputs it can have quadratic time complexity: +

+ + +Pattern.matches("^(\\+|-)?(\\d+|(\\d*\\.\\d*))?(E|e)?([-+])?(\\d+)?$", str); + +

+ It is not immediately obvious how to rewrite this regular expression + to avoid the problem. However, you can mitigate performance issues by limiting the length + to 1000 characters, which will always finish in a reasonable amount + of time. +

+ + +if (str.length() > 1000) { + throw new IllegalArgumentException("Input too long"); +} + +Pattern.matches("^(\\+|-)?(\\d+|(\\d*\\.\\d*))?(E|e)?([-+])?(\\d+)?$", str); + + diff --git a/javascript/ql/src/Performance/PolynomialReDoS.qhelp b/javascript/ql/src/Performance/PolynomialReDoS.qhelp index 210a4a8a84bc..2a96c60edd86 100644 --- a/javascript/ql/src/Performance/PolynomialReDoS.qhelp +++ b/javascript/ql/src/Performance/PolynomialReDoS.qhelp @@ -15,8 +15,7 @@

- text.replace(/^\s+|\s+$/g, ''); // BAD - +text.replace(/^\s+|\s+$/g, ''); // BAD

@@ -71,8 +70,7 @@

- /^0\.\d+E?\d+$/.test(str) // BAD - +/^0\.\d+E?\d+$/.test(str) // BAD

@@ -103,6 +101,33 @@ + +

+ Sometimes it is unclear how a regular expression can be rewritten to + avoid the problem. In such cases, it often suffices to limit the + length of the input string. For instance, the following + regular expression is used to match numbers, and on some non-number + inputs it can have quadratic time complexity: +

+ + +/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/.test(str) // BAD + +

+ It is not immediately obvious how to rewrite this regular expression + to avoid the problem. However, you can mitigate performance issues by limiting the length + to 1000 characters, which will always finish in a reasonable amount + of time. +

+ + +if (str.length > 1000) { + throw new Error("Input too long"); +} + +/^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/.test(str) + + diff --git a/python/ql/src/Security/CWE-730/PolynomialReDoS.qhelp b/python/ql/src/Security/CWE-730/PolynomialReDoS.qhelp index fa8a3563d23a..9157fc442ebb 100644 --- a/python/ql/src/Security/CWE-730/PolynomialReDoS.qhelp +++ b/python/ql/src/Security/CWE-730/PolynomialReDoS.qhelp @@ -15,8 +15,7 @@

- re.sub(r"^\s+|\s+$", "", text) # BAD - +re.sub(r"^\s+|\s+$", "", text) # BAD

@@ -71,8 +70,7 @@

- ^0\.\d+E?\d+$ # BAD - +^0\.\d+E?\d+$ # BAD

@@ -103,6 +101,32 @@ + +

+ Sometimes it is unclear how a regular expression can be rewritten to + avoid the problem. In such cases, it often suffices to limit the + length of the input string. For instance, the following + regular expression is used to match numbers, and on some non-number + inputs it can have quadratic time complexity: +

+ + +match = re.search(r'^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$', str) + +

+ It is not immediately obvious how to rewrite this regular expression + to avoid the problem. However, you can mitigate performance issues by limiting the length + to 1000 characters, which will always finish in a reasonable amount + of time. +

+ + +if len(str) > 1000: + raise ValueError("Input too long") + +match = re.search(r'^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$', str) + + diff --git a/ruby/ql/src/queries/security/cwe-1333/PolynomialReDoS.qhelp b/ruby/ql/src/queries/security/cwe-1333/PolynomialReDoS.qhelp index 0a93a3a245c3..f66fd40b792b 100644 --- a/ruby/ql/src/queries/security/cwe-1333/PolynomialReDoS.qhelp +++ b/ruby/ql/src/queries/security/cwe-1333/PolynomialReDoS.qhelp @@ -15,8 +15,7 @@

- text.gsub!(/^\s+|\s+$/, '') # BAD - +text.gsub!(/^\s+|\s+$/, '') # BAD

@@ -74,8 +73,7 @@

- /^0\.\d+E?\d+$/ # BAD - +/^0\.\d+E?\d+$/ # BAD

@@ -108,6 +106,33 @@ + +

+ Sometimes it is unclear how a regular expression can be rewritten to + avoid the problem. In such cases, it often suffices to limit the + length of the input string. For instance, the following + regular expression is used to match numbers, and on some non-number + inputs it can have quadratic time complexity: +

+ + +is_matching = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/.match?(str) + +

+ It is not immediately obvious how to rewrite this regular expression + to avoid the problem. However, you can mitigate performance issues by limiting the length + to 1000 characters, which will always finish in a reasonable amount + of time. +

+ + +if str.length > 1000 + raise ArgumentError, "Input too long" +end + +is_matching = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/.match?(str) + +