MXS-3021: Make strictness of dbfwfilter configurable

In some cases the dbfwfilter is too strict and SQL that would not match a
rule is blocked due to it not being fully parsed. To allow a more lenient
mode of operation, the requirement for full parsing must be made
configurable.
This commit is contained in:
Markus Mäkelä 2020-06-03 08:27:01 +03:00
parent ac1e2d4202
commit da5af75c1c
No known key found for this signature in database
GPG Key ID: 5CE746D557ACC499
3 changed files with 42 additions and 7 deletions

View File

@ -113,31 +113,46 @@ Log all queries that do not match a rule. The matched user and the query is
logged. The log messages are logged at the notice level.
#### `treat_string_as_field`
This optional parameter specifies how the database firewall should treat
strings. If true, they will be handled as fields, which will cause column
blocking rules to match even if `ANSI_QUOTES` has been enabled and `"` is
used instead of backtick.
```
treat_string_as_field=false
```
The default value is `true`.
Note that this may cause a false positive, if a "true" string contains the
name of a column to be blocked.
#### `treat_string_arg_as_field`
This optional parameter specifies how the database firewall should treat
strings used as arguments to functions. If true, they will be handled
as fields, which will cause function column blocking rules to match even
even if `ANSI_QUOTES` has been enabled and `"` is used instead of backtick.
```
treat_string_arg_as_field=false
```
The default value is `true`.
Note that this may cause a false positive, if a "true" string contains the
name of a column to be blocked.
#### `strict`
Whether to treat unsupported SQL or multi-statement SQL as an error. This is a
boolean parameter and the default value is `true`.
When disabled, SQL that cannot be fully parsed is allowed to pass if the rules
do not cause it to be blocked. This can be used to provide a best-effort mode
where uncertainly about the SQL is allowed.
## Rule syntax
The rules are defined by using the following syntax:

View File

@ -635,6 +635,11 @@ MXS_MODULE* MXS_CREATE_MODULE()
MXS_MODULE_PARAM_BOOL,
"true"
},
{
"strict",
MXS_MODULE_PARAM_BOOL,
"true"
},
{MXS_END_MODULE_PARAMS}
}
};
@ -1254,6 +1259,7 @@ Dbfw::Dbfw(MXS_CONFIG_PARAMETER* params)
, m_treat_string_arg_as_field(params->get_bool("treat_string_arg_as_field"))
, m_filename(params->get_string("rules"))
, m_version(atomic_add(&global_version, 1))
, m_strict(params->get_bool("strict"))
{
if (params->get_bool("log_match"))
{
@ -1533,7 +1539,7 @@ int DbfwSession::routeQuery(GWBUF* buffer)
type = qc_get_type_mask(buffer);
}
if (modutil_is_SQL(buffer) && modutil_count_statements(buffer) > 1)
if (m_instance->strict() && modutil_is_SQL(buffer) && modutil_count_statements(buffer) > 1)
{
set_error("This filter does not support multi-statements.");
rval = send_error();
@ -1810,13 +1816,16 @@ bool rule_matches(Dbfw* my_instance,
{
qc_parse_result_t parse_result = qc_parse(queue, QC_COLLECT_ALL);
if (parse_result == QC_QUERY_INVALID)
if (my_instance->strict())
{
msg = create_parse_error(my_instance, "tokenized", query, &matches);
}
else if (parse_result != QC_QUERY_PARSED && rule->need_full_parsing(queue))
{
msg = create_parse_error(my_instance, "parsed completely", query, &matches);
if (parse_result == QC_QUERY_INVALID)
{
msg = create_parse_error(my_instance, "tokenized", query, &matches);
}
else if (parse_result != QC_QUERY_PARSED && rule->need_full_parsing(queue))
{
msg = create_parse_error(my_instance, "parsed completely", query, &matches);
}
}
}

View File

@ -244,6 +244,16 @@ public:
return m_treat_string_arg_as_field;
}
/**
* Whether unsupported SQL is an error
*
* @return True if unsupported SQL is an error
*/
bool strict() const
{
return m_strict;
}
/**
* Get logging option bitmask
*
@ -292,6 +302,7 @@ private:
mutable std::mutex m_lock; /*< Instance spinlock */
std::string m_filename; /*< Path to the rule file */
int m_version; /*< Latest rule file version, incremented on reload */
bool m_strict;
Dbfw(MXS_CONFIG_PARAMETER* param);
bool do_reload_rules(std::string filename);