Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Placing Directives before(-each) and after(-each) rule generation #9

Open
Sebitosh opened this issue Dec 16, 2024 · 0 comments
Open

Comments

@Sebitosh
Copy link
Contributor

Objective

When writing a test, the objective is to test the SecRule in the template, relative to any variation that might be relevant to testing it's behavior. One kind of variation to check behavior for is the directives that can be present around a rule.
What if for example, a SecRule is expected to increment a variable. If multiple of these rules are generated, it would be necessary to set and reset the incremented variables before each newly generated rule to avoid that generated rules have an impact on each others behavior by having them all interact on the same variable.
In an other example, we might want to test a rule when it is under a specific section container, such as <Location URL-path> to ensure it only has effect when accessing a specific URL.

For writing those test cases, we propose a feature to place directives before(-each) and after(-each) rule generation using the templates selected for a test set.

Current feature

Let's describe how MRTS generates SecRules and SecActions with templates.

global:
  version: MRTS/0.1
  baseid: 100000
  default_operator: "@rx"
  templates:
  - name: "SecRule for TARGETS"
    template: |
      SecRule $TARGET "$OPERATOR $OPARG" \
          "id:$CURRID,\
          phase:$PHASE,\
          deny,\
          t:none,\
          log,\
          msg:'%{MATCHED_VAR_NAME} was caught in phase:$PHASE',\
          ver:'$VERSION'"

Templates are defined globally, and used per-file for a collection of test cases.

General variables in templates are simply replaced with their value in a dictionnary, such as $VERSION with what is found in version.

Other variables however, are used in generating combinations of test cases, such as $TARGET $OPERATOR $OPARG and $PHASE. For each of these variables, there is either one variable per file, making the generated tests only use this variable, or their is a list of variables used to generate combinations of test cases. Those rule combinations are placed in the same rule file, which is then included with every other rule file in the ModSecurity configuration.

Proposition

In configuration files, a directives section would be added, with special key-value pairs within. Keys before, before_each, after, after_each could be defined:

before would add the specified directives before all generated rules.

after would add the specified directives after all generated rules.

before_each would add the specified directives before each generated rule.

after_each would add the specified directives after each generated rule.

For example (note that, as for templates, the | yaml symbol is used to write in multiline):

...

templates:
- SecRule for TARGETS
directives:
  before: SecAction "id:100,phase:1,pass,initsid:abc"
  after: Header set X-ReqBodyLength %{length}
  before_each: |
      <Location /xml>
      SecAction "id:$CURRID,phase:$PHASE,pass,setvar:tx.var=%{tx.var},123"
      SecRule TX:var "^,(.*)$" "id:$CURRID,phase:$PHASE,pass,capture, setvar:tx.var=%{tx.1}"
  after_each: |
      SecRule TX:var "123" "id:$CURRID,phase:$PHASE,pass,log,msg:'TX.var was not modified'"
      </Location>
phase:
- 2
- 3

...

Would add the following directives :

SecAction "id:100,phase:1,pass,initsid:abc" # Before

<Location /xml> # Before-Each
SecAction "id:100000,phase:2,pass,setvar:tx.var=%{tx.var},123" # Before-Each
SecRule TX:var "^,(.*)$" "id:100001,phase:2,pass,capture, setvar:tx.var=%{tx.1}" # Before-Each

# Template
SecRule ARGS "@contains attack" \
    "id:100002,\
    phase:2,\
    t:none,\
    log,\
    msg:'%{MATCHED_VAR_NAME} was caught in phase:2',\
    ver:'MRTS/0.1'"

SecRule TX:var "123" "id:100003,phase:2,pass,log,msg:'TX.var was not modified'" # After-Each
</Location> # After-Each
 
<Location /xml> # Before-Each
SecAction "id:100004,phase:2,pass,setvar:tx.var=%{tx.var},123" # Before-Each
SecRule TX:var "^,(.*)$" "id:100005,phase:$PHASE,pass,capture, setvar:tx.var=%{tx.1}" # Before-Each

# Template
SecRule ARGS "@contains attack" \
    "id:100006,\
    phase:3,\
    t:none,\
    log,\
    msg:'%{MATCHED_VAR_NAME} was caught in phase:3',\
    ver:'MRTS/0.1'"

SecRule TX:var "123" "id:100007,phase:3,pass,log,msg:'TX.var was not modified'" # After-Each
</Location> # After-Each

Header set X-ReqBodyLength %{length} # After
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant