MXS-1461 Introduce 'not_function' rule
Using 'not_function' it is possible to match functions other than a specific set of ones. That will make it significantly easier to allow certain functions to be used with certain columns. The special handling of no arguments to `function` in conjunction with an allowing filter has been removed. The same effect can now be achieved, without special handling, using `not_function`, no arguments and a blocking filter. Implementation will follow in a subsequent commit.
This commit is contained in:
@ -161,24 +161,36 @@ matched. The symbolic comparison operators (`<`, `>`, `>=` etc.) are also
|
|||||||
considered functions whereas the text versions (`NOT`, `IS`, `IS NOT` etc.) are
|
considered functions whereas the text versions (`NOT`, `IS`, `IS NOT` etc.) are
|
||||||
not considered functions.
|
not considered functions.
|
||||||
|
|
||||||
If the rule is given no values then the rule will match any query which does not
|
|
||||||
use functions. By combining this with the `action=allow` parameter, it is
|
|
||||||
possible to enable whitelisting of all queries which do not use functions. One
|
|
||||||
such use case is preventing functions from being used to circumvent masking done
|
|
||||||
by the masking filter.
|
|
||||||
|
|
||||||
When the filter is in whitelist mode (`action=allow`) the function rule
|
|
||||||
will match any query that does not use a function. This means that queries
|
|
||||||
that do not use functions will be allowed through a function type rule.
|
|
||||||
|
|
||||||
##### Example
|
##### Example
|
||||||
|
|
||||||
Deny SUM and COUNT functions:
|
Match queries using the _sum_ and _count_ functions:
|
||||||
|
|
||||||
```
|
```
|
||||||
rule examplerule match function sum count
|
rule examplerule match function sum count
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `not_function`
|
||||||
|
|
||||||
|
This rule expects a list of values after the `not_function` keyword. These values
|
||||||
|
are interpreted as function names and if a query uses any function other than these,
|
||||||
|
it is matched. The symbolic comparison operators (`<`, `>`, `>=` etc.) are also
|
||||||
|
considered functions whereas the text versions (`NOT`, `IS`, `IS NOT` etc.) are
|
||||||
|
not considered functions.
|
||||||
|
|
||||||
|
If the rule is given no values, then the rule will match a query using any function.
|
||||||
|
|
||||||
|
#### Example
|
||||||
|
|
||||||
|
Match queries using other functions but the _length_ function:
|
||||||
|
```
|
||||||
|
rule examplerule match not_function length
|
||||||
|
```
|
||||||
|
|
||||||
|
Match queries using functions:
|
||||||
|
```
|
||||||
|
rule examplerule match not_function
|
||||||
|
```
|
||||||
|
|
||||||
#### `uses_function`
|
#### `uses_function`
|
||||||
|
|
||||||
This rule expects a list of column names after the keyword. If any of the
|
This rule expects a list of column names after the keyword. If any of the
|
||||||
@ -207,6 +219,31 @@ Deny use of the _sum_ function with _name_ or _address_ columns:
|
|||||||
rule examplerule match function sum columns name address
|
rule examplerule match function sum columns name address
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `not_function` and `columns`
|
||||||
|
|
||||||
|
This rule combines the `not_function` and `columns` type rules to match if
|
||||||
|
one of the listed columns is used in conjunction with functions other than
|
||||||
|
the listed ones. The rule expects the `not_function` and `columns` keywords
|
||||||
|
both followed by a list of values.
|
||||||
|
|
||||||
|
If `not_function` is not provided with a list of values, then the rule
|
||||||
|
matches if any of the columns is used with any function.
|
||||||
|
|
||||||
|
##### Example
|
||||||
|
|
||||||
|
Match if any other function but _length_ is used with the _name_ or _address_
|
||||||
|
columns:
|
||||||
|
|
||||||
|
```
|
||||||
|
rule examplerule match not_function length columns name address
|
||||||
|
```
|
||||||
|
|
||||||
|
Match if any function is used with the _ssn_column:
|
||||||
|
|
||||||
|
```
|
||||||
|
rule examplerule match not_function columns ssn
|
||||||
|
```
|
||||||
|
|
||||||
#### `regex`
|
#### `regex`
|
||||||
|
|
||||||
This rule blocks all queries matching a regex enclosed in single or double
|
This rule blocks all queries matching a regex enclosed in single or double
|
||||||
|
@ -870,11 +870,11 @@ void define_columns_rule(void* scanner)
|
|||||||
*
|
*
|
||||||
* @param scanner Current scanner
|
* @param scanner Current scanner
|
||||||
*/
|
*/
|
||||||
void define_function_rule(void* scanner)
|
void define_function_rule(void* scanner, bool inverted)
|
||||||
{
|
{
|
||||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||||
ss_dassert(rstack);
|
ss_dassert(rstack);
|
||||||
rstack->add(new FunctionRule(rstack->name, rstack->values));
|
rstack->add(new FunctionRule(rstack->name, rstack->values, inverted));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -894,11 +894,11 @@ void define_function_usage_rule(void* scanner)
|
|||||||
*
|
*
|
||||||
* @param scanner Current scanner
|
* @param scanner Current scanner
|
||||||
*/
|
*/
|
||||||
void define_column_function_rule(void* scanner)
|
void define_column_function_rule(void* scanner, bool inverted)
|
||||||
{
|
{
|
||||||
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
struct parser_stack* rstack = (struct parser_stack*)dbfw_yyget_extra((yyscan_t) scanner);
|
||||||
ss_dassert(rstack);
|
ss_dassert(rstack);
|
||||||
rstack->add(new ColumnFunctionRule(rstack->name, rstack->values, rstack->auxiliary_values));
|
rstack->add(new ColumnFunctionRule(rstack->name, rstack->values, rstack->auxiliary_values, inverted));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,9 +43,9 @@ void define_wildcard_rule(void* scanner);
|
|||||||
void define_where_clause_rule(void* scanner);
|
void define_where_clause_rule(void* scanner);
|
||||||
bool define_regex_rule(void* scanner, char* pattern);
|
bool define_regex_rule(void* scanner, char* pattern);
|
||||||
void define_columns_rule(void* scanner);
|
void define_columns_rule(void* scanner);
|
||||||
void define_function_rule(void* scanner);
|
void define_function_rule(void* scanner, bool inverted);
|
||||||
void define_function_usage_rule(void* scanner);
|
void define_function_usage_rule(void* scanner);
|
||||||
void define_column_function_rule(void* scanner);
|
void define_column_function_rule(void* scanner, bool inverted);
|
||||||
void define_limit_queries_rule(void* scanner, int max, int timeperiod, int holdoff);
|
void define_limit_queries_rule(void* scanner, int max, int timeperiod, int holdoff);
|
||||||
bool add_at_times_rule(void* scanner, const char* range);
|
bool add_at_times_rule(void* scanner, const char* range);
|
||||||
void add_on_queries_rule(void* scanner, const char* sql);
|
void add_on_queries_rule(void* scanner, const char* sql);
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
%token FWTOK_RULE FWTOK_USERS FWTOK_RULES FWTOK_ANY FWTOK_ALL
|
%token FWTOK_RULE FWTOK_USERS FWTOK_RULES FWTOK_ANY FWTOK_ALL
|
||||||
%token FWTOK_STRICT_ALL FWTOK_MATCH FWTOK_WILDCARD FWTOK_COLUMNS FWTOK_REGEX
|
%token FWTOK_STRICT_ALL FWTOK_MATCH FWTOK_WILDCARD FWTOK_COLUMNS FWTOK_REGEX
|
||||||
%token FWTOK_LIMIT_QUERIES FWTOK_WHERE_CLAUSE FWTOK_AT_TIMES FWTOK_ON_QUERIES
|
%token FWTOK_LIMIT_QUERIES FWTOK_WHERE_CLAUSE FWTOK_AT_TIMES FWTOK_ON_QUERIES
|
||||||
%token FWTOK_FUNCTION FWTOK_USES_FUNCTION FWTOK_COMMENT FWTOK_PIPE
|
%token FWTOK_FUNCTION FWTOK_USES_FUNCTION FWTOK_COMMENT FWTOK_PIPE FWTOK_NOT_FUNCTION
|
||||||
|
|
||||||
/** Terminal typed symbols */
|
/** Terminal typed symbols */
|
||||||
%token <floatval>FWTOK_FLOAT <strval>FWTOK_TIME <strval>FWTOK_BTSTR
|
%token <floatval>FWTOK_FLOAT <strval>FWTOK_TIME <strval>FWTOK_BTSTR
|
||||||
@ -124,9 +124,15 @@ mandatory
|
|||||||
{define_limit_queries_rule(scanner, $2, $3, $4);}
|
{define_limit_queries_rule(scanner, $2, $3, $4);}
|
||||||
| FWTOK_REGEX FWTOK_QUOTEDSTR {define_regex_rule(scanner, $2);}
|
| FWTOK_REGEX FWTOK_QUOTEDSTR {define_regex_rule(scanner, $2);}
|
||||||
| FWTOK_COLUMNS valuelist {define_columns_rule(scanner);}
|
| FWTOK_COLUMNS valuelist {define_columns_rule(scanner);}
|
||||||
| FWTOK_FUNCTION valuelist {define_function_rule(scanner);}
|
| FWTOK_FUNCTION valuelist {define_function_rule(scanner, false);}
|
||||||
| FWTOK_FUNCTION {define_function_rule(scanner);}
|
| FWTOK_NOT_FUNCTION valuelist {define_function_rule(scanner, true);}
|
||||||
| FWTOK_FUNCTION valuelist FWTOK_COLUMNS auxiliaryvaluelist {define_column_function_rule(scanner);}
|
| FWTOK_NOT_FUNCTION {define_function_rule(scanner, true);}
|
||||||
|
| FWTOK_FUNCTION valuelist FWTOK_COLUMNS auxiliaryvaluelist
|
||||||
|
{define_column_function_rule(scanner, false);}
|
||||||
|
| FWTOK_NOT_FUNCTION valuelist FWTOK_COLUMNS auxiliaryvaluelist
|
||||||
|
{define_column_function_rule(scanner, true);}
|
||||||
|
| FWTOK_NOT_FUNCTION FWTOK_COLUMNS auxiliaryvaluelist
|
||||||
|
{define_column_function_rule(scanner, true);}
|
||||||
| FWTOK_USES_FUNCTION valuelist {define_function_usage_rule(scanner);}
|
| FWTOK_USES_FUNCTION valuelist {define_function_usage_rule(scanner);}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -180,12 +180,16 @@ class FunctionRule: public ValueListRule
|
|||||||
FunctionRule& operator=(const FunctionRule&);
|
FunctionRule& operator=(const FunctionRule&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FunctionRule(std::string name, const ValueList& values):
|
FunctionRule(std::string name, const ValueList& values, bool inverted):
|
||||||
ValueListRule(name, "FUNCTION", values)
|
ValueListRule(name, inverted ? "NOT_FUNCTION" : "FUNCTION", values),
|
||||||
|
m_inverted(inverted)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool matches_query(DbfwSession* session, GWBUF* buffer, char** msg) const;
|
bool matches_query(DbfwSession* session, GWBUF* buffer, char** msg) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_inverted; /*< Should the match be inverted. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,9 +218,10 @@ class ColumnFunctionRule: public ValueListRule
|
|||||||
ColumnFunctionRule& operator=(const ColumnFunctionRule&);
|
ColumnFunctionRule& operator=(const ColumnFunctionRule&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ColumnFunctionRule(std::string name, const ValueList& values, const ValueList& columns):
|
ColumnFunctionRule(std::string name, const ValueList& values, const ValueList& columns, bool inverted):
|
||||||
ValueListRule(name, "COLUMN_FUNCTION", values),
|
ValueListRule(name, inverted ? "NOT_COLUMN_FUNCTION" : "COLUMN_FUNCTION", values),
|
||||||
m_columns(columns)
|
m_columns(columns),
|
||||||
|
m_inverted(inverted)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +229,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ValueList m_columns; /*< List of columns to match */
|
ValueList m_columns; /*< List of columns to match */
|
||||||
|
bool m_inverted; /*< Should the match be inverted. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -40,6 +40,7 @@ CMP [=<>!]+
|
|||||||
deny|allow MXS_WARNING("Use of '%s' is deprecated, use 'match' instead", yytext);return FWTOK_MATCH;
|
deny|allow MXS_WARNING("Use of '%s' is deprecated, use 'match' instead", yytext);return FWTOK_MATCH;
|
||||||
rule return FWTOK_RULE;
|
rule return FWTOK_RULE;
|
||||||
function return FWTOK_FUNCTION;
|
function return FWTOK_FUNCTION;
|
||||||
|
not_function return FWTOK_NOT_FUNCTION;
|
||||||
uses_function return FWTOK_USES_FUNCTION;
|
uses_function return FWTOK_USES_FUNCTION;
|
||||||
no_where_clause return FWTOK_WHERE_CLAUSE;
|
no_where_clause return FWTOK_WHERE_CLAUSE;
|
||||||
wildcard return FWTOK_WILDCARD;
|
wildcard return FWTOK_WILDCARD;
|
||||||
|
Reference in New Issue
Block a user