change parsing of SetVar actions

Change tokenization of SetVar expressions and use syntax
analyzer (seclang-parser) to process them. More precisely:
 1 SetVar expression is tokenized in two modes, quoted and
   not quoted, depending on whether it started with single
   quote (')
 2 Variable name and value can consist of multiple tokens,
   which are assembled back in syntax analyzer.
This allows to support escapes (escape single/double quote,
spaces etc.) and correctly detect where the expression ends.
Fixes #1529
This commit is contained in:
asterite
2017-08-17 16:44:01 +03:00
committed by Felipe Zimmerle
parent e0ebf28540
commit 0be821ded7
2 changed files with 116 additions and 72 deletions

View File

@@ -649,6 +649,8 @@ using modsecurity::operators::Operator;
RUN_TIME_VAR_TIME_SEC "RUN_TIME_VAR_TIME_SEC"
RUN_TIME_VAR_TIME_WDAY "RUN_TIME_VAR_TIME_WDAY"
RUN_TIME_VAR_TIME_YEAR "RUN_TIME_VAR_TIME_YEAR"
SETVAR_VARIABLE_PART "SETVAR_VARIABLE_PART"
SETVAR_CONTENT_PART "SETVAR_CONTENT_PART"
VARIABLE "VARIABLE"
DICT_ELEMENT "Dictionary element"
DICT_ELEMENT_REGEXP "Dictionary element, selected by regexp"
@@ -656,6 +658,10 @@ using modsecurity::operators::Operator;
%type <std::unique_ptr<actions::Action>> act
%type <std::unique_ptr<actions::Action>> setvar_action
%type <std::string> setvar_variable
%type <std::string> setvar_content
%type <std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > >
actions_may_quoted
actions
@@ -2321,25 +2327,9 @@ act:
{
ACTION_CONTAINER($$, new actions::SetUID($1));
}
| ACTION_SETVAR NOT VARIABLE
| ACTION_SETVAR setvar_action
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::unsetOperation, $3));
}
| ACTION_SETVAR VARIABLE
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setToOneOperation, $2));
}
| ACTION_SETVAR VARIABLE SETVAR_OPERATION_EQUALS FREE_TEXT
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setOperation, $2, $4));
}
| ACTION_SETVAR VARIABLE SETVAR_OPERATION_EQUALS_PLUS FREE_TEXT
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, $2, $4));
}
| ACTION_SETVAR VARIABLE SETVAR_OPERATION_EQUALS_MINUS FREE_TEXT
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, $2, $4));
$$ = std::move($2);
}
| ACTION_SEVERITY
{
@@ -2487,6 +2477,53 @@ act:
}
;
setvar_action:
NOT setvar_variable
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::unsetOperation, $2));
}
| setvar_variable
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setToOneOperation, $1));
}
| setvar_variable SETVAR_OPERATION_EQUALS setvar_content
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setOperation, $1, $3));
}
| setvar_variable SETVAR_OPERATION_EQUALS_PLUS setvar_content
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, $1, $3));
}
| setvar_variable SETVAR_OPERATION_EQUALS_MINUS setvar_content
{
ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, $1, $3));
}
;
setvar_variable:
SETVAR_VARIABLE_PART
{
$$ = $1;
}
|
SETVAR_VARIABLE_PART setvar_variable
{
$$ = $1 + $2;
}
;
setvar_content:
SETVAR_CONTENT_PART
{
$$ = $1;
}
|
SETVAR_CONTENT_PART setvar_content
{
$$ = $1 + $2;
}
;
%%
void yy::seclang_parser::error (const location_type& l, const std::string& m) {