diff --git a/rules/security/format_string_injection.py b/rules/security/format_string_injection.py new file mode 100644 index 0000000..cabf16c --- /dev/null +++ b/rules/security/format_string_injection.py @@ -0,0 +1,38 @@ +from frappe import _ + + +def bad_examples(): + try: + some_method() + except Exception as e: + # ruleid: frappe-format-string-injection + _("Failed to get method {0} with {1}").format(cmd, e) + + try: + some_method() + except Exception as e: + # ruleid: frappe-format-string-injection + _("Error: {}").format(e) + + +def good_examples(): + try: + some_method() + except Exception as e: + # ok: frappe-format-string-injection + _("Failed to get method {0} with {1}").format(cmd, str(e)) + + try: + some_method() + except Exception as e: + # ok: frappe-format-string-injection + _("Error: {}").format(str(e)) + + # ok: frappe-format-string-injection + _("Hello {0}").format(user_name) + + try: + some_method() + except Exception as e: + # ok: frappe-format-string-injection + _("Error: {}").format(cstr(e)) diff --git a/rules/security/format_string_injection.yml b/rules/security/format_string_injection.yml new file mode 100644 index 0000000..db29479 --- /dev/null +++ b/rules/security/format_string_injection.yml @@ -0,0 +1,32 @@ +rules: +- id: frappe-format-string-injection + patterns: + - pattern-either: + - pattern: _("...").format(..., $ERR, ...) + - pattern: _("...").format($ERR, ...) + - pattern: _("...").format($ERR) + - pattern-not: _("...").format(..., str($ERR), ...) + - pattern-not: _("...").format(str($ERR), ...) + - pattern-not: _("...").format(str($ERR)) + - pattern-not: _("...").format(..., cstr($ERR), ...) + - pattern-not: _("...").format(cstr($ERR), ...) + - pattern-not: _("...").format(cstr($ERR)) + - pattern-not: _("...").format(..., repr($ERR), ...) + - pattern-not: _("...").format(repr($ERR), ...) + - pattern-not: _("...").format(repr($ERR)) + - metavariable-pattern: + metavariable: $ERR + pattern: $ERR + - pattern-inside: | + try: + ... + except $ETYPE as $ERR: + ... + message: | + Exception object passed directly to `.format()` on a translated string. + Use `str($ERR)` to convert the exception to a plain string first. + languages: [python] + severity: ERROR + paths: + exclude: + - "**/test_*.py"