MXS-2457 Add treat_string_as_field to firewall
Necessary if the firewall should be able to block columns when
'ANSI_QUOTES' as enabled and " instead of backticks are used.
Without this, the following
> set @@sql_mode='ANSI_QUOTES';
> select "ssn" from person;
will not be blocked if the database firewall has been configured
to block the column ssn.
This commit is contained in:
@ -146,16 +146,32 @@ query itself is logged. The log messages are logged at the notice level.
|
|||||||
Log all queries that do not match a rule. The matched user and the query is
|
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.
|
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`
|
#### `treat_string_arg_as_field`
|
||||||
This optional parameter specifies how the database firewall should treat
|
This optional parameter specifies how the database firewall should treat
|
||||||
strings used as arguments to functions. If true, they will be handled
|
strings used as arguments to functions. If true, they will be handled
|
||||||
as fields, which will cause fields to be masked even if `ANSI_QUOTES` has
|
as fields, which will cause function column blocking rules to match even
|
||||||
been enabled and `"` is used instead of backtick.
|
even if `ANSI_QUOTES` has been enabled and `"` is used instead of backtick.
|
||||||
```
|
```
|
||||||
treat_string_arg_as_field=false
|
treat_string_arg_as_field=false
|
||||||
```
|
```
|
||||||
The default value is `true`.
|
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.
|
||||||
|
|
||||||
## Rule syntax
|
## Rule syntax
|
||||||
|
|
||||||
The rules are defined by using the following syntax:
|
The rules are defined by using the following syntax:
|
||||||
|
|||||||
@ -632,6 +632,11 @@ MXS_MODULE* MXS_CREATE_MODULE()
|
|||||||
MXS_MODULE_PARAM_BOOL,
|
MXS_MODULE_PARAM_BOOL,
|
||||||
"true"
|
"true"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"treat_string_as_field",
|
||||||
|
MXS_MODULE_PARAM_BOOL,
|
||||||
|
"true"
|
||||||
|
},
|
||||||
{MXS_END_MODULE_PARAMS}
|
{MXS_END_MODULE_PARAMS}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1247,6 +1252,7 @@ int global_version = 1;
|
|||||||
Dbfw::Dbfw(MXS_CONFIG_PARAMETER* params)
|
Dbfw::Dbfw(MXS_CONFIG_PARAMETER* params)
|
||||||
: m_action((enum fw_actions)config_get_enum(params, "action", action_values))
|
: m_action((enum fw_actions)config_get_enum(params, "action", action_values))
|
||||||
, m_log_match(0)
|
, m_log_match(0)
|
||||||
|
, m_treat_string_as_field(config_get_bool(params, "treat_string_as_field"))
|
||||||
, m_treat_string_arg_as_field(config_get_bool(params, "treat_string_arg_as_field"))
|
, m_treat_string_arg_as_field(config_get_bool(params, "treat_string_arg_as_field"))
|
||||||
, m_filename(config_get_string(params, "rules"))
|
, m_filename(config_get_string(params, "rules"))
|
||||||
, m_version(atomic_add(&global_version, 1))
|
, m_version(atomic_add(&global_version, 1))
|
||||||
@ -1276,6 +1282,32 @@ Dbfw* Dbfw::create(const char* zName, MXS_CONFIG_PARAMETER* pParams)
|
|||||||
if (process_rule_file(file, &rules, &users))
|
if (process_rule_file(file, &rules, &users))
|
||||||
{
|
{
|
||||||
rval = new(std::nothrow) Dbfw(pParams);
|
rval = new(std::nothrow) Dbfw(pParams);
|
||||||
|
|
||||||
|
if (rval)
|
||||||
|
{
|
||||||
|
if (rval->treat_string_as_field() || rval->treat_string_arg_as_field())
|
||||||
|
{
|
||||||
|
MXS_NOTICE("The parameter 'treat_string_arg_as_field' and/or "
|
||||||
|
"'treat_string_as_field' is enabled for %s. "
|
||||||
|
"As a consequence, the query classifier cache must be disabled.",
|
||||||
|
zName);
|
||||||
|
|
||||||
|
QC_CACHE_PROPERTIES cache_properties;
|
||||||
|
qc_get_cache_properties(&cache_properties);
|
||||||
|
|
||||||
|
if (cache_properties.max_size != 0)
|
||||||
|
{
|
||||||
|
cache_properties.max_size = 0;
|
||||||
|
qc_set_cache_properties(&cache_properties);
|
||||||
|
|
||||||
|
MXS_NOTICE("Query classifier cache disabled.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MXS_NOTICE("The query classifier cache was disabled already.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return rval;
|
return rval;
|
||||||
@ -1517,7 +1549,18 @@ int DbfwSession::routeQuery(GWBUF* buffer)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t option = m_instance->treat_string_arg_as_field() ? QC_OPTION_STRING_ARG_AS_FIELD : 0;
|
uint32_t option = 0;
|
||||||
|
|
||||||
|
if (m_instance->treat_string_as_field())
|
||||||
|
{
|
||||||
|
option |= QC_OPTION_STRING_AS_FIELD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_instance->treat_string_arg_as_field())
|
||||||
|
{
|
||||||
|
option |= QC_OPTION_STRING_ARG_AS_FIELD;
|
||||||
|
}
|
||||||
|
|
||||||
EnableOption enable(option);
|
EnableOption enable(option);
|
||||||
GWBUF* analyzed_queue = buffer;
|
GWBUF* analyzed_queue = buffer;
|
||||||
|
|
||||||
|
|||||||
@ -224,6 +224,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
fw_actions get_action() const;
|
fw_actions get_action() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should strings be treated as fields?
|
||||||
|
*
|
||||||
|
* @return True, if they should, false otherwise.
|
||||||
|
*/
|
||||||
|
bool treat_string_as_field() const
|
||||||
|
{
|
||||||
|
return m_treat_string_as_field;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Should string args be treated as fields?
|
* Should string args be treated as fields?
|
||||||
*
|
*
|
||||||
@ -277,6 +287,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
fw_actions m_action; /*< Default operation mode, defaults to deny */
|
fw_actions m_action; /*< Default operation mode, defaults to deny */
|
||||||
int m_log_match; /*< Log matching and/or non-matching queries */
|
int m_log_match; /*< Log matching and/or non-matching queries */
|
||||||
|
bool m_treat_string_as_field;
|
||||||
bool m_treat_string_arg_as_field;
|
bool m_treat_string_arg_as_field;
|
||||||
mutable std::mutex m_lock; /*< Instance spinlock */
|
mutable std::mutex m_lock; /*< Instance spinlock */
|
||||||
std::string m_filename; /*< Path to the rule file */
|
std::string m_filename; /*< Path to the rule file */
|
||||||
|
|||||||
Reference in New Issue
Block a user