diff --git a/docs/security-tuning.md b/docs/security-tuning.md index 1f2b615d3..bb44bc5d7 100644 --- a/docs/security-tuning.md +++ b/docs/security-tuning.md @@ -264,7 +264,7 @@ ModSecurity is integrated and enabled by default alongside the OWASP Core Rule S You can choose between the following versions of the OWASP Core Rule Set : -- **3** : The version [v3.3.6](https://github.com/coreruleset/coreruleset/releases/tag/v3.3.6) of the OWASP Core Rule Set +- **3** : The version [v3.3.7](https://github.com/coreruleset/coreruleset/releases/tag/v3.3.7) of the OWASP Core Rule Set - **4** : The version [v4.8.0](https://github.com/coreruleset/coreruleset/releases/tag/v4.8.0) of the OWASP Core Rule Set (***default***) - **nightly** : The latest [nightly](https://github.com/coreruleset/coreruleset/releases/tag/nightly) build of the OWASP Core Rule Set which is updated every day diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.editorconfig b/src/common/core/modsecurity/files/coreruleset-v3/.editorconfig deleted file mode 100644 index 037ae5e38..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.editorconfig +++ /dev/null @@ -1,24 +0,0 @@ -# EditorConfig is awesome: https://EditorConfig.org - -# top-most EditorConfig file -root = true - -# Unix-style newlines with a newline ending every file -[*] -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -# Matches multiple files with brace expansion notation -# Set default charset -[*.py] -charset = utf-8 -# 4 space indentation -indent_style = space -indent_size = 4 - -# Indentation override for all JS under lib directory -[tests/regression/tests/**/*.yaml] -indent_style = space -indent_size = 2 - diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/FUNDING.yml b/src/common/core/modsecurity/files/coreruleset-v3/.github/FUNDING.yml deleted file mode 100644 index c0386a3ec..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -custom: https://coreruleset.org/donate diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/01_false-positive.md b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/01_false-positive.md index 8dfb24b59..eeb0b7a3e 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/01_false-positive.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/01_false-positive.md @@ -1,68 +1,31 @@ --- name: 'False positive' -about: Report a false positive (blocking of benign traffic) +about: Report a false positive (incorrect blocking) title: '' -labels: ':heavy_plus_sign: False Positive' +labels: 'False Positive' assignees: '' --- - - ### Description - + + -It is safest if you assume we know nothing about your service or software. ---> +### Audit Logs / Triggered Rule Numbers -### How to reproduce the misbehavior (-> curl call) - - - -### Logs - - + + ### Your Environment - + + -* CRS version (e.g., v3.3.4): -* Paranoia level setting (e.g. PL1) : -* ModSecurity version (e.g., 2.9.6): -* Web Server and version or cloud provider / CDN (e.g., Apache httpd 2.4.54): +* CRS version (e.g., v3.2.0): +* Paranoia level setting: +* ModSecurity version (e.g., 2.9.3): +* Web Server and version (e.g., apache 2.4.41): * Operating System and version: ### Confirmation diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/02_false-negative.md b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/02_false-negative.md index 76a9b4a90..75b0e3544 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/02_false-negative.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/02_false-negative.md @@ -1,68 +1,30 @@ --- name: 'False negative' -about: Report a false negative (ignoring of malicious traffic) +about: Report a false negative (incorrect bypass) title: '' -labels: ':heavy_minus_sign: False Negative - Evasion' +labels: 'False Negative - Evasion' assignees: '' --- - - ### Description - - -### How to reproduce the misbehavior (-> curl call) - - - -### Logs - - + + + + + + + ### Your Environment - + + -* CRS version (e.g., v3.3.4): -* Paranoia level setting (e.g. PL1) : -* ModSecurity version (e.g., 2.9.6): -* Web Server and version or cloud provider / CDN (e.g., Apache httpd 2.4.54): +* CRS version (e.g., v3.2.0): +* Paranoia level setting: +* ModSecurity version (e.g., 2.9.3): +* Web Server and version (e.g., apache 2.4.41): * Operating System and version: ### Confirmation diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/03_bug-report.md b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/03_bug-report.md index 689b2b2a6..bc130f67f 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/03_bug-report.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/03_bug-report.md @@ -2,7 +2,7 @@ name: '🐞 Bug report' about: Create a report to help us improve title: '' -labels: ':bug: bug' +labels: 'Bug' assignees: '' --- diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/04_feature.md b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/04_feature.md index 04939383a..b2e82b611 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/04_feature.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/04_feature.md @@ -2,16 +2,10 @@ name: '🚀 Feature request' about: Suggest an idea for this project title: '' -labels: ':+1: Feature Request' +labels: 'Feature Request' assignees: '' --- - ### Motivation diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/config.yml b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/config.yml index 73951bb2c..4c1d7af74 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/config.yml +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ blank_issues_enabled: false contact_links: - name: Help and support - url: https://security.stackexchange.com/questions/tagged/owasp-crs + url: https://security.stackexchange.com/questions/tagged/owasp-crs about: For help and support please go here. - name: OWASP Core Rule Set mailing list - url: https://groups.google.com/a/owasp.org/g/modsecurity-core-rule-set-project + url: https://groups.google.com/a/owasp.org/forum/#!forum/modsecurity-core-rule-set-project about: Ask general usage questions and participate in discussions on the CRS. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/src/common/core/modsecurity/files/coreruleset-v3/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md deleted file mode 100644 index e71cd07cd..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ /dev/null @@ -1,30 +0,0 @@ -## Proposed changes - -Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. - - - -## PR Checklist - - - -- [ ] I have read the [CONTRIBUTING](https://github.com/coreruleset/coreruleset/blob/v4.0/dev/CONTRIBUTING.md) doc -- [ ] I have added positive tests proving my fix/feature works as intended. -- [ ] I have added negative tests that prove my fix/feature considers common cases that might end in false positives -- [ ] In case you changed a regular expression, you are not adding a ReDOS for pcre. You can check this using [regexploit](https://github.com/doyensec/regexploit) -- [ ] My test use the `comment` field to write the expected behavior -- [ ] I have added documentation for the rule or change (when appropriate) - -## Further comments - - - -## For the reviewer - - - -- [ ] Positive and negative tests were added -- [ ] Tests cover the intended fix/feature properly -- [ ] No usage of dangerous constructs like `ctl:requestBodyAccess=Off` were used in the rule -- [ ] In case a regular expression was changed, [there is no ReDOS](https://github.com/coreruleset/coreruleset/wiki/Testing-for-Regular-Expresion-DoS) -- [ ] Documentation is clear for the rule/change diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/release.yml b/src/common/core/modsecurity/files/coreruleset-v3/.github/release.yml deleted file mode 100644 index c2c0535ae..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/release.yml +++ /dev/null @@ -1,29 +0,0 @@ -# .github/release.yml - -changelog: - exclude: - labels: - - ignore-for-release - - release:ignore - authors: - - octocat - - changelog-pr-bot - categories: - - title: ⭐ Important changes - labels: - - release:important - - title: Breaking Changes 🛠 - labels: - - Semver-Major - - breaking-change - - release:breaking - - title: 🆕 New features and detections 🎉 - labels: - - Semver-Minor - - enhancement - - release:new-detection - - release:new-feature - - title: 🧰 Other Changes - labels: - - "*" - diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/check-pr-dependencies.yaml b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/check-pr-dependencies.yaml deleted file mode 100644 index b93b11ce7..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/check-pr-dependencies.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Check PR dependencies -on: - pull_request_target: - types: - - opened - - reopened - - edited - - synchronize - -jobs: - check_dependencies: - runs-on: ubuntu-latest - name: Check Dependencies - permissions: - pull-requests: read # Reason: To check PRs for dependencies. - steps: - - uses: gregsdennis/dependencies-action@main - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/check-pr-title.yaml b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/check-pr-title.yaml deleted file mode 100644 index 93ff570b4..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/check-pr-title.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Check PR title - -# default token permissions: none -permissions: {} - -on: - pull_request_target: - types: - - opened - - reopened - - edited - - synchronize - -jobs: - main: - name: Validate PR title - runs-on: ubuntu-latest - permissions: - pull-requests: read - steps: - - uses: amannn/action-semantic-pull-request@e9fabac35e210fea40ca5b14c0da95a099eff26f # v5.4.0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/lint.yaml b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/lint.yaml index 285712271..839317240 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/lint.yaml +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/lint.yaml @@ -1,77 +1,37 @@ +--- name: Lint -on: [push, pull_request, merge_group] - -# Pin versions to not disrupt test pipelines -env: - CRS_TOOLCHAIN_VERSION: '2.1.0' - SECRULES_PARSING_VERSION: '0.2.9' +on: [push, pull_request] jobs: check-syntax: runs-on: ubuntu-latest + strategy: + fail-fast: true + # check why is failing and change afterwards steps: - name: Checkout repo - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2 - with: - # required for version detection using `git describe` - fetch-depth: 50 + uses: actions/checkout@v2 - name: Lint Yaml - uses: ibiqlik/action-yamllint@2576378a8e339169678f9939646ee3ee325e845c # v3.1.1 + uses: ibiqlik/action-yamllint@v3 with: format: github file_or_dir: tests/regression/tests config_file: .yamllint.yml - name: Linelint - uses: fernandrone/linelint@7907a5dca0c28ea7dd05c6d8d8cacded713aca11 # v0.0.6 + uses: fernandrone/linelint@master id: linelint - name: Set up Python 3 - uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0 + uses: actions/setup-python@v2 with: python-version: 3.7 - name: "Check CRS syntax" run: | pip install --upgrade setuptools - pip install secrules-parsing==${{ env.SECRULES_PARSING_VERSION }} + pip install secrules-parsing secrules-parser -c --output-type github -f rules/*.conf - - name: Fetch upstream tags for version detection in next step - run: | - git remote add upstream https://github.com/coreruleset/coreruleset - git fetch --tags upstream - - - - name: "Check CRS formatting" - run: | - pip install --upgrade setuptools - pip install -r ./util/crs-rules-check/requirements.txt - ./util/crs-rules-check/rules-check.py --output=github -r crs-setup.conf.example -r rules/*.conf -t util/APPROVED_TAGS - - - name: "Find rules without test" - run: | - pip install --upgrade setuptools - pip install -r ./util/find-rules-without-test/requirements.txt - ./util/find-rules-without-test/find-rules-without-test.py --output=github . - - - name: "Install crs-toolchain ${{ env.CRS_TOOLCHAIN_VERSION }}" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download -R coreruleset/crs-toolchain "v${{ env.CRS_TOOLCHAIN_VERSION }}" \ - -p "crs-toolchain_${{ env.CRS_TOOLCHAIN_VERSION }}_linux_amd64.tar.gz" -O - | tar -xzvf - crs-toolchain - - - name: "Check that all assembly files are properly formatted" - run: | - ./crs-toolchain regex format -aco github - - - name: "Check that all rules are up to date" - run: | - ./crs-toolchain regex compare -ao github - - - name: "Check that all tests are properly numbered" - run: | - ./crs-toolchain util renumber-tests -cao github diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/nightly.yml b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/nightly.yml deleted file mode 100644 index 8640bff7e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/nightly.yml +++ /dev/null @@ -1,73 +0,0 @@ - -name: Nightly Release -on: - schedule: - - cron: '0 2 * * *' # run at 2 AM UTC - -jobs: - nightly: - name: Nightly Release - runs-on: ubuntu-latest - steps: - - name: Check GH API rate limits - run: | - gh api -i repos/coreruleset/coreruleset/releases/latest | grep -i "x-ratelimit" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: "Checkout repo" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2 - - - name: Delete previous nightly release - run: | - gh release delete --repo coreruleset/coreruleset --cleanup-tag --yes nightly - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Create nightly release - run: | - notes=$(cat <<"EOF" - Nightly releases are snapshots of the development activity on the Core Rule Set project that may include new features and bug fixes scheduled for upcoming releases. These releases are made available to make it easier for users to test their existing configurations against the Core Rule Set code base for potential issues or to experiment with new features, with a chance to provide feedback on ways to improve the changes before being released. - - As these releases are snapshots of the latest code, you may encounter an issue compared to the latest stable release so users are encouraged to run nightly releases in a non production environment. If you encounter an issue, please check our issue tracker to see if the issue has already been reported; if a report hasn't been made, please report it so we can review the issue and make any needed fixes. - EOF - ) - - gh release create \ - --repo coreruleset/coreruleset \ - --latest \ - --prerelease \ - --draft=false \ - --title "Latest Nightly" \ - --notes "${notes}" \ - nightly - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Publish draft if necessary - run: | - echo "A race condition in the GH API can cause a release published for a previously existing tag to be published as draft." - echo "Wait for 30 seconds for the API to catch up to the actual state, then check that the release has been properly published." - echo "If the release is still a draft, publish it." - sleep 30 - if gh release list --repo coreruleset/coreruleset --exclude-drafts | grep --quiet nightly; then - echo "Nightly release was created properly" - exit 0 - fi - - echo "Nightly release was created as draft. Publishing now." - - gh release edit \ - --repo coreruleset/coreruleset \ - --latest \ - --prerelease \ - --draft=false \ - nightly - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Check GH API rate limits - run: | - gh api -i repos/coreruleset/coreruleset/releases/latest | grep -i "x-ratelimit" - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/stale.yml b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/stale.yml index 13136db46..f3e129c8b 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/stale.yml +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/stale.yml @@ -10,11 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e # v9.0.0 + - uses: actions/stale@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - stale-issue-message: 'This issue has been open 30 days waiting for feedback. Remove the stale label or comment, or this will be closed in 14 days' + stale-issue-message: 'This issue has been open 120 days with no activity. Remove the stale label or comment, or this will be closed in 14 days' stale-issue-label: 'Stale issue' - days-before-stale: 30 + days-before-stale: 120 days-before-close: 14 - only-issue-labels: ':hourglass_flowing_sand: awaiting feedback' diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/test.yml b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/test.yml index 9fbb13269..0e8f3e7a9 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/test.yml +++ b/src/common/core/modsecurity/files/coreruleset-v3/.github/workflows/test.yml @@ -1,3 +1,4 @@ +--- name: Regression Tests on: @@ -10,13 +11,7 @@ on: paths: - 'rules/**' - 'tests/**' - - 'util/**' - '.github/**' - merge_group: - -# Pin tool versions to prevent problems -env: - GO_FTW_VERSION: '1.0.3' jobs: regression: @@ -26,39 +21,33 @@ jobs: modsec_version: [modsec2-apache] steps: - name: "Checkout repo" - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.2 + uses: actions/checkout@v4 - name: "Install dependencies" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GO_FTW_VERSION: '0.4.6' run: | - gh release download -R coreruleset/go-ftw "v${{ env.GO_FTW_VERSION }}" \ - -p "ftw_${{ env.GO_FTW_VERSION }}_linux_amd64.tar.gz" -O - | tar -xzvf - ftw + gh release download -R coreruleset/go-ftw v${GO_FTW_VERSION} -p "ftw_${GO_FTW_VERSION}_linux_amd64.tar.gz" -O - | tar -xzvf - ftw - name: "Run tests for ${{ matrix.modsec_version }}" + env: + FTW_LOGFILE: './tests/logs/${{ matrix.modsec_version }}/error.log' run: | - mkdir -p "tests/logs/${{ matrix.modsec_version }}/{nginx,apache2}" + mkdir -p "tests/logs/${{ matrix.modsec_version }}" docker compose -f ./tests/docker-compose.yml up -d "${{ matrix.modsec_version }}" docker compose -f ./tests/docker-compose.yml logs - if ! [ "$(docker inspect ${{ matrix.modsec_version }} --format='{{.State.Running}}')" = "true" ]; then - echo "Web server failed to start. Aborting." - exit 1 - fi - + [ $(docker inspect ${{ matrix.modsec_version }} --format='{{.State.Running}}') = 'true' ] ./ftw check -d tests/regression/tests - ./ftw run \ - -d tests/regression/tests \ - --log-file "tests/logs/${{ matrix.modsec_version }}/error.log" \ - --overrides tests/regression/httpd-overrides.yaml \ - --show-failures-only + ./ftw run -d tests/regression/tests --show-failures-only - - name: "Change permissions of artifacts for upload" + - name: "Change permissions if failed" if: failure() run: | - # Files created from the container will belong to root - sudo chmod -R a+r tests/logs + # we want to get the audit log, so change permissions (file is only for root on docker) + sudo chmod 644 tests/logs/${{ matrix.modsec_version }}/modsec_audit.log - - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 + - uses: actions/upload-artifact@v4 if: failure() with: name: waf-logs @@ -66,5 +55,4 @@ jobs: - name: Clean docker-compose run: | - docker compose -f ./tests/docker-compose.yml stop "${{ matrix.modsec_version }}" - docker compose -f ./tests/docker-compose.yml down + docker compose -f ./tests/docker-compose.yml down -t 0 diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.gitignore b/src/common/core/modsecurity/files/coreruleset-v3/.gitignore index dabe18fda..a8f9bac6b 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.gitignore +++ b/src/common/core/modsecurity/files/coreruleset-v3/.gitignore @@ -10,10 +10,6 @@ rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf # util/upgrade.py geoip util/geo-location/GeoIP.dat -# PHP functions frequency list generated and updated by running -# util/php-dictionary-gen.sh -util/php-dictionary-gen/frequencylist.txt - # Unit test caches .cache @@ -23,12 +19,3 @@ __pycache__/ *$py.class .idea/ - -# Ignore test logs -tests/logs/ - -# ignore .env in tests for docker-compose variables -tests/.env - -# Ignore Go-FTW configuration file -.ftw.yaml diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.gitmodules b/src/common/core/modsecurity/files/coreruleset-v3/.gitmodules index e69de29bb..592118760 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.gitmodules +++ b/src/common/core/modsecurity/files/coreruleset-v3/.gitmodules @@ -0,0 +1,4 @@ +[submodule "docs/OWASP-CRS-Documentation"] + path = docs/OWASP-CRS-Documentation + url = https://github.com/SpiderLabs/OWASP-CRS-Documentation + branch = master diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.linelint.yml b/src/common/core/modsecurity/files/coreruleset-v3/.linelint.yml index e2111917a..12e7c88e6 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.linelint.yml +++ b/src/common/core/modsecurity/files/coreruleset-v3/.linelint.yml @@ -10,4 +10,3 @@ rules: # will be ignored only by this rule ignore: - .pytest_cache/* - - .changes-pending.md diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.pre-commit-config.yaml b/src/common/core/modsecurity/files/coreruleset-v3/.pre-commit-config.yaml deleted file mode 100644 index 01e1a0fb2..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/.pre-commit-config.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -# Update the rev variable with the release version that you want, from the yamllint repo -# You can pass your custom .yamllint with args attribute. -repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 - hooks: - - id: check-yaml - args: [--allow-multiple-documents] - - id: end-of-file-fixer - - id: trailing-whitespace - exclude: '^regex-assembly/' - args: [--markdown-linebreak-ext=md] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.travis.yml b/src/common/core/modsecurity/files/coreruleset-v3/.travis.yml new file mode 100644 index 000000000..96765998f --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/.travis.yml @@ -0,0 +1,31 @@ +os: linux +language: python +python: + - 2.7 + +# no more required in travis +#sudo: required + +services: + - docker + +jobs: + include: + script: + - | + if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then + docker run -ti --name crs-test --entrypoint /docker-entrypoint.sh -e REPO=$TRAVIS_PULL_REQUEST_SLUG -e BRANCH=$TRAVIS_PULL_REQUEST_BRANCH themiddle/crs-test + else + docker run -ti --name crs-test --entrypoint /docker-entrypoint.sh -e REPO=$TRAVIS_REPO_SLUG -e BRANCH=$TRAVIS_BRANCH themiddle/crs-test + fi + +# safelist +branches: + only: + - v3.1/dev + - v3.2/dev + - v3.3/dev + - fix-travis + +#notifications: +# irc: "chat.freenode.net#modsecurity" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/.yamllint.yml b/src/common/core/modsecurity/files/coreruleset-v3/.yamllint.yml index 9064fad92..c07e5911d 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/.yamllint.yml +++ b/src/common/core/modsecurity/files/coreruleset-v3/.yamllint.yml @@ -11,8 +11,6 @@ rules: tests/regression/tests/REQUEST-920-PROTOCOL-ENFORCEMENT/920380.yaml tests/regression/tests/REQUEST-920-PROTOCOL-ENFORCEMENT/920390.yaml tests/regression/tests/REQUEST-941-APPLICATION-ATTACK-XSS/941360.yaml - tests/regression/tests/REQUEST-942-APPLICATION-ATTACK-SQLI/942521.yaml - tests/regression/tests/REQUEST-942-APPLICATION-ATTACK-SQLI/942522.yaml # don't bother me with this rule indentation: disable diff --git a/src/common/core/modsecurity/files/coreruleset-v3/CHANGES.md b/src/common/core/modsecurity/files/coreruleset-v3/CHANGES.md index 3c88ae2e9..a2026f3e5 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/CHANGES.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/CHANGES.md @@ -1,583 +1,23 @@ -# OWASP CRS CHANGES +# OWASP ModSecurity Core Rule Set (CRS) CHANGES ## Report Bugs/Issues to GitHub Issues Tracker or the mailinglist -* https://github.com/coreruleset/coreruleset/issues + +* or the CRS Google Group at -* https://groups.google.com/a/owasp.org/g/modsecurity-core-rule-set-project +* -## Nightly builds -New changelog entries are written to `.changes-pending.md`. They will be moved to the main changelog before a release. +## Version 3.3.7 - 2024-10-28 -## Version 4.4.0 - 2024-06-23 +### ⭐ Important changes -### 🆕 New features and detections 🎉 -* fix: ignore checking compressed response body by @azurit in https://github.com/coreruleset/coreruleset/pull/3712 +* fix: 9EA-241022 v3 by @RedXanadu in https://github.com/coreruleset/coreruleset/pull/3906 -### 🧰 Other Changes -* fix(934140): update regex by @fzipi in https://github.com/coreruleset/coreruleset/pull/3731 -* fix: replacing t:UrlDecode with t:UrlDecodeUni (921240 PL1, 932170 PL1, 932171 PL1, 932190 PL3, 932190 PL1, 933211 PL3, 941310 PL1, 941350 PL1) by @azurit in https://github.com/coreruleset/coreruleset/pull/3713 -* feat: skip response rules if data are compressed by @azurit in https://github.com/coreruleset/coreruleset/pull/3742 - -## Version 4.3.0 - 2024-05-24 - -### 🆕 New features and detections 🎉 - -* feat: catch Java PostgreSQL errors (951240 PL1) by @azurit in https://github.com/coreruleset/coreruleset/pull/3686 -* feat: block The Mysterious Mozlila User Agent bot (913100 PL1) by @brentclark in https://github.com/coreruleset/coreruleset/pull/3646 - -### 🧰 Other Changes -* fix: Oracle SQL database data leakage FP (951120 PL1) by @azurit in https://github.com/coreruleset/coreruleset/pull/3685 -* fix: typos in 920330 and 942280 tests by @TimDiam0nd in https://github.com/coreruleset/coreruleset/pull/3688 -* test: change pl-1 to pl1 to be inline with others by @TimDiam0nd in https://github.com/coreruleset/coreruleset/pull/3690 -* feat: use renovate to update docker-compose by @theseion in https://github.com/coreruleset/coreruleset/pull/3697 -* fix: FP for `sched` (932235 PL1, 932236 PL2, 932237 PL3, 932239 PL2, … by @theseion in https://github.com/coreruleset/coreruleset/pull/3701 -* fix: collections not being initialized without User-Agent header by @azurit in https://github.com/coreruleset/coreruleset/pull/3645 -* feat: refactoring of rule 941310 (PL1 941310) by @azurit in https://github.com/coreruleset/coreruleset/pull/3700 -* fix: resolving more FPs with Oracle error messages (951120 PL1) by @azurit in https://github.com/coreruleset/coreruleset/pull/3703 -* fix: removing double t:urlDecodeUni (920221 PL1, 920440 PL1, 932200 PL2, 932205 PL2, 932206 PL2) by @azurit in https://github.com/coreruleset/coreruleset/pull/3699 -* fix: false positives from PHP config directives and functions (933120 PL1, 933151 PL2) by @ssigwart in https://github.com/coreruleset/coreruleset/pull/3638 -* feat: prevent detection of web shells rules as malware by Windows Defender (955260 PL1) by @azurit in https://github.com/coreruleset/coreruleset/pull/3687 -* fix: fp with name axel by removing it from rce rule (932260 PL1) by @franbuehler in https://github.com/coreruleset/coreruleset/pull/3705 - -## Version 4.2.0 - 2024-04-23 - -Changes with direct rule impact (sorted by lowest rule ID per change where available): - - * fix: increase length of Accept-Encoding header from 50 to 100 (920520 PL1) (Franziska Bühler) [#3661] - * fix: add missing roundcube files (930120 PL1, 930121 PL2, 930130 PL1, 932180 PL1) (Esad Cetiner) [#3635] - * fix: add visudo and cscli to unix-shell.data (932160 PL1, 932161 PL2) (Esad Cetiner) [#3663] - * feat: block crowdsec cscli and visudo commands (932235 PL1, 932236 PL2, 932237 PL3, 932239 PL2, 932260 PL1) (Esad Cetiner) [#3649] - * fix: add detection for php evasion attempt (933100 PL1) (Franziska Bühler) [#3667] - -Changes without direct rule impact: - - * feat: disassemble php rule (933100 PL1) (Franziska Bühler) [#3662] - * chore: remove references to nonexistant 942110 rule (Esad Cetiner) [#3648] - -## Version 4.1.0 - 2024-03-21 - -Changes with direct rule impact (sorted by lowest rule ID per change where available): - - * feat: add support for additional ansible and chef commands (932160 PL1, 932161 PL2, 932235 PL1, 932260 PL1, 932236 PL2, 932239 PL2, 932237 PL3) (Esad Cetiner) [#3601] - * feat: move HTTP header rules to phase 1 (932161 PL2, 932205 PL2, 932206 PL2, 932237 PL3) (Esad Cetiner) [#3570] - * fix: remove t:lowercase from rules that use '(?i)' modifier in their regex (942150 PL2, 942151 PL1, 942152 PL2) (Ervin Hegedus) [#3585] - * fix: prevent FPs against names due to "cron" (932260 PL1, 932236 PL2, 932237 PL3, 932239 PL2) (@superlgn) [#3578] - * fix: add missing tags and ver action (various rules) (Jozef Sudolský) [#3571] - * fix: adding more missing tags and ver actions (Jozef Sudolský) [#3593] - * fix: do not check URL fragments in referer headers as part of the existing rule to prevent FPs (932205 PL2) (Max Leske) [#3485] - * fix: range expressions must not start with `\v` (various rules) (Max Leske) [#3615] - -Changes without direct rule impact: - - * feat: add check for combinations of t:lowercase and (?i) to lint (Franziska Bühler) [#3584] - * chore: add Esad Cetiner to list of developers (@EsadCetiner) [#3589] - * chore(deps): update workflow actions (Max Leske) [#3613] - * test: change HTTP method to uppercase for test 932260-28 (Matteo Pace) [#3580] - -## Version 4.0.0 - 2024-02-14 +## Version 3.3.6 - 2024-08-27 Important changes: - * feat: introduce plugin architecture for extending CRS and minimizing attack surface. (Christian Folini, Max Leske, Jozef Sudolský, Andrew Howe) [#2038, #2448, #2404] - * feat: migrate application exclusions and less-used functionality to plugins (Christian Folini, Max Leske, Jozef Sudolský, Andrew Howe) - * feat: introduce early blocking option (Christian Folini) [#1955] - * feat: introduce new rule file/category to detect use of common web shells in responses (955100-955340 PL1, 955350 PL2) (Jozef Sudolský, Andrea Menin) [#1962, #2039, #2116] - * feat: rename 'Node.js' category to 'generic' (Felipe Zipitría) [#2340] - * feat: make all formerly PCRE-only regular expressions compatible with RE2/Hyperscan regular expression engines (Max Leske, Felipe Zipitría, Allan Boll, Franziska Bühler) [#1868, #2356, #2425, #2426, #2371, #2372] - * feat: add support for HTTP/3 (Jozef Sudolský) [#3218] - * feat: add granular control over reporting levels in 9801xx rules (Simon Studer, Andrew Howe, Christian Folini) [#2482, #2488] - * feat: add new rule to explicitly detect multiple Content-Type abuse (CVE-2023-38199) (920620 PL1) (Andrea Menin) [#3237] - * feat: add enable_default_collections flag to not initialize collections by default (Matteo Pace) [#3141] - * feat: extend definition of restricted headers to include `Content-Encoding` and `Accept-Charset` by default (920450 PL1, 920451 PL2) (Walter Hop) [#2780, #2782] - * feat: drop HTTP/0.9 support to resolve FP (Federico G. Schwindt) [#1966] - * fix: refactor and rename anomaly scoring variables and paranoia level definition (Simon Studer) [#2417] - * tests: complete goal of 100% test coverage for rules (entire team, Juan-Pablo Tosso, NiceYouKnow) - * feat: switch to using WordNet instead of spell for finding English words in spell.sh (Max Leske) [#3242] - * feat: publish nightly packages regularly (Felipe Zipitría) [#2207] -Tool changes: - * feat: extend spell.sh script with an opt-in manual list of common and partial words. (Matteo Pace) [#3273] - * feat: rework spell.sh utility to help with detection of false positives English words (Andrea Menin) [#3029] - * feat: improve usability of spell.sh utility (Max Leske) [#3238] - * feat: extend rules-check.py script to better enforce rule format in project guidelines (Ervin Hegedus) [#3113] - * feat: extend rules-check.py script to ensure that `auditLogParts` is only used in last chained rule (Ervin Hegedus) [#2609] - * feat: extend rules-check.py script to ensure that rules use `@rx` operator explicitly (Ervin Hegedus) [#2541] - * feat: extend rules-check.py script to strip comments when parsing crs-setup.conf.example (Ervin Hegedus) [#3161] - * feat: add utility to change version numbers (Ervin Hegedus) [#2085] - * feat: add utility script to find rules without tests (Ervin Hegedus) [#2279] - * feat: add crs-rules-check tool that runs sanity checks against rules (Ervin Hegedus) [#2236] - * feat: add utility to find longest data lengths (Ervin Hegedus) [#2277] - * feat: improve rule-ctl script to modify rules (Max Leske) [#2193] - * feat: improve unique ID matching and documentation in send-payload-pls.sh (Manuel Spartan) [#2288] - * feat: unify regexp utils to automate error-prone actions and automatically update rules from regular expression sources (Max Leske) [#2149, #2223, #2423, #2495, #2489, #2473] - * fix: adjust log directories needed for volume mounts to Git (Max Leske) [#2103] - * fix: replace backend docker container for tests to fix JSON Unicode reflection (Max Leske) [#3464] - * feat: add new test method: check for tags on rules against allowlist (Ervin Hegedus) [#3437] - -Changes with direct rule impact (sorted by lowest rule ID per change where available): - * feat: add placeholder files for new plugin architecture (Walter Hop) [#2515] - * feat: check initialization and use for all TX variables (Ervin Hegedus) [#3043] - * feat: extend rule to detect restricted `method override` headers (Mark Zeman / KramNamez) [#3056] - * feat: extend rules to detect keyword `time` as prefix of \*nix and Windows RCE rules (rules later replaced) (Franziska Bühler) [#2819] - * feat: improve Unix shell evasion prefix (various rules) (Jitendra Patro, Max Leske) [#3518] - * feat: improve performance by removing unnecessary lowercase transformations (various rules) (Jozef Sudolský) [#2106] - * feat: add additional prefix commands to 'unix-shell-evasion-prefix' (various rules) (Jitendra Patro) [#3557 - * feat: consolidate 'unix-evasion-prefix*' files to ensure they don't diverge (various rules) (Franziska Bühler, Max Leske, Andrew Howe) [#3531] - * feat: move regexp-assemble data files to root directory (Felipe Zipitría) [#3002] - * feat: move rules to the earliest phase possible based on their inputs (various rules) (Ervin Hegedus) [#1941] - * feat: remove superfluous 'urlDecodeUni' transformations (various rules) (Federico G. Schwindt) [#1845] - * feat: rename 'tx.blocking_early' to 'tx.early_blocking' (various rules) (Christian Folini) [#2414] - * feat: simplify regular expressions by replacing upper-case with lower-case matches if the expression is case-insensitive (various rules) (Felipe Zipitría) [#2485] - * feat: remove SecCollectionTimeout from crs-setup.conf (Christian Folini) [#3559] - * fix: do not log 'MATCHED_VAR' when the it contains the full response body (various rules) (Jozef Sudolský) [#1985] - * fix: do not unnecessarily escape forward slashes in regular expressions (various rules) (Federico G. Schwindt) [#1842] - * fix: reformat several initialization rules to follow project guidelines (Ervin Hegedus) [#3157] - * fix: remove auditLogParts actions from all rules where present (Andrea Menin, Ervin Hegedus) [#3034, #3081] - * fix: remove uncommon Content Types from default in `crs-setup.conf.example` (Andrea Menin) [#2768] - * fix: update diverse rules to follow new naming convention with paranoia level TX variables (Christoph Hansen) [#2937] - * fix: update various rules to consolidate use of backslashes to \x5c representation for better compatibility with known WAF engines (various rules) (Andrew Howe, Max Leske) [#2335, #2345, #2375, #2376, #2399, #2400, #2402, #2410, #2420, #2441, #2442, #2454, #2426] - * fix: remove initialization rules for redundant IP reputation variables (901150, 901152) (Andrew Howe) [#2833] - * fix: initialize all variables used properly (901169) (Ervin Hegedus) [#2802] - * feat: improve sampling mode efficiency (901410, 901420, 901440) (Paul Beckett) [#2094] - * fix: replace uses of 'ctl:ruleEngine=Off' with "ctl:ruleRemoveByTag=OWASP_CRS" to accomodate more than one ruleset (901450, 905100, 905110) (Jozef Sudolský) [#2156] - * feat: remove old, commented-out IP reputation check rule (910110 PL1) (Paul Beckett) [#2148] - * feat: detect 'burpcollaborator' scanner (913100 PL1) (Amir Hosein Aliakbarian) [#2152] - * feat: detect 'httpx' scanner (913100 PL1) (Will Woodson) [#2045] - * feat: detect 'LeakIX' scanner (913100 PL1) (Jozef Sudolský) [#1961] - * feat: detect 'QQGameHall' malware (913100 PL1) (Walter Hop) [#2144] - * feat: detect User-Agent of Tsunami Security Scanner (913100 PL1) (@hoexter) [#3480] - * fix: avoid FP for YAM package manager (913100 PL1) (Jozef Sudolský) [#2022] - * fix: move 'ecairn' from scanners to crawlers (913100 PL1) (Felipe Zipitría) [#2408] - * feat: detect 'CensysInspect' and seoscanners.net crawlers (913102 PL2) (Andrew Howe) [#2155] - * feat: detect 'ecairn' crawler (913102 PL2) (Jozef Sudolský) [#2024] - * feat: detect 'Krzana' bot (913102 PL2) (Deepshikha Sinha) [#2432] - * fix: remove rule to detect security scanner http headers (913110 PL1) (Christian Folini) [#3241] - * feat: remove ineffective anti-scanner list scanners-urls.data and associated rule (913120 PL1) (Christian Folini) [#3235] - * fix: correct the regular expression assembly (920120 PL1) (Max Leske) [#2333] - * feat: increase rule score from warning to critial (920220 PL1) (Max Leske) [#3512] - * fix: reduce FPs by handling the last path segment separately in new rule (920220 PL1, 920221 PL1) (Max Leske) [#3512] - * fix: reduce FPs by matching on decoded variables (920220 PL1) (Max Leske) [#3512] - * feat: prevent FPs by moving rule to higher PL (920240 PL2) (Max Leske) [#3506] - * feat: valiadate 'SEC-CH-UA' and 'SEC-CH-UA-MOBILE' request headers (920274 PL4) (Chaim Sanders) [#1970] - * fix: use the right kind of validation for 'Sec-CH-UA' and 'Sec-CH-UA-Mobile' request headers (920274 PL4, 920275 PL4) (somechris) [#2028] - * fix: make validatioin of 'Sec-Fetch-User' header more strict (920275 PL4) (somechris) [#2020] - * feat: move rule from PL2 to PL3 (920300 PL3) (Franziska Bühler) [#2013] - * fix: amend rule to exclude CONNECT requests from requiring an Accept header (920300 PL3) (Andrew Howe) [#2297] - * feat: add IPv6 to the 'Host header is a numeric IP address' check (920350 PL1) (itsTheFae, Ervin Hegedus, Jozef Sudolský) [#1929] - * fix: avoid FP on '.axd' in restricted extensions, these are public (920440 PL1) (Jozef Sudolský) [#1925] - * feat: rework restricted headers mechanism into two separate lists (920450 PL1, 920451 PL2) (Andrew Howe) [#3152] - * fix: avoid FP in 'application/\*+json' Content-Type (920470 PL1) (Mirko Dziadzka, Walter Hop) [#2455] - * fix: avoid FP in CalDAV Content-Type (920470 PL1) (Vandan Rohatgi) [#2505] - * fix: avoid FP in 'Content-Type' header with '#' character (920470 PL1) (Jozef Sudolský) [#1856] - * fix: avoid FP on 'version' string in Content-Type header (920470 PL1) (Jozef Sudolský) [#1901] - * fix: resolve false negative when matching against allowed charsets variable (920480 PL1) (katef, Federico G. Schwindt) [#1957] - * fix: replace unnecessary capture groups in regular expressions with non-capturing groups (920510 PL3, 932200 PL2, 942510 PL2, 942511 PL3) (Federico G. Schwindt) [#1983] - * feat: improve explanatory rule comments (920520 PL1) (Max Leske) [#2391] - * feat: validate 'Accept-Encoding' header (920520 PL1, 920521 PL3) (Franziska Bühler) [#2357] - * feat: new rule detect multiple occurrences of charset keyword in content type header (920530 PL1) (Jan Gora / terjanq) [#2571] - * feat: new rule to detect Unicode character bypass check for non JSON requests (920540 PL1) (Franziska Bühler, 0SPwn) [#2512] - * feat: new rule to detect # char in URIs (920610 PL1) (Karel Knibbe) [#2919] - * fix: use correct anomaly scoring variables and paranoia level tags across several rules (921170 PL1, 921220 PL4, 932220 PL2, 932331 PL3, 933211 PL3, 934101 PL1, 942362 PL2, 951100) (Christoph Hansen) [#2931] - * feat: new rules to detect HTTP parameter pollution bypasses (921210 PL3, 921220 PL4) (Christian Folini) [#2747] - * fix: use correct anomaly scoring variables and paranoia level tags across several rules (921220 PL4, 932101 PL2, 932331 PL3, 933211 PL3, 942362 PL2) (Ervin Hegedus) [#2832] - * feat: new rule to detect range header that is now forbidden on PL3 and up (921230 PL3) (Christian Folini) [#2760] - * feat: new rule to detect mod_proxy attack (CVE-2021-40438) (921240 PL1) (Franziska Bühler) [#2818] - * fix: add urlDecodeUni transformation rules with REQUEST_URI / REQUEST_BASENAME in phase 1 (921240 PL1, 920440 PL1, 920201 PL2, 920202 PL4) (Christian Folini) [#3411] - * feat: new rules to detecting ModSecurity body processor confusion using the `Content-Type` HTTP header (921421 PL1, 921422 PL2) (Simon Studer, Ervin Hegedus) [#2763] - * fix: handle false positives when detecting ModSecurity body processor confusion (921422 PL2) (Ervin Hegedus) [#2784] - * feat: new rules detecting attacks on multipart headers (922100 PL1, 922110 PL1, 922120 PL1) (Felipe Zipitría) [#2769] - * fix: prevent unintended match of character set substrings in multipart/form-data requests (922100 PL1) (Jozef Sudolský) [#3470] - * feat: remove redundant t:lowercase for a little performance (922110 PL1) (Jozef Sudolský) [#3469] - * fix: remove possessive quantifiers (922110 PL1) (Felipe Zipitría) [#2989] - * fix: update comments (922110 PL1, 942440 PL2) (Jozef Sudolský) [#3468] - * fix: add missing quotes at the end of action lists (930050) (Ervin Hegedus) [#2184] - * feat: disassemble regular expression (930100 PL1) (Andrew Howe) [#2298] - * fix: detect path traversal in uploaded file names (930100 PL1, 930110 PL1) (k4n5ha0, Franziska Bühler, Felipe Zipitría) [#2451] - * fix: detect triple dot path traversal (930100 PL1, 930110 PL1) (Franziska Bühler) [#2309, #2310] - * feat: extended rule to detect Tomcat specific path traversal attack (930110 PL1) (Christoph Hansen) [#2915] - * fix: avoid FP for '..' without slashes (930110 PL1) (Tetrik, Walter Hop) [#2016] - * feat: block access to AWS CLI files (930120 PL1, 930121 PL2) (Jozef Sudolský) [#2439] - * feat: block access to extended list of sensitive files (930120 PL1, 930121 PL2, 930130 PL1) (Jozef Sudolský) [#1960] - * feat: detect /proc and /sys access attempts (930120 PL1, 930130 PL1) (Andrew Howe) [#2154] - * feat: extend rule to detect access attempts to /tmp/ (930120 PL1, 930121 PL2) (Max Leske) [#3131] - * feat: extend rule to detect ECDSA type SSH identity files via list of sensitive \*nix files (930120 PL1) (Pinaki Mondal / 0xInfection) [#2586] - * fix: avoid detecting Google OAuth2 callback requests as malicious (930120 PL1, 930121 PL1) (Jozef Sudolský, Christian Folini) [#1958] - * feat: extend rule to detect additional sensitive files on \*nix systems (930121 PL2, 930130 PL1) (Gwendal Le Coguic / gwen001) [#2560] - * feat: new rules to detect LFI and SQLi in user-agent and referer request headers (930121 PL2, 942152 PL2, 942321 PL2) (Franziska Bühler, Max Leske, Shivam Bathla) [#3102] - * fix: extend rule to detect more LFI (930121 PL2) (Felipe Zipitría) [#2791] - * feat: add BlockCypher.log to restricted-files.data (930130 PL1) (Jozef Sudolský) [#3501] - * feat: add 'sslvpn_websession' to restricted-files.data (930130 PL1) (Jozef Sudolský) [#2338] - * feat: add .vscode to restricted-files.data (930130 PL1) (Frederik Himpe) [#3471] - * feat: extend data file to include additional restricted file names (restricted-files.data, 930130 PL1) (Jitendra Patro) [#3219] - * feat: extend data file to include PrestaShop configuration file (restricted-files.data, 930130 PL1) (Jean-François Viguier) [#3192] - * feat: extend rule to detect `npm-shrinkwrap.json` to restricted-files (930130 PL1) (Esa Jokinen / oh2fih) [#2627] - * fix: block access to the Java-related WEB-INF directory (930130 PL1) (Jozef Sudolský) [#2092] - * fix: remove duplicate keyword (930130 PL1) (Jozef Sudolský) [#3517] - * feat: extend rules to detect additional protocols in RFI attacks (931130 PL2, 934120 PL2) (Karel Knibbe) [#2572] - * feat: extend rule to detect `url:file:` schema in Java RFI attacks (931130 PL2) (Andrew Howe) [#2727] - * fix: add local_file scheme from Python 2 (931130 PL2, 934120 PL2) (Felipe Zipitría) [#2809] - * fix: close userinfo-based bypass (931130 PL2) (Andrea Menin) [#2479] - * feat: new rule to detect path traversal attacks using URL encoded URL schemes in Java applications (931131 PL2) (Christoph Hansen) [#2902] - * feat: extend rule to detect additional \*nix shell commands (931160 PL1) (Gwendal Le Coguic / gwen001) [#2563] - * feat: disassemble complex regexes for 932xxx rules that were subsequently replaced by other rules (Max Leske) [#2566] - * feat: detect additional Unix RCE commands (932100 PL1, 932105 PL1) (Felipe Zipitría) [#2129] - * feat: extend rule to detect additional entries to \*nix command lists (932100 PL1, 932105 PL1) (Finn Westendorf / wfinn) [#2552] - * feat: extend rule to detect additional \*nix commands (932100 PL1) (Felipe Zipitría) [#2676] - * feat: improve and extend cmdline processor to find more evasions (932100 PL1, 932105 PL1, 932230 PL1, 932150 PL1, 932175 PL1, 932220 PL2, 932240 PL1, 932106 PL3) (Felipe Zipitría) [#2907] - * fix: avoid false positive with certain HTML character entities (932100 PL1) (Franziska Bühler) [#1954] - * feat: move \*nix command injection rule 932101, 932106 into the same range as the other \*nix command injection rules (932231 PL2, 932232 PL3) (Felipe Zipitría, Max Leske) [#3092] - * feat: extend rule to detect additional \*nix commands (932105 PL1) (Felipe Zipitría) [#2677] - * feat: extend rule to detect `mshta` in Windows shell commands (932110 PL1) (Somdev Sangwan / s0md3v) [#2588] - * feat: new Windows commands rules based on lolbas-project replacing 932110, 932115 (932370 PL1, 932380 PL1) (Felipe Zipitría, Franziska Bühler, Max Leske) [#3059, 3170] - * fix: avoid false positive on 'sort' (932115 PL1) (Franziska Bühler) [#2012] - * feat: detect 'Invoke-WebRequest' command (932120 PL1) (Paul Beckett) [#2271] - * feat: extend rule to detect additional PowerShell cmdlet on Windows (932120 PL1) (Pinaki Mondal / 0xInfection) [#2589] - * feat: extend rule to detect PowerShell RCEs better via new automation (932120 PL1) (Felipe Zipitría) [#2669] - * feat: new rule to detect Windows cmdlet aliases (932125 PL1) (Pinaki Mondal / 0xInfection) [#2589] - * fix: extend rule to detect character class \*nix expressions (932130 PL1) (Somdev Sangwan / s0md3v, Walter Hop) [#2594] - * feat: new rules to detect Log4j / Log4Shell attacks (932131 PL2, 944150 PL1, 944151 PL2, 944152 PL4) (Christian Folini, Max Leske) [#2349] - * fix: prevent false positives against brackets in User-Agent header (932131 PL2) (Max Leske) [#3486] - * feat: extend rule to detect `busybox`, `$SHELL`, and `${SHELL}` in \*nix RCE attacks (932150 PL1) (Walter Hop) [#2728] - * feat: extend rule to detect C99 and printf utilities (932150 PL1) (Karel Knibbe) [#2569] - * feat: extend rule to detect `ksh` in \*nix RCE attacks (932150 PL1) (Andrew Howe) [#2721] - * feat: extend rule to detect RCE attacks using compression utilities (932150 PL1) (Andrew Howe) [#2712] - * feat: extend rule to detect RCEs using Base64 evasions (932150 PL1) (Somdev Sangwan / s0md3v, Andrew Howe) [#2590] - * feat: extend rule to detect RCEs using evasions quotes with `python...` commands (932150 PL1) (Somdev Sangwan / s0md3v, Andrew Howe) [#2590] - * feat: new rule to detect generalised \*nix RCE (932150 PL2) (Karel Knibbe) [#2583] - * feat: replace \*nix command injection rules 932150 PL1, 932151 PL1 with new rules for commands of less than 4 characters and commands of more than 4 characters in length respectively (932250 PL1, 932260 PL1) (Felipe Zipitría, Max Leske) [#3092] - * fix: avoid FP on 'time' and 'ping' keywords (932150 PL1) (Walter Hop) [#2457] - * feat: extend rule to detect RCE better via automation (932160 PL1) (Felipe Zipitría) [#2662] - * fix: remove unnecessary prefixes from paths in `unix-shell.data` (932160 PL1) (Felipe Zipitría) [#2662] - * feat: extend rule to detect `expre` in unix-shell list (932161 PL2) (Felipe Zipitría) [#2667] - * feat: new rules to detect \*nix commands in user-agent and referer request headers (932161 PL2, 932237 PL3) (Franziska Bühler, Max Leske, Shivam Bathla) [#3132] - * feat: new rule detecting `alias` builtin (932175 PL1) (Felipe Zipitría) [#2796] - * feat: use new automation to generate `restricted-uploads.data` from `restricted-files.data` (932180 PL1) (Max Leske) [#3282] - * fix: use correct anomaly scoring variable (932180 PL1, 932200 PL2) (Jozef Sudolský) [#2324] - * feat: detect RCE attempts with uninitialized shell vars (932200 PL2) (Andrea Menin) [#2151] - * feat: extend rule to detect RCE in user-agent request header (932200 PL2) (Franziska Bühler, Shivam Bathla) [#3108] - * feat: reduce FPs by removing User-Agent from individual target list (932200 PL2) (Max Leske) [#3489] - * fix: generate correct log entries when using 'MATCHED_VAR_NAME' in conjunction with chain rules (932200 PL2, 933120 PL1, 933151 PL2) (Jozef Sudolský) [#2347] - * fix: new rules to handle referer header and fix false positive (932205 PL2, 932206 PL2) (Max Leske) [#3300] - * feat: extend rule to detect quote evasion (932210 PL2) (Max Leske) [#3120] - * feat: extend rule to detect `sh` (932210 PL2) (Franziska Bühler) [#2816] - * feat: extend rule to detect SQLi via automation of keyword list updates (932210 PL2) (Felipe Zipitría) [#2801] - * feat: new rule to detect SQLite system command injection (932210 PL2) (flo405, Andrea Menin, Christian Folini) [#2032] - * fix: add word boundaries for sh in RCE rules (932230 PL1, 932250 PL1) (Max Leske) [#3186] - * fix: avoid FPs in RCE detections against words 'environment' and 'performance' (932230 PL1, 932235 PL1, 932260 PL1, 932236 PL2, 932237 PL3, 932239 PL2) (Esad Cetiner) [#3477] - * fix: handle false positive against `sh` in \*nix command injection attacks (932230 PL1, 932250 PL1, 932236 PL2) (Max Leske) [#3186] - * feat: add unix commands pyversions and py3versions (932235 PL1, 932260 PL1, 932236 PL2, 932237 PL3, 932239 PL2) (Jitendra Patro) [#3465] - * feat: replace \*-with-params.ra files with suffix replacements (932235 PL1, 932236 PL2, 932239 PL2, 932237 PL3) (Max Leske) [#3331] - * fix: prevent FP on keywords 'more' and 'time' in Unix RCE (932235 PL1) (Franziska Bühler) [#3488] - * fix: reduce FPs at the start of strings by excluding 'as' and 'at' (932236 PL2) (Franziska Bühler, Max Leske, Andrew Howe) [#3531 - * fix: prevent FPs against names due to "axel" and "perl" (932235 PL1, 932260 PL1, 932236 PL2, 932239 PL2, 932237 PL3) (@superlgn) [#3492] - * fix: add whitespace after keywords `mail` and `task` to solve false positives (932236 PL2) (Franziska Bühler) [#3274] - * fix: align unix-shell-upto3* files (932236 PL2) (Max Leske) [#3128] - * fix: handle false positives with word "settings" (932236 PL2, 932237 PL3, 932239 PL2) (Esad Cetiner) [#3394] - * fix: prevent FP on keywords more and time in Unix RCE (932236 PL2) (Franziska Bühler) [#3487] - * fix: solved false positives with creation of word boundaries for commonly used words used in \*nix RCE rules (932236 PL2) (Max Leske) [#3187] - * fix: use correct anomaly scoring variable (932236 PL2) (Ervin Hegedus) [#3112] - * fix: improve rule by matching non-word-boundary of commands with options (932237 PL3) (Max Leske) [#3425] - * feat: new rule to detect \*nix commands in user-agent and referer request headers (932239 PL2) (Franziska Bühler, Shivam Bathla) [#3104, #3318] - * fix: reduce FPs in generic quote evasion detection (932240 PL2) (Max Leske) [#3494] - * fix: remove ARGS_NAME from target variables in (932240 PL2) (Andrea Menin) [#2960] - * fix: use correct anomaly scoring variables and paranoia level tags across for rule (932240 PL2) (Ervin Hegedus) [#2963] - * fix: false positives by requiring specific tokens to follow commands (932250 PL1) (Max Leske) [#3186] - * fix: Added missing target name to logdata (932260 PL1, 932240 PL2) (Ervin Hegedus) [#3409] - * fix: remove chained rule (932260 PL1) (Max Leske) [#3521] - * feat: new rules to detect email protocol attacks (932300 PL2, 932310 PL2, 932320 PL2) (Felipe Zipitría) [#2322] - * fix: remove additional range expression that cause parsing errors for RE2 (932311 PL3) (Felipe Zipitría) [#2484] - * feat: new rules to detect detecting \*nix shell history invocations (932330 PL1, 932331 PL3) (Karel Knibbe) [#2577] - * fix: remove 'time' prefix from Windows RCE detection (932370 PL1, 932380 PL1) (Max Leske) [#3528] - * feat: extend rule to detect additional file extensions via list of executable PHP files (933110) (Jan Gora / terjanq) [#2585] - * feat: extend data file to add missing PHP config directives (php-config-directives.data, 933120 PL1) (Max Leske) [#3028] - * feat: extend rule to detect additional sensitive PHP directives (933120 PL1) (Gwendal Le Coguic / gwen001) [#2561] - * feat: extend rule to detect PHP config directives via automation of keyword list updates (933120 PL1) (Felipe Zipitría) [#2696] - * feat: extend rule to detect sensitive PHP variables better (933130 PL1) (Felipe Zipitría) [#2668] - * tests: clean test definitions and provide proper descriptions (933150 PL1, 933160 PL1) (Andrea Menin, Matteo Pace, Max Leske) [#3462] - * feat: extend data file to include additional php function names (php-function-names-933151.data, 933151 PL2) (Jitendra Patro) [#3212] - * feat: automate generation of PHP function dictionaries, revisited detection (933160 PL1, 933161 PL3, 933150 PL1, 933151 PL2) (Juan-Pablo Tosso, Christian Folini, Matteo Pace) [#3273] - * feat: extend rule to detect `document.domain` XSS (933160 PL1, 941180 PL1) (Franziska Bühler, 0SPwn) [#2567] - * feat: extend rule to detect evasions in PHP contexts with `"` (933160 PL1) (Somdev Sangwan / s0md3v) [#2596] - * feat: rearrange keywords (933160 PL1, 941390 PL1) (Karel Knibbe) [#2905] - * fix: handle false positive by fixing whitespace matching after PHP command (933160 PL1) (Max Leske) [#3432] - * fix: solve ReDoS issue in rule (933161 PL3) (Andrea Menin) [#2302] - * feat: extend rule to detect `bzip2` wrapper in PHP injection attacks (933200 PL1) (Andrew Howe) [#2723] - * feat: extend rule to detect `ssh2.\*` wrappers in PHP injection attacks (933200 PL1) (Andrew Howe) [#2731] - * fix: avoid false positive when cookie contains slash (933210 PL1) (Ervin Hegedus) [#1996] - * fix: close PHP whitespace bypass (933210 PL1) (Walter Hop) [#2033] - * fix: prevent excessive backtracking (933210 PL1) (Andrea Menin) [#2214] - * feat: new rule to detect PHP injection attacks without terminating semi-colon (933211 PL3) (Karel Knibbe) [#2581] - * feat: extended rule to detect Node.js injection attacks using `require` and `child_process` (934100 PL1, 932101 PL2) (Andrea Menin) [#2893] - * feat: extend rule to detect Node.js RCE better (934100 PL1) (rektor0) [#2578] - * feat: improve transformation pipeline to detect Base64-encoded evasions (934100 PL1) (Andrew Howe) [#3203] - * feat: new rule to detect Node.js RCE detection (934101 PL2) (rektor0) [#2578] - * fix: improve js rule transformation pipelines (934101 PL1, 934130 PL1, 934169 PL1, 934131 PL2) (Andrew Howe) [#3312] - * feat: extend data file to include additional indicators (ssrf.data, 934110 PL1) (Jitendra Patro) [#3213] - * feat: extend rule to detect SSRF better (934110 PL1) (Felipe Zipitría) [#2660] - * feat: new rules to detect common IP-based SSRF targets (934110 PL1, 934120 PL2) (Felipe Zipitría) [#2259] - * feat: extend rule to detect additional schema and IP evasion techniques in SSRF (934120 PL2) (Felipe Zipitría, Max Leske) [#2599] - * feat: extend rule to detect octal address of AWS metadata endpoints (934120 PL2) (Karel Knibbe) [#2555] - * feat: extend rule to detect SSRF better by inspecting targets beyond just ARGS (934120 PL2) (Karel Knibbe) [#2555] - * feat: new rules to detect JavaScript prototype pollution (934130 PL1, 934131 PL2) (Walter Hop) [#2411] - * fix: remove base64 transformation due to limited effectiveness and to align behavior across ModSecurity v2.x and libModSecurity v3.x engines (934130 PL1) (Andrea Menin) [#3378] - * fix: remove overly specific rule with limited benefits and lack of cross-engine compatibility (934131 PL2) (Andrea Menin) [#3378] - * feat: new rules to detect detection of Perl and Ruby RCE signatures in a generic way (934140 PL2, 934150 PL1) (Karel Knibbe) [#2587] - * feat: new rule to detect Node DoS attack via expressions resolving to true (934160 PL1) (Karel Knibbe) [#2917] - * feat: new rule for PHP supporting `data:` scheme without using `//` before the content-type (934170 PL1) (Felipe Zipitría) [#3018] - * feat: extend rules to detect path based XSS via new target REQUEST_FILENAME in 941xxx rules (Walter Hop) [#2894] - * feat: run libinjection XSS detector on request filename in PL2 (941101 PL2) (Andrew Howe) [#2208] - * feat: move rule from PL1 to PL2 (941120 PL2) (Christian Folini) [#2306] - * fix: avoid false positive by adding character limit (941120 PL2) (Christian Folini) [#1872] - * fix: avoid FP in Base64 content (941120 PL1) (Jozef Sudolský) [#2226] - * fix: remove unnecessary character escape (941120 PL2) (Andrew Howe) [#2805] - * fix: avoid FP in XMLNLS (941130 PL1) (Walter Hop) [#2192] - * fix: solve ReDoS issue in rule (941140 PL1) (Andrea Menin) [#2050] - * feat: detect 'dialog' tag in XSS no-script payloads (941160 PL1) (Jitendra Patro) [#3473] - * feat: disassemble complex regex fully (941160 PL1) (Felipe Zipitría) [#2701] - * fix: make regular expression more restrictive (941170 PL1) (Andrea Menin) [#2292] - * fix: new rule at PL2 to move the detection of '-->' out of PL1 due to false positives (941181 PL2) (Paul Beckett) [#2082] - * feat: disassemble complex regex (941210 PL1) (Felipe Zipitría) [#3262] - * feat: extend rule to detect XSS evasions using carriage return (\r) and new line (\n) characters (941210 PL1) (oct0pus7) [#2576] - * feat: disassemble complex regex (941220 PL1) (Felipe Zipitría) [#3263] - * fix: correct numerical values used for HTML entity evasion detection (941220 PL1) (Jitendra Patro) [#3479] - * fix: avoid false positive with Russian characters (941310 PL1) (Max Leske) [#2107] - * feat: improve detection by adding missing javascript `prompt` and `confirm` methods (941390 PL1) (Jitendra Patro) [#3395] - * feat: new rule to detect JavaScript methods (941390 PL1) (Franziska Bühler) [#2702] - * feat: extend rule and moved rule from PL3 to PL2 (942101 PL2) (Matteo Pace) [#2922] - * feat: extended rule to detect common SQL injection probing in path segments (942110 PL2) (Andrea Menin) [#2914] - * feat: prevent FPs by removing rule (942110 PL2) (Max Leske) [#3505] - * feat: add target REQUEST_FILENAME to rule to detect path-based SQLi attacks (942120 PL2) (Andrew Howe) [#3057] - * feat: extend rule to detect use of `collate` in SQLite injection attacks (942120 PL2) (Jan Gora / terjanq) [#2584] - * fix: extend rule to detect more SQLi (942120 PL2) (Karel Knibbe) [#2556] - * fix: resolve issue with regular expression and improve SQLi detection by detecting 'not between' (942120 PL2) (NiceYouKnow, Max Leske, Franziska Bühler) [#2115] - * fix: update SQL reserved words (942120 PL2) (Felipe Zipitría) [#2798] - * feat: extend rule to detect `glob` in list of SQLi tautologies (942130 PL2) (Franziska Bühler) [#2729] - * fix: remove unneeded TX variables (942130 PL2, 942131 PL2, 942521 PL3) (Andrea Menin) [#3293] - * feat: detect more error-based SQL injections (942150 PL2, 951230 PL1) (Jozef Sudolský) [#2429] - * feat: extend rule to detect more SQL function names (942150 PL2) (Karel Knibbe) [#2895] - * feat: extend rules to detect more SQL error messages and functions (942151 PL1, 942152 PL1, 951220 PL1, 951230 PL1, 951240 PL1) (Jitendra Patros) [#3336] - * feat: extend rule to detect additional SQL function signatures (942151 PL1) (Karel Knibbe) [#2570] - * feat: extend rule to detect `endswith`, `startswith`, `unistr`, `pg_client_encoding` and various JSON SQL functions (942151 PL1) (Franziska Bühler) [#2874] - * feat: extend rule to detect various JSON functions (942151 PL1) (Franziska Bühler) [#3041] - * fix: avoid FP in SQL function names by splitting between PL1/PL2 (942151 PL1, 942150 PL2) (Jozef Sudolský) [#2480] - * feat: extend rule to detect `sql_compileoption_get` in SQLite injection attacks (942152 PL1) (Andrew Howe) [#2718] - * fix: extend blind SQLi detection (942160 PL1) (Franziska Bühler, Christian Folini) [#1956] - * feat: new regex-assembly file for rule (942170 PL1) (Andrea Menin) [#2939] - * feat: extend rule to detect SQL injection authentication bypasses (942180 PL2) (rekter0) [#2575] - * feat: improve SQLi detection with spaces (942190 PL1, 942390 PL2) (Manuel Spartan, Max Leske) [#2436] - * fix: avoid FP in SQLi by adding word boundary checks (942190 PL1) (Jozef Sudolský) [#2078] - * fix: avoid FP in SQLi with keyword 'union' (942190 PL1) (Franziska Bühler) [#2058] - * fix: prevent comment-based SQL evasion (942190 PL1) (Andrea Menin) [#1910] - * fix: resolve bug in regular expression and add test case (942190 PL1) (NiceYouKnow, Max Leske, Franziska Bühler) [#2112] - * feat: disassemble complex regex (942200 PL2) (Franziska Bühler, Max Leske) [#2932] - * feat: extend rule to detect SQLi in user-agent and referer request headers (942200 PL2, 942370 PL2) (Franziska Bühler, Shivam Bathla) [#3106] - * feat: improve regex-assembly file for rule (942210 PL2) (Andrew Howe) [#2945] - * fix: detect the correct magic numbers that crash old PHP versions (942220 PL1) (Kyzentun, Walter Hop) [#2010] - * fix: avoid false positive with 'case' (942230 PL1) (Franziska Bühler) [#2035] - * fix: detect SQL false negative (942230 PL1) (Max Leske) [#2348] - * feat: disassemble complex regex (942240 PL1) (Franziska Bühler, Max Leske) [#2938] - * fix: avoid FP in 'having' SQLi (942251 PL3) (Felipe Zipitría) [#2248] - * feat: new regex-assembly file for rule (942280 PL1) (Andrea Menin) [#2933] - * feat: extend rule to detect additional MongoDB operators via NoSQL commands list (942290 PL1) (rekter0) [#2579] - * feat: new regex-assembly file for rule (942290 PL1) (Andrea Menin) [#2942] - * feat: improve regex-assembly format (942300 PL2) (Felipe Zipitría) [#3296] - * fix: avoid false positive by adding word boundary checks (942300 PL2) (Franziska Bühler) [#2099] - * fix: remove unnecessary part of regular expression (942310 PL2) (NiceYouKnow) [#2189] - * feat: extend rule to detect `::int` and `::bool` SQL data conversions (942320 PL1) (Franziska Bühler) [#2872] - * feat: extend rule to detect `lo_get` and `::text` via PostgreSQL functions list (942320 PL2) (Franziska Bühler, Walter Hop, Shivam Bathla) [#2925] - * feat: extend rule to detect `lo_import` and `div` via PostgreSQL functions list (942320 PL2) (Franziska Bühler, Shivam Bathla) [#2916] - * feat: extend rule to detect more PostgreSQL data types (942320 PL2) (Franziska Bühler, Shivam Bathla) [#3019] - * fix: add word boundaries to keywords to solve false positives (942330 PL2) (Franziska Bühler) [#3207] - * feat: extend rule to detect SQL injection better (942340 PL2) (Karel Knibbe) [#2557] - * fix: extend rule to detect more SQLi (942340 PL2) (Jan Gora / terjanq) [#2559] - * feat: detect SQLi using the 'drop' keyword (942350 PL1, 942360 PL1, 942200 PL2, 942362 PL2) (Jozef Sudolský) [#2218] - * fix: solve ReDoS issue in rule (942350 PL1) (Andrea Menin) [#2300] - * feat: new regex-assembly file for rule (942370 PL2) (Christoph Hansen, Max Leske) [#2954] - * feat: detect SQLi with 'if exists' (942380 PL2) (NiceYouKnow) [#2121] - * feat: optimize regex (942400 PL2) (Jozef Sudolský) [#2323] - * feat: disassemble complex chained regex (942440 PL2) (Felipe Zipitría) [#3295] - * feat: optimize regex (942440 PL2) (Felipe Zipitría) [#2459] - * fix: adapt rule to work in all ModSecurity versions (942440 PL2) (Andrew Howe) [#2201] - * fix: avoid FP in JWT tokens (942440 PL2) (Andrea Menin) [#2460] - * fix: reformat rules to follow project guidelines (942440 PL2, 949959, 949159, 959059, 959159) (Ervin Hegedus) [#3206] - * fix: solve errors in regex pattern (942440 PL2) (Andrea Menin) [#3290] - * fix: prevent FPs for click identifiers in query string by placing arg specific rule exclusions in rule set (942441, 942442) (Max Leske) [#3500] - * feat: extend rules to detect `current_user` and `overlay` (942470 PL1, 942480 PL2) (Franziska Bühler) [#2875] - * feat: extended rule to detect detect SQL injection attacks using headers (942480 PL2) (Paul Beckett) [#2911] - * feat: extend rule to detect newlines in overlay (942480 PL2) (Franziska Bühler, Shivam Bathla) [#3040] - * fix: detect MySQL optimizer hints (942500 PL1) (Max Leske) [#3431] - * feat: new rules to detect SQL authentication bypasses (942520 PL2, 942521 PL2, 942522 PL2) (Jan Gora / terjanq) [#2603] - * feat: extend rule to detect SQLi in user-agent and referer request headers (942521 PL2) (Franziska Bühler, Shivam Bathla) [#3107] - * fix: replace 'MATCHED_VAR' in 'logdata' argument with stable variable (942521 PL2, 943110 PL1, 943120 PL1) (Ervin Hegedus) [#3543] - * feat: new rule to detect `';` in SQLi (942530 PL3) (Franziska Bühler) [#2808] - * feat: new rule to detect authentication bypass via SQL injection that abuses semi-colons to end the SQL query (942540 PL1) (Karel Knibbe) [#2904] - * fix: update scoring variable (942540 PL2) (Walter Hop) [#2970] - * feat: new rule to detect MySQL scientific notation attacks (942560 PL1) (Jitendra Patro) [#3316] - * fix: remove unnessecary 'lowercase' transformation from chain rule (944120 PL1) (Federico G. Schwindt) [#1852] - * feat: extend rule to detect JAVA exploits better via java-classes.data file (944130 PL1) (Dennis Brown) [#3048] - * feat: new rule to deny uploading .jsp and .jspx files (944140 PL1) (Walter Hop) [#2456] - * feat: new rule to detect Spring4Shell (944260 PL2) (Christian Folini, Andrea Menin) [#2464] - * fix: update administrative rule ids for consistent operation (950011, 950012, 950018) (Ervin Hegedus) [#3339] - * feat: improve rule file 951xxx via the use of `skipAfter` instead of variable `TX:sql_error_match` (Jozef Sudolský) [#2754] - * feat: extend data file to include additional SQL error messages (sql-errors.data, 951100 PL1) (Jitendra Patro) [#3214] - * fix: avoid FP in MySQL data leakage rule (951230 PL1) (Jozef Sudolský) [#2490] - * fix: avoid FP in PostgreSQL error messages (951240 PL1) (Jozef Sudolský, Franziska Bühler) [#1870, #2313] - * fix: handle false positive in SQL error leakage detection (951240 PL1) (Jozef Sudolský) [#3169] - * fix: avoid FP in Sybase error message (951260 PL1) (Jozef Sudolský) [#2307] - * feat: extend rule to detect PHP errors better via new automation (953100 PL1) (Felipe Zipitría) [#2663] - * feat: new rules to detect PHP error leakages with high false positive rates at paranoia level 2 instead of 1 (953100 PL1, 953101 PL2) (Andrea Menin) [#3119] - * fix: solve false positive by shifting "Field cannot be empty" to PL2 (953100 PL1, 953101 PL2) (Esad Cetiner) [#3407] - * fix: ignore case of `PHP` tag in response text (953210 PL1) (Felipe Zipitría) [#2664] - * feat: extend rule to detect IIS errors via automation of pattern updates (954120 PL1) (Felipe Zipitría) [#2810] - * fix: log response body to audit log only when full rule chain matches (954130 PL1) (Franziska Bühler) [#2202] - * feat: added new webshells and tests (955100 PL1) (Jozef Sudolský) [#3405] - * feat: extend data file to include additional web shells (web-shells-php.data, 955100 PL1) (Jitendra Patro) [#3215] - * feat: extend data file to include additional web shells (web-shells-php.data, 955100 PL1) (Jozef Sudolský) [#2687] - * fix: make regular expression more strict to reduce noise in logs (955120 PL1) (Jozef Sudolský) [#2315] - * fix: use correct variable in chained condition for correlation rules (980120 PL0, 980150 PL0) (Simon Studer) [#1898] - -Changes without direct rule impact: - * chore: improve changelog-pr workflow (Max Leske) [#3416] - * chore: generate changelog entries with leading space (Max Leske) [#3550] - * chore: move regexp-assembly to separate directory (Felipe Zipitría) [#2327] - * chore: parse changelog PR author names from contributors (Max Leske) [#3408] - * docs: add a note to a commented rule about unsupported action in v3 (Ervin Hegedus) [#2098] - * docs: add documentation on blocking of archive file extensions that are not blocked by default (Andrew Howe) [#2758] - * docs: add example exclusion rule for monitoring agents (Andrea Menin) [#2037] - * docs: add file sponsors.md (Christian Folini) [#2174] - * docs: add link to run tests (Ervin Hegedus) [#3438] - * docs: add link to slack invitation to README (Christian Folini) [#2122] - * docs: add missing PL tags to all rules (Ervin Hegedus) [#1882] - * docs: add note of lack of rule range support in ModSecv3 (Andrew Howe) [#3303] - * docs: add to CONTRIBUTING.MD chain rule commenting guidance (Ervin Hegedus) [#3196] - * docs: align actions in right order (Ervin Hegedus) [#2237] - * docs: bring CONTRIBUTING.MD in line with documentation (Andrew Howe) [#2558] - * docs: change documentation git module link to https (İlteriş Eroğlu) [#2461] - * docs: change-version: fix typo (Deepshikha Sinha) [#2430] - * docs: contributing.md: add more information for new developers (Andrew Howe) [#2487] - * docs: crs-setup.conf: add note to allowed_request_content_type settings (Ervin Hegedus) [#2164] - * docs: enhance installation process for Nginx / IIS (Jozef Sudolský) [#1988] - * docs: explained to leave audit log settings alone in CONTRIBUTING.md (Christian Folini) [#3090] - * docs: fix capec id for crawlers (Jozef Sudolský) [#2258] - * docs: fix changed Trustwave URLs (Elia Pinto, henkworks, Felipe Zipitría) [#2213, #2364, #2204] - * docs: fix docs for Apache (Jozef Sudolský) [#2238] - * docs: fix donate URL (Felipe Zipitría) [#2132] - * docs: fixed minor typo in comment in file rules/restricted-files.data (Homesteady) [#3305] - * docs: fix NextCloud example comments (Joost de Keijzer) [#2282] - * docs: fix ruleid typos in comments (Paul Beckett) [#2263] - * docs: fix stricter sibling comment for SQL Injection () (Stephen Sigwart) [#1913] - * docs: fix typo in initialization(Elia Pinto) [#2366] - * docs: fix typo in sampling mode description (Christian Folini) [#2090] - * docs: fix typos across the entire project as reported by codespell (Ervin Hegedus) [#2519] - * docs: fix typos in README (Priyam Patel) [#2494] - * docs: improve changelog organization (Christian Folini) [#3536] - * docs: missing space after comment mark (Ervin Hegedus) [#2097] - * docs: update OWASP Slack URL (Jozef Sudolský) [#2056] - * docs: remove 'log' from rules and let SecDefaultAction decide what to do (Federico G. Schwindt) [#1876] - * docs: replace terms Blacklist and Whitelist with Deny list and Allow list (Paul Beckett) [#2137] - * docs: reword comment (900300 config) (Christian Folini) [#3417] - * docs: reword contributing.md (Christian Folini) [#2077] - * docs: sync CONTRIBUTING.MD with HTML version (Andrew Howe) [#3301] - * docs: transferred CHANGES to CHANGES.md (Felipe Zipitría) [#2606] - * docs: update and tidy CHANGES.md file for v4.0 release (Andrew Howe, Max Leske) [#3540] - * docs: update CONTRIBUTORS.md for new release (Ervin Hegedus) [#3340] - * docs: update description of rule 920350 (Christian Folini) [#1952] - * docs: update documentation hyperlinks on rules (Dexter Chang) [#3232] - * docs: update links and format of known bugs (Felipe Zipitría) [#2186] - * docs: update OWASP vulnerability URLs (Walter Hop) [#2467] - * docs: update policy to include signed releases (Felipe Zipitría) [#2465] - * docs: update README for Nginx (vijayasija99) [#2158] - * docs: update SPONSORS.md for new release (Christian Folini) [#3341] - * docs: remove sponsor F5 / VMWare (Christian Folini) [#3555] - * feat: add consistent rule references to initialization rule comments (Andrew Howe) [#2813] - * feat: add editorconfig file to keep spacing in good shape (Felipe Zipitría) [#2407] - * feat: add timezone variable to docker-compose (Felipe Zipitría) [#1995] - * fix: indentations (Ervin Hegedus) [#1851] - * fix: link for docs/OWASP-CRS-Documentation submodule (Ervin Hegedus) [#1885] - * fix: multiple fixes when generating changelog PR (Max Leske) [#3418], [#3420], [#3422], [#3424] [#3429] - * fix: nginx logging in docker-compose (Felipe Zipitría) [#2036] - * fix: remove all whitespace at EOL (Felipe Zipitría) [#2405, #2406] - * fix: remove full stop from end of log message (920181 PL1) (Federico G. Schwindt) [#2011] - * fix: yamllint (Felipe Zipitría) [#2387] - * tests: add a Chrome and Firefox version 100 UA (Mike Taylor) [#2325] - * tests: add common and uniform http headers to tests (Felipe Zipitría) [#2362] - * tests: additional tests for use in PHP wrappers in PHP injection attacks (rule 933200 PL1) (Andrew Howe) [#2723] - * tests: add positive test 920100-16 for rule 920100 PL1 (Andrew Howe) [#2952] - * tests: add positive test 920190-3 for rule 920190 PL1 (Andrew Howe) [#2956] - * tests: add positive test 920250-4 for rule 920250 PL1 (Andrew Howe) [#2971] - * tests: add positive test 920340-3 for rule 920340 PL1 (Andrew Howe) [#2972] - * tests: add positive test 920470-18 for rule 920470 PL1 (Andrew Howe) [#3058] - * tests: add positive test 921120-4 for rule 921120 PL1 (Andrew Howe) [#3083] - * tests: add positive test 921150-2 for rule 921150 PL1 (Andrew Howe) [#3158] - * tests: add positive test 932160-8 for rule 932160 PL1 (Christian Folini) [#2997] - * tests: add test against FP when using urlDecode for 932140 (Max Leske) [#2191] - * tests: add test for rule 941130 PL1 (Paul Beckett) [#2923] - * tests: add test for rule 941140 PL1 (Franziska Bühler) [#2995] - * tests: add test for rule 941170 PL1 (Franziska Bühler) [#2994] - * tests: add test for rule 941200 PL1 (Franziska Bühler) [#2993] - * tests: add test for rule 941240 PL1 (Franziska Bühler) [#2975] - * tests: add test for rule 941310 PL1 (Franziska Bühler) [#2974] - * tests: add test for rule 941400 PL1 (Franziska Bühler) [#2969] - * tests: add test for rule 942170 PL1 (Franziska Bühler) [#2968] - * tests: add test for rule 942270 PL1 (Franziska Bühler) [#2967] - * tests: add test for rule 942350 PL1 (Franziska Bühler) [#2965] - * tests: add test for rule 942500 PL1 (Franziska Bühler) [#2964] - * tests: add test for rule 942520 PL2 (Franziska Bühler) [#2706] - * tests: add test for rule 943100 PL1 (Franziska Bühler) [#2962] - * tests: add test for `sql_compileoption_used` detection (rule 942151 PL1) (Andrew Howe) [#2714] - * tests: add tests for 920120 (Max Leske) [#2369] - * tests: add tests for 920121, 932150, 932160, 932120, 932130, 921151 (Paul Beckett) [#2264, #2275, #2276, #2272, #2273, #2270] - * tests: add tests for 920275, 913101, 913102, 920410, 920171, 932190, 932110, 932105 (Ervin Hegedus) [#2021, #2253, #2257, #2294, #2295, #2285, #2286, #2287] - * tests: add tests for 920341 (Juan-Pablo Tosso) [#2266] - * tests: add tests for 921180 (Juan-Pablo Tosso, Christian Folini) [#2308] - * tests: add tests for 932170, 932171, 932106, 932180, 942170, 942251, 942460 (Franziska Bühler) [#2252, #2254, #2255, #2280, #2283, #2284, #2269, #2268] - * tests: add tests for 933111, 933190, 933200 (NiceYouKnow) [#2281] - * tests: add tests for FP 921110 request smuggling (Franziska Bühler) [#2102] - * tests: add tests for rules 942521 and 942522 PL2 (Franziska Bühler) [#2708] - * tests: add test to prove we cover complex shell variables usage in rule 932230 (Felipe Zipitría) [#2966] - * tests: clean up quoting (Max Leske) [#2370] - * tests: deprecate ftw in favor of go-ftw (Felipe Zipitría) [#3076] - * tests: detection of \*nix RCE using multiple variable assignments (932200 PL2) (Christian Folini) [#2899] - * tests: enable UTF8 encoding validation (Felipe Zipitría) [#2992] - * tests: extend coverage for rule 932120 (Felipe Zipitría) [#2996] - * tests: extend coverage for rule 932200 (Felipe Zipitría) [#2950] - * tests: extend coverage for rule 932220 (Felipe Zipitría) [#3063] - * tests: fix 933160-21 and 942500-1 due to invalid URI (Takaya Saeki) [#2168] - * tests: fix duplicated tests for rule 934130 PL1 (Walter Hop) [#2918] - * tests: fixed end boundary in 932180-2 (Ervin Hegedus) [#2377] - * tests: fixed URLs tests for rule 932130 PL1 (Matteo Pace) [#2880] - * tests: fixed URLs tests for rules 934130 PL1 and 934131 PL2 (Matteo Pace) [#3133] - * tests: fix logging problem for Nginx (vijayasija99) [#2157] - * tests: fix Python version for tests (Max Leske) [#2247] - * tests: fix requirements version (nobletrout) [#2004] - * tests: fix tests lacking charset (Felipe Zipitría) [#1932] - * tests: fix tests on rule 932200 to detect FPs (Max Leske) [#3309] - * tests: fix test titles (bxlxx.wu, Ervin Hegedus) [#2504, #2497] - * tests: fix test using old syntax and add go-ftw check (Felipe Zipitría) [#2715] - * tests: improve test setup, rewrite of log checker (Max Leske) [#2363] - * tests: increase tests (920280-3, 920430-3, 920430-9) compatibility with other proxies (Matteo Pace) [#3134] - * tests: normalized keys in test files (Ervin Hegedus) [#2493] - * tests: rearranged tests for rule 920340 (Christian Folini) [#3089] - * tests: rearranged tests for rule 920400 PL1 (Matteo Pace) [#2877] - * tests: remove Accept-Charset from test files (Felipe Zipitría) [#2781] - * tests: remove broken test 932100-3 (Felipe Zipitría) [#2165] - * tests: use only valid YAML (Felipe Zipitría) [#2080] - * tests: use same user-agent (Felipe Zipitría) [#2393] - -Functionality that has been moved to plugins for this release: - * feat: add Google OAuth 2 exclusion plugin (Jozef Sudolský) [#2388] - * feat: add phpBB exclusion rules (now a plugin) (Jozef Sudolský) [#1893] - * feat: add phpMyAdmin exclusion rules (now a plugin) (Jozef Sudolský) [#1951] - * feat: move IP reputation rules to plugins (Simon Studer) [#2482] - * feat: move exclusion profiles and DOS rules to plugins (Andrew Howe) [#2469] - * feat: ownCloud: Fix rule 9003001 to match both DAV and WebDAV (now a plugin) (Abu Dawud) [#2130] - * fix: nextcloud: fix FPs (now a plugin) (kam821, Jozef Sudolský, ntimo, Felipe Zipitría, pyllyukko) [#1840, #1843, #1847, #1946] - * fix: phpBB: Fix FPs (now a plugin) (Jozef Sudolský) [#2057, #2180, #2299, #2343] - * fix: phpMyAdmin: Fix FPs (now a plugin) (Jozef Sudolský) [#2172, #2249, #2321, #2351] - * fix: replace ARGS by ARGS_GET in rules in phase:1 (various rule exclusion rules) (Ervin Hegedus) [#2063] - * fix: wordPress: fix FPs (now a plugin) (Jozef Sudolský) [#1899, #1971, #2320] - * fix: wordPress: fix FPs and improve performance (now a plugin) (Walter Hop) [#1997, #2311] - * fix: wordPress: fix FPs in Site Health page (now a plugin) (Robert de Boer, Fregf, Walter Hop) [#1895, #1920] - * fix: xenForo: fix FPs (now a plugin) (Walter Hop, ThanhPT) [#1844, #1865, #1894, #1998, #2421] +* Backport fix for 3MU-240701-1 - catch invalid character in multipart headers via new rule 922130 (Ervin Hegedus, Felipe Zipitría) +* Backport fix for 3MU-240701-2 - prevent using backslash in file names from v4 - updated rule 920120 - pl1, 920121 - pl2 (Felipe Zipitria) ## Version 3.3.5 - 2023-07-18 @@ -624,629 +64,640 @@ Fixes and improvements: ## Version 3.3.2 - 2021-06-30 Fixes and improvements: - * Fix CVE-2021-35368 WAF bypass using pathinfo (Christian Folini) + +* Fix CVE-2021-35368 WAF bypass using pathinfo (Christian Folini) ## Version 3.3.0 - 2020-07-01 Important changes: - * The format of crs-setup.conf variable "tx.allowed_request_content_type" has been changed to be more in line with the other variables. If you have overridden this variable, please see the example in crs-setup.conf for the new separator to use. + +* The format of crs-setup.conf variable "tx.allowed_request_content_type" has been changed to be more in line with the other variables. If you have overridden this variable, please see the example in crs-setup.conf for the new separator to use. New functionality: - * Block backup files ending with ~ in filename (Andrea Menin) - * Detect ffuf vuln scanner (Will Woodson) - * Detect Nuclei vuln scanner (azurit) - * Detect SemrushBot crawler (Christian Folini) - * Detect WFuzz vuln scanner (azurit) - * New LDAP injection rule (Christian Folini) - * New HTTP Splitting rule (Andrea Menin) - * Add .swp to restricted extensions (Andrea Menin) - * Allow CloudEvents content types (Bobby Earl) - * Add CAPEC tags for attack classification (Fernando Outeda, Christian Folini) - * Detect Unix RCE bypass techniques via uninitialized variables, string concatenations and globbing patterns (Andrea Menin) + +* Block backup files ending with ~ in filename (Andrea Menin) +* Detect ffuf vuln scanner (Will Woodson) +* Detect Nuclei vuln scanner (azurit) +* Detect SemrushBot crawler (Christian Folini) +* Detect WFuzz vuln scanner (azurit) +* New LDAP injection rule (Christian Folini) +* New HTTP Splitting rule (Andrea Menin) +* Add .swp to restricted extensions (Andrea Menin) +* Allow CloudEvents content types (Bobby Earl) +* Add CAPEC tags for attack classification (Fernando Outeda, Christian Folini) +* Detect Unix RCE bypass techniques via uninitialized variables, string concatenations and globbing patterns (Andrea Menin) Removed functionality: - * Removed outdated rule tags WASCTC, OWASP_TOP_10, OWASP_AppSensor/RE1, and OWASP_CRS/FOO/BAR; note that tags 'OWASP_CRS' and 'attack-type' are kept. (Christian Folini) + +* Removed outdated rule tags WASCTC, OWASP_TOP_10, OWASP_AppSensor/RE1, and OWASP_CRS/FOO/BAR; note that tags 'OWASP_CRS' and 'attack-type' are kept. (Christian Folini) Improved compatibility: - * Changed variable to lowercase (modsec3 behavior fix) (Ervin Hegedus) + +* Changed variable to lowercase (modsec3 behavior fix) (Ervin Hegedus) Fixes and improvements: - * WordPress: Add support for upload image/media in Gutenberg Editor (agusmu) - * Prevent bypass of rule 921110 (Amit Klein, Franziska Bühler) - * Prevent bypass of rule 921130 (Amit Klein, Franziska Bühler) - * fix CVE msg in rules 944120 944240 (Fernando Outeda) - * Remove broken or no longer used files (Federico G. Schwindt) - * Make content-type case insensitive (Franziska Bühler) - * Move /util/docker folder from v3.3/dev branch to dedicated repo (Peter Bittner) - * feat(lint): split actions in linting and regression (Felipe Zipitria) - * Fix FP in 921120 (Franziska Bühler) - * Add missing OWASP_CRS tags (Christian Folini) - * Fix GHA badges (Federico G. Schwindt) - * feat(badge): add apache license badge - * fix typos found by fossies codespell (Tim Herren) - * Decrease processing time of rules (Ervin Hegedus) - * handle multiple directives in 920510 (Andrea Menin) - * handle multiple directives in 920510 (Andrea Menin) - * fix(ci): use log_contains instead (Felipe Zipitria) - * Move test where it belongs (Federico G. Schwindt) - * fix(ci): use docker in DetectionOnly (Felipe Zipitria) - * fix(rule): remove dangling whitespace (Felipe Zipitria) - * fix(ci): run actions on .github change (Felipe Zipitria) - * fix(docs): update badges and links in readme (Felipe Zipitria) - * README: update repo link (Walter Hop) - * Update README: Copyright 2019 -> 2020 (Christian Folini) - * fix(ci): run tests also on PRs (Felipe Zipitria) - * fix(ci): change test name and fix default params (Felipe Zipitria) - * Restore Travis Status (was in the wrong repo) (Christian Folini) - * Remove outdated Travis status after migration (Christian Folini) - * feat(ci): adds github actions testing (Felipe Zipitria) - * fix(migration): post migration tasks (Felipe Zipitria) - * feat(templates): add text to github templates about migration. To be reverted after migration is done. (Felipe Zipitria) - * Added more explanations to comment of 920300 (Christian Folini) - * Added 'ver' action with current version to all necessary rules (Ervin Hegedus) - * Update nextcloud excl rules and shorten var (Franziska Bühler) - * Change to preferred lowercase var (Franziska Bühler) - * Set var to lowercase and change comment (Franziska Bühler) - * Resolve issue with allowed_request_content_types (Franziska Bühler) - * Allow REPORT requests without Content-Type header in Nextcloud (pyllyukko) - * Suppress rule 200002 when editing contacts in Nextcloud (pyllyukko) - * XenForo: update exclusions (Walter Hop) - * WordPress: exclude additional URL fields in profile editor (Walter Hop) - * add www to link (NullIsNot0) - * Fix link for 941310 Old link does not work anymore. Change it to new one. (NullIsNot0) - * Add Content-Type: multipart/related as allowed default (jeremyjpj0916) - * Resolve issue 1722 and fix content-type whitelisting (Franziska Bühler) - * make severities and scores consistent (Walter Hop) - * add QQGameHall UA (#1731) (Andrea Menin) - * another test (Allan Boll) - * Add word boundaries around values in SQL tautologies (942130) (Allan Boll) - * Move tests to their own file, while here also correct permissions for 920180. (Federico G. Schwindt) - * Rule to check if both C-L and T-E are present (#1310) (Federico G. Schwindt) - * Fixes for 2 tests in 921200 (Christian Folini) - * XenForo: add exclusions, remove unnecessary chains (#1673) (Walter Hop) - * Fix FPs for 942350 (#1706) (Franziska Bühler) - * Fix typos found by codespell / Fossies project (#1702) (Simon Studer) - * Ignore check of CT header in POST request if protocol is HTTP/2 (Ervin Hegedus) - * Narrowing down the subpattern .\*? in 941130 (Christian Folini) - * Restricting a wide regex a bit (Christian Folini) - * Drop escapes (Christian Folini) - * Fix FP in 941130 and rearrange regex with new regex-assemble file (Christian Folini) - * Ignore check of CT header in POST request if protocol is HTTP/2 (Ervin Hegedus) - * Remove trailing dot in several msg actions (#1678) (Tim Herren) - * Replace REQUEST_BODY with ARGS on 930100 and 930110 (#1659) (Andrea Menin) - * Temporary travis workaround to buy time and fix it for good (#1684) (Andrea Menin) - * Add regression tests (Franziska Bühler) - * Fix FP with create with 942360 (Franziska Bühler) - * Avoid embedded anchors in CRS rule 942330 (Allan Boll) - * Update 942450 for less false positives, more tests (#1662) (Will Woodson) - * Ensure single ranges are also checked (#1661) (Federico G. Schwindt) - * WordPress: also exclude posts/pages endpoint in subdirectories (Walter Hop) - * For bugs, also ask for the environment (#1657) (Federico G. Schwindt) - * XenForo: fix incorrect escape (Walter Hop) - * XenForo: additional exclusions (Walter Hop) - * Pattern cleanup across several rules (#1643). Drop unneeded non-capture groups; No need to escape "-" outside character classes And only if it is not at the end. (Federico G. Schwindt) - * Improve rule 941350: Previously, this rule will also match on the equivalent to "<..<". Rewrite it so it is only triggered by the equivalent to "<..>", simplifying the pattern quite a bit as a bonus. While here add a link describing the bypass for future reference. - * Fix test Was using the equivalent to "<...<" instead of "<...>". (Federico G. Schwindt) - * Move the help and support link to contacts (#1647) While here rename to ensure they are presented in the right order and minor cosmetics. (Federico G. Schwindt) - * Move remaining regression test data file to new folder, cleanup README (#1646) (Peter Bittner) - * Also ask for the paranoia level (Federico G. Schwindt) - * Make it a tiny bit more colorful (Federico G. Schwindt) - * Spacing (Federico G. Schwindt) - * Fix emoji (Federico G. Schwindt) - * Switch to multiple templates for github issues (#1644) (Federico G. Schwindt) - * Fix paranoia-level log description (Andrea Menin) - * change IRC to Slack (Walter Hop) - * fix spacing (Walter Hop) - * Moving tests and documentation folders (#1627) (Soufiane Benali) - * add triggered rule (#1636) (Andrea Menin) - * Drop the translate header from the restricted list Fixes #1410. (Federico G. Schwindt) - * Mark stale issues (Federico G. Schwindt) - * Added support for >). Use negated classes for better performance. (Federico G. Schwindt) - * Add test for issue #1580 (#1612) (Federico G. Schwindt) - * removes t:lowercase (Andrea Menin) - * Move integration tests to their own job (#1608) Also cleanup branches' list. (Federico G. Schwindt) - * Add PL1 tag. (Anna Winkler) - * Change version number for full version name (Felipe Zipitria) - * Better document legacy conversion procedure Add text with instructions for a simple conversion utility. (Felipe Zipitria) - * Correct example text regarding GeoIP. Add maxmind tool for downloading files (Felipe Zipitria) - * Ignore configuration files generated by the JetBrains editors (Anna Winkler) - * Update name of branch to use for feature branches. Minor syntax updates. (Anna Winkler) - * Minor optimisation (Emile-Hugo SPIR) - * Also fix the `as herefrom` pattern (Emile-Hugo SPIR) - * More conservative fix (Emile-Hugo SPIR) - * Update the source file (Emile-Hugo SPIR) - * Fix a FP (`, aside from`) (Emile-Hugo SPIR) - * regression fix for #1581 (emphazer) - * Change order to check ip first in both rules (Felipe Zipitria) - * Change chain order (Felipe Zipitria) - * Fix spacing in text (Felipe Zipitria) - * Add link to mailing list archives (Felipe Zipitria) - * Adding new test for 941150 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941340 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941280 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941170 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941250 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941220 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941330 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941300 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941230 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941260 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941290 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 941270 based on XSS cheatsheet by portswigger (Christian Folini) - * Adding new test for 942180 based on XSS cheatsheet by portswigger (Christian Folini) - * Update mailing list links to google group (Felipe Zipitria) - * Fix typo and add 2 new entries to 941160 (Franziska Bühler) - * Switch to dates in YYYY-MM-DD format IOW iso 8601. While here add newlines and drop empty categories. (Federico G. Schwindt) - * Update badges, add v3.3 and remove v3.0 (#1557) (Federico G. Schwindt) - * Rearrange characters and add positive and negative test cases. Moved the dash to the end of the character set to avoid escaping it. Added test with all the new characters and a test for multiple whitespaces. Allowed a previously blocked charset. (Tim Herren) - * 920470: include chars from rfc 2046 RFC 2046 allows additional chars for the boundary. \d removed as it is covered by \w in the regex. Removed unnecessary escapes. (Tim Herren) - * Fix bypass in 931130 Don't rely on beginsWith as it might allow attackers to create subdomains matching the prefix. Add tests to cover this and other cases. The latter fixes #1404. (Federico G. Schwindt) - * fix rule regex due to remove t:removeComments (Andrea Menin) - * 920470: include chars from rfc 2046 RFC 2046 allows additional chars for the boundary. \d removed as it is covered by \w in the regex. Removed unnecessary escapes. (Tim Herren) - * update Dockerfiles and Travis to use v3.3/dev (Walter Hop) + +* WordPress: Add support for upload image/media in Gutenberg Editor (agusmu) +* Prevent bypass of rule 921110 (Amit Klein, Franziska Bühler) +* Prevent bypass of rule 921130 (Amit Klein, Franziska Bühler) +* fix CVE msg in rules 944120 944240 (Fernando Outeda) +* Remove broken or no longer used files (Federico G. Schwindt) +* Make content-type case insensitive (Franziska Bühler) +* Move /util/docker folder from v3.3/dev branch to dedicated repo (Peter Bittner) +* feat(lint): split actions in linting and regression (Felipe Zipitria) +* Fix FP in 921120 (Franziska Bühler) +* Add missing OWASP_CRS tags (Christian Folini) +* Fix GHA badges (Federico G. Schwindt) +* feat(badge): add apache license badge +* fix typos found by fossies codespell (Tim Herren) +* Decrease processing time of rules (Ervin Hegedüs) +* handle multiple directives in 920510 (Andrea Menin) +* handle multiple directives in 920510 (Andrea Menin) +* fix(ci): use log_contains instead (Felipe Zipitria) +* Move test where it belongs (Federico G. Schwindt) +* fix(ci): use docker in DetectionOnly (Felipe Zipitria) +* fix(rule): remove dangling whitespace (Felipe Zipitria) +* fix(ci): run actions on .github change (Felipe Zipitria) +* fix(docs): update badges and links in readme (Felipe Zipitria) +* README: update repo link (Walter Hop) +* Update README: Copyright 2019 -> 2020 (Christian Folini) +* fix(ci): run tests also on PRs (Felipe Zipitria) +* fix(ci): change test name and fix default params (Felipe Zipitria) +* Restore Travis Status (was in the wrong repo) (Christian Folini) +* Remove outdated Travis status after migration (Christian Folini) +* feat(ci): adds github actions testing (Felipe Zipitria) +* fix(migration): post migration tasks (Felipe Zipitria) +* feat(templates): add text to gihub templates about migration. To be reverted after migation is done. (Felipe Zipitria) +* Added more explanations to comment of 920300 (Christian Folini) +* Added 'ver' action with current version to all necessary rules (Ervin Hegedus) +* Update nextcloud excl rules and shorten var (Franziska Bühler) +* Change to preferred lowercase var (Franziska Bühler) +* Set var to lowercase and change comment (Franziska Bühler) +* Resolve issue with allowed_request_content_types (Franziska Bühler) +* Allow REPORT requests without Content-Type header in Nextcloud (pyllyukko) +* Suppress rule 200002 when editing contacts in Nextcloud (pyllyukko) +* XenForo: update exclusions (Walter Hop) +* WordPress: exclude additional URL fields in profile editor (Walter Hop) +* add www to link (NullIsNot0) +* Fix link for 941310 Old link does not work anymore. Change it to new one. (NullIsNot0) +* Add Content-Type: multipart/related as allowed default (jeremyjpj0916) +* Resolve issue 1722 and fix content-type whitelisting (Franziska Bühler) +* make severities and scores consistent (Walter Hop) +* add QQGameHall UA (#1731) (Andrea Menin) +* another test (Allan Boll) +* Add word boundaries around values in SQL tautologies (942130) (Allan Boll) +* Move tests to their own file, while here also correct permissions for 920180. (Federico G. Schwindt) +* Rule to check if both C-L and T-E are present (#1310) (Federico G. Schwindt) +* Fixes for 2 tests in 921200 (Christian Folini) +* XenForo: add exclusions, remove unnecessary chains (#1673) (Walter Hop) +* Fix FPs for 942350 (#1706) (Franziska Bühler) +* Fix typos found by codespell / Fossies project (#1702) (Simon Studer) +* Ignore check of CT header in POST request if protocol is HTTP/2 (Ervin Hegedus) +* Narrowing down the subpattern .*? in 941130 (Christian Folini) +* Restricting a wide regex a bit (Christian Folini) +* Drop escapes (Christian Folini) +* Fix FP in 941130 and rearrange regex with new regex-assemble file (Christian Folini) +* Ignore check of CT header in POST request if protocol is HTTP/2 (Ervin Hegedus) +* Remove trailing dot in several msg actions (#1678) (Tim Herren) +* Replace REQUEST_BODY with ARGS on 930100 and 930110 (#1659) (Andrea Menin) +* Temporary travis workaround to buy time and fix it for good (#1684) (Andrea Menin) +* Add regression tests (Franziska Bühler) +* Fix FP with create with 942360 (Franziska Bühler) +* Avoid embedded anchors in CRS rule 942330 (Allan Boll) +* Update 942450 for less false positives, more tests (#1662) (Will Woodson) +* Ensure single ranges are also checked (#1661) (Federico G. Schwindt) +* WordPress: also exclude posts/pages endpoint in subdirectories (Walter Hop) +* For bugs, also ask for the environment (#1657) (Federico G. Schwindt) +* XenForo: fix incorrect escape (Walter Hop) +* XenForo: additional exclusions (Walter Hop) +* Pattern cleanup across several rules (#1643). Drop unneeded non-capture groups; No need to escape "-" outside character classes And only if it is not at the end. (Federico G. Schwindt) +* Improve rule 941350: Previously, this rule will also match on the equivalent to "<..<". Rewrite it so it is only triggered by the equivalent to "<..>", simplifying the pattern quite a bit as a bonus. While here add a link describing the bypass for future reference. +* Fix test Was using the equivalent to "<...<" instead of "<...>". (Federico G. Schwindt) +* Move the help and support link to contacts (#1647) While here rename to ensure they are presented in the right order and minor cosmetics. (Federico G. Schwindt) +* Move remaining regression test data file to new folder, cleanup README (#1646) (Peter Bittner) +* Also ask for the paranoia level (Federico G. Schwindt) +* Make it a tiny bit more colorful (Federico G. Schwindt) +* Spacing (Federico G. Schwindt) +* Fix emoji (Federico G. Schwindt) +* Switch to multiple templates for github issues (#1644) (Federico G. Schwindt) +* Fix paranoia-level log description (Andrea Menin) +* change IRC to Slack (Walter Hop) +* fix spacing (Walter Hop) +* Moving tests and documentation folders (#1627) (Soufiane Benali) +* add triggered rule (#1636) (Andrea Menin) +* Drop the translate header from the restricted list Fixes #1410. (Federico G. Schwindt) +* Mark stale issues (Federico G. Schwindt) +* Added support for >). Use negated classes for better performance. (Federico G. Schwindt) +* Add test for issue #1580 (#1612) (Federico G. Schwindt) +* removes t:lowercase (Andrea Menin) +* Move integration tests to their own job (#1608) Also cleanup branches' list. (Federico G. Schwindt) +* Add PL1 tag. (Anna Winkler) +* Change version number for full version name (Felipe Zipitria) +* Better document legacy conversion procedure Add text with instructions for a simple conversion utility. (Felipe Zipitria) +* Correct example text regarding GeoIP. Add maxmind tool for downloading files (Felipe Zipitria) +* Ignore configuration files generated by the JetBrains editors (Anna Winkler) +* Update name of branch to use for feature branches. Minor syntax updates. (Anna Winkler) +* Minor optimisation (Emile-Hugo SPIR) +* Also fix the `as herefrom` pattern (Emile-Hugo SPIR) +* More conservative fix (Emile-Hugo SPIR) +* Update the source file (Emile-Hugo SPIR) +* Fix a FP (`, aside from`) (Emile-Hugo SPIR) +* regression fix for #1581 (emphazer) +* Change order to check ip first in both rules (Felipe Zipitria) +* Change chain order (Felipe Zipitria) +* Fix spacing in text (Felipe Zipitria) +* Add link to mailing list archives (Felipe Zipitria) +* Adding new test for 941150 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941340 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941280 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941170 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941250 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941220 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941330 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941300 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941230 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941260 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941290 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 941270 based on XSS cheatsheet by portswigger (Christian Folini) +* Adding new test for 942180 based on XSS cheatsheet by portswigger (Christian Folini) +* Update mailing list links to google group (Felipe Zipitria) +* Fix typo and add 2 new entries to 941160 (Franziska Bühler) +* Switch to dates in YYYY-MM-DD format IOW iso 8601. While here add newlines and drop empty categories. (Federico G. Schwindt) +* Update badges, add v3.3 and remove v3.0 (#1557) (Federico G. Schwindt) +* Rearange characters and add positive and negative test cases. Moved the dash to the end of the character set to avoid escaping it. Added test with all the new characters and a test for multiple whitespaces. Allowed a previously blocked charset. (Tim Herren) +* 920470: include chars from rfc 2046 RFC 2046 allows additional chars for the boundary. \d removed as it is covered by \w in the regex. Removed unnecessary escapes. (Tim Herren) +* Fix bypass in 931130 Don't rely on beginsWith as it might allow attackers to create subdomains matching the prefix. Add tests to cover this and other cases. The latter fixes #1404. (Federico G. Schwindt) +* fix rule regex due to remove t:removeComments (Andrea Menin) +* 920470: include chars from rfc 2046 RFC 2046 allows additional chars for the boundary. \d removed as it is covered by \w in the regex. Removed unnecessary escapes. (Tim Herren) +* update Dockerfiles and Travis to use v3.3/dev (Walter Hop) ## Version 3.2.0 - 2019-09-24 New functionality: - * Add AngularJS client side template injection 941380 PL2 (Franziska Bühler) - * Add docker-compose.yaml and example rule exclusion files for docker-compose (Franziska Bühler) - * Add extended access.log format to Docker (Franziska Bühler) - * Add libinjection check on last path segment (Max Leske, Christian Folini) - * Add PUBLIC identifier for XML entities (#1490) (Rufus125) - * Add .rdb to default restricted_extensions (Walter Hop) - * Add .swp to default restricted_extensions (Andrea Menin) - * Add rule 933200 PHP Wrappers (Andrea Menin) - * Add send-payload-pls.sh script to test payload against multiple paranoia levels (Christian Folini, Manuel Spartan) - * Add support for shell evasions with $IFS (Walter Hop, Chaim Sanders) - * Add unix-shell commands (Christoph Hansen, Chaim Sanders) - * Also inspect the path for the script tag (Federico G. Schwindt) - * Detect 80legs, sysscan, Gobuster scanners (Brent Clark) - * Detect CGI source code leakages (Christoph Hansen, Walter Hop) - * Detect 'crawler' user-agent (Federico G. Schwindt) - * Detect Jorgee, Zgrab scanners (Walter Hop) - * Detect MySQL in-line comments (Franziska Bühler) - * Detect Wappalyzer scanner (Christian Folini, Chaim Sanders) - * Java RCE: Add struts namespaces (Walter Hop) - * Java RCE: Detect more java classes (Manuel Leos) - * Javascript: Add 941370 preventing a bypass for 941180 (Andrea Menin) - * Make CRS variables configurable in Docker image (Franziska Bühler) - * New PL3 rule 920490 to protect against content-type charset bypassing (Christian Folini) - * Node.js unserialization + javascript RCE snippets (Walter Hop) - * Request smuggling: Also cover pre http/1.0 requests (Federico G. Schwindt) - * Restricted files: Added many dotfiles (Dan Ehrlich) - * SQLi bypass detection: ticks and backticks (Franziska Bühler) - * XenForo rule exclusion profile (Walter Hop) + +* Add AngularJS client side template injection 941380 PL2 (Franziska Bühler) +* Add docker-compose.yaml and example rule exclusion files for docker-compose (Franziska Bühler) +* Add extended access.log format to Docker (Franziska Bühler) +* Add libinjection check on last path segment (Max Leske, Christian Folini) +* Add PUBLIC identifier for XML entities (#1490) (Rufus125) +* Add .rdb to default restricted_extensions (Walter Hop) +* Add .swp to default restricted_extensions (Andrea Menin) +* Add rule 933200 PHP Wrappers (Andrea Menin) +* Add send-payload-pls.sh script to test payload against multiple paranoia levels (Christian Folini, Manuel Spartan) +* Add support for shell evasions with $IFS (Walter Hop, Chaim Sanders) +* Add unix-shell commands (Christoph Hansen, Chaim Sanders) +* Also inspect the path for the script tag (Federico G. Schwindt) +* Detect 80legs, sysscan, Gobuster scanners (Brent Clark) +* Detect CGI source code leakages (Christoph Hansen, Walter Hop) +* Detect 'crawler' user-agent (Federico G. Schwindt) +* Detect Jorgee, Zgrab scanners (Walter Hop) +* Detect MySQL in-line comments (Franziska Bühler) +* Detect Wappalyzer scanner (Christian Folini, Chaim Sanders) +* Java RCE: Add struts namespaces (Walter Hop) +* Java RCE: Detect more java classes (Manuel Leos) +* Javascript: Add 941370 preventing a bypass for 941180 (Andrea Menin) +* Make CRS variables configurable in Docker image (Franziska Bühler) +* New PL3 rule 920490 to protect against content-type charset bypassing (Christian Folini) +* Node.js unserialization + javascript RCE snippets (Walter Hop) +* Request smuggling: Also cover pre http/1.0 requests (Federico G. Schwindt) +* Restricted files: Added many dotfiles (Dan Ehrlich) +* SQLi bypass detection: ticks and backticks (Franziska Bühler) +* XenForo rule exclusion profile (Walter Hop) Removed functionality: - * Remove unused protected_uploads setting from setup (Walter Hop) - * Remove deprecated tx.msg and tx.%{rule.id}-... (Federico G. Schwindt) - * Remove deprecated upgrade script (Walter Hop) + +* Remove unused protected_uploads setting from setup (Walter Hop) +* Remove deprecated tx.msg and tx.%{rule.id}-... (Federico G. Schwindt) +* Remove deprecated upgrade script (Walter Hop) Improved compatibility: - * Add OWASP_CRS tags for ModSec 3 changes and replace ruleRemoveTargetByTag arguments (Ervin Hegedus) - * Replace @contain % with @rx 25; ModSec 3 fails to parse % by itself (or escaped). (Federico G. Schwindt) - * RE2 compatibility for 941130, 920220, 920240, 920230, 920460, 942200, 942370 (Allan Boll) - * Hyperscan compatibility and simplification for 942450 (Allan Boll) + +* Add OWASP_CRS tags for ModSec 3 changes and replace ruleRemoveTargetByTag arguments (Ervin Hegedus) +* Replace @contain % with @rx 25; ModSec 3 fails to parse % by itself (or escaped). (Federico G. Schwindt) +* RE2 compatibility for 941130, 920220, 920240, 920230, 920460, 942200, 942370 (Allan Boll) +* Hyperscan compatibility and simplification for 942450 (Allan Boll) Fixes and improvements: - * 932140: fix ReDoS in FOR expression (Walter Hop) - * 933200: Simplify pattern (Federico G. Schwindt, Andrea Menin) - * 941380: fix anomaly score variable (Franziska Bühler) - * 942510, 942511: fix anomaly score variable (Walter Hop) - * Add content-type application/csp-report (Andrea Menin) - * Add content-type application/xss-auditor-report (Andrea Menin) - * Add CRS 3.2 Badge build support. (Chaim Sanders) - * Add CVE numbers for Apache Struts vulnerabilities to comments in rules (Franziska Bühler) - * Add CVE-2018-11776 to comments of 933160 and 933161 (Franziska Bühler) - * Add CVE-2018-2380 to comments of rules (Franziska Bühler) - * Add default env vars for anomaly scores in Docker (Franziska Bühler) - * Add missing OWASP_CRS tags to 921xxx rules (Walter Hop) - * Add REQUEST_FILENAME to rule id 944130 and add exploits to comment (Franziska Bühler) - * Add spaces in front of closing square brackets (Franziska Bühler) - * Add travis changes (#1316) (Chaim Sanders) - * Allow dot characters in Content-Type multipart boundary (Walter Hop) - * Also handle dot variant of X_Filename. PHP will transform dots to underscore in variable names since dot is invalid. (Federico G. Schwindt) - * As per the ref manual, it is compressWhitespace (Federico G. Schwindt) - * Avoid php leak false positive with WOFF files (Manuel Spartan) - * Bring back CRS 2.x renumbering utility (Walter Hop) - * Clean up travis and reorg (Federico G. Schwindt) - * Code cosmetics: reorder the actions of rules (Ervin Hegedus) - * Content-Type is case insensitive (Federico G. Schwindt) - * Disassembled 941160 (Franziska Bühler) - * Drop separate regexp files. They are not really needed and save us from updating multiple places. (Federico G. Schwindt) - * Drop t:lowercase from 941350 (Federico G. Schwindt) - * Drop unneeded capture groups and tidy up (Federico G. Schwindt) - * Drop unneeded capture groups and tidy up regexps (Federico G. Schwindt) - * Drop unneeded unicode from 941110. Add tests to cover a few more variants as well as a negative test (Federico G. Schwindt) - * Fix 920440 "URL file extension is restricted by policy" regex (Andrea Menin) - * Fix 920460 test (Federico G. Schwindt) - * Fix 942101 and 942460 by adding to sqli_score variable (Christian Folini) - * Fix checking the existence of 'HTTP' trailing request verb and request path in the payload for HTTP request smuggling; decreases false-positives on free-form text. (Yu Yagihashi) - * Fix commit default for non 2.9 branch (Chaim Sanders) - * Fix CRS2->CRS3 mapping table (973344 -> 941100) (Chaim Sanders) - * Fix date (Chaim Sanders) - * Fix Docker image SSL support (Franziska Bühler) - * Fix duplicate .env (jschleus, Chaim Sanders) - * Fix executing paranoia level counters (Christian Folini) - * Fix indentation and python version in crs2-renumbering script (Chaim Sanders) - * Fix input / headers misordering (Christian Folini) - * Fix path traversal attack pattern at id:930110 (Ervin Hegedus) - * Fix regexp in Docker image (Franziska Bühler) - * Fix regexp with incorrect dot '.' escape in rule 943120 (XeroChen) - * Fix request header Sec-Fetch-User false positive (na1ex) - * Fix runaway regexp in 942260. Add variant regexp assemble script to handle possessive qualifiers. Use possessive qualifiers to tight this up and solve ReDoS problem. (Federico G. Schwindt) - * Fix small typo in variable (Felipe Zipitria) - * Fix spelling error in variable name (supplient) - * Fix transform name pointed out by secrules_parsing (Federico G. Schwindt) - * Fix Travis Merge not being able to find HEAD (Chaim Sanders) - * Fix vulnerable regexp in rule 942490 (CVE-2019-11387) (Christoph Hansen) - * Fix wrong regex, assembly result, in 942370 (Franziska Bühler) - * INSTALL: advise to use release zips, remove upgrade.py, update Nginx (Walter Hop) - * Java: change tag from COMMAND_INJECTION to JAVA_INJECTION (Manuel Spartan) - * Jwall auditconsole outbound anomaly scoring requirements (Christoph Hansen) - * Mark patterns not supported by RE2 (Federico G. Schwindt) - * Move duplicated 900270 to 900280 Fixes #1236. (Federico G. Schwindt) - * Move PROXYLOCATION var (Franziska Bühler) - * PHP: move get_defined_functions() and friends into PL1 (Walter Hop) - * Pin the ftw version to 1.1.7 for now (Federico G. Schwindt) - * Prevent bypass 933180 PHP Variable Function (Andrea Menin) - * Reduce comments, introduction of triggered exploits (Franziska Bühler) - * Remove all trailing spaces from ftw yaml test files (Ervin Hegedus) - * Remove auditlog No other rules specify it. Add missing quotes and drop rev (Federico G. Schwindt) - * Remove capture, remove tx.0, add transformation functions, fix regex, add presentation link (Andrea Menin) - * Remove old and unwanted setvar constructs (Federico G. Schwindt) - * Remove superfluous comments (Walter Hop) - * Remove superfluous pmf (Federico G. Schwindt) - * Remove t:lowercase from 920490 (Christian Folini) - * Remove WARNING from php-errors.data (Andrea Menin) - * Reorder actions (Federico G. Schwindt) - * Replacing all @pmf with @pmFromFile (Christian Treutler) - * Restricted-files.data: add AWS config (Walter Hop) - * SQLI: removed unnecessary + (Christoph Hansen) - * Switch Docker image to owasp/modsecurity:2.9-apache-ubuntu (Federico G. Schwindt) - * unix-shell.data: fix typo in 'more' (Walter Hop) - * Update .travis.yml Update to support v3.1 (Chaim Sanders) - * Update dockerfile to always use 3.2/dev (Federico G. Schwindt) - * Update OWASP CRS Docker image to support the new upstream and 2.9.3 (Peter Bittner, Chaim Sanders) - * Update RESPONSE-950-DATA-LEAKAGES.conf (Christoph Hansen) - * Update RESPONSE-959-BLOCKING-EVALUATION.conf (Christoph Hansen) - * Wordpress: add support for Gutenberg editor (siric_, Walter Hop) - * Wordpress: allow searching for any term in admin posts/pages overview (Walter Hop) - * WordPress: exclude Gutenberg via rest_route (Walter Hop) - * WordPress: exclude some more profile.php fields from RFI rule (Walter Hop) - * WordPress: exclude SQL comment rule from _wp_http_referer (Walter Hop) - * XML Soap Encoding fix 920240 (Christoph Hansen) + +* 932140: fix ReDoS in FOR expression (Walter Hop) +* 933200: Simplify pattern (Federico G. Schwindt, Andrea Menin) +* 941380: fix anomaly score variable (Franziska Bühler) +* 942510, 942511: fix anomaly score variable (Walter Hop) +* Add content-type application/csp-report (Andrea Menin) +* Add content-type application/xss-auditor-report (Andrea Menin) +* Add CRS 3.2 Badge build support. (Chaim Sanders) +* Add CVE numbers for Apache Struts vulnerabilities to comments in rules (Franziska Bühler) +* Add CVE-2018-11776 to comments of 933160 and 933161 (Franziska Bühler) +* Add CVE-2018-2380 to comments of rules (Franziska Bühler) +* Add default env vars for anomaly scores in Docker (Franziska Bühler) +* Add missing OWASP_CRS tags to 921xxx rules (Walter Hop) +* Add REQUEST_FILENAME to rule id 944130 and add exploits to comment (Franziska Bühler) +* Add spaces in front of closing square brackets (Franziska Bühler) +* Add travis changes (#1316) (Chaim Sanders) +* Allow dot characters in Content-Type multipart boundary (Walter Hop) +* Also handle dot variant of X_Filename. PHP will transform dots to underscore in variable names since dot is invalid. (Federico G. Schwindt) +* As per the ref manual, it is compressWhitespace (Federico G. Schwindt) +* Avoid php leak false positive with WOFF files (Manuel Spartan) +* Bring back CRS 2.x renumbering utility (Walter Hop) +* Clean up travis and reorg (Federico G. Schwindt) +* Code cosmetics: reorder the actions of rules (Ervin Hegedus) +* Content-Type is case insensitive (Federico G. Schwindt) +* Disassembled 941160 (Franziska Bühler) +* Drop separate regexp files. They are not really needed and save us from updating multiple places. (Federico G. Schwindt) +* Drop t:lowercase from 941350 (Federico G. Schwindt) +* Drop unneeded capture groups and tidy up (Federico G. Schwindt) +* Drop unneeded capture groups and tidy up regexps (Federico G. Schwindt) +* Drop unneeded unicode from 941110. Add tests to cover a few more variants as well as a negative test (Federico G. Schwindt) +* Fix 920440 "URL file extension is restricted by policy" regex (Andrea Menin) +* Fix 920460 test (Federico G. Schwindt) +* Fix 942101 and 942460 by adding to sqli_score variable (Christian Folini) +* Fix checking the existence of 'HTTP' trailing request verb and request path in the payload for HTTP request smuggling; decreases false-positives on free-form text. (Yu Yagihashi) +* Fix commit default for non 2.9 branch (Chaim Sanders) +* Fix CRS2->CRS3 mapping table (973344 -> 941100) (Chaim Sanders) +* Fix date (Chaim Sanders) +* Fix Docker image SSL support (Franziska Bühler) +* Fix duplicate .env (jschleus, Chaim Sanders) +* Fix executing paranoia level counters (Christian Folini) +* Fix indentation and python version in crs2-renumbering script (Chaim Sanders) +* Fix input / headers misordering (Christian Folini) +* Fix path traversal attack pattern at id:930110 (Ervin Hegedus) +* Fix regexp in Docker image (Franziska Bühler) +* Fix regexp with incorrect dot '.' escape in rule 943120 (XeroChen) +* Fix request header Sec-Fetch-User false positive (na1ex) +* Fix runaway regexp in 942260. Add variant regexp assemble script to handle possessive qualifiers. Use possessive qualifiers to tight this up and solve ReDoS problem. (Federico G. Schwindt) +* Fix small typo in variable (Felipe Zipitria) +* Fix spelling error in variable name (supplient) +* Fix transform name pointed out by secrules_parsing (Federico G. Schwindt) +* Fix Travis Merge not being able to find HEAD (Chaim Sanders) +* Fix vulnerable regexp in rule 942490 (CVE-2019-11387) (Christoph Hansen) +* Fix wrong regex, assembly result, in 942370 (Franziska Bühler) +* INSTALL: advise to use release zips, remove upgrade.py, update Nginx (Walter Hop) +* Java: change tag from COMMAND_INJECTION to JAVA_INJECTION (Manuel Spartan) +* Jwall auditconsole outbound anomaly scoring requirements (Christoph Hansen) +* Mark patterns not supported by re2 (Federico G. Schwindt) +* Move duplicated 900270 to 900280 Fixes #1236. (Federico G. Schwindt) +* Move PROXYLOCATION var (Franziska Bühler) +* PHP: move get_defined_functions() and friends into PL1 (Walter Hop) +* Pin the ftw version to 1.1.7 for now (Federico G. Schwindt) +* Prevent bypass 933180 PHP Variable Function (Andrea Menin) +* Reduce comments, introduction of triggered exploits (Franziska Bühler) +* Remove all trailing spaces from ftw yaml test files (Ervin Hegedus) +* Remove auditlog No other rules specify it. Add missing quotes and drop rev (Federico G. Schwindt) +* Remove capture, remove tx.0, add transformation functions, fix regex, add presentation link (Andrea Menin) +* Remove old and unwanted setvar constructs (Federico G. Schwindt) +* Remove superfluous comments (Walter Hop) +* Remove superfluous pmf (Federico G. Schwindt) +* Remove t:lowercase from 920490 (Christian Folini) +* Remove WARNING from php-errors.data (Andrea Menin) +* Reorder actions (Federico G. Schwindt) +* Replacing all @pmf with @pmFromFile (Christian Treutler) +* Restricted-files.data: add AWS config (Walter Hop) +* SQLI: removed unnecessary + (Christoph Hansen) +* Switch Docker image to owasp/modsecurity:2.9-apache-ubuntu (Federico G. Schwindt) +* unix-shell.data: fix typo in 'more' (Walter Hop) +* Update .travis.yml Update to support v3.1 (Chaim Sanders) +* Update dockerfile to always use 3.2/dev (Federico G. Schwindt) +* Update OWASP CRS Docker image to support the new upstream and 2.9.3 (Peter Bittner, Chaim Sanders) +* Update RESPONSE-950-DATA-LEAKAGES.conf (Christoph Hansen) +* Update RESPONSE-959-BLOCKING-EVALUATION.conf (Christoph Hansen) +* Wordpress: add support for Gutenberg editor (siric_, Walter Hop) +* Wordpress: allow searching for any term in admin posts/pages overview (Walter Hop) +* WordPress: exclude Gutenberg via rest_route (Walter Hop) +* WordPress: exclude some more profile.php fields from RFI rule (Walter Hop) +* WordPress: exclude SQL comment rule from _wp_http_referer (Walter Hop) +* XML Soap Encoding fix 920240 (Christoph Hansen) Unit tests: - * 932140: add regression tests (Walter Hop) - * 933180: fix tests which were doing nothing (Walter Hop) - * 941370: add some more tests, fix whitespace (Walter Hop) - * Add more tests for 941130 (Christian Folini) - * Add regression test for 941101 (Avery Wong) - * Add regression tests for 942150, 942100, 942260 (Christian Folini) - * Add regression tests to 941160 (Franziska Bühler) - * Add some regression tests (Ervin Hegedus) - * Add testing support for libmodsecurity running on Apache and Nginx (Chaim Sanders) - * Add tests for 941360 that fights JSFuck and Hieroglyphy (Christian Folini) - * Add tests for rule 921110 (Yu Yagihashi) - * Added regression tests for rules 942320, 942360, 942361, 942210, 942380, 942410, 942470, 942120, 942240, 942160, 942190, 942140, 942490, 942120 (Christoph Hansen) - * Drop tests for removed rules (Federico G. Schwindt) - * Fix failing regression tests (Ervin Hegedus) - * Fix failing tests (Manuel Spartan, Chaim Sanders) - * Fix readme typos in example rule (Walter Hop) - * Fix test 941110-2 (Federico G. Schwindt) - * Fix YAML 1.2 compliance with "true" (Federico G. Schwindt) - * RCE: Add tests for the for command (Federico G. Schwindt) - * Update regression tests for rules 931110, 931120, 931130 (Simon Studer) + +* 932140: add regression tests (Walter Hop) +* 933180: fix tests which were doing nothing (Walter Hop) +* 941370: add some more tests, fix whitespace (Walter Hop) +* Add more tests for 941130 (Christian Folini) +* Add regression test for 941101 (Avery Wong) +* Add regression tests for 942150, 942100, 942260 (Christian Folini) +* Add regression tests to 941160 (Franziska Bühler) +* Add some regression tests (Ervin Hegedus) +* Add testing support for libmodsecurity running on Apache and Nginx (Chaim Sanders) +* Add tests for 941360 that fights JSFuck and Hieroglyphy (Christian Folini) +* Add tests for rule 921110 (Yu Yagihashi) +* Added regression tests for rules 942320, 942360, 942361, 942210, 942380, 942410, 942470, 942120, 942240, 942160, 942190, 942140, 942490, 942120 (Christoph Hansen) +* Drop tests for removed rules (Federico G. Schwindt) +* Fix failing regression tests (Ervin Hegedus) +* Fix failing tests (Manuel Spartan, Chaim Sanders) +* Fix readme typos in example rule (Walter Hop) +* Fix test 941110-2 (Federico G. Schwindt) +* Fix YAML 1.2 compliance with "true" (Federico G. Schwindt) +* RCE: Add tests for the for command (Federico G. Schwindt) +* Update regression tests for rules 931110, 931120, 931130 (Simon Studer) Documentation: - * Add details to README for Dockerhub (Franziska Bühler) - * Add intro/comment to CVE comments (Franziska Bühler) - * CONTRIBUTING: add note about separate PRs (Walter Hop) - * Erased gitter chat. Added CII badge (Felipe Zipitria) - * Replaced descriptions (Christian Folini) - * Summarized authors on single line in tests for 941160 (Christian Folini) - * Update broken link in regexp-assemble blog URLs (Walter Hop) - * Update CONTRIBUTING.md To base changes on v3.2/dev. (Felipe Zipitría) - * Update CONTRIBUTORS order (Andrea Menin) - * Update README.md (Rufus125) - * Updating crs site location (Chaim Sanders) + +* Add details to README for Dockerhub (Franziska Bühler) +* Add intro/comment to CVE comments (Franziska Bühler) +* CONTRIBUTING: add note about separate PRs (Walter Hop) +* Erased gitter chat. Added CII badge (Felipe Zipitria) +* Replaced descriptions (Christian Folini) +* Summarized authors on single line in tests for 941160 (Christian Folini) +* Update broken link in regexp-assemble blog URLs (Walter Hop) +* Update CONTRIBUTING.md To base changes on v3.2/dev. (Felipe Zipitría) +* Update CONTRIBUTORS order (Andrea Menin) +* Update README.md (Rufus125) +* Updating crs site location (Chaim Sanders) ## Version 3.1.1 - 2019-06-26 - * Fix CVE-2019-11387 ReDoS against CRS on ModSecurity 3 at PL 2 (Christoph Hansen, Federico G. Schwindt) - * Content-Type made case insensitive in 920240, 920400 (Federico G. Schwindt) - * Allow % encoding in 920240 (Christoph Hansen) - * Fix bug in 920440 (Andrea Menin) - * Fix bug in 920470 (Walter Hop) - * Reduce false positives in 921110 (Yu Yagihashi, Federico G. Schwindt) - * Fix bug in 943120 (XeroChen) +* Fix CVE-2019-11387 ReDoS against CRS on ModSecurity 3 at PL 2 (Christoph Hansen, Federico G. Schwindt) +* Content-Type made case insensitive in 920240, 920400 (Federico G. Schwindt) +* Allow % encoding in 920240 (Christoph Hansen) +* Fix bug in 920440 (Andrea Menin) +* Fix bug in 920470 (Walter Hop) +* Reduce false positives in 921110 (Yu Yagihashi, Federico G. Schwindt) +* Fix bug in 943120 (XeroChen) ## Version 3.1.0 - 2018-08-07 - * Add Detectify scanner (Andrea Menin) - * Renaming matched_var/s (Victor Hora) - * Remove lines with bare '#' comment char (Walter Hop) - * Drop the XML variable from rule 932190 (Federico G. Schwindt) - * Update outdated URLs (Walter Hop) - * remove unused rule 901180 (Walter Hop) - * Drop exit from unix and windows RCE (Federico G. Schwindt) - * Fix anomaly_score counters (Federico G. Schwindt) - * Remove mostly redundant 944220 in favor of 944240 (Christian Folini) - * Add self[ and document[ to rule 941180 (Andrea Menin) - * Provide proxy support within CRS docker image (Scott O'Neil) - * Prevent bypass in rule 930120 PL3 (Andrea Menin) - * Fix small typo in variable (Felipe Zipitría) - * Fix bug #1166 in Docker image (Franziska Bühler) - * Remove revision status from rules (Federico G. Schwindt) - * Add template for issues (Federico G. Schwindt) - * Correct failing travis tests in merge situations (Federico G. Schwindt) - * Remove unused global variable in IIS rules (Chaim Sanders) - * Refactor to use phase number instead of name (Federico G. Schwindt) - * Add uploaded file name check; refresh LFI / filename checks (Walter Hop) - * Introduce critical sibling of 920340 in PL2 (Walter Hop) - * Fix bypass caused by multiple spaces in RCE rules (Walter Hop) - * Remove unneeded regex capture groups (Federico G. Schwindt) - * Add built-in exceptions for CPanel (Christoph Hansen) - * Add additional file restrictions for ws_ftp, DS_Store... (Jose Nazario) - * Fix missing strings in 942410 (Franziska Bühler) - * Add 2 missing PDO errors (Christoph Hansen) - * Fix issues with FPs in regression tests (Chaim Sanders) - * Add Nextcloud client exclusion support (Christoph Hansen) - * Fix spelling mistakes in REQUEST-942- (Padraig Doran, Chaim Sanders) - * Explicitly ignore the user defined rules (Aaron Haaf, Chaim Sanders) - * Add regression tests for 942490 (Christoph Hansen, Chaim Sanders) - * Add Owncloud client exclusion support (Christoph Hansen, Christian Folini) - * Adding 'F-Secure Radar' vulnerability scanner UA (Christian Folini, Chaim Sanders) - * Update DockerFile to use Ubuntu as base (Chaim Sanders) - * False positives 942360: move alter and union (Franziska Bühler, Chaim Sanders) - * Add support for Java style attacks (Manuel Spartan, Walter Hop) - * Fix various regression tests issues caused by webserver handling (azhao155, Chaim Sanders) - * Update TravisCI to build on a per PR basis (Chaim Sanders) - * Optimized rule 921160 and regex (Allan Boll, Chaim Sanders) - * Update the consistency across various files (Federico G. Schwindt) - * Add missing transform, 944120 sibling 944240 (Manuel Spartan) - * Fix false positive for 'like' in 942120 (Walter Hop) - * Add regression tests for Java Rules (Manuel Spartan) - * Fixup and small reorg of dokuwiki rule exclusion package (Christian Folini) - * Make TravisCI tests fail if Apache can't load rules (Felipe Zipitría) - * Add exclusion rules for Dokuwiki (Matt Bagley, Christian Folini) - * Initial exclusions for NextCloud installs (Matt Bagley, Christian Folini) - * Added struts-pwn UA to list (Manuel Spartan) - * Uses MULTIPART_MISSING_SEMICOLON instead of MULTIPART_SEMICOLON_MISSING (Felipe Zimmerle) - * Add file upload checks (Manuel Spartan) - * Check if Transfer-Encoding is missing (Federico G. Schwindt, Christian Folini) - * Remove duplicated variables (Federico G. Schwindt) - * Reduce FP by splitting classic SQL injection rule 942370 (Christoph Hansen) - * Fix typo in REQUEST-920-PROTOCOL-ENFORCEMENT (ihacku, Franziska Bühler) - * Add configurable timestamp format to FTW integration (Christian Folini) - * Add badges to README (Felipe Zipitría) - * Add clarifying comments to 910110 (Christian Folini) - * Making rule 933131 case-insensitive (Manuel Spartan) - * Merge and reorder rules as part of cleanup (Federico G. Schwindt) - * Update copyright date and syntax (Jose Nazario, Felipe Zipitría) - * Updated SecMarker and SkipAfter names to use meet guidelines (Felipe Zipitría) - * Tidy up single quotes and other guidelines updates (Felipe Zipitría) - * Syntax fix for setvar crs_exclusions_wordpress (Manuel Spartan) - * Updated various contributors to developers (Christian Folini) - * Revise SQL rules by disassembling them into their core protections (Franziska Bühler) - * Add an example payload to 920220 (coolt) - * Add a missing regex to rule 942310 (Franziska Bühler) - * Detect GET or HEAD with Transfer-Encoding header (Federico G. Schwindt) - * Fix broken links in references (Pásztor Gábor) - * Add contributing guidelines (Felipe Zipitría) - * Fix processing bypasses in rule 931130 (Felipe Zipitría, Christian Folini) - * Correct small omissions in unix-shell.data (Walter Hop) - * Add IIS specific detection to LFI-os-files.data (Manuel Spartan) - * Update examples to match the current cleanup (Federico G. Schwindt) - * Corrected the ordering of actions to meet guidelines (Felipe Zipitría) - * Remove unused capture groups (Federico G. Schwindt) - * Use explicit rx operator (Federico G. Schwindt) - * Update the RCE regular expressions(Walter Hop, Federico G. Schwindt) - * Removing maturity & accuracy from rules (Felipe Zipitría) - * Increasing range header (Christoph Hansen) - * Fixed upgrade.py script argument options (Glyn Mooney) - * Updating to reflect OWASP flagship status (Chaim Sanders) - * Adding Docker support for CRS (Chaim Sanders) - * Initial Travis deployment (Zack Allen, Walter Hop) - * Initial commit of regression tests (Chaim Sanders, Walter Hop) - * Remove test for 921170 because it won't ever fire (Chaim Sanders, Walter Hop) - * Update minor incorrectness in asp.net regex (Chaim Sanders, Walter Hop) - * Add notification for builds against #modsecurity on freenode (Zack Allen, Walter Hop) - * Add all past code contributors and convert to markdown (Walter Hop) - * Block uploads of files with .phps extension (Walter Hop) - * Improve message for script upload with superfluous extension (Walter Hop) - * Remove trailing whitespace in various regexs (Walter Hop) - * Add command popd to direct unix rce list in rule 932150 (Franziska Bühler) - * Remove unnecessary END_XSS_CHECKS marker (Christian Folini) - * Ignore Whitespaces in Rule 942110 (Christoph Hansen) - * Update missing RCE Commands (Umar Farook) - * Update lfi-os-files.data (Umar Farook) - * Removed deprecated t:removeComments from 942100 (Christian Folini) - * Add word boundary to rule 942410 (Franziska Bühler) +* Add Detectify scanner (Andrea Menin) +* Renaming matched_var/s (Victor Hora) +* Remove lines with bare '#' comment char (Walter Hop) +* Drop the XML variable from rule 932190 (Federico G. Schwindt) +* Update outdated URLs (Walter Hop) +* remove unused rule 901180 (Walter Hop) +* Drop exit from unix and windows RCE (Federico G. Schwindt) +* Fix anomaly_score counters (Federico G. Schwindt) +* Remove mostly redundant 944220 in favor of 944240 (Christian Folini) +* Add self[ and document[ to rule 941180 (Andrea Menin) +* Provide proxy support within CRS docker image (Scott O'Neil) +* Prevent bypass in rule 930120 PL3 (Andrea Menin) +* Fix small typo in variable (Felipe Zipitría) +* Fix bug #1166 in Docker image (Franziska Bühler) +* Remove revision status from rules (Federico G. Schwindt) +* Add template for issues (Federico G. Schwindt) +* Correct failing travis tests in merge situations (Federico G. Schwindt) +* Remove unused global variable in IIS rules (Chaim Sanders) +* Refactor to use phase number instead of name (Federico G. Schwindt) +* Add uploaded file name check; refresh LFI / filename checks (Walter Hop) +* Introduce critical sibling of 920340 in PL2 (Walter Hop) +* Fix bypass caused by multiple spaces in RCE rules (Walter Hop) +* Remove unneeded regex capture groups (Federico G. Schwindt) +* Add built-in exceptions for CPanel (Christoph Hansen) +* Add additional file restrictios for ws_ftp, DS_Store... (Jose Nazario) +* Fix missing strings in 942410 (Franziska Bühler) +* Add 2 missing PDO errors (Christoph Hansen) +* Fix issues with FPs in regression tests (Chaim Sanders) +* Add Nextcloud client exclusion support (Christoph Hansen) +* Fix spelling mistakes in REQUEST-942- (Padraig Doran, Chaim Sanders) +* Explicitly ignore the user defined rules (Aaron Haaf, Chaim Sanders) +* Add regression tests for 942490 (Christoph Hansen, Chaim Sanders) +* Add Owncloud client exclusion support (Christoph Hansen, Christian Folini) +* Adding 'F-Secure Radar' vulnerability scanner UA (Christian Folini, Chaim Sanders) +* Update DockerFile to use Ubuntu as base (Chaim Sanders) +* False positives 942360: move alter and union (Franziska Bühler, Chaim Sanders) +* Add support for Java style attacks (Manuel Spartan, Walter Hop) +* Fix various regression tests issues caused by webserver handling (azhao155, Chaim Sanders) +* Update TravisCI to build on a per PR basis (Chaim Sanders) +* Optimized rule 921160 and regex (Allan Boll, Chaim Sanders) +* Update the consistency across various files (Federico G. Schwindt) +* Add missing transform, 944120 sibling 944240 (Manuel Spartan) +* Fix false positive for 'like' in 942120 (Walter Hop) +* Add regression tests for Java Rules (Manuel Spartan) +* Fixup and small reorg of dokuwiki rule exclusion package (Christian Folini) +* Make TravisCI tests fail if Apache can't load rules (Felipe Zipitría) +* Add exclusion rules for Dokuwiki (Matt Bagley, Christian Folini) +* Initial exclusions for NextCloud installs (Matt Bagley, Christian Folini) +* Added struts-pwn UA to list (Manuel Spartan) +* Uses MULTIPART_MISSING_SEMICOLON instead of MULTIPART_SEMICOLON_MISSING (Felipe Zimmerle) +* Add file upload checks (Manuel Spartan) +* Check if Transfer-Encoding is missing (Federico G. Schwindt, Christian Folini) +* Remove duplicated variables (Federico G. Schwindt) +* Reduce FP by splitting classic SQL injection rule 942370 (Christoph Hansen) +* Fix typo in REQUEST-920-PROTOCOL-ENFORCEMENT (ihacku, Franziska Bühler) +* Add configurable timestamp format to FTW integration (Christian Folini) +* Add badges to README (Felipe Zipitría) +* Add clarifying comments to 910110 (Christian Folini) +* Making rule 933131 case-insensitive (Manuel Spartan) +* Merge and reorder rules as part of cleanup (Federico G. Schwindt) +* Update copyright date and syntax (Jose Nazario, Felipe Zipitría) +* Updated SecMarker and SkipAfter names to use meet guidelines (Felipe Zipitría) +* Tidy up single quotes and other guidelines updates (Felipe Zipitría) +* Syntax fix for setvar crs_exclusions_wordpress (Manuel Spartan) +* Updated various contributors to developers (Christian Folini) +* Revise SQL rules by disassembling them into their core protections (Franziska Bühler) +* Add an example payload to 920220 (coolt) +* Add a missing regex to rule 942310 (Franziska Bühler) +* Detect GET or HEAD with Transfer-Encoding header (Federico G. Schwindt) +* Fix broken links in references (Pásztor Gábor) +* Add contributing guidelines (Felipe Zipitría) +* Fix processing bypasses in rule 931130 (Felipe Zipitría, Christian Folini) +* Correct small omissions in unix-shell.data (Walter Hop) +* Add IIS specific detection to LFI-os-files.data (Manuel Spartan) +* Update examples to match the current cleanup (Federico G. Schwindt) +* Corrected the ordering of actions to meet guidelines (Felipe Zipitría) +* Remove unused capture groups (Federico G. Schwindt) +* Use explicit rx operator (Federico G. Schwindt) +* Update the RCE regular expressions(Walter Hop, Federico G. Schwindt) +* Removing maturity & accuracy from rules (Felipe Zipitría) +* Increasing range header (Christoph Hansen) +* Fixed upgrade.py script argument options (Glyn Mooney) +* Updating to reflect OWASP flagship status (Chaim Sanders) +* Adding Docker support for CRS (Chaim Sanders) +* Initial Travis deployment (Zack Allen, Walter Hop) +* Initial commit of regression tests (Chaim Sanders, Walter Hop) +* Remove test for 921170 because it won't ever fire (Chaim Sanders, Walter Hop) +* Update minor incorrectness in asp.net regex (Chaim Sanders, Walter Hop) +* Add notification for builds against #modsecurity on freenode (Zack Allen, Walter Hop) +* Add all past code contributors and convert to markdown (Walter Hop) +* Block uploads of files with .phps extension (Walter Hop) +* Improve message for script upload with superfluous extension (Walter Hop) +* Remove trailing whitespace in various regexs (Walter Hop) +* Add command popd to direct unix rce list in rule 932150 (Franziska Bühler) +* Remove unnecessary END_XSS_CHECKS marker (Christian Folini) +* Ignore Whitespaces in Rule 942110 (Christoph Hansen) +* Update missing RCE Commands (Umar Farook) +* Update lfi-os-files.data (Umar Farook) +* Removed deprecated t:removeComments from 942100 (Christian Folini) +* Add word boundary to rule 942410 (Franziska Bühler) ## Version 3.0.2 - 2017-05-12 - * Remove debug rule that popped up in 3.0.1 (Christian Folini) - +* Remove debug rule that popped up in 3.0.1 (Christian Folini) ## Version 3.0.1 - 2017-05-09 - * SECURITY: Removed insecure handling of X-Forwarded-For header; +* SECURITY: Removed insecure handling of X-Forwarded-For header; reported by Christoph Hansen (Walter Hop) - * Fixed documentation errors in RESPONSE-999-... (Chaim Sanders) - * Reduced FPs on 942190 by adding a word boundary to regex (Franziska Bühler) - * Reduced FPs on 932150 by removing keyword reset (Franziska Bühler) - * Tidied exceptions in 930100 (Roberto Paprocki) - * Reduced FPs for 920120 by splitting into stricter sibling (Franziska Bühler) - * Simplified some Drupal rule exclusions (Damien McKenna, Christian Folini) - * Extended KNOWN_BUGS with remarks on JSON support on Debian (Franziska Bühler) - * Updated README to add gitter support (Chaim Sanders) - * Clarified DoS documentation for static extensions (Roberto Paprocki) - * Added application/octet-stream to allowed content types (Christian Folini) - * Typo in 942220 alert message (Chaim Sanders, @bossloper) - * Moved referrer check of 941100 into new PL2 rule (Franziska Bühler) - * Closed multiple @pmf evasions via lowercase transformation (Roberto Paprocki) - * Clarified libinjection bundling in INSTALL file (@cjdp) - * Reduced FPs via Wordpress Rule Exclusions (Walter Hop) - * Support for RFC 3902 (Content Type application/soap+xml; Christoph Hansen) +* Fixed documentation errors in RESPONSE-999-... (Chaim Sanders) +* Reduced FPs on 942190 by adding a word boundary to regex (Franziska Bühler) +* Reduced FPs on 932150 by removing keyword reset (Franziska Bühler) +* Tidied exceptions in 930100 (Roberto Paprocki) +* Reduced FPs for 920120 by splitting into stricter sibling (Franziska Bühler) +* Simplified some Drupal rule exclusions (Damien McKenna, Christian Folini) +* Extended KNOWN_BUGS with remarks on JSON support on Debian (Franziska Bühler) +* Updated README to add gitter support (Chaim Sanders) +* Clarified DoS documentation for static extensions (Roberto Paprocki) +* Added application/octet-stream to allowed content types (Christian Folini) +* Typo in 942220 alert message (Chaim Sanders, @bossloper) +* Moved referrer check of 941100 into new PL2 rule (Franziska Bühler) +* Closed multiple @pmf evasions via lowercase transformation (Roberto Paprocki) +* Clarified libinjection bundling in INSTALL file (@cjdp) +* Reduced FPs via Wordpress Rule Exclusions (Walter Hop) +* Support for RFC 3902 (Content Type application/soap+xml; Christoph Hansen) Make sure you update ModSecurity recommended rule 200000 as well. - * Bugfix in 942410 regex (Christian Folini) - * Reduced FPs for 942360 (Walter Hop) - * Reduced FPs for 941120 by restricting event handler names (Franziska Bühler) - * Extended 931000 with scheme "file" to fix false negative (Federico Schwindt) - * Extended 905100 and 905110 for HTTP/2.0 (includes bugfix, Christoph Hansen) - * Moved 941150 from PL1 to PL2; includes Bugfix for rule (Christian Folini) - * Updated documentation for 920260 (Chaim Sanders) - * Bugfix in upgrade.py (Victor Hora) - * Fixed FP in RCE rule 932140 (Walter Hop) - * Fixed comment for arg limit check rule 920370 (Christian Folini) - * Created CONTRIBUTORS file - * Added Christoph Hansen (emphazer) to CONTRIBUTORS file - * Added Franziska Bühler (Franziska Bühler) to CONTRIBUTORS file - * Fixed bug with DoS rule 912160 (@loudly-soft, Christian Folini) - +* Bugfix in 942410 regex (Christian Folini) +* Reduced FPs for 942360 (Walter Hop) +* Reduced FPs for 941120 by restricting event handler names (Franziska Bühler) +* Extended 931000 with scheme "file" to fix false negative (Federico Schwindt) +* Extended 905100 and 905110 for HTTP/2.0 (includes bugfix, Christoph Hansen) +* Moved 941150 from PL1 to PL2; includes Bugfix for rule (Christian Folini) +* Updated documentation for 920260 (Chaim Sanders) +* Bugfix in upgrade.py (Victor Hora) +* Fixed FP in RCE rule 932140 (Walter Hop) +* Fixed comment for arg limit check rule 920370 (Christian Folini) +* Created CONTRIBUTORS file +* Added Christoph Hansen (emphazer) to CONTRIBUTORS file +* Added Franziska Bühler (Franziska Bühler) to CONTRIBUTORS file +* Fixed bug with DoS rule 912160 (@loudly-soft, Christian Folini) ## Version 3.0.0 - 2016-11-10 Huge changeset running in separate branch from September 2013 to September 2016. This is a cursory summary of the most important changes: - * Huge reduction of false positives (Ryan Barnett, Felipe Zimmerle, Chaim +* Huge reduction of false positives (Ryan Barnett, Felipe Zimmerle, Chaim Sanders, Walter Hop, Christian Folini) - * Anomaly scoring is the new default, renamed thresholds from +* Anomaly scoring is the new default, renamed thresholds from tx.(in|out)bound_anomaly_score_level to tx.(in|out)bound_anomaly_score_threshold - * Introduction of libinjection for SQLi detection - * Introduction of libinjection for XSS detection - * Big improvement on detection of Remote Command Execution (Walter Hop) - * Big improvement on PHP function name detection (Walter Hop) - * Paranoia Mode (Christian Folini, Noël Zindel, Franziska Bühler, +* Introduction of libinjection for SQLi detection +* Introduction of libinjection for XSS detection +* Big improvement on detection of Remote Command Execution (Walter Hop) +* Big improvement on PHP function name detection (Walter Hop) +* Paranoia Mode (Christian Folini, Noël Zindel, Franziska Bühler, Manuel Leos, Walter Hop) - * Shifted dozens of rules into higher paranoia levels - * Introduced a lot of stricter sibling rules in higher levels - * Generic mechanism to support application specific rule exclusions +* Shifted dozens of rules into higher paranoia levels +* Introduced a lot of stricter sibling rules in higher levels +* Generic mechanism to support application specific rule exclusions (Chaim Sanders) - * Initial Wordpress rule exclusions (Walter Hop) - * Initial Drupal rule exclusions (Christian Folini, @emphazer) - * Renumbering of rules. See folder id_renumbering for a +* Initial Wordpress rule exclusions (Walter Hop) +* Initial Drupal rule exclusions (Christian Folini, @emphazer) +* Renumbering of rules. See folder id_renumbering for a csv map (Chaim Sanders) - * Consolidation of rules, namely XSS and SQLi (Spider Labs/Trustwave team) - * Sampling mode / Easing in (Christian Folini) - * Cleanup of reputation checks / persistent blocking +* Consolidation of rules, namely XSS and SQLi (Spider Labs/Trustwave team) +* Sampling mode / Easing in (Christian Folini) +* Cleanup of reputation checks / persistent blocking (Christian Folini / Walter Hop) - * Tags much more systematic (Walter Hop) - * IP reputation checks / persistent blocking of certain clients +* Tags much more systematic (Walter Hop) +* IP reputation checks / persistent blocking of certain clients (Spider Labs/Trustwave team) - * Phase actions use request/response/logging now instead of +* Phase actions use request/response/logging now instead of numerical phases (Spider Labs/Trustwave team) - * Added NoScript XSS Filters (Spider Labs/Trustwave team) - * Updated "severity" action to use words (CRITICAL, WARNING, etc...) +* Added NoScript XSS Filters (Spider Labs/Trustwave team) +* Updated "severity" action to use words (CRITICAL, WARNING, etc...) vs. numbers (5, 4, etc..) - * Various regex fixes after research by Vladimir Ivanov (Chaim Sanders) - * Overhaul of the regression mode into debug mode (Walter Hop, Ryan Barnett) - * Introduction of util/upgrade.py (Walter Hop) - * Removal of GeoIP database. Download via util/upgrade.py now. - * Introduction of Initialization rules with +* Various regex fixes after research by Vladimir Ivanov (Chaim Sanders) +* Overhaul of the regression mode into debug mode (Walter Hop, Ryan Barnett) +* Introduction of util/upgrade.py (Walter Hop) +* Removal of GeoIP database. Download via util/upgrade.py now. +* Introduction of Initialization rules with default values (Walter Hop, Christian Folini) - * Sorting out terminology with +* Sorting out terminology with whitelisting and rule exclusions (Christian Folini) - * Overhaul of testing (Chaim Sanders) - * Protection from HTTP Parameter Pollution (Franziska Bühler) - * Simplification of setup config file, renamed file to crs-setup.conf.example - * Improved session fixation detection logic (Christian Peron, credits to +* Overhaul of testing (Chaim Sanders) +* Protection from HTTP Parameter Pollution (Franziska Bühler) +* Simplification of setup config file, renamed file to crs-setup.conf.example +* Improved session fixation detection logic (Christian Peron, credits to Eric Hodel for the discovery) - * Updated list of malicious webscanners - * Splitting scanner user agents data files (github user @ygrek) - * Countless bugfixes in severities, anomaly scores, tags, etc. +* Updated list of malicious webscanners +* Splitting scanner user agents data files (github user @ygrek) +* Countless bugfixes in severities, anomaly scores, tags, etc. across the board - * Cleanup of formerly experimental DDoS rules, +* Cleanup of formerly experimental DDoS rules, fix documentation (Ryan Barnett, Christian Folini) - * Improves http blacklist checks (Walter Hop) - * Extended XSS detection (as suggested by Mazin Ahmed) - * Added support for Travis CI - * Added support for HTTP/2 in recent Apache 2.4 (Walter Hop) - * Added many, many bots and scanners (among others suggested by +* Improves http blacklist checks (Walter Hop) +* Extended XSS detection (as suggested by Mazin Ahmed) +* Added support for Travis CI +* Added support for HTTP/2 in recent Apache 2.4 (Walter Hop) +* Added many, many bots and scanners (among others suggested by github user @toby78, @jamuse, Matt Koch) - * Fixed mime types suitable for XML processor (Chaim Sanders) - * Include script in util/join-multiline-rules to work around +* Fixed mime types suitable for XML processor (Chaim Sanders) +* Include script in util/join-multiline-rules to work around Apache 2.4 < 2.4.11 bug with long lines (Walter Hop) - * New detection for request smuggling attacks (Achim Hofmann, +* New detection for request smuggling attacks (Achim Hofmann, Christian Folini) - * Fixes with project honeypot setup (Ryan Barnett) - * Separated DB / SQL messages by DB software (Ryan Barnett) - * CPanel integration (Chaim Sanders) - * Introduction of var for static resources (Chaim Sanders) - * Many improvements to rules in 2014/5 (Ryan Barnett) - +* Fixes with project honeypot setup (Ryan Barnett) +* Separated DB / SQL messages by DB software (Ryan Barnett) +* CPanel integration (Chaim Sanders) +* Introduction of var for static resources (Chaim Sanders) +* Many improvements to rules in 2014/5 (Ryan Barnett) ## Version 2.2.9 - 2013-09-30 Improvements: + * Updated the /util directory structure - Bug Fixes: + * fix 950901 - word boundary added * modsecurity_35_bad_robots.data - gecko/25 blocks Firefox Android - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/157 - + ## Version 2.2.8 - 2013-06-30 Improvements: -* Updated the /util directory structure + +* Updatd the /util directory structure * Added scripts to check Rule ID duplicates * Added script to remove v2.7 actions so older ModSecurity rules will work - - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/43 + * * Added new PHP rule (958977) to detect PHP exploits (Plesk 0-day from king cope) - - http://seclists.org/fulldisclosure/2013/Jun/21 - - http://blog.spiderlabs.com/2013/06/honeypot-alert-active-exploits-attempts-for-plesk-vulnerability-.html - + * + * Bug Fixes: -* fix 950901 - word boundary added - - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/48 -* fix regex error - - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/44 -* Updated the Regex in 981244 to include word boundaries - - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/36 -* Problem with Regression Test (Invalid use of backslash) - Rule 960911 - Test2 - - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/34 -* ModSecurity: No action id present within the rule - ignore_static.conf - - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/17 -* "Bad robots" rule blocks all Java applets on Windows XP machines - - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/16 -* duplicated rules id 981173 - - https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/18 +* fix 950901 - word boundary added + * +* fix regex error + * +* Updated the Regex in 981244 to include word boundaries + * +* Problem with Regression Test (Invalid use of backslash) - Rule 960911 - Test2 + * +* ModSecurity: No action id present within the rule - ignore_static.conf + * +* "Bad robots" rule blocks all Java applets on Windows XP machines + * +* duplicated rules id 981173 + * ## Version 2.2.7 - 2012-12-19 Improvements: + * Added JS Overrides file to identify successful XSS probes -* Added new XSS Detection Rules from Ashar Javed (http://twitter.com/soaj1664ashar) - - http://jsfiddle.net/U9RmU/4/ +* Added new XSS Detection Rules from Ashar Javed () + * * Updated the SQLi Filters to add in Oracle specific functions - - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/7 + * Bug Fixes: -* Fixed Session Hijacking rules - - https://github.com/SpiderLabs/owasp-modsecurity-crs/pull/8 -* Fixed bug in XSS rules checking TX:PM_XSS_SCORE variable +* Fixed Session Hijacking rules + * +* Fixed bug in XSS rules checking TX:PM_XSS_SCORE variable ## Version 2.2.6 - 2012-09-14 Improvements: + * Started rule formatting update for better readability * Added maturity and accuracy action data to each rule * Updated rule revision (rev) action @@ -1257,25 +708,27 @@ Improvements: * Added new Session Fixation rules Bug Fixes: + * Fixed missing ending double-quotes in XSS rules file * Moved SecDefaultAction setting from phase:2 to phase:1 * Fixed Session Hijacking SessionID Regex - https://www.modsecurity.org/tracker/browse/CORERULES-79 + * Changed the variable listing for many generic attack rules to exclude REQUEST_FILENAME - https://www.modsecurity.org/tracker/browse/CORERULES-78 - + ## Version 2.2.5 - 2012-06-14 Security Fixes: + * Updated the anomaly scoring value for rule ID 960000 to critical (Identified by Qualys Vulnerability & Malware Research Labs (VMRL)) - (https://community.qualys.com/blogs/securitylabs/2012/06/15/modsecurity-and-modsecurity-core-rule-set-multipart-bypasses) + () * Updated Content-Type check to fix possible evasion with @within (Identified by Qualys Vulnerability & Malware Research Labs (VMRL)) - (https://community.qualys.com/blogs/securitylabs/2012/06/15/modsecurity-and-modsecurity-core-rule-set-multipart-bypasses) + () Improvements: + * Renamed main config file to modsecurity_crs_10_setup.conf * Updated the rule IDs to start from CRS reserved range: 900000 * Updated rule formatting for readability @@ -1286,12 +739,13 @@ Improvements: * Added Arachni Scanner Integration Lua script/rules files Bug Fixes: -* Added forceRequestBodyVariable action to rule ID 960904 +* Added forceRequestBodyVariable action to rule ID 960904 ## Version 2.2.4 - 2012-03-14 Improvements: + * Added Location and Set-Cookie checks to Response Splitting rule ID 950910 * Added a README file to the activated_rules directory * Consolidate a number of SQL Injection rules into optimized regexs @@ -1301,30 +755,31 @@ Improvements: * Removed PARANOID mode rules Bug Fixes: -* Fixed missing comma before severity action in rules 958291, 958230 and 958231 -* Fixed duplicate rule IDs +* Fixed missing comma before severity action in rules 958291, 958230 and 958231 +* Fixed duplidate rule IDs ## Version 2.2.3 - 2011-12-19 Improvements: + * Added Watcher Cookie Checks to optional_rules/modsecurity_crs_55_appication_defects.conf file - http://websecuritytool.codeplex.com/wikipage?title=Checks#cookies + * Added Watcher Charset Checks to optional_rules/modsecurity_crs_55_application_defects.conf file - http://websecuritytool.codeplex.com/wikipage?title=Checks#charset + * Added Watcher Header Checks to optional_rules/modsecurity_crs_55_application_defects.conf file - http://websecuritytool.codeplex.com/wikipage?title=Checks#header + Bug Fixes: + * Fixed Content-Type evasion issue by adding ctl:forceRequestBodyVariable action to rule ID 960010. (Identified by Andrew Wilson of Trustwave SpiderLabs). * Updated the regex and added tags for RFI rules. - ## Version 2.2.2 - 2011-09-28 - Improvements: + * Updated the AppSensor Profiling (to use Lua scripts) for Request Exceptions Detection Points * Added new Range header detection checks to prevent Apache DoS * Added new Security Scanner User-Agent strings @@ -1334,39 +789,39 @@ Improvements: * Added Host header info to the RESOURCE collection key for AppSensor profiling rules Bug Fixes: + * Fixed action list for XSS rules (replaced pass,nolog,auditlog with block) * Fixed Request Limit rules by removing & from variables * Fixed Session Hijacking IP/UA hash captures * Updated the SQLi regex for rule ID 981242 - ## Version 2.2.1 - 2011-07-20 - Improvements: + * Extensive SQL Injection signature updates as a result of the SQLi Challenge - http://www.modsecurity.org/demo/challenge.html + * Updated the SQL Error message detection in response bodies * Updated SQL Injection signatures to include more DB functions * Updated the WEAK SQL Injection signatures * Added tag AppSensor/RE8 to rule ID 960018 Bug Fixes: + * Fixed Bad Robot logic for rule ID 990012 to further qualify User-Agent matches - https://www.modsecurity.org/tracker/browse/CORERULES-70 + * Fixed Session Hijacking rules to properly capture IP address network hashes. * Added the multiMatch action to the SQLi rules * Fixed a false negative logic flaw within the advanced_filter_converter.lua script * Fixed missing : in id action in DoS ruleset. * Updated rule ID 971150 signature to remove ; - ## Version 2.2.0 - 2011-05-26 - Improvements: + * Changed Licensing from GPLv2 to Apache Software License v2 (ASLv2) - http://www.apache.org/licenses/LICENSE-2.0.txt + * Created new INSTALL file outlining quick config setup * Added a new rule regression testing framework to the /util directory * Added new activated_rules directory which will allow users to place symlinks pointing @@ -1374,29 +829,30 @@ Improvements: * Adding in new RULE_MATURITY and RULE_ACCURACY tags * Adding in a check for X-Forwarded-For source IP when creating IP collection * Added new Application Defect checks (55 app defect file) from Watcher tool (Check Charset) - http://websecuritytool.codeplex.com/wikipage?title=Checks#charset + * Added new AppSensor rules to experimental_dir - https://owasp.org/www-project-appsensor/ + * Added new Generic Malicious JS checks in outbound content * Added experimental IP Forensic rules to gather Client hostname/whois info - http://blog.spiderlabs.com/2010/11/detecting-malice-with-modsecurity-ip-forensics.html + * Added support for Mozilla's Content Security Policy (CSP) to the experimental_rules - http://blog.spiderlabs.com/2011/04/modsecurity-advanced-topic-of-the-week-integrating-content-security-policy-csp.html + * Global collection in the 10 file now uses the Host Request Header as the collection key. This allows for per-site global collections. * Added new SpiderLabs Research (SLR) rules directory (slr_rules) for known vulnerabilities. This includes both converted web rules from Emerging Threats (ET) and from SLR Team. * Added new SLR rule packs for known application vulns for WordPress, Joomla and phpBB * Added experimental rules for detecting Open Proxy Abuse - http://blog.spiderlabs.com/2011/03/detecting-malice-with-modsecurity-open-proxy-abuse.html + * Added experimental Passive Vulnerability Scanning ruleset using OSVDB and Lua API - http://blog.spiderlabs.com/2011/02/modsecurity-advanced-topic-of-the-week-passive-vulnerability-scanning-part-1-osvdb-checks.html + * Added additional URI Request Validation rule to the 20 protocol violations file (Rule ID - 981227) * Added new SQLi detection rules (959070, 959071 and 959072) * Added "Toata dragostea mea pentru diavola" to the malicious User-Agent data - https://www.modsecurity.org/tracker/browse/CORERULES-64 + Bug Fixes: + * Assigned IDs to all active SecRules/SecActions * Removed rule inversion (!) from rule ID 960902 * Fixed false negative issue in Response Splitting Rule @@ -1405,16 +861,15 @@ Bug Fixes: * Updated TX data for REQBODY processing * Changed the pass action to block in the RFI rules in the 40 generic file * Updated RFI regex to catch IP address usage in hostname - https://www.modsecurity.org/tracker/browse/CORERULES-68 + * Changed REQUEST_URI_RAW variable to REQUEST_LINE in SLR rules to allow matches on request methods. * Updated the RFI rules in the 40 generic attacks conf file to remove explicit logging actions. They will now inherit the settings from the SecDefaultAction - ## Version 2.1.2 - 2011-02-17 - Improvements: + * Added experimental real-time application profiling ruleset. * Added experimental Lua script for profiling the # of page scripts, iframes, etc.. which will help to identify successful XSS attacks and planting of malware links. @@ -1422,13 +877,13 @@ Improvements: quickly (need to use the Ignore Static Content rules). Bug Fixes: -* Added missing " in the skipAfter SecAction in the CC Detection rule set +* Added missing " in the skipAfter SecAction in the CC Detection rule set ## Version 2.1.1 - 2010-12-30 - Bug Fixes: + * Updated the 10 config conf file to add in pass action to User-Agent rule * Updated the CSRF ruleset to conditionally do content injection - if the csrf token was created by the session hijacking conf file @@ -1437,11 +892,10 @@ Bug Fixes: * Fixed macro expansion setvar bug in the restricted file extension rule * Moved the comment spam data file into the optional_rules directory - ## Version 2.1.0 - 2010-12-29 - Improvements: + * Added Experimental Lua Converter script to normalize payloads. Based on PHPIDS Converter code and it used with the advanced filters conf file. * Changed the name of PHPIDS converted rules to Advanced Filters @@ -1467,26 +921,23 @@ Improvements: * Adding the REQUEST_HEADERS:User-Agent macro data to the initcol in 10 config file, which will help to make collections a bit more unique - - ## Version 2.0.10 - 2010-11-29 - Improvements: + * Commented out the Anomaly Scoring Blocking Mode TX variable since, by default, the CRS is running in traditional mode. Bug Fixes: + * Moved all skipAfter actions in chained rules to chain starter SecRules - https://www.modsecurity.org/tracker/browse/MODSEC-159 + * Changed phases on several rules in the 20 protocol anomaly rules file to phase:1 to avoid FNs - - ## Version 2.0.9 - 2010-11-17 - Improvements: + * Changed the name of the main config file to modsecurity_crs_10_config.conf.example so that it will not overwrite existing config settings. Users should rename this file to activate it. @@ -1506,22 +957,22 @@ Improvements: * Moved some files to optional_rules directory (phpids, Emerging Threats rules) Bug Fixes: + * Fixed Rule ID 960023 in optional_rules/modsecurity_crs_40_experimental.conf is missing 1 single quote - https://www.modsecurity.org/tracker/browse/CORERULES-63 + * Moved all skipAfter actions in chained rules to the rule starter line (must have ModSec v2.5.13 or higher) - https://www.modsecurity.org/tracker/browse/MODSEC-159 + * Fixed restricted file extension bug with macro expansion - https://www.modsecurity.org/tracker/browse/CORERULES-60 + * Updated the SQLI TX variable macro expansion data in the 49 and 60 files so that it matches what is being set in the sql injection conf file * Fixed typo in SQL Injection regexs - missing backslash for word boundary (b) - https://www.modsecurity.org/tracker/browse/CORERULES-62 - + ## Version 2.0.8 - 2010-08-27 - Improvements: + * Updated the PHPIDS filters * Updated the SQL Injection filters to detect boolean attacks (1<2, foo == bar, etc..) * Updated the SQL Injection filters to account for different quotes @@ -1530,21 +981,21 @@ Improvements: * Added two experimental rules to detect anomalous use of special characters Bug Fixes: + * Fixed Encoding Detection RegEx (950107 and 950108) * Fixed rules-updater.pl script to better handle whitespace - https://www.modsecurity.org/tracker/browse/MODSEC-167 + * Fixed missing pass action bug in modsecurity_crs_21_protocol_anomalies.conf - https://www.modsecurity.org/tracker/browse/CORERULES-55 + * Fixed the anomaly scoring in the modsecurity_crs_41_phpids_filters.conf file - https://www.modsecurity.org/tracker/browse/CORERULES-54 + * Updated XSS rule id 958001 to improve the .cookie regex to reduce false positives - https://www.modsecurity.org/tracker/browse/CORERULES-29 - + ## Version 2.0.7 - 2010-06-04 - Improvements: + * Added CSRF Protection Ruleset which will use Content Injection to add javascript to specific outbound data and then validate the csrf token on subsequent requests. * Added new Application Defect Ruleset which will identify/fix missing HTTPOnly cookie @@ -1556,41 +1007,39 @@ Improvements: * Added new SQLi keyword for ciel() and reverse() functions. * Updated the PHPIDS filters - Bug Fixes: + * Fixed false positives for Request Header Name matching in the 30 file by adding boundary characters. * Added missing pass actions to @pmFromFile prequalifier rules * Added backslash to SQLi regex - https://www.modsecurity.org/tracker/browse/CORERULES-41 + * Fixed hard coded anomaly score in PHPIDS filter file - https://www.modsecurity.org/tracker/browse/CORERULES-45 + * Fixed restricted_extension false positive by adding boundary characters - ## Version 2.0.6 - 2010-02-26 - Bug Fixes: -* Added missing transformation functions to SQLi rules. - https://www.modsecurity.org/tracker/browse/CORERULES-32 -* Fixed duplicate rule IDs. - https://www.modsecurity.org/tracker/browse/CORERULES-33 -* Fixed typo in @pmFromFile in the Comment SPAM rules - https://www.modsecurity.org/tracker/browse/CORERULES-34 -* Added macro expansion to Restricted Headers rule - https://www.modsecurity.org/tracker/browse/CORERULES-35 -* Fixed misspelled SecMarker - https://www.modsecurity.org/tracker/browse/CORERULES-36 -* Fixed missing chain action in Content-Type header check - https://www.modsecurity.org/tracker/browse/CORERULES-37 -* Update phpids filters to use pass action instead of block +* Added missing transformation functions to SQLi rules. + +* Fixed duplicate rule IDs. + +* Fixed typo in @pmFromFile in the Comment SPAM rules + +* Added macro expansion to Restricted Headers rule + +* Fixed misspelled SecMarker + +* Fixed missing chain action in Content-Type header check + +* Update phpids filters to use pass action instead of block ## Version 2.0.5 - 2010-02-01 - Improvements: + * Removed previous 10 config files as they may conflict with local customized Mod configs. * Added a new 10 config file that allows the user to globally set TX variables to turn on/off PARANOID_MODE inspection, set anomaly score levels and http policies. @@ -1605,8 +1054,8 @@ Improvements: * Created an experimental rules file * Updated HTTP Parameter Pollution (HPP) rule logic to concat data into a TX variable for inspection * Removed TX inspections for generic attacks and reverted to standard ARGS inspection - https://www.modsecurity.org/tracker/browse/MODSEC-120 -* Updated the variable list for standard inspections (ARGS|ARGS_NAMES|XML:/\*) and moved the other + +* Updated the variable list for standard inspections (ARGS|ARGS_NAMES|XML:/*) and moved the other variables to the PARANOID list (REQUEST_URI|REQUEST_BODY|REQUEST_HEADERS|TX:HPP_DATA) * Moved converted ET Snort rules to the /optional_rules directory * Created a new Header Tagging ruleset (optional_rules) that will add matched rule data to the @@ -1620,18 +1069,18 @@ Improvements: Identified by SOGETI ESEC R&D Bug Fixes: + * Removed Non-numeric Rule IDs - https://www.modsecurity.org/tracker/browse/CORERULES-28 + * Updated the variable list on SQLi rules. * Fixed outbound @pmFromFile action from allow to skipAfter to allow for outbound anomaly scoring and blocking - ## Version 2.0.4 - 2009-11-30 - Improvements: -* Updated converted PHPIDS signatures (https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml) + +* Updated converted PHPIDS signatures () * Updated PHPIDS rules logic to first search for payloads in ARGS and then if there is no match found then search more generically in request_body|request_uri_raw * Updated PHPIDS rules logic to only set TX variables and to not log. This allows for more clean @@ -1640,68 +1089,68 @@ Improvements: alerts for any variable matches that exist. Bug Fixes: + * Added Anomaly Score check to the 60 correlation file to recheck the anomaly score at the end of phase:4 which would allow for blocking based on information leakage issues. - ## Version 2.0.3 - 2009-11-05 - Improvements: -* Updated converted PHPIDS signatures (https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml) -* Create a new PHPIDS Converter rules file (https://svn.php-ids.org/svn/trunk/lib/IDS/Converter.php) + +* Updated converted PHPIDS signatures () +* Create a new PHPIDS Converter rules file () * Added new rules to identify multipart/form-data bypass attempts * Increased anomaly scoring (+100) for REQBODY_PROCESSOR_ERROR alerts Bug Fixes: -* Added t:urlDecodeUni transformation function to phpids rules to fix both false positives/negatives - https://www.modsecurity.org/tracker/browse/CORERULES-17 -* Added new variable locations to the phpids filters - https://www.modsecurity.org/tracker/browse/CORERULES-19 -* Use of transformation functions can cause false negatives - added multiMatch action to phpids rules - https://www.modsecurity.org/tracker/browse/CORERULES-20 -* Fixed multipart parsing evasion issues by adding strict parsing rules - https://www.modsecurity.org/tracker/browse/CORERULES-21 -* Fixed typo in xss rules (missing |) - https://www.modsecurity.org/tracker/browse/CORERULES-22 -* Fixed regex text in IE8 XSS filters (changed to lowercase) - https://www.modsecurity.org/tracker/browse/CORERULES-23 +* Added t:urlDecodeUni transformation function to phpids rules to fix both false positives/negatives + +* Added new variable locations to the phpids filters + +* Use of transformation functions can cause false negatives - added multiMatch action to phpids rules + +* Fixed multipart parsing evasion issues by adding strict parsing rules + +* Fixed typo in xss rules (missing |) + +* Fixed regex text in IE8 XSS filters (changed to lowercase) + ## Version 2.0.2 - 2009-09-11 - Improvements: -* Added converted PHPIDS signatures (https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xml) - https://www.modsecurity.org/tracker/browse/CORERULES-13 + +* Added converted PHPIDS signatures () + Bug Fixes: -* Rule 958297 - Fixed Comment SPAM UA false positive that triggered only on mozilla. - https://www.modsecurity.org/tracker/browse/CORERULES-15 +* Rule 958297 - Fixed Comment SPAM UA false positive that triggered only on mozilla. + ## Version 2.0.1 - 2009-08-07 - Improvements: + * Updated the transformation functions used in the XSS/SQLi rules to improve performance - https://www.modsecurity.org/tracker/browse/CORERULES-10 + * Updated the variable/target list in the XSS rules - https://www.modsecurity.org/tracker/browse/CORERULES-11 + * Added XSS Filters from IE8 - https://www.modsecurity.org/tracker/browse/CORERULES-12 + Bug Fixes: -* Rule 958297 - Fixed unescaped double-quote issue in Comment SPAM UA rule. - https://www.modsecurity.org/tracker/browse/CORERULES-9 +* Rule 958297 - Fixed unescaped double-quote issue in Comment SPAM UA rule. + ## Version 2.0.0 - 2009-07-29 - New Rules & Features: + * Fine Grained Policy The rules have been split to having one signature per rule instead of having all signatures combined into one optimized regular expression. @@ -1709,42 +1158,42 @@ New Rules & Features: instead of having to deal with the whole rule. * Converted Snort Rules Emerging Threat web attack rules have been converted. - http://www.emergingthreats.net/ + * Anomaly Scoring Mode Option The rules have been updated to include anomaly scoring variables which allow you to evaluate the score at the end of phase:2 and phase:5 and decide on what logging and disruptive actions to take based on the score. * Correlated Events There are rules in phase:5 that will provide some correlation between inbound - events and outbound events and will provide a result of successful attack or + events and outbound events and will provide a result of successful atttack or attempted attack. * Updated Severity Ratings The severity ratings in the rules have been updated to the following: - - 0: Emergency - is generated from correlation where there is an inbound attack and + * 0: Emergency - is generated from correlation where there is an inbound attack and an outbound leakage. - - 1: Alert - is generated from correlation where there is an inbound attack and an + * 1: Alert - is generated from correlation where there is an inbound attack and an outbound application level error. - - 2: Critical - is the highest severity level possible without correlation. It is + * 2: Critical - is the highest severity level possible without correlation. It is normally generated by the web attack rules (40 level files). - - 3: Error - is generated mostly from outbound leakabe rules (50 level files). - - 4: Warning - is generated by malicious client rules (35 level files). - - 5: Notice - is generated by the Protocol policy and anomaly files. - - 6: Info - is generated by the search engine clients (55 marketing file). + * 3: Error - is generated mostly from outbound leakabe rules (50 level files). + * 4: Warning - is generated by malicious client rules (35 level files). + * 5: Notice - is generated by the Protocol policy and anomaly files. + * 6: Info - is generated by the search engine clients (55 marketing file). * Updated Comment SPAM Protections Updated rules to include RBL lookups and client fingerprinting concepts from - Bad Behavior (www.bad-behavior.ioerror.us) + Bad Behavior () * Creation of Global Collection - Automatically create a Global collection in the *10* config file. Other rules + Automatically create a Global collection in the _10_ config file. Other rules can then access it. * Use of Block Action Updated the rules to use the "block" action. This allows the Admin to globally - set the desired block action once with SecDefaultAction in the *10* config file + set the desired block action once with SecDefaultAction in the _10_ config file rather than having to edit the disruptive actions in all of the rules or for the need to have multiple versions of the rules (blocking vs. non-blocking). * "Possible HTTP Parameter Pollution Attack: Multiple Parameters with the same Name." - http://tacticalwebappsec.blogspot.com/2009/05/http-parameter-pollution.html + * Added new generic RFI detection rules. - http://tacticalwebappsec.blogspot.com/2009/06/generic-remote-file-inclusion-attack.html + * "Possibly malicious iframe tag in output" (Rules 981001,981002) Planting invisible iframes in a site can be used by attackers to point users from the victim site to their malicious site. This is actually as if the @@ -1752,6 +1201,7 @@ New Rules & Features: process the content in the attacker's site. New Events: + * Rule 960019 - Expect Header Not Allowed. * Rule 960020 - Pragma Header Requires Cache-Control Header * Rule 958290 - Invalid Character in Request - Browsers should not send the (#) character @@ -1766,6 +1216,7 @@ New Events: * Rule 958298 - Common SPAM/Email Harvester crawler Bug Fixes: + * Rule 950107 - Split the rule into 2 separate rules to factor in the Content-Type when inspecting the REQUEST_BODY variable. * Rule 960017 - Bug fix for when having port in the host header. @@ -1777,13 +1228,14 @@ Bug Fixes: * Rule 950117 - Updated the RFI logic to factor in both a trailing "?" in the ARG and to identify offsite hosts by comparing the ARG URI to the Host header. Due to this rule now being stronger, moved it from optional - tight security rule to *40* generic attacks file. + tight security rule to _40_ generic attacks file. Other Fixes: -* Added more HTTP Protocol violations to *20* file. -* Set the SecDefaultAction in the *10* config file to log/pass (This was the + +* Added more HTTP Protocol violations to _20_ file. +* Set the SecDefaultAction in the _10_ config file to log/pass (This was the default setting, however this sets it explicitly. -* Added SecResponseBodyLimitAction ProcessPartial to the *10* config file. This +* Added SecResponseBodyLimitAction ProcessPartial to the _10_ config file. This was added so that when running the SecRuleEngine in DetectionOnly mode, it will not deny response bodies that go over the size restrictions. * Changed SecServerSignature to "Apache/1.3.28" @@ -1795,19 +1247,16 @@ Other Fixes: * Updated rule formatting to easily show rule containers (SecMarkers, pre-qualifier rules and chained rules). - ## Version 1.6.1 - 2008-04-22 - * Fixed a bug where phases and transformations where not specified explicitly in rules. The issue affected a significant number of rules, and we strongly recommend to upgrade. - ## Version 1.6.0 - 2008-02-19 - New Rulesets & Features: + * 42 - Tight Security This ruleset contains currently 2 rules which are considered highly prone to FPs. They take care of Path Traversal attacks, and RFI attacks. This @@ -1827,11 +1276,13 @@ New Rulesets & Features: WEB_ATTACK/SQL_INJECTION. False Positives Fixes: + * Rule 960903 - Moved to phase 4 instead of 5 to avoid FPs * Rule 950107 - Will look for invalid url decoding in variables that are not automatically url decoded Additional rules logic: + * Using the new "logdata" action for logging the matched signature in rules * When logging an event once, init the collection only if the alert needs to log * Using the new operator @pm as a qualifier before large rules to enhance @@ -1840,41 +1291,42 @@ Additional rules logic: only 1=1. (Thanks to Marc Stern for the idea) * New XSS signatures - iframe & flash XSS - - ## Version 1.5.1 - 2007-12-06 - False Positives Fixes: + * Protocol Anomalies (file 21) - exception for Apache SSL pinger (Request: GET /) New Events: + * 960019 - Detect HTTP/0.9 Requests HTTP/0.9 request are not common these days. This rule will log by default, and block in the blocking version of file 21 Other Fixes: + * File 40, Rules 950004,950005 - Repaired the correction for the double url decoding problem * File 55 contained empty regular expressions. Fixed. - ## Version 1.5 - 2007-11-23 - New Rulesets: + * 23 - Request Limits "Judging by appearances". This rulesets contains rules blocking based on the size of the request, for example, a request with too many arguments will be denied. Default policy changes: + * XML protection off by default * BLOCKING dir renamed to optional_rules * Ruleset 55 (marketing) is now optional (added to the optional_rules dir) * Ruleset 21 - The exception for apache internal monitor will not log anymore New Events: + * 960912 - Invalid request body Malformed content will not be parsed by modsecurity, but still there might be applications that will parse it, ignoring the errors. @@ -1883,10 +1335,12 @@ New Events: code 400, without going through ModSecurity rules. Additional rules logic: + * 950001 - New signature: delete from * 950007 - New signature: waitfor delay False Positives Fixes: + * 950006 - Will not be looking for /cc pattern in User-Agent header * 950002 - "Internet Explorer" signature removed * Double decoding bug used to cause FPs. Some of the parameters are already @@ -1897,14 +1351,13 @@ False Positives Fixes: * 950801 - Commented out entirely. NOTE: If your system uses UTF8 encoding, then you should uncomment this rule (in file 20) - version 1.4.3 - 2007-07-21 - New Events: + * 950012 - HTTP Request Smuggling For more info on this attack: - http://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf + * 960912 - Invalid request body Malformed content will not be parsed by modsecurity, but still there might be applications that will parse it, ignoring the errors. @@ -1913,31 +1366,32 @@ New Events: code 400, without going through ModSecurity rules. False Positives Fixes: + * 950107 - Will allow a % sign in the middle of a string as well * 960911 - A more accurate expression based on the rfc: - http://www.ietf.org/rfc/rfc2396.txt + * 950015 - Will not look for http/ pattern in the request headers Additional rules logic: + * Since Apache applies scope directives only after ModSecurity phase 1 this directives cannot be used to exclude phase 1 rules. Therefore we moved all inspection rules to phase 2. - - version 1.4 build 2 - 2007-05-17 - New Feature: + * Search for signatures in XML content - XML Content will be parsed and inspected for signatures + XML Content will be parsed and ispected for signatures New Events: + * 950116 - Unicode Full/Half Width Abuse Attack Attempt Full-width unicode can by used to bypass content inspection. Such encoding will be forbidden - http://www.kb.cert.org/vuls/id/739224 + * 960911 - Invalid HTTP request line - Enforce request line to be valid, i.e.: + Enforce request line to be valid, i.e.: ` ` * 960904 - Request Missing Content-Type (when there is content) When a request contains content, the content-type must be specified. If not, the content will not be inspected * 970018 - IIS installed in default location (any drive) @@ -1946,22 +1400,23 @@ New Events: Web forms used for sending mail (such as "tell a friend") are often manipulated by spammers for sending anonymous emails Regular expressions fixes: + * Further optimization of some regular expressions (using the non-greediness operator) The non-greediness operator, , prevents excessive backtracking FP fixes: -* Rule 950107 - Will allow a parameter to end in a % sign from now on +* Rule 950107 - Will allow a parameter to end in a % sign from now on version 1.4 - 2007-05-02 - New Events: + * 970021 - WebLogic information disclosure - Matching of "JSP compile error" in the response body, will trigger this rule, with severity 4 (Warning) + Matching of `"JSP compile error"` in the response body, will trigger this rule, with severity 4 (Warning) * 950015,950910,950911 - HTTP Response Splitting Looking for HTTP Response Splitting patterns as described in Amit Klein's excellent white paper: - http://www.packetstormsecurity.org/papers/general/whitepaper_httpresponse.pdf + ModSecurity does not support compressed content at the moment. Thus, the following rules have been added: * 960902 - Content-Encoding in request not supported Any incoming compressed request will be denied @@ -1969,8 +1424,9 @@ ModSecurity does not support compressed content at the moment. Thus, the followi An outgoing compressed response will be logged to alert, but ONLY ONCE. False Positives Fixes: + * Removed <.exe>,<.shtml> from restricted extensions -* Will not be looking for SQL Injection signatures , in the Via request header +* Will not be looking for SQL Injection signatures ``,`` in the Via request header * Excluded Referer header from SQL injection, XSS and command injection rules * Excluded X-OS-Prefs header from command injection rule * Will be looking for command injection signatures in @@ -1978,49 +1434,47 @@ False Positives Fixes: * Allowing charset specification in the Content-Type Additional rules logic: + * Corrected match of OPTIONS method in event 960015 * Changed location for event 960014 (proxy access) to REQUEST_URI_RAW * Moved all rules apart from method inspection from phase 1 to phase 2 - This will enable viewing content if such a rule triggers as well as setting exceptions using Apache scope tags. -* Added match for double quote in addition to single quote for signature (SQL Injection) +* Added match for double quote in addition to single quote for `` signature (SQL Injection) * Added 1=1 signature (SQL Injection) - version 1.3.2 build 4 2007-01-17 - Fixed apache 2.4 dummy requests exclusion Added persistent PDF UXSS detection rule - ## Version 1.3.2 build 3 2007-01-10 - Fixed regular expression in rule 960010 (file #30) to allow multipart form data content - ## Version 1.3.2 - 2006-12-27 - New events: + * 960037 Directory is restricted by policy * 960038 HTTP header is restricted by policy Regular expressions fixes: + * Regular expressions with @ at end of beginning (for example "@import) * Regular expressions with un-escaped "." * Command Injections now always require certain characters both before and after the command. Important since many are common English words (finger, mail) * The command injection wget is not searched in the UA header as it has different meaning there. * LDAP Fixed to reduce FPs: - + More accurate regular expressions - + high bit characters not accepted between signature tokens. + * More accurate regular expressions + * high bit characters not accpeted between signature tokens. * Do not detect The CRS project values third party contributions. To make the contribution process as easy as possible, a helpful set of contribution guidelines are in place which all contributors and developers are asked to adhere to. +## Getting Started -## Getting Started with a New Contribution - -1. Sign in to [GitHub](https://github.com/join). -2. Open a [new issue](https://github.com/coreruleset/coreruleset/issues) for the contribution, *assuming a similar issue doesn't already exist*. - * **Clearly describe the issue**, including steps to reproduce if reporting a bug. - * **Specify the CRS version in question** if reporting a bug. - * Bonus points for submitting tests along with the issue. -3. Fork the repository on GitHub and begin making changes there. -4. Signed commits are preferred. (For more information and help with this, refer to the [GitHub documentation](https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits)). +* You will need a [GitHub account](https://github.com/signup/free). +* Submit a [ticket for your issue](https://github.com/SpiderLabs/owasp-modsecurity-crs/issues), assuming one does not already exist. + * Clearly describe the issue including steps to reproduce when it is a bug. + * Make sure you specify the version that you know has the issue. + * Bonus points for submitting a failing test along with the ticket. +* If you don't have push access, fork the repository on GitHub. ## Making Changes -* Base any changes on branch `main`. -* Create a topic branch for each new contribution. -* Fix only one problem at a time. This helps to quickly test and merge submitted changes. If intending to fix *multiple unrelated problems* then use a separate branch for each problem. +* Please base your changes on branch ```v3.3/dev``` +* Create a topic branch for your feature or bug fix. +* Please fix only one problem at a time; this will help to quickly test and merge your change. If you intend to fix multiple unrelated problems, please use a separate branch for each problem. * Make commits of logical units. -* Make sure commits adhere to the contribution guidelines presented in this document. -* Make sure commit messages follow the [standard Git format](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). -* Make sure changes are submitted as a pull request (PR) on [GitHub](https://github.com/coreruleset/coreruleset/pulls). - * PR titles should follow the [Conventional Commits format](https://www.conventionalcommits.org/en/v1.0.0/), for example: `fix(rce): Fix a FP in rule 912345 with keyword 'time'`. - * If a PR only affects a single rule then the rule ID should be included in the title. - * If a PR title does not follow the correct format then a CRS developer will fix it. +* Make sure your commits adhere to the rules guidelines below. +* Make sure your commit messages are in the [proper format](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html): The first line of the message should have 50 characters or less, separated by a blank line from the (optional) body. The body should be wrapped at 70 characters and paragraphs separated by blank lines. Bulleted lists are also fine. -## General Formatting Guidelines for Rules Contributions +## General Formatting Guidelines for rules contributions -* American English should be used throughout. -* 4 spaces should be used for indentation (no tabs). -* Files must end with a single newline character. -* No trailing whitespace at EOL. -* No trailing blank lines at EOF (only the required single EOF newline character is allowed). -* Adhere to an 80 character line length limit where possible. -* Add comments where possible and clearly explain any new rules. -* Comments must not appear between chained rules and should instead be placed before the start of a rule chain. -* All [chained rules](https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v2.x)#chain) should be indented like so, for readability: + - 4 spaces per indentation level, no tabs + - no trailing whitespace at EOL or trailing blank lines at EOF + - comments are good, especially when they clearly explain the rule + - try to adhere to a 80 character line length limit + - if it is a [chained rule](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#chain), alignment should be like ``` -SecRule .. .. \ - "..." - SecRule .. .. \ - "..." - SecRule .. .. \ + SecRule .. ..\ + "...." + SecRule .. ..\ "..." + SecRule .. ..\ + ".." ``` -- Action lists in rules must always be enclosed in double quotes for readability, even if there is only one action (e.g., use `"chain"` instead of `chain`, and `"ctl:requestBodyAccess=Off"` instead of `ctl:requestBodyAccess=Off`). -- Always use numbers for phases instead of names. -- Format all use of `SecMarker` using double quotes, using UPPERCASE, and separating words with hyphens. For example: + - use quotes even if there is only one action, it improves readability (e.g., use `"chain"`, not `chain`, or `"ctl:requestBodyAccess=Off"` instead of `ctl:requestBodyAccess=Off`) + - always use numbers for phases, instead of names + - format your `SecMarker` between double quotes, using UPPERCASE and separating words using hyphens. Examples are: ``` -SecMarker "END-RESPONSE-959-BLOCKING-EVALUATION" -SecMarker "END-REQUEST-910-IP-REPUTATION" + SecMarker "END-RESPONSE-959-BLOCKING-EVALUATION" + SecMarker "END-REQUEST-910-IP-REPUTATION" ``` -- Rule actions should appear in the following order, for consistency: + - the proposed order for actions is: ``` -id -phase -allow | block | deny | drop | pass | proxy | redirect -status -capture -t:xxx -log -nolog -auditlog -noauditlog -msg -logdata -tag -sanitiseArg -sanitiseRequestHeader -sanitiseMatched -sanitiseMatchedBytes -ctl -ver -severity -multiMatch -initcol -setenv -setvar -expirevar -chain -skip -skipAfter -``` -- Rule operators must always be explicitly specified. Although ModSecurity defaults to using the `@rx` operator, for clarity `@rx` should always be explicitly specified when used. For example, write: -``` -SecRule ARGS "@rx foo" "id:1,phase:1,pass,t:none" -``` -instead of -``` -SecRule ARGS "foo" "id:1,phase:1,pass,t:none" -``` - * Only the tags listed in the [util/APPROVED_TAGS](util/APPROVED_TAGS) file can be added to a rule. If you want to add a new tag, you **must** add it to this file. - -## Variable Naming Conventions - -* Variable names should be lowercase and should use the characters a-z, 0-9, and underscores only. -* To reflect the different syntax between *defining* a variable (using `setvar`) and *using* a variable, the following visual distinction should be applied: - * **Variable definition:** Lowercase letters for collection name, dot as the separator, variable name. E.g.: `setvar:tx.foo_bar_variable` - * **Variable use:** Capital letters for collection name, colon as the separator, variable name. E.g.: `SecRule TX:foo_bar_variable` - -## Writing Regular Expressions - -* Use the following character class, in the stated order, to cover alphanumeric characters plus underscores and hyphens: `[a-zA-Z0-9_-]` - -### Portable Backslash Representation - -CRS uses `\x5c` to represent the backslash `\` character in regular expressions. Some of the reasons for this are: - -* It's portable across web servers and WAF engines: it works with Apache, Nginx, and Coraza. -* It works with the [crs-toolchain](https://coreruleset.org/docs/development/crs_toolchain/) for building optimized regular expressions. - -The older style of representing a backslash using the character class `[\\\\]` must _not_ be used. This was previously used in CRS to get consistent results between Apache and Nginx, owing to a quirk with how Apache would "double un-escape" character escapes. For future reference, the decision was made to stop using this older method because: - -* It can be confusing and difficult to understand how it works. -* It doesn't work with [crs-toolchain](https://coreruleset.org/docs/development/crs_toolchain/). -* It doesn't work with Coraza. -* It isn't obvious how to use it in a character class, e.g., `[a-zA-Z]`. - -### Forward Slash Representation - -CRS uses literal, *unescaped* forward slash `/` characters in regular expressions. - -Regular expression engines and libraries based on PCRE use the forward slash `/` character as the default delimiter. As such, forward slashes are often escaped in regular expression patterns. In the interests of readability, CRS does *not* escape forward slashes in regular expression patterns, which may seem unusual at first to new contributors. - -If testing a CRS regular expression using a third party tool, it may be useful to change the delimiter to something other than `/` if a testing tool raises errors because a CRS pattern features unescaped forward slashes. - -### When and Why to Anchor Regular Expressions - -Engines running the OWASP CRS will use regular expressions to _search_ the input string, i.e., the regular expression engine is asked to find the first match in the input string. If an expression needs to match the entire input then the expression must be anchored appropriately. - -#### Beginning of String Anchor (^) - -It is often necessary to match something at the start of the input to prevent false positives that match the same string in the middle of another argument, for example. Consider a scenario where the goal is to match the value of `REQUEST_HEADERS:Content-Type` to `multipart/form-data`. The following regular expression could be used: - -```python -"@rx multipart/form-data" + id + phase + allow | block | deny | drop | pass | proxy | redirect + status + capture + t:xxx + log + nolog + auditlog + noauditlog + msg + logdata + tag + sanitiseArg + sanitiseRequestHeader + sanitiseMatched + sanitiseMatchedBytes + ctl + ver + severity + multiMatch + initcol + setenv + setvar + expirevar + chain + skip + skipAfter ``` -HTTP headers can contain multiple values, and it may be necessary to guarantee that the value being searched for is the _first_ value of the header. There are different ways to do this but the simplest one is to use the `^` caret anchor to match the beginning of the string: +## Variable naming conventions -```python -"@rx ^multipart/form-data" -``` +* Variable names are lowercase using chars from `[a-z0-9_]` +* To somewhat reflect the fact that the syntax for variable usage is different when you define it (using setvar) and when you use it, we propose the following visual distinction: + * Lowercase letters for collection, dot as separator, variable name. E.g.,: `setvar:tx.foo_bar_variable` + * Capital letters for collection, colon as separator, variable name. E.g.,: `SecRule TX:foo_bar_variable` -It will also be useful to ignore case sensitivity in this scenario: +## Rules compliance with each Paranoia Level (PL) -```python -"@rx (?i)^multipart/form-data" -``` +Rules in the CRS are organized in Paranoia Levels, which allows you to choose the desired level of rule checks. -#### End of String Anchor ($) +Please read file ```crs-setup.conf.example``` for an introduction and a more detailed explanation of Paranoia Levels in the section `# -- [[ Paranoia Level Initialization ]]`. -Consider, for example, needing to find the string `/admin/content/assets/add/evil` in the `REQUEST_FILENAME`. This could be achieved with the following regular expression: +**PL0:** -```python -"@rx /admin/content/assets/add/evil" -``` +* Modsec installed, but almost no rules -If the input is changed, it can be seen that this expression can easily produce a false positive: `/admin/content/assets/add/evilbutactuallynot/nonevilfile`. If it is known that the file being searched for can't be in a subdirectory of `add` then the `$` anchor can be used to match the end of the input: +**PL1:** -```python -"@rx /admin/content/assets/add/evil$" -``` - -This could be made a bit more general: - -```python -"@rx /admin/content/assets/add/[a-z]+$" -``` - -#### Matching the Entire Input String - -It is sometimes necessary to match the entire input string to ensure that it _exactly_ matches what is expected. It might be necessary to find the "edit" action transmitted by WordPress, for example. To avoid false positives on variations (e.g., "myedit", "the edit", "editable", etc.), the `^` caret and `$` dollar anchors can be used to indicate that an exact string is expected. For example, to only match the _exact_ strings `edit` or `editpost`: - -```python -"@rx ^(?:edit|editpost)$" -``` - -#### Other Anchors - -Other anchors apart from `^` caret and `$` dollar exist, such as `\A`, `\G`, and `\Z` in PCRE. CRS **strongly discourages** the use of other anchors for the following reasons: - -- Not all regular expression engines support all anchors and the OWASP CRS should be compatible with as many regular expression engines as possible. -- Their function is sometimes not trivial. -- They aren't well known and would require additional documentation. -- In most cases that would justify their use the regular expression can be transformed into a form that doesn't require them, or the rule can be transformed (e.g., with an additional chain rule). - -### Use Capture Groups Sparingly - -Capture groups, i.e., parts of the regular expression surrounded by parentheses (`(` and `)`), are used to store the matched information from a string in memory for later use. Capturing input uses both additional CPU cycles and additional memory. In many cases, parentheses are *mistakenly* used for grouping and ensuring precedence. - -To group parts of a regular expression, or to ensure that the expression uses the precedence required, surround the concerning parts with `(?:` and `)`. Such a group is referred to as being "non-capturing". The following will create a capture group: - -```python -"@rx a|(b|c)d" -``` - -On the other hand, this will create a _non-capturing_ group, guaranteeing the precedence of the alternative _without_ capturing the input: - -```python -"@rx a|(?:b|c)d" -``` - -### Lazy Matching - -The question mark `?` can be used to turn "greedy" quantifiers into "lazy" quantifiers, i.e., `.+` and `.*` are greedy while `.+?` and `.*?` are lazy. Using lazy quantifiers can help with writing certain expressions that wouldn't otherwise be possible. However, in backtracking regular expression engines, like PCRE, lazy quantifiers can also be a source of performance issues. The following is an example of an expression that uses a lazy quantifier: - -```python -"@rx (?i)\.cookie\b.*?;\W*?(?:expires|domain)\W*?=" -``` - -This expression matches cookie values in HTML to detect session fixation attacks. The input string could be `document.cookie = "name=evil; domain=https://example.com";`. - -The lazy quantifiers in this expression are used to reduce the amount of backtracking that engines such as PCRE have to perform (others, such as RE2, are not affected by this). Since the asterisk `*` is greedy, `.*` would match every character in the input up to the end, at which point the regular expression engine would realize that the next character, `;`, can't be matched and it will backtrack to the previous position (`;`). A few iterations later, the engine will realize that the character `d` from `domain` can't be matched and it will backtrack again. This will happen again and again, until the `;` at `evil;` is found. Only then can the engine proceed with the next part of the expression. - -Using lazy quantifiers, the regular expression engine will instead match _as few characters as possible_. The engine will match ` ` (a space), then look for `;` and will not find it. The match will then be expanded to ` =` and, again, a match of `;` is attempted. This continues until the match is ` = "name=evil` and the engine finds `;`. While lazy matching still includes some work, in this case, backtracking would require many more steps. - -Lazy matching can have the inverse effect, though. Consider the following expression: - -```python -"@rx (?i)\b(?:s(?:tyle|rc)|href)\b[\s\S]*?=" -``` - -It matches some HTML attributes and then expects to see `=`. Using a somewhat contrived input, the lazy quantifier will require more steps to match then the greedy version would: `style                     =`. With the lazy quantifier, the regular expression engine will expand the match by one character for each of the space characters in the input, which means 21 steps in this case. With the greedy quantifier, the engine would match up to the end in a single step, backtrack one character and then match `=` (note that `=` is included in `[\s\S]`), which makes 3 steps. - -To summarize: **be very mindful about when and why you use lazy quantifiers in your regular expressions**. - -### Possessive Quantifiers and Atomic Groups - -Lazy and greedy matching change the order in which a regular expression engine processes a regular expression. However, the order of execution does not influence the backtracking behavior of backtracking engines. - -Possessive quantifiers (e.g., `x++`) and atomic groups (e.g., `(?>x)`) are tools that can be used to prevent a backtracking engine from backtracking. They _can_ be used for performance optimization but are only supported by backtracking engines and, therefore, are not permitted in CRS rules. - -### Writing Regular Expressions for Non-Backtracking Compatibility - -Traditional regular expression engines use backtracking to solve some additional problems, such as finding a string that is preceded or followed by another string. While this functionality can certainly come in handy and has its place in certain applications, it can also lead to performance issues and, in uncontrolled environments, open up possibilities for attacks (the term "[ReDoS](https://en.wikipedia.org/wiki/ReDoS)" is often used to describe an attack that exhausts process or system resources due to excessive backtracking). - -The OWASP CRS tries to be compatible with non-backtracking regular expression engines, such as RE2, because: - -- Non-backtracking engines are less vulnerable to ReDoS attacks. -- Non-backtracking engines can often outperform backtracking engines. -- CRS aims to leave the choice of the engine to the user/system. - -To ensure compatibility with non-backtracking regular expression engines, the following operations are **not** permitted in regular expressions: - -- positive lookahead (e.g., `(?=regex)`) -- negative lookahead (e.g., `(?!regex)`) -- positive lookbehind (e.g., `(?<=regex)`) -- negative lookbehind (e.g., `(?regex)`) -- backreferences (e.g., `\1`) -- named backreferences (e.g., `(?P=name)`) -- conditionals (e.g., `(?(regex)then|else)`) -- recursive calls to capture groups (e.g., `(?1)`) -- possessive quantifiers (e.g., `(?:regex)++`) -- atomic (or possessive) groups (e.g., `(?>regex`)) - -This list is not exhaustive but covers the most important points. The [RE2 documentation](https://github.com/google/re2/wiki/Syntax) includes a complete list of supported and unsupported features that various engines offer. - -### When and How to Optimize Regular Expressions - -Optimizing regular expressions is hard. Often, a change intended to improve the performance of a regular expression will change the original semantics by accident. In addition, optimizations usually make expressions harder to read. Consider the following example of URL schemes: - -```python -mailto|mms|mumble|maven -``` - -An optimized version (produced by the [crs-toolchain]({{< ref "crs_toolchain" >}})) could look like this: - -```python -m(?:a(?:ilto|ven)|umble|ms) -``` - -The above expression is an optimization because it reduces the number of backtracking steps when a branch fails. The regular expressions in the CRS are often comprised of lists of tens or even hundreds of words. Reading such an expression in an optimized form is difficult: even the _simple_ optimized example above is difficult to read. - -In general, contributors should not try to optimize contributed regular expressions and should instead strive for clarity. New regular expressions will usually be required to be submitted as a `.ra` file for the [crs-toolchain]({{< ref "crs_toolchain" >}}) to process. In such a file, the regular expression is decomposed into individual parts, making manual optimizations much harder or even impossible (and unnecessary with the `crs-toolchain`). The `crs-toolchain` performs some common optimizations automatically, such as the one shown above. - -Whether optimizations make sense in a contribution is assessed for each case individually. - -## Rules Compliance with Paranoia Levels - -The rules in CRS are organized into **paranoia levels** (PLs) which makes it possible to define how aggressive CRS is. See the documentation on [paranoia levels](https://coreruleset.org/docs/concepts/paranoia_levels/) for an introduction and more detailed explanation. - -Each rule that is placed into a paranoia level must contain the tag `paranoia-level/N`, where *N* is the PL value, however this tag can only be added if the rule does **not** use the nolog action. - -The types of rules that are allowed at each paranoia level are as follows: - -**PL 0:** - -* ModSecurity / WAF engine installed, but almost no rules - -**PL 1:** - -* Default level: keep in mind that most installations will normally use this level -* Any complex, memory consuming evaluation rules will surely belong to a higher level, not this one -* CRS will normally use atomic checks in single rules at this level -* Confirmed matches only; all scores are allowed -* No false positives / low false positives: try to avoid adding rules with potential false positives! +* Default level, keep in mind that most installations will normally use this one +* If there is a complex memory consuming/evaluation rule it surely will be on upper levels, not this one +* Normally we will use atomic checks in single rules +* Confirmed matches only, all scores are allowed +* No false positives / Low FP (Try to avoid adding rules with potential false positives!) * False negatives could happen -**PL 2:** +**PL2:** -* [Chain](https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-%28v2.x%29#chain) usage is allowed +* Chains usage are OK * Confirmed matches use score critical -* Matches that cause false positives are limited to using scores notice or warning -* Low false positive rates +* Matches that cause false positives are limited to use score notice or warning +* Low False positive rates * False negatives are not desirable -**PL 3:** +**PL3:** -* Chain usage with complex regular expression look arounds and macro expansions are allowed -* Confirmed matches use scores warning or critical -* Matches that cause false positives are limited to using score notice -* False positive rates are higher but limited to multiple matches (not single strings) +* Chains usage with complex regex look arounds and macro expansions +* Confirmed matches use score warning or critical +* Matches that cause false positives are limited to use score notice +* False positive rates increased but limited to multiple matches (not single string) * False negatives should be a very unlikely accident -**PL 4:** +**PL4:** * Every item is inspected -* Variable creations are allowed to avoid engine limitations -* Confirmed matches use scores notice, warning, or critical -* Matches that cause false positives are limited to using scores notice or warning -* False positive rates are higher (even on single strings) -* False negatives should not happen at this level -* Check everything against RFCs and allow listed values for the most popular elements +* Variable creations allowed to avoid engine limitations +* Confirmed matches use score notice, warning or critical +* Matches that cause false positives are limited to use score notice and warning +* False positive rates increased (even on single string) +* False negatives should not happen here +* Check everything against RFC and white listed values for most popular elements + ## ID Numbering Scheme -The CRS project uses the numerical ID rule namespace from 900,000 to 999,999 for CRS rules, as well as 9,000,000 to 9,999,999 for default CRS rule exclusion packages and plugins. +The CRS project used the numerical id rule namespace from 900,000 to 999,999 for the CRS rules as well as 9,000,000 to 9,999,999 for default CRS rule exclusion packages. -- Rules applying to the **incoming request** use the ID range 900,000 to 949,999. -- Rules applying to the **outgoing response** use the ID range 950,000 to 999,999. +Rules applying to the incoming request use the id range 900,000 to 949,999. +Rules applying to the outgoing response use the id range 950,000 to 999,999. -The rules are grouped by the vulnerability class they address (SQLi, RCE, etc.) or the functionality they provide (e.g., initialization). These groups occupy blocks of thousands (e.g., SQLi: 942,000 - 942,999). These grouped rules are defined in files dedicated to a single group or functionality. The filename takes up the first three digits of the rule IDs defined within the file (e.g., SQLi: `REQUEST-942-APPLICATION-ATTACK-SQLI.conf`). +The rules are grouped by vulnerability class they address (SQLi, RCE, etc.) or functionality (initialization). These groups occupy blocks of thousands (e.g. SQLi: 942,000 - 942,999). +The grouped rules are defined in files dedicated to a single group or functionality. The filename takes up the first three digits of the rule ids defined within the file (e.g. SQLi: REQUEST-942-APPLICATION-ATTACK-SQLI.conf). -The individual rules within each file for a vulnerability class are organized by the paranoia level of the rules. PL 1 is first, then PL 2, etc. +The individual rule files for the vulnerability classes are organized by the paranoia level of the rules. PL 1 is first, then PL 2 etc. -The ID block 9xx000 - 9xx099 is reserved for use by CRS helper functionality. There are no blocking or filtering rules in this block. +The block from 9XX000 - 9XX099 is reserved for use by CRS helper functionality. There are no blocking or filtering rules in this block. -Among the rules providing CRS helper functionality are rules that skip other rules depending on the paranoia level. These rules always use the following reserved rule IDs: 9xx011 - 9xx018, with very few exceptions. +Among the rules serving a CRS helper functionality are rules that skip rules depending on the paranoia level. These rules always use the following reserved rule ids: 9XX011-9XX018 with very few exceptions. -The blocking and filter rules start at 9xx100 with a step width of 10, e.g., 9xx100, 9xx110, 9xx120, etc. +The blocking or filter rules start with 9XX100 with a step width of 10. E.g. 9XX100, 9XX110, 9XX120 etc. The rule id does not correspond directly with the paranoia level of a rule. Given the size of a rule group and the organization by lower PL rules first, PL2 and above tend to have rule IDs with higher numbers. -The ID of a rule does not correspond directly with its paranoia level. Given the size of rule groups and how they're organized by paranoia level (starting with the lower PL rules first), PL 2 and above tend to be composed of rules with higher ID numbers. +Within a rule file / block, there are sometimes smaller groups of rules that belong to together. They are closely linked and very often represent copies of the original rules with a stricter limit (alternatively, they can represent the same rule addressing a different target in a second rule where this was necessary). These are stricter siblings of the base rule. Stricter siblings usually share the first five digits of the rule ID and raise the rule ID by one. E.g., Base rule at 9XX160, stricter sibling at 9XX161. -### Stricter Siblings - -Within a rule file / block, there are sometimes smaller groups of rules that belong together. They're closely linked and very often represent copies of the original rules with a stricter limit (alternatively, they can represent the same rule addressing a different *target* in a second rule, where this is necessary). These are **stricter siblings** of the base rule. Stricter siblings usually share the first five digits of the rule ID and raise the rule ID by one, e.g., a base rule at 9xx160 and a stricter sibling at 9xx161. - -Stricter siblings often have different paranoia levels. This means that the base rule and the stricter siblings don't usually reside next to each another in the rule file. Instead, they're ordered by paranoia level and are linked by the first digits of their rule IDs. It's good practice to introduce all stricter siblings together as part of the definition of the base rule: this can be done in the comments of the base rule. It's also good practice to refer back to the base rule with the keywords "stricter sibling" in the comments of the stricter siblings themselves. For example: "...This is performed in two separate stricter siblings of this rule: 9xxxx1 and 9xxxx2", and "This is a stricter sibling of rule 9xxxx0." - -## Writing Tests - -Each rule should be accompanied by tests. Rule tests are an invaluable way to check that a rule behaves as expected: - -- Does the rule correctly match against the payloads and behaviors that the rule is designed to detect? (**Positive tests**) -- Does the rule correctly **not** match against legitimate requests, i.e., the rule doesn't cause obvious false positives? (**Negative tests**) - -Rule tests also provide an excellent way to test WAF engines and implementations to ensure they behave and execute CRS rules as expected. - -The rule tests are located under `tests/regression/tests`. Each CRS rule *file* has a corresponding *directory* and each individual *rule* has a corresponding *YAML file* containing all the tests for that rule. For example, the tests for rule 911100 *(Method is not allowed by policy)* are in the file `REQUEST-911-METHOD-ENFORCEMENT/911100.yaml`. - -Full documentation of the required formatting and available options of the YAML tests can be found at https://github.com/coreruleset/ftw/blob/main/docs/YAMLFormat.md. - -Documentation on how to run the CRS test suite can be found in the [online documentation](https://coreruleset.org/docs/development/testing/). - -### Positive Tests - -Example of a simple *positive test*: - -```yaml -- test_id: 26 - desc: "Unix command injection" - stages: - - input: - dest_addr: 127.0.0.1 - headers: - Host: localhost - User-Agent: "OWASP CRS test agent" - Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 - method: POST - port: 80 - uri: "/post" - data: "var=` /bin/cat /etc/passwd`" - version: HTTP/1.1 - output: - log: - expect_ids: [932230] -``` - -This test will succeed if the log output contains `id "932230"`, which would indicate that the rule in question matched and generated an alert. - -It's important that tests consistently include the HTTP header fields `Host`, `User-Agent`, and `Accept`. CRS includes rules that detect if these headers are missing or empty, so these headers should be included in each test to avoid unnecessarily causing those rules to match. Ideally, *each positive test should cause* **only** *the rule in question to match*. - -The rule's description field, `desc`, is important. It should describe what is being tested: what *should* match, what should *not* match, etc. - -### Negative Tests - -Example of a simple *negative test*: - -```yaml -- test_id: 4 - stages: - - input: - dest_addr: "127.0.0.1" - method: "POST" - port: 80 - headers: - User-Agent: "OWASP CRS test agent" - Host: "localhost" - Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 - data: 'foo=ping pong tables' - uri: '/post' - output: - log: - no_expect_ids: [932260] -``` - -This test will succeed if the log output does **not** contain `id "932260"`, which would indicate that the rule in question did **not** match and so did **not** generate an alert. - -### Encoded and Raw Requests - -It is possible to *encode* an entire test request. This encapsulates the request and means that the request headers and payload don't need to be explicitly declared. This is useful when a test request needs to use unusual bytes which might break YAML parsers, or when a test request must be intentionally malformed in a way that is impossible to describe otherwise. An encoded request is sent exactly as intended. - -The `encoded_request` field works like so: - -```yaml -encoded_request: -``` - -For example: -```yaml -encoded_request: "R0VUIFwgSFRUUA0KDQoK" -``` - -where `R0VUIFwgSFRUUA0KDQoK` is the base64-encoded equivalent of `GET \ HTTP\r\n\r\n`. - -The older method of using `raw_request` is deprecated as it's difficult to maintain and less portable than `encoded_request`. - -### Using The Correct HTTP Endpoint - -The CRS project uses [kennthreitz/httpbin](https://hub.docker.com/r/kennethreitz/httpbin) as the backend server for tests. This backend provides one dedicated endpoint for each HTTP method. Tests should target these endpoints to: - -- improve test throughput (prevent HTML from being returned by the backend) -- add automatic HTTP method verification (the backend will respond with status code `405` (method not allowed) to requests whose method does not match the endpoint) - -Test URIs should be structured as follows, where `` must be replaced by the name of the HTTP method the test uses: - -```yaml -#... - method: - uri: //some/arbitrary/url -#... -``` - -## Further Guidance on Rule Writing - -### Leaving Audit Log Configuration Unchanged - -Former versions of CRS dynamically included the HTTP response body in the audit log via special `ctl` statements on certain individual response rules. This was never applied in a systematic way and, regardless, CRS should not change the format of the audit log by itself, namely because this can lead to information leakages. Therefore, the use of `ctl:auditLogParts=+E` or any other form of `ctl:auditLogParts` is not allowed in CRS rules. - -## Non-Rules General Guidelines - -* Remove trailing spaces from files (if they're not needed). This will make linters happy. -* EOF should have an EOL. - -The `pre-commit` framework can be used to check for and fix these issues automatically. First, go to the [pre-commit](https://pre-commit.com/) website and download the framework. Then, after installing, use the command `pre-commit install` so that the tools are installed and run each time a commit is made. CRS provides a config file that will keep the repository clean. +Stricter siblings often have a different paranoia level. This means that the base rule and the stricter sibling do not reside next to one another in the rule file. Instead they are ordered in their appropriate paranoia level and can be linked via the first digits of the rule id. It is a good practice to introduce stricter siblings together with the base rule in the comments of the base rule and to reference the base rule with the keyword stricter sibling in the comments of the stricter sibling. E.g., "... This is +performed in two separate stricter siblings of this rule: 9XXXX1 and 9XXXX2", "This is a stricter sibling of rule 9XXXX0." diff --git a/src/common/core/modsecurity/files/coreruleset-v3/CONTRIBUTORS.md b/src/common/core/modsecurity/files/coreruleset-v3/CONTRIBUTORS.md index beef1f8f3..a6768d405 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/CONTRIBUTORS.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/CONTRIBUTORS.md @@ -1,34 +1,30 @@ # Contributors -## Project Co-Leads: +## Project Co-Leads - [Christian Folini](https://github.com/dune73) - [Felipe Zipitría](https://github.com/fzipi) -## Developers: +## Developers - [Franziska Bühler](https://github.com/franbuehler) -- [Esad Cetiner](https://github.com/esadcetiner) - [Ervin Hegedus](https://github.com/airween) - [Andrew Howe](https://github.com/RedXanadu) -- [Karel Knibbe](https://github.com/karelorigin) - [Max Leske](https://github.com/theseion) -- [Matteo Pace](https://github.com/M4tteoP) -- [Jitendra Patro](https://github.com/Xhoenix) - [Jozef Sudolský](https://github.com/azurit) -## Former and Inactive Developers: +## Past Developers +- [Walter Hop](https://github.com/lifeforms) - [Paul Beckett](https://github.com/53cur3M3) - [Christoph Hansen](https://github.com/emphazer) -- [Walter Hop](https://github.com/lifeforms) † -- [Manuel Leos Rivas](https://github.com/spartantri) - [Andrea Menin](https://github.com/theMiddleBlue) - [Chaim Sanders](https://github.com/csanders-git) - [Federico G. Schwindt](https://github.com/fgsch) +- [Manuel Leos Rivas](https://github.com/spartantri) - [Simon Studer](https://github.com/studersi) -## Contributors: +## Contributors - [luelueking](https://github.com/luelueking) - [agusmu](https://github.com/agusmu) @@ -58,6 +54,7 @@ - [Pásztor Gábor](https://github.com/gpasztor87) - [Jan Gora](https://github.com/terjanq) - [Aaron Haaf](https://github.com/Everspace) +- [Karel Knibbe](https://github.com/karelorigin) - [Michael Haas](https://github.com/MichaelHaas) - [henkworks](https://github.com/henkworks) - [Tim Herren](https://github.com/nerrehmit) @@ -118,34 +115,3 @@ - Josh Zlatin - [Zou Guangxian](https://github.com/zouguangxian) - [4ft35t](https://github.com/4ft35t) -- [Andy Clapson](https://github.com/Homesteady) -- [Anuraag Agrawal](https://github.com/anuraaga) -- [Christian Aistleitner](https://github.com/somechris) -- [Dennis Brown](https://github.com/MutableLoss) -- [Dexter Chang](https://github.com/dextermallo) -- [Esa Jokinen](https://github.com/oh2fih) -- [Finn Westendorf](https://github.com/wfinn) -- [Gwendal Le Coguic](https://github.com/gwen001) -- [Jean-François Viguier](https://github.com/jf-viguier) -- [Juan Pablo Tosso](https://github.com/jptosso) -- [Karel](https://github.com/karelorigin) -- [Khiem Doan](https://github.com/khiemdoan) -- [Mark Zeman](https://github.com/KramNamez) -- [Priyam Patel](https://github.com/priyam001) -- [Robert DeBoer](https://github.com/robertdeboer) -- [Somdev Sangwan](https://github.com/s0md3v) -- [Stephen Sigwart](https://github.com/ssigwart) -- [Zerorigin](https://github.com/Zerorigin) -- [Syin Wu](https://github.com/bxlxx) -- [henkdswiss](https://github.com/henkworks) -- [ignatiev](https://github.com/ignatiev) -- [oct0pus7](https://github.com/oct0pus7) -- [Timo](https://github.com/ntimo) -- [rekter0](https://github.com/rekter0) -- [ThanhPT](https://github.com/thanhpt1708) -- [Vandan Rohatgi](https://github.com/vandanrohatgi) -- [NiceYouKnow](https://github.com/NiceYouKnow) -- [floyd](https://github.com/floyd) -- [superlgn](https://github.com/superlgn) -- [TimDiam0nd](https://github.com/TimDiam0nd) -- [brentclark](https://github.com/brentclark) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/INSTALL b/src/common/core/modsecurity/files/coreruleset-v3/INSTALL new file mode 100644 index 000000000..cf83cdb77 --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/INSTALL @@ -0,0 +1,305 @@ + _____ _____ _____ ____ + / ____| __ \ / ____| |___ \ + | | | |__) | (___ __) | + | | | _ / \___ \ |__ < + | |____| | \ \ ____) | ___) | + \_____|_| \_\_____/ |____/ + + OWASP Core Rule Set 3.x + +Installing ModSecurity +===================== + + This document does NOT detail how to install ModSecurity. Rather, + only information pertaining to the installation of the OWASP Core + Rule Set (CRS) is provided. However, ModSecurity is a prerequisite + for the CRS installation. Information on installing ModSecurity + can be found within the ModSecurity project at + https://github.com/SpiderLabs/ModSecurity or at ModSecurity.org. + +Installing From a Package Manager +================================= + + The OWASP Core Rule Set (CRS) is available from many sources. On + multiple platforms this includes package managers. These packages are + maintained by independent packagers who package CRS in their own time. + Historically, many of these packages have been out of date. As such, + it is recommended that you install, where possible, from our GitHub + repository. The following CRS 3.x packages are known to exist: + + modsecurity-crs - Debian + mod_security_crs - Fedora + modsecurity-crs - Gentoo + + Packages of CRS 2.x are incompatible with CRS 3.x. + +Installing +========== + + You can download a copy of the CRS from the following URL: + https://coreruleset.org/installation/ + + Our release zip/tar.gz files are the preferred way to install CRS. + + However, if you want to follow rule development closely and get + the newest protections quickly, you can also clone our GitHub + repository to get the current work-in-progress for the next release. + +Prerequisites +------------- + + CRS is designed to be used with ModSecurity (although many other + projects also use the provided rules). CRS version 3.x is designed for + ModSecurity 2.8 or above. CRS version 3.x makes use of libinjection + and libXML2. Failure to provide these prerequisites may result in + serious false negatives and CRS version 3.x should NOT be run without + these. Note, however, that libinjection is bundled with ModSecurity + since version 2.8. Additionally, if you are downloading from the + GitHub repo you will need to install 'git' on your system. + +Upgrading from CRS 2.x +---------------------- + CRS 3.x is a major release incompatible with CRS 2.x. + The rule IDs have changed. The file id_renumbering/IdNumbering.csv + contains a list with old and new rule IDs. However, a key feature + of the release 3.x is the reduction of false positives in the + default installation and we recommend you start with a fresh + install from scratch. + Key parameter variables have changed their name and new features + have been introduced. Your former modsecurity_crs_10_setup.conf + file is thus no longer usable. + We recommend you to start with a fresh install from scratch. + +Installing on Apache +-------------------- + 1. Install ModSecurity for Apache + 2. Ensure that ModSecurity is loading correctly by checking error.log + at start up for lines indicating ModSecurity is installed. An example + might appear as follows: + ```ModSecurity for Apache/2.9.1 (http://www.modsecurity.org/) configured.``` + 3. The most common method of deploying ModSecurity we have seen is + to create a new folder underneath the Apache directory (typically + /usr/local/apache/, /etc/httpd/, or /etc/apache2). Often this folder + is called 'modsecurity.d'. Create this folder and cd into it. + 4. Download our release from https://coreruleset.org/installation/ + and unpack it into a new owasp-modsecurity-crs folder. + 5. Move the crs-setup.conf.example file to crs-setup.conf. + Please take the time to go through this file and customize the settings + for your local environment. Failure to do so may result in false + negatives and false positives. See the section entitled OWASP CRS + Configuration for more detail. + 6. Rename rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example and + rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example to remove the + '.example' extension. This will allow you to add exclusions without updates + overwriting them in the future. + 7. Add the following line to your httpd.conf/apache2.conf (the following + assumes you've put CRS into modsecurity.d/owasp-modsecurity-crs). You + can alternatively place these in any config file included by Apache: + ``` + + Include modsecurity.d/owasp-modsecurity-crs/crs-setup.conf + Include modsecurity.d/owasp-modsecurity-crs/rules/*.conf + + ``` + 8. Restart web server and ensure it starts without errors + 9. Make sure your web sites are still running fine. + 10. Proceed to the section "Testing the Installation" below. + +Installing on Nginx +------------------- + 1. Compile ModSecurity into Nginx + 2. Ensure that ModSecurity is loading correctly by checking error.log + at start up for lines indicating ModSecurity is installed. An example + might appear as follows: + ```ModSecurity for nginx (STABLE)/2.9.1 (http://www.modsecurity.org/) configured.``` + 3. The most common method of deploying ModSecurity we have seen is + to create a new folder underneath the Nginx directory (typically + /usr/local/nginx/conf/). Often this folder + is called 'owasp-modsecurity-crs'. Create this folder and cd into it. + 4. Download our release from https://coreruleset.org/installation/ + and unpack it into a new owasp-modsecurity-crs folder. + 5. Move the crs-setup.conf.example file to crs-setup.conf. + Please take this time to go through this + file and customize the settings for your local environment. Failure to + do so may result in false negatives and false positives. See the + section entitled OWASP CRS Configuration for more detail. + 6. Rename rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example and + rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example to remove the + '.example' extension. This will allow you to add exceptions without updates + overwriting them in the future. + 7. Nginx requires the configuration of a single ModSecurity + configuration file within the nginx.conf file using the + 'ModSecurityConfig' directive (when using ModSecurity 2.x). + Best practice is to set 'ModSecurityConfig' to a file from + which you will include your other ModSecurity configuration + files. In this example we will use: + ```ModSecurityConfig modsec_includes.conf;``` + 7. Within modsec_includes.conf create your includes to the + CRS folder similar to as follows (The modsecurity.conf file from the + ModSecurity installation is included in this example): + ``` + include modsecurity.conf + include owasp-modsecurity-crs/crs-setup.conf + include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf + include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf + include owasp-modsecurity-crs/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf + include owasp-modsecurity-crs/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf + include owasp-modsecurity-crs/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf + include owasp-modsecurity-crs/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf + include owasp-modsecurity-crs/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf + include owasp-modsecurity-crs/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf + include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf + include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf + include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf + include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf + include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf + include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf + include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf + include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf + include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf + include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf + include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf + include owasp-modsecurity-crs/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf + include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf + include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf + include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf + include owasp-modsecurity-crs/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf + include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf + include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf + include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf + include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf + include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf + include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf + include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf + include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf + include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf + ``` + 8. Restart web server and ensure it starts without errors + 9. Make sure your web sites are still running fine. + 10. Proceed to the section "Testing the Installation" below. + +Installing on IIS +----------------- + The IIS installer comes with an optional version of CRS built in. + To upgrade or install this after the fact follow the following + steps. + 1. Navigate to "[drive_letters]:\Program Files\ModSecurity IIS\" + 2. Download our release from https://coreruleset.org/installation/ + and unpack it into the current folder. + 3. Move the crs-setup.conf.example file to crs-setup.conf. + Please take this time to go through this + file and customize the settings for your local environment. Failure to + do so may result in false negatives and false positives. See the + section entitled OWASP CRS Configuration for more detail. + 4. Rename rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example and + rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example to remove the + '.example' extension. This will allow you to add exceptions without updates + overwriting them in the future. + 5. Navigate back to the 'ModSecurity IIS' folder and modify the + 'modsecurity_iis' to include the following: + ``` + include owasp-modsecurity-crs/crs-setup.conf + include owasp-modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf + include owasp-modsecurity-crs/rules/REQUEST-901-INITIALIZATION.conf + include owasp-modsecurity-crs/rules/REQUEST-905-COMMON-EXCEPTIONS.conf + include owasp-modsecurity-crs/rules/REQUEST-910-IP-REPUTATION.conf + include owasp-modsecurity-crs/rules/REQUEST-911-METHOD-ENFORCEMENT.conf + include owasp-modsecurity-crs/rules/REQUEST-912-DOS-PROTECTION.conf + include owasp-modsecurity-crs/rules/REQUEST-913-SCANNER-DETECTION.conf + include owasp-modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf + include owasp-modsecurity-crs/rules/REQUEST-921-PROTOCOL-ATTACK.conf + include owasp-modsecurity-crs/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf + include owasp-modsecurity-crs/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf + include owasp-modsecurity-crs/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf + include owasp-modsecurity-crs/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf + include owasp-modsecurity-crs/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf + include owasp-modsecurity-crs/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf + include owasp-modsecurity-crs/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf + include owasp-modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf + include owasp-modsecurity-crs/rules/RESPONSE-950-DATA-LEAKAGES.conf + include owasp-modsecurity-crs/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf + include owasp-modsecurity-crs/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf + include owasp-modsecurity-crs/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf + include owasp-modsecurity-crs/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf + include owasp-modsecurity-crs/rules/RESPONSE-959-BLOCKING-EVALUATION.conf + include owasp-modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf + include owasp-modsecurity-crs/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf + ``` + 6. Restart web server and ensure it starts without errors + 7. Make sure your web sites are still running fine. + 8. Proceed to the section "Testing the Installation" below. + +Testing the Installation +======================== + To test your installation you should be able to use any number + of attacks. A typical request which should trigger CRS would be + ```http://localhost/?param=">``` + Upon sending this request you should see events reported in the + error log (nginx apache) or the event viewer (IIS). + + If have not changed the defaults with regards to anomaly scoring, + blocking and sampling percentage, then this request should have + been blocked and access forbidden. Likewise if you have configured + ModSecurity debug logging and/or audit logging this event should + log to these locations as well. + +OWASP CRS Configuration +======================= + The crs-setup.conf file includes management rules + and directives that can control important CRS functions. + The crs-setup.conf file comes with extensive comments. + This section here brings only the essential parts. + + By default we do not include settings within the crs-setup.conf + that configure ModSecurity itself. Instead those configuration + settings are set during the installation of ModSecurity proper. + An example for such such a + configuration file is available via the ModSecurity project + (https://github.com/SpiderLabs/ModSecurity/blob/master/modsecurity.conf-recommended). + Be aware the crs-setup.conf file DOES specify + configuration directives such as SecDefaultAction. The default + is the anomaly scoring mode with the appropriate + SecDefaultAction as defined in the crs-setup.conf. + Alternative configuration modes are supported and explained + in crs-setup.conf. + + The default anomaly/correlation mode establishes an incoming + anomaly score threshold of 5 and an outgoing anomaly score + threshold of 4. The default installation has been tuned to + reduce false positives in a way that will allow most requests + to pass in this default setup. + + However, testing the setup and tuning false positives + before going to production is vital. This is especially true + if you raise the paranoia level with is set to 1 by default. + Higher paranoia levels ranging from 2 to 4 include more + aggressive rules which will raise additional false positives + but also raise the security level of your service. + + If you are unsure about the performance impact of the CRS + or if you are unsure about the number of false positives, then + you may want to use the sampling percentage. This number, + which is set to 100 by default, controls the percentage + of requests which is funneled into the CRS. Fresh installs + on high traffic sites are advised to start with a low, or + very low number of percentages and raise the number + slowly up to 100. Be aware that any number below 100 allows + a random number of requests to bypass the ruleset completely. + + Update the TX policy settings for allowed Request Methods, File + Extensions, maximum numbers of arguments, etc to better reflect + your environment that is being protected. + + Make sure your GeoIP and Project Honeypot settings are specified + if you are using them. + The GeoIP database is no longer included with the CRS. Instead + you are advised to download it regularly. + + The use of Project Honeypot requires a + free API key. These require an account but can be obtained at + https://www.projecthoneypot.org/httpbl_configure.php. + + Be sure to check out the other settings present within the + crs-setup.conf file. There are many other options that have to + do with aspects of web application security that are beyond + this document but are well explained in crs-setup.conf. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/INSTALL.md b/src/common/core/modsecurity/files/coreruleset-v3/INSTALL.md deleted file mode 100644 index 19eb0ac9f..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/INSTALL.md +++ /dev/null @@ -1,185 +0,0 @@ -# Installing CRS - -This guide aims to get a CRS installation up and running. This guide assumes that a compatible ModSecurity engine is already present and working. If unsure then refer to the [extended install](https://coreruleset.org/docs/deployment/extended_install/) page for full details. - -## Downloading the Rule Set - -The first step is to download the CRS itself. The CRS project strongly recommends using a [supported version](https://github.com/coreruleset/coreruleset/security/policy). - -Official CRS releases can be found at the following URL: https://github.com/coreruleset/coreruleset/releases. - -For *production* environments, it is recommended to use the latest release, which is v4.0.0. For *testing* the bleeding edge CRS version, nightly releases are also provided. - -### Verifying Releases - -{{% notice note %}} -Releases are signed using the CRS project's [GPG key](https://coreruleset.org/security.asc) (fingerprint: 3600 6F0E 0BA1 6783 2158 8211 38EE ACA1 AB8A 6E72). Releases can be verified using GPG/PGP compatible tooling. - -To retrieve the CRS project's public key from public key servers using `gpg`, execute: `gpg --keyserver pgp.mit.edu --recv 0x38EEACA1AB8A6E72` (this ID should be equal to the last sixteen hex characters in the fingerprint). - -It is also possible to use `gpg --fetch-key https://coreruleset.org/security.asc` to retrieve the key directly. -{{% /notice %}} - -The following steps assume that a \*nix operating system is being used. Installation is similar on Windows but likely involves using a zip file from the CRS [releases page](https://github.com/coreruleset/coreruleset/releases). - -To download the release file and the corresponding signature: - -```bash -wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v4.0.0.tar.gz -wget https://github.com/coreruleset/coreruleset/releases/download/v4.0.0/coreruleset-4.0.0.tar.gz.asc -``` - -To verify the integrity of the release: - -```bash -gpg --verify coreruleset-4.0.0.tar.gz.asc v4.0.0.tar.gz -gpg: Signature made Wed Jun 30 10:05:48 2021 -03 -gpg: using RSA key 36006F0E0BA167832158821138EEACA1AB8A6E72 -gpg: Good signature from "OWASP Core Rule Set " [unknown] -gpg: WARNING: This key is not certified with a trusted signature! -gpg: There is no indication that the signature belongs to the owner. -Primary key fingerprint: 3600 6F0E 0BA1 6783 2158 8211 38EE ACA1 AB8A 6E72 -``` - -If the signature was good then the verification succeeds. If a warning is displayed, like the above, it means the CRS project's public key is *known* but is not *trusted*. - -To trust the CRS project's public key: - -```bash -gpg --edit-key 36006F0E0BA167832158821138EEACA1AB8A6E72 -gpg> trust -Your decision: 5 (ultimate trust) -Are you sure: Yes -gpg> quit -``` - -The result when verifying a release will then look like so: - -```bash -gpg --verify coreruleset-4.0.0.tar.gz.asc v4.0.0.tar.gz -gpg: Signature made Wed Jun 30 15:05:48 2021 CEST -gpg: using RSA key 36006F0E0BA167832158821138EEACA1AB8A6E72 -gpg: Good signature from "OWASP Core Rule Set " [ultimate] -``` - -## Installing the Rule Set - -### Extracting the Files - -Once the rule set has been downloaded and verified, extract the rule set files to a well known location on the server. This will typically be somewhere in the web server directory. - -The examples presented below demonstrate using Apache. For information on configuring Nginx or IIS see the [extended install](https://coreruleset.org/docs/deployment/extended_install/) page. - -Note that while it's common practice to make a new `modsecurity.d` folder, as outlined below, this isn't strictly necessary. The path scheme outlined is common on RHEL-based operating systems; the Apache path used may need to be adjusted to match the server's installation. - -```bash -mkdir /etc/crs4 -tar -xzvf v4.0.0.tar.gz --strip-components 1 -C /etc/crs4 -``` - -Now all the CRS files will be located below the `/etc/crs4` directory. - -### Setting Up the Main Configuration File - -After extracting the rule set files, the next step is to set up the main OWASP CRS configuration file. An example configuration file is provided as part of the release package, located in the main directory: `crs-setup.conf.example`. - -{{% notice note %}} -Other aspects of ModSecurity, particularly engine-specific parameters, are controlled by the ModSecurity "recommended" configuration rules, `modsecurity.conf-recommended`. This file comes packaged with ModSecurity itself. -{{% /notice %}} - -In many scenarios, the default example CRS configuration will be a good enough starting point. It is, however, a good idea to take the time to look through the example configuration file *before* deploying it to make sure it's right for a given environment. - -Once any settings have been changed within the example configuration file, as needed, it should be renamed to remove the .example portion, like so: - -```bash -cd /etc/crs4 -mv crs-setup.conf.example crs-setup.conf -``` - -### Include-ing the Rule Files - -The last step is to tell the web server where the rules are. This is achieved by `include`-ing the rule configuration files in the `httpd.conf` file. Again, this example demonstrates using Apache, but the process is similar on other systems (see the [extended install](https://coreruleset.org/docs/deployment/extended_install/) page for details). - -```bash -echo 'IncludeOptional /etc/crs4/crs-setup.conf' >> /etc/httpd/conf/httpd.conf -echo 'IncludeOptional /etc/crs4/plugins/*-config.conf' >> /etc/httpd/conf/httpd.conf -echo 'IncludeOptional /etc/crs4/plugins/*-before.conf' >> /etc/httpd/conf/httpd.conf -echo 'IncludeOptional /etc/crs4/rules/*.conf' >> /etc/httpd/conf/httpd.conf -echo 'IncludeOptional /etc/crs4/plugins/*-after.conf' >> /etc/httpd/conf/httpd.conf -``` - -Now that everything has been configured, it should be possible to restart and being using the OWASP CRS. The CRS rules typically require a bit of tuning with rule exclusions, depending on the site and web applications in question. For more information on tuning, see [false positives and tuning](https://coreruleset.org/docs/concepts/false_positives_tuning/). - -```bash -systemctl restart httpd.service -``` - -## Alternative: Using Containers - -Another quick option is to use the official CRS [pre-packaged containers](https://coreruleset.org/docs/development/useful_tools/#official-crs-maintained-docker-images). Docker, Podman, or any compatible container engine can be used. The official CRS images are published in the Docker Hub. The image most often deployed is `owasp/modsecurity-crs`: it already has everything needed to get up and running quickly. - -The CRS project pre-packages both Apache and Nginx web servers along with the appropriate corresponding ModSecurity engine. More engines, like [Coraza](https://coraza.io/), will be added at a later date. - -To protect a running web server, all that's required is to get the appropriate image and set its configuration variables to make the WAF receives requests and proxies them to your backend server. - -Below is an example `docker-compose` file that can be used to pull the container images. All that needs to be changed is the `BACKEND` variable so that the WAF points to the backend server in question: - -```docker-compose -services: - modsec2-apache: - container_name: modsec2-apache - image: owasp/modsecurity-crs:apache - environment: - SERVERNAME: modsec2-apache - BACKEND: http:// - PORT: "80" - MODSEC_RULE_ENGINE: DetectionOnly - BLOCKING_PARANOIA: 2 - TZ: "${TZ}" - ERRORLOG: "/var/log/error.log" - ACCESSLOG: "/var/log/access.log" - MODSEC_AUDIT_LOG_FORMAT: Native - MODSEC_AUDIT_LOG_TYPE: Serial - MODSEC_AUDIT_LOG: "/var/log/modsec_audit.log" - MODSEC_TMP_DIR: "/tmp" - MODSEC_RESP_BODY_ACCESS: "On" - MODSEC_RESP_BODY_MIMETYPE: "text/plain text/html text/xml application/json" - COMBINED_FILE_SIZES: "65535" - volumes: - ports: - - "80:80" -``` - -That's all that needs to be done. Simply starting the container described above will instantly provide the protection of the latest stable CRS release in front of a given backend server or service. There are [lots of additional variables](https://github.com/coreruleset/modsecurity-crs-docker) that can be used to configure the container image and its behavior, so be sure to read the full documentation. - -## Verifying that the CRS is active - -Always verify that CRS is installed correctly by sending a 'malicious' request to your site or application, for instance: - -```bash -curl 'https://www.example.com/?foo=/etc/passwd&bar=/bin/sh' -``` - -Depending on your configurated thresholds, this should be detected as a malicious request. If you use blocking mode, you should receive an Error 403. The request should also be logged to the audit log, which is usually in `/var/log/modsec_audit.log`. - -## Upgrading - -### Upgrading from CRS 3.x to CRS 4 - -The most impactful change is the removal of application exclusion packages in favor of a plugin system. If you had activated the exclusion packages in CRS 3, you should download the plugins for them and place them in the plugins subdirectory. We maintain the list of plugins in our [Plugin Registry](https://github.com/coreruleset/plugin-registry). You can find detailed information on working with plugins in our [plugins documentation]()https://coreruleset.org/docs/concepts/plugins/. - -In terms of changes to the detection rules, the amount of changes is smaller than in the CRS 2—3 changeover. Most rules have only evolved slightly, so it is recommended that you keep any existing custom exclusions that you have made under CRS 3. - -We recommend to start over by copying our `crs-setup.conf.example` to `crs-setup.conf` with a copy of your old file at hand, and re-do the customizations that you had under CRS 3. - -Please note that we added a large number of new detections, and any new detection brings a certain risk of false alarms. Therefore, we recommend to test first before going live. - -### Upgrading from CRS 2.x to CRS 3 - -In general, you can update by unzipping our new release over your older one, and updating the `crs-setup.conf` file with any new settings. However, CRS 3.0 is a major rewrite, incompatible with CRS 2.x. Key setup variables have changed their name, and new features have been introduced. Your former modsecurity_crs_10_setup.conf file is thus no longer usable. We recommend you to start with a fresh crs-setup.conf file from scratch. - -Most rule IDs have been changed to reorganize them into logical sections. This means that if you have written custom configuration with exclusion rules (e.g. `SecRuleRemoveById`, `SecRuleRemoveTargetById`, `ctl:ruleRemoveById` or `ctl:ruleRemoveTargetById`) you must renumber the rule numbers in that configuration. You can do this using the supplied utility util/id_renumbering/update.py or find the changes in util/id_renumbering/IdNumbering.csv. - -However, a key feature of the CRS 3 is the reduction of false positives in the default installation, and many of your old exclusion rules may no longer be necessary. Therefore, it is a good option to start fresh without your old exclusion rules. - -If you are experienced in writing exclusion rules for CRS 2.x, it may be worthwhile to try running CRS 3 in Paranoia Level 2 (PL2). This is a stricter mode, which blocks additional attack patterns, but brings a higher number of false positives — in many situations the false positives will be comparable with CRS 2.x. This paranoia level however will bring you a higher protection level than CRS 2.x or a CRS 3 default install, so it can be worth the investment. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/KNOWN_BUGS.md b/src/common/core/modsecurity/files/coreruleset-v3/KNOWN_BUGS similarity index 77% rename from src/common/core/modsecurity/files/coreruleset-v3/KNOWN_BUGS.md rename to src/common/core/modsecurity/files/coreruleset-v3/KNOWN_BUGS index 221d0f21e..d8083dcc2 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/KNOWN_BUGS.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/KNOWN_BUGS @@ -1,10 +1,9 @@ -# CRS KNOWN BUGS +== OWASP ModSecurity Core Rule Set (CRS) KNOWN BUGS == -## Report Bugs/Issues to GitHub Issues Tracker or the mailinglist - -* https://github.com/coreruleset/coreruleset/issues +== Report Bugs/Issues to GitHub Issues Tracker or the mailinglist == +* https://github.com/SpiderLabs/owasp-modsecurity-crs/issues or the CRS Google Group at -* https://groups.google.com/a/owasp.org/g/modsecurity-core-rule-set-project +* https://groups.google.com/a/owasp.org/forum/#!forum/modsecurity-core-rule-set-project * There are still false positives for standard web applications in the default install (paranoia level 1). Please report these when @@ -27,7 +26,7 @@ or the CRS Google Group at We advise to upgrade your Apache version. If upgrading is not possible, we have provided a script in the util/join-multiline-rules directory which converts the rules into a format that works around the bug. - You have to re-run this script whenever you modify or update + You have to re-run this script whenever you modify or update the CRS rules. * Debian up to and including Jessie lacks YAJL/JSON support in ModSecurity, which causes the following error in the Apache ErrorLog or SecAuditLog: @@ -39,11 +38,13 @@ or the CRS Google Group at type by default, as specified in RFC 3902. OF IMPORTANCE, application/soap+xml is indicative that XML will be provided. In accordance with this, ModSecurity's XML Request Body Processor should also be configured to support this MIME type. Within - the ModSecurity project, [commit 5e4e2af](https://github.com/owasp-modsecurity/ModSecurity/commit/5e4e2af7a6f07854fee6ed36ef4a381d4e03960e) + the ModSecurity project, commit 5e4e2af + (https://github.com/SpiderLabs/ModSecurity/commit/5e4e2af7a6f07854fee6ed36ef4a381d4e03960e) has been merged to support this endeavour. However, if you are running a modified or preexisting version of the modsecurity.conf provided by this repository, you may wish to upgrade rule '200000' accordingly. The rule now appears as follows: - ``` - SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \ - "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" - ``` + +``` +SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \ + "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML" +``` diff --git a/src/common/core/modsecurity/files/coreruleset-v3/LICENSE b/src/common/core/modsecurity/files/coreruleset-v3/LICENSE index 5dbb91909..b671fe62a 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/LICENSE +++ b/src/common/core/modsecurity/files/coreruleset-v3/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 OWASP CRS project + Copyright 2006 the OWASP Core Rule Set contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/README.md b/src/common/core/modsecurity/files/coreruleset-v3/README.md index ea0319ea7..c2d7d46d5 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/README.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/README.md @@ -1,34 +1,33 @@ +![GHA build v3.3/dev](https://github.com/coreruleset/coreruleset/workflows/Regression%20Tests/badge.svg?branch=v3.3%2Fdev) +![GHA build v3.2/dev](https://github.com/coreruleset/coreruleset/workflows/Regression%20Tests/badge.svg?branch=v3.2%2Fdev) [![OWASP Flagship](https://img.shields.io/badge/owasp-flagship%20project-38a047.svg)](https://owasp.org/projects/) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/1390/badge)](https://bestpractices.coreinfrastructure.org/projects/1390) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) -| Branch | Status | ----------|-------| -| main | ![GHA build main](https://github.com/coreruleset/coreruleset/actions/workflows/test.yml/badge.svg?branch=main) | -| v3.3/master | ![GHA build v3.3/master](https://github.com/coreruleset/coreruleset/workflows/Regression%20Tests/badge.svg?branch=v3.3%2Fmaster) | # OWASP CRS The OWASP CRS is a set of generic attack detection rules for use with ModSecurity or compatible web application firewalls. The CRS aims to protect web applications from a wide range of attacks, including the OWASP Top Ten, with a minimum of false alerts. -## CRS Resources +## Resources -Please see the [OWASP CRS page](https://coreruleset.org/) to get introduced to the CRS and view resources on installation, configuration, and working with the CRS. +Please see our [website](https://coreruleset.org/) to get introduced to the CRS and view resources on installation, configuration, and working with the CRS. -## Contributing to the CRS +## Contributing -We strive to make the OWASP ModSecurity CRS accessible to a wide audience of beginner and experienced users. We are interested in hearing any bug reports, false-positive alert reports, evasions, usability issues, and suggestions for new detections. +We strive to make CRS accessible to a wide audience of beginner and experienced users. We are interested in hearing any bug reports, false positive alert reports, evasions, usability issues, and suggestions for new detections. -[Create an issue on GitHub](https://github.com/coreruleset/coreruleset/issues) to report a false positive or false negative (evasion). Please include your installed version and the relevant portions of your ModSecurity audit log. We will try and address your issue and potentially ask for additional information to reproduce your problem. Please also note that stale issues will be flagged and closed after 120 days. You can search for stale issues with the following [search query](https://github.com/coreruleset/coreruleset/issues?q=label%3A%22Stale+issue%22). +[Create an issue on GitHub](https://github.com/coreruleset/coreruleset/issues) to report a false positive or false negative (evasion). Please include your installed version and the relevant portions of your ModSecurity audit log. -[Sign up for our Google Group](https://groups.google.com/a/owasp.org/g/modsecurity-core-rule-set-project) to ask general usage questions and participate in discussions on the CRS. Also [here](https://lists.owasp.org/pipermail/owasp-modsecurity-core-rule-set/index) you can find the archives for the previous mailing list. +[Sign up for our Google Group](https://groups.google.com/a/owasp.org/forum/#!forum/modsecurity-core-rule-set-project) to ask general usage questions and participate in discussions on the CRS. Also [here](https://lists.owasp.org/pipermail/owasp-modsecurity-core-rule-set/index) you can find the archives for the previous mailing list. -[Join the #coreruleset channel on OWASP Slack](https://owasp.slack.com/) to chat about the CRS. ([Click here](https://owasp.org/slack/invite) to get an invitation if you are not yet registered on the OWASP slack. It's open to non-members too.) +[Join the #coreruleset channel on OWASP Slack](http://owaspslack.com) to chat about the CRS. ## License -Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
+Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. + Copyright (c) 2021-2024 CRS project. All rights reserved. The OWASP CRS is distributed under Apache Software License (ASL) version 2. Please see the enclosed LICENSE file for full details. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/SECURITY.md b/src/common/core/modsecurity/files/coreruleset-v3/SECURITY.md index d91d6d53a..f8921987b 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/SECURITY.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/SECURITY.md @@ -1,95 +1,4 @@ # Security Policy -## Supported Versions +See policy here: https://github.com/coreruleset/coreruleset/blob/v4.0/dev/SECURITY.md -OWASP CRS has two types of releases, Major releases (3.0.0, 3.1.0, 3.2.0 etc.) and point releases (3.0.1, 3.0.2 etc.). -For more information see our [wiki](https://github.com/coreruleset/coreruleset/wiki/Release-Policy). - -The OWASP CRS officially supports the two latest point releases with severe security patches. -We are happy to receive and merge PR's that address security issues in older versions of the project, but the team itself may choose not to fix these. -Along those lines, OWASP CRS team may not issue security notifications for unsupported software. - -| Version | Supported | -| --------- | ------------------ | -| 4.5.x | :white_check_mark: | -| 4.4.x | :white_check_mark: | -| 4.3.x | :x: | -| 4.2.x | :x: | -| 4.1.x | :x: | -| 4.0.x | :x: | -| 3.3.x | :white_check_mark: | -| 3.2.x | :x: | -| 3.1.x | :x: | -| 3.0.x | :x: | -| 2.x | :x: | - -## GPG Signed Releases - -Releases are signed using [our GPG key](https://coreruleset.org/security.asc), (fingerprint: 3600 6F0E 0BA1 6783 2158 8211 38EE ACA1 AB8A 6E72). You can verify the release using GPG/PGP compatible tooling. - -### Importing the GPG Key - -To get our key using gpg: `gpg --keyserver pgp.mit.edu --recv 0x38EEACA1AB8A6E72` (this id should be equal to the last sixteen hex characters in our fingerprint). -You can also use `gpg --fetch-key https://coreruleset.org/security.asc` directly. - -### Verifying the CRS Release - -Download the release file and the corresponding signature. The following example shows how to do it for `v4.0.0` release: - -```bash -$ wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v4.0.0.tar.gz -$ wget https://github.com/coreruleset/coreruleset/releases/download/v4.0.0/coreruleset-4.0.0.tar.gz.asc -``` - -**Verification**: - -```bash -❯ gpg --verify coreruleset-4.0.0.tar.gz.asc v4.0.0.tar.gz -gpg: Signature made Wed Jun 30 10:05:48 2021 -03 -gpg: using RSA key 36006F0E0BA167832158821138EEACA1AB8A6E72 -gpg: Good signature from "OWASP Core Rule Set " [unknown] -gpg: WARNING: This key is not certified with a trusted signature! -gpg: There is no indication that the signature belongs to the owner. -Primary key fingerprint: 3600 6F0E 0BA1 6783 2158 8211 38EE ACA1 AB8A 6E72 -``` - -If the signature was good, the verification succeeded. If you see a warning like the above, it means you know our public key, but you are not trusting it. You can trust it by using the following method: - -```bash -gpg edit-key 36006F0E0BA167832158821138EEACA1AB8A6E72 -gpg> trust -Your decision: 5 (ultimate trust) -Are you sure: Yes -gpg> quit -``` - -Then you will see this result when verifying: -```bash -gpg --verify coreruleset-4.0.0.tar.gz.asc v4.0.0.tar.gz -gpg: Signature made Wed Jun 30 15:05:48 2021 CEST -gpg: using RSA key 36006F0E0BA167832158821138EEACA1AB8A6E72 -gpg: Good signature from "OWASP Core Rule Set " [ultimate] -``` - -## Reporting a Vulnerability - -We strive to make the OWASP CRS accessible to a wide audience of beginner and experienced users. -We welcome bug reports, false positive alert reports, evasions, usability issues, and suggestions for new detections. -Submit these types of non-vulnerability related issues via Github. -Please include your installed version and the relevant portions of your audit log. -False negative or common bypasses should [create an issue](https://github.com/coreruleset/coreruleset/issues/new) so they can be addressed. - -Do this before submitting a vulnerability using our email: -1) Verify that you have the latest version of OWASP CRS. -2) Validate which Paranoia Level this bypass applies to. If it works in PL4, please send us an email. -3) If you detected anything that causes unexpected behavior of the engine via manipulation of existing CRS provided rules, please send it by email. - -We also provide you with the [Sandbox project](https://coreruleset.org/docs/development/sandbox/), where you can test your bypass and report back to us. If testing using the sandbox, please include the `X-Unique-ID` from the response in your email. - -Our email is [security@coreruleset.org](mailto:security@coreruleset.org). You can send us encrypted email using the same GPG key we use to sign releases, fingerprint: `3600 6F0E 0BA1 6783 2158 8211 38EE ACA1 AB8A 6E72`. - -We are happy to work with the community to provide CVE identifiers for any discovered security issues if requested. - -If in doubt, feel free to reach out to us! - -The OWASP CRS Team. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/SPONSORS.md b/src/common/core/modsecurity/files/coreruleset-v3/SPONSORS.md index 7e4a32e6d..ef2759359 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/SPONSORS.md +++ b/src/common/core/modsecurity/files/coreruleset-v3/SPONSORS.md @@ -6,3 +6,4 @@ ## SILVER SPONSORS * Swiss Post + diff --git a/src/common/core/modsecurity/files/coreruleset-v3/crs-setup.conf.example b/src/common/core/modsecurity/files/coreruleset-v3/crs-setup.conf.example index 721e8fd42..8a54e4a39 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/crs-setup.conf.example +++ b/src/common/core/modsecurity/files/coreruleset-v3/crs-setup.conf.example @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -12,15 +12,15 @@ # # -- [[ Introduction ]] -------------------------------------------------------- # -# The OWASP CRS is a set of generic attack +# The OWASP ModSecurity Core Rule Set (CRS) is a set of generic attack # detection rules that provide a base level of protection for any web # application. They are written for the open source, cross-platform # ModSecurity Web Application Firewall. # # See also: # https://coreruleset.org/ -# https://github.com/coreruleset/coreruleset -# https://owasp.org/www-project-modsecurity-core-rule-set/ +# https://github.com/SpiderLabs/owasp-modsecurity-crs +# https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project # @@ -175,14 +175,12 @@ SecDefaultAction "phase:2,log,auditlog,pass" # Uncomment this rule to change the default: # #SecAction \ -# "id:900000,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.blocking_paranoia_level=1" +# "id:900000,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.paranoia_level=1" # It is possible to execute rules from a higher paranoia level but not include @@ -191,26 +189,24 @@ SecDefaultAction "phase:2,log,auditlog,pass" # the new rules would lead to false positives that raise your score above the # threshold. # This optional feature is enabled by uncommenting the following rule and -# setting the tx.detection_paranoia_level. -# Technically, rules up to the level defined in tx.detection_paranoia_level -# will be executed, but only the rules up to tx.blocking_paranoia_level affect the +# setting the tx.executing_paranoia_level. +# Technically, rules up to the level defined in tx.executing_paranoia_level +# will be executed, but only the rules up to tx.paranoia_level affect the # anomaly scores. -# By default, tx.detection_paranoia_level is set to tx.blocking_paranoia_level. -# tx.detection_paranoia_level must not be lower than tx.blocking_paranoia_level. +# By default, tx.executing_paranoia_level is set to tx.paranoia_level. +# tx.executing_paranoia_level must not be lower than tx.paranoia_level. # -# Please notice that setting tx.detection_paranoia_level to a higher paranoia +# Please notice that setting tx.executing_paranoia_level to a higher paranoia # level results in a performance impact that is equally high as setting -# tx.blocking_paranoia_level to said level. +# tx.paranoia_level to said level. # #SecAction \ -# "id:900001,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.detection_paranoia_level=1" +# "id:900001,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.executing_paranoia_level=1" # @@ -229,18 +225,16 @@ SecDefaultAction "phase:2,log,auditlog,pass" # Uncomment this rule to change the default: # #SecAction \ -# "id:900010,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.enforce_bodyproc_urlencoded=1" +# "id:900010,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.enforce_bodyproc_urlencoded=1" # -# -- [[ Anomaly Scoring Mode Severity Levels ]] -------------------------------- +# -- [[ Anomaly Mode Severity Levels ]] ---------------------------------------- # # Each rule in the CRS has an associated severity level. # These are the default scoring points for each severity level. @@ -264,21 +258,19 @@ SecDefaultAction "phase:2,log,auditlog,pass" # that all configuration variables are set before the CRS rules are processed.) # #SecAction \ -# "id:900100,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.critical_anomaly_score=5,\ -# setvar:tx.error_anomaly_score=4,\ -# setvar:tx.warning_anomaly_score=3,\ -# setvar:tx.notice_anomaly_score=2" +# "id:900100,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.critical_anomaly_score=5,\ +# setvar:tx.error_anomaly_score=4,\ +# setvar:tx.warning_anomaly_score=3,\ +# setvar:tx.notice_anomaly_score=2" # -# -- [[ Anomaly Scoring Mode Blocking Threshold Levels ]] ---------------------- +# -- [[ Anomaly Mode Blocking Threshold Levels ]] ------------------------------ # # Here, you can specify at which cumulative anomaly score an inbound request, # or outbound response, gets blocked. @@ -318,129 +310,57 @@ SecDefaultAction "phase:2,log,auditlog,pass" # Uncomment this rule to change the defaults: # #SecAction \ -# "id:900110,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.inbound_anomaly_score_threshold=5,\ -# setvar:tx.outbound_anomaly_score_threshold=4" - +# "id:900110,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.inbound_anomaly_score_threshold=5,\ +# setvar:tx.outbound_anomaly_score_threshold=4" # -# -- [[ Application Specific Rule Exclusions ]] -------------------------------- +# -- [[ Application Specific Rule Exclusions ]] ---------------------------------------- # -# CRS 3.x contained exclusion packages to tweak the CRS for use with common -# web applications, lowering the number of false positives. +# Some well-known applications may undertake actions that appear to be +# malicious. This includes actions such as allowing HTML or Javascript within +# parameters. In such cases the CRS aims to prevent false positives by allowing +# administrators to enable prebuilt, application specific exclusions on an +# application by application basis. +# These application specific exclusions are distinct from the rules that would +# be placed in the REQUEST-900-EXCLUSION-RULES-BEFORE-CRS configuration file as +# they are prebuilt for specific applications. The 'REQUEST-900' file is +# designed for users to add their own custom exclusions. Note, using these +# application specific exclusions may loosen restrictions of the CRS, +# especially if used with an application they weren't designed for. As a result +# they should be applied with care. +# To use this functionality you must specify a supported application. To do so +# uncomment rule 900130. In addition to uncommenting the rule you will need to +# specify which application(s) you'd like to enable exclusions for. Only a +# (very) limited set of applications are currently supported, please use the +# filenames prefixed with 'REQUEST-903' to guide you in your selection. +# Such filenames use the following convention: +# REQUEST-903.9XXX-{APPNAME}-EXCLUSIONS-RULES.conf # -# In CRS 4, these are no longer part of the CRS itself, but they are available -# as "CRS plugins". Some plugins improve support for web applications, and others -# may bring new functionality. Plugins are not installed by default, but can be -# downloaded from the plugin registry: -# https://github.com/coreruleset/plugin-registry -# -# For detailed information about using and installing plugins, please see: -# https://coreruleset.org/docs/concepts/plugins/ - +# It is recommended if you run multiple web applications on your site to limit +# the effects of the exclusion to only the path where the excluded webapp +# resides using a rule similar to the following example: +# SecRule REQUEST_URI "@beginsWith /wordpress/" setvar:tx.crs_exclusions_wordpress=1 # -# -- [[ Anomaly Score Reporting Level ]] --------------------------------------- -# -# When a request is blocked due to the anomaly score meeting or exceeding the -# anomaly threshold then the blocking rule will also report the anomaly score. -# This applies to the separate inbound and outbound anomaly scores. -# -# In phase 5, there are additional rules that can perform additional reporting -# of anomaly scores with a verbosity that depends on the reporting level defined -# below. -# -# By setting the reporting level you control whether you want additional -# reporting beyond the blocking rule or not and, if yes, which requests should -# be covered. The higher the reporting level, the more verbose the reporting is. -# -# There are 6 reporting levels: -# -# 0 - Reporting disabled -# 1 - Reporting for requests with a blocking anomaly score >= a threshold -# 2 - Reporting for requests with a detection anomaly score >= a threshold -# 3 - Reporting for requests with a blocking anomaly score greater than 0 -# 4 - Reporting for requests with a detection anomaly score greater than 0 -# 5 - Reporting for all requests -# -# Note: Reporting levels 1 and 2 make it possible to differentiate between -# requests that are blocked and requests that are *not* blocked but would have -# been blocked if the blocking PL was equal to detection PL. This may be useful -# for certain FP tuning methodologies, for example moving to a higher PL. -# -# A value of 5 can be useful on platforms where you are interested in logging -# non-scoring requests, yet it is not possible to report this information in -# the request/access log. This applies to Nginx, for example. +# Modify and uncomment this rule to select which application: # #SecAction \ -# "id:900115,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.reporting_level=4" - - -# -# -- [[ Early Anomaly Scoring Mode Blocking ]] ------------------------------ -# -# The anomaly scores for the request and the responses are generally summed up -# and evaluated at the end of phase:2 and at the end of phase:4 respectively. -# However, it is possible to enable an early evaluation of these anomaly scores -# at the end of phase:1 and at the end of phase:3. -# -# If a request (or a response) hits the anomaly threshold in this early -# evaluation, then blocking happens immediately (if blocking is enabled) and -# the phase 2 (and phase 4 respectively) will no longer be executed. -# -# Enable the rule 900120 that sets the variable tx.early_blocking to 1 in order -# to enable early blocking. The variable tx.early_blocking is set to 0 by -# default. Early blocking is thus disabled by default. -# -# Please note that early blocking will hide potential alerts from you. This -# means that a payload that would appear in an alert in phase 2 (or phase 4) -# does not get evaluated if the request is being blocked early. So when you -# disabled early blocking again at some point in the future, then new alerts -# from phase 2 might pop up. -#SecAction \ -# "id:900120,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.early_blocking=1" - - -# -# -- [[ Initialize Default Collections ]] ----------------------------------- -# -# CRS provides a centralized option to initialize and populate collections -# meant to be used by plugins (E.g.DoS protection plugin). -# By default, Global and IP collections (see rule 901320), -# being not used by core rules, are not initialized. -# -# Uncomment this rule to change the default: -# -#SecAction \ -# "id:900130,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.enable_default_collections=1" - +# "id:900130,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.crs_exclusions_cpanel=1,\ +# setvar:tx.crs_exclusions_drupal=1,\ +# setvar:tx.crs_exclusions_dokuwiki=1,\ +# setvar:tx.crs_exclusions_nextcloud=1,\ +# setvar:tx.crs_exclusions_wordpress=1,\ +# setvar:tx.crs_exclusions_xenforo=1" # # -- [[ HTTP Policy Settings ]] ------------------------------------------------ @@ -451,6 +371,7 @@ SecDefaultAction "phase:2,log,auditlog,pass" # # These variables are used in the following rule files: # - REQUEST-911-METHOD-ENFORCEMENT.conf +# - REQUEST-912-DOS-PROTECTION.conf # - REQUEST-920-PROTOCOL-ENFORCEMENT.conf # HTTP methods that a client is allowed to use. @@ -460,19 +381,16 @@ SecDefaultAction "phase:2,log,auditlog,pass" # MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH PUT UNLOCK # Uncomment this rule to change the default. #SecAction \ -# "id:900200,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'" +# "id:900200,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'" # Content-Types that a client is allowed to send in a request. -# Default: |application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| -# |text/xml| |application/xml| |application/soap+xml| |application/json| -# |application/cloudevents+json| |application/cloudevents-batch+json| +# Default: |application/x-www-form-urlencoded| |multipart/form-data| |text/xml| +# |application/xml| |application/soap+xml| |application/json| # # Please note, that the rule where CRS uses this variable (920420) evaluates it with operator # `@within`, which is case sensitive, but uses t:lowercase. You must add your whole custom @@ -486,157 +404,116 @@ SecDefaultAction "phase:2,log,auditlog,pass" # content type may still be interpreted as JSON by a backend application but would not trigger the # JSON body parser at the WAF, leading to a bypass. # +# When additional JSON content types are legitimately used in a deployment, +# e.g. application/cloudevents+json, it is extremely important to ensure that a +# rule exists to enable the engine's JSON body processor for these additional +# JSON content types. Failure to do so can lead to a request body bypass. The +# default JSON rule in modsecurity.conf-recommended (200001) will only activate +# the JSON body processor for the specific content type application/json. The +# optional modsecurity.conf-recommended rule 200006 can be used to enable the +# JSON body processor for a wide variety of JSON content types. +# # To prevent blocking request with not allowed content-type by default, you can create an exclusion # rule that removes rule 920420. For example: -#SecRule REQUEST_HEADERS:Content-Type "@rx ^text/plain" \ -# "id:1234,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ctl:ruleRemoveById=920420,\ -# ver:'OWASP_CRS/4.6.0',\ -# chain" -# SecRule REQUEST_URI "@rx ^/foo/bar" \ -# "t:none" +# SecRule REQUEST_HEADERS:Content-Type "@rx ^text/plain" \ +# "id:1234,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# ctl:ruleRemoveById=920420,\ +# chain" +# SecRule REQUEST_URI "@rx ^/foo/bar" "t:none" # # Uncomment this rule to change the default. # #SecAction \ -# "id:900220,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|'" +# "id:900220,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |text/xml| |application/xml| |application/soap+xml| |application/json|'" # Allowed HTTP versions. -# Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 HTTP/3 HTTP/3.0 -# Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 HTTP/3 HTTP/3.0 +# Default: HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 +# Example for legacy clients: HTTP/0.9 HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 # Note that some web server versions use 'HTTP/2', some 'HTTP/2.0', so # we include both version strings by default. # Uncomment this rule to change the default. #SecAction \ -# "id:900230,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 HTTP/3 HTTP/3.0'" +# "id:900230,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'" # Forbidden file extensions. # Guards against unintended exposure of development/configuration files. -# Default: .asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pem/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/ +# Default: .asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/ # Example: .bak/ .config/ .conf/ .db/ .ini/ .log/ .old/ .pass/ .pdb/ .rdb/ .sql/ -# Note that .axd was removed due to false positives (see PR 1925). -# -# To additionally guard against configuration/install archive files from being -# accidentally exposed, common archive file extensions can be added to the -# restricted extensions list. An example list of common archive file extensions -# is presented below: -# .7z/ .br/ .bz/ .bz2/ .cab/ .cpio/ .gz/ .img/ .iso/ .jar/ .rar/ .tar/ .tbz2/ .tgz/ .txz/ .xz/ .zip/ .zst/ -# (Source: https://en.wikipedia.org/wiki/List_of_archive_formats) -# # Uncomment this rule to change the default. #SecAction \ -# "id:900240,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pem/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'" +# "id:900240,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'" -# Restricted request headers. -# The HTTP request headers that CRS restricts are split into two categories: -# basic (always forbidden) and extended (may be forbidden). All header names -# should be lowercase and enclosed by /slashes/ as delimiters. +# Forbidden request headers. +# Header names should be lowercase, enclosed by /slashes/ as delimiters. +# Default: /accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ # -# [ Basic ] -# Includes deprecated headers and headers with known security risks. Always -# forbidden. -# Default: /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/ +# Note: Accept-Charset is a deprecated header that should not be used by clients and +# ignored by servers. It can be used for a response WAF bypass, by asking for a charset +# that the WAF cannot decode. +# Reference: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset # -# /content-encoding/ -# Used to list any encodings that have been applied to the original payload. -# Only used for compression, which isn't supported by CRS by default since CRS -# blocks newlines and null bytes inside the request body. Most compression -# algorithms require at least null bytes per RFC. Blocking Content-Encoding -# shouldn't break anything and increases security since WAF engines, including -# ModSecurity, are typically incapable of properly scanning compressed request -# bodies. +# Note: Content-Encoding is used to list any encodings that have been applied to the +# original payload. It is only used for compression, which isn't supported by CRS by +# default since it blocks newlines and null bytes inside the request body. Most +# compression algorithms require at least null bytes per RFC. Blocking it shouldn't +# break anything and increases security since ModSecurity is incapable of properly +# scanning compressed request bodies. # -# /proxy/ -# Blocking this prevents the 'httpoxy' vulnerability: https://httpoxy.org -# -# /lock-token/ -# -# /content-range/ -# -# /if/ -# -# /x-http-method-override/ -# /x-http-method/ -# /x-method-override/ -# Blocking these headers prevents method override attacks, as described here: -# https://www.sidechannel.blog/en/http-method-override-what-it-is-and-how-a-pentester-can-use-it +# Note: Blocking Proxy header prevents 'httpoxy' vulnerability: https://httpoxy.org # # Uncomment this rule to change the default. #SecAction \ -# "id:900250,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:'tx.restricted_headers_basic=/content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/'" -# -# [ Extended ] -# Includes deprecated headers that are still in use (so false positives are -# possible) and headers with possible security risks. Forbidden at a higher -# paranoia level. -# Default: /accept-charset/ -# -# /accept-charset/ -# Deprecated header that should not be used by clients and should be ignored -# by servers. Can be used for a response WAF bypass by asking for a charset -# that the WAF cannot decode. Considered to be a good indicator of suspicious -# behavior but produces too many false positives to be forbidden by default. -# References: -# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Charset -# https://github.com/coreruleset/coreruleset/issues/3140 -# +# "id:900250,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.restricted_headers=/accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/'" + +# File extensions considered static files. +# Extensions include the dot, lowercase, enclosed by /slashes/ as delimiters. +# Used in DoS protection rule. See section "Anti-Automation / DoS Protection". +# Default: /.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/ # Uncomment this rule to change the default. #SecAction \ -# "id:900255,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:'tx.restricted_headers_extended=/accept-charset/'" +# "id:900260,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'" # Content-Types charsets that a client is allowed to send in a request. -# The content-types are enclosed by |pipes| as delimiters to guarantee exact matches. -# Default: |utf-8| |iso-8859-1| |iso-8859-15| |windows-1252| +# Default: utf-8|iso-8859-1|iso-8859-15|windows-1252 # Uncomment this rule to change the default. +# Use "|" to separate multiple charsets like in the rule defining +# tx.allowed_request_content_type. #SecAction \ -# "id:900280,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'" +# "id:900280,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.allowed_request_content_type_charset=utf-8|iso-8859-1|iso-8859-15|windows-1252'" # # -- [[ HTTP Argument/Upload Limits ]] ----------------------------------------- @@ -651,94 +528,80 @@ SecDefaultAction "phase:2,log,auditlog,pass" # Block request if number of arguments is too high # Default: unlimited # Example: 255 -# Note that a hard limit by the engine may also apply here (SecArgumentsLimit). -# This would override this soft limit. # Uncomment this rule to set a limit. #SecAction \ -# "id:900300,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.max_num_args=255" +# "id:900300,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.max_num_args=255" # Block request if the length of any argument name is too high # Default: unlimited # Example: 100 # Uncomment this rule to set a limit. #SecAction \ -# "id:900310,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.arg_name_length=100" +# "id:900310,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.arg_name_length=100" # Block request if the length of any argument value is too high # Default: unlimited # Example: 400 # Uncomment this rule to set a limit. #SecAction \ -# "id:900320,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.arg_length=400" +# "id:900320,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.arg_length=400" # Block request if the total length of all combined arguments is too high # Default: unlimited # Example: 64000 # Uncomment this rule to set a limit. #SecAction \ -# "id:900330,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.total_arg_length=64000" +# "id:900330,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.total_arg_length=64000" # Block request if the file size of any individual uploaded file is too high # Default: unlimited # Example: 1048576 # Uncomment this rule to set a limit. #SecAction \ -# "id:900340,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.max_file_size=1048576" +# "id:900340,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.max_file_size=1048576" # Block request if the total size of all combined uploaded files is too high # Default: unlimited # Example: 1048576 # Uncomment this rule to set a limit. #SecAction \ -# "id:900350,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.combined_file_sizes=1048576" +# "id:900350,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.combined_file_sizes=1048576" # # -- [[ Easing In / Sampling Percentage ]] ------------------------------------- # -# Adding the CRS to an existing productive site can lead to false +# Adding the Core Rule Set to an existing productive site can lead to false # positives, unexpected performance issues and other undesired side effects. # # It can be beneficial to test the water first by enabling the CRS for a @@ -757,7 +620,7 @@ SecDefaultAction "phase:2,log,auditlog,pass" # following directive somewhere after the inclusion of the CRS # (E.g., RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf). # -#SecRuleUpdateActionById 901450 "nolog" +# SecRuleUpdateActionById 901150 "nolog" # # ATTENTION: If this TX.sampling_percentage is below 100, then some of the # requests will bypass the Core Rules completely and you lose the ability to @@ -765,16 +628,148 @@ SecDefaultAction "phase:2,log,auditlog,pass" # # Uncomment this rule to enable this feature: # -#SecAction \ -# "id:900400,\ -# phase:1,\ -# pass,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.sampling_percentage=100" +#SecAction "id:900400,\ +# phase:1,\ +# pass,\ +# nolog,\ +# setvar:tx.sampling_percentage=100" +# +# -- [[ Project Honey Pot HTTP Blacklist ]] ------------------------------------ +# +# Optionally, you can check the client IP address against the Project Honey Pot +# HTTPBL (dnsbl.httpbl.org). In order to use this, you need to register to get a +# free API key. Set it here with SecHttpBlKey. +# +# Project Honeypot returns multiple different malicious IP types. +# You may specify which you want to block by enabling or disabling them below. +# +# Ref: https://www.projecthoneypot.org/httpbl.php +# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecHttpBlKey +# +# Uncomment these rules to use this feature: +# +#SecHttpBlKey XXXXXXXXXXXXXXXXX +#SecAction "id:900500,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.block_search_ip=1,\ +# setvar:tx.block_suspicious_ip=1,\ +# setvar:tx.block_harvester_ip=1,\ +# setvar:tx.block_spammer_ip=1" + + +# +# -- [[ GeoIP Database ]] ------------------------------------------------------ +# +# There are some rulesets that inspect geolocation data of the client IP address +# (geoLookup). The CRS uses geoLookup to implement optional country blocking. +# +# To use geolocation, we make use of the MaxMind GeoIP database. +# This database is not included with the CRS and must be downloaded. +# +# There are two formats for the GeoIP database. ModSecurity v2 uses GeoLite (.dat files), +# and ModSecurity v3 uses GeoLite2 (.mmdb files). +# +# If you use ModSecurity 3, MaxMind provides a binary for updating GeoLite2 files, +# see https://github.com/maxmind/geoipupdate. +# +# Download the package for your OS, and read https://dev.maxmind.com/geoip/geoipupdate/ +# for configuration options. +# +# Warning: GeoLite (not GeoLite2) databases are considered legacy, and not being updated anymore. +# See https://support.maxmind.com/geolite-legacy-discontinuation-notice/ for more info. +# +# Therefore, if you use ModSecurity v2, you need to regenerate updated .dat files +# from CSV files first. +# +# You can achieve this using https://github.com/sherpya/geolite2legacy +# Pick the zip files from maxmind site: +# https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country-CSV.zip +# +# Follow the guidelines for installing the tool and run: +# ./geolite2legacy.py -i GeoLite2-Country-CSV.zip \ +# -f geoname2fips.csv -o /usr/share/GeoliteCountry.dat +# +# Update the database regularly, see Step 3 of the configuration link above. +# +# By default, when you execute `sudo geoipupdate` on Linux, files from the free database +# will be downloaded to `/usr/share/GeoIP` (both v1 and v2). +# +# Then choose from: +# - `GeoLite2-Country.mmdb` (if you are using ModSecurity v3) +# - `GeoLiteCountry.dat` (if you are using ModSecurity v2) +# +# Ref: http://blog.spiderlabs.com/2010/10/detecting-malice-with-modsecurity-geolocation-data.html +# Ref: http://blog.spiderlabs.com/2010/11/detecting-malice-with-modsecurity-ip-forensics.html +# +# Uncomment only one of the next rules here to use this feature. +# Choose the one depending on the ModSecurity version you are using, and change the path accordingly: +# +# For ModSecurity v3: +#SecGeoLookupDB /usr/share/GeoIP/GeoLite2-Country.mmdb +# For ModSecurity v2 (points to the converted one): +#SecGeoLookupDB /usr/share/GeoIP/GeoLiteCountry.dat + +# +# -=[ Block Countries ]=- +# +# Rules in the IP Reputation file can check the client against a list of high +# risk country codes. These countries have to be defined in the variable +# tx.high_risk_country_codes via their ISO 3166 two-letter country code: +# https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements +# +# If you are sure that you are not getting any legitimate requests from a given +# country, then you can disable all access from that country via this variable. +# The rule performing the test has the rule id 910100. +# +# This rule requires SecGeoLookupDB to be enabled and the GeoIP database to be +# downloaded (see the section "GeoIP Database" above.) +# +# By default, the list is empty. A list used by some sites was the following: +# setvar:'tx.high_risk_country_codes=UA ID YU LT EG RO BG TR RU PK MY CN'" +# +# Uncomment this rule to use this feature: +# +#SecAction \ +# "id:900600,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.high_risk_country_codes='" + + +# +# -- [[ Anti-Automation / DoS Protection ]] ------------------------------------ +# +# Optional DoS protection against clients making requests too quickly. +# +# When a client is making more than 100 requests (excluding static files) within +# 60 seconds, this is considered a 'burst'. After two bursts, the client is +# blocked for 600 seconds. +# +# Requests to static files are not counted towards DoS; they are listed in the +# 'tx.static_extensions' setting, which you can change in this file (see +# section "HTTP Policy Settings"). +# +# For a detailed description, see rule file REQUEST-912-DOS-PROTECTION.conf. +# +# Uncomment this rule to use this feature: +# +#SecAction \ +# "id:900700,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:'tx.dos_burst_time_slice=60',\ +# setvar:'tx.dos_counter_threshold=100',\ +# setvar:'tx.dos_block_timeout=600'" + # # -- [[ Check UTF-8 encoding ]] ------------------------------------------------ @@ -786,14 +781,80 @@ SecDefaultAction "phase:2,log,auditlog,pass" # Uncomment this rule to use this feature: # #SecAction \ -# "id:900950,\ -# phase:1,\ -# pass,\ -# t:none,\ -# nolog,\ -# tag:'OWASP_CRS',\ -# ver:'OWASP_CRS/4.6.0',\ -# setvar:tx.crs_validate_utf8_encoding=1" +# "id:900950,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.crs_validate_utf8_encoding=1" + + +# +# -- [[ Blocking Based on IP Reputation ]] ------------------------------------ +# +# Blocking based on reputation is permanent in the CRS. Unlike other rules, +# which look at the individual request, the blocking of IPs is based on +# a persistent record in the IP collection, which remains active for a +# certain amount of time. +# +# There are two ways an individual client can become flagged for blocking: +# - External information (RBL, GeoIP, etc.) +# - Internal information (Core Rules) +# +# The record in the IP collection carries a flag, which tags requests from +# individual clients with a flag named IP.reput_block_flag. +# But the flag alone is not enough to have a client blocked. There is also +# a global switch named tx.do_reput_block. This is off by default. If you set +# it to 1 (=On), requests from clients with the IP.reput_block_flag will +# be blocked for a certain duration. +# +# Variables +# ip.reput_block_flag Blocking flag for the IP collection record +# ip.reput_block_reason Reason (= rule message) that caused to blocking flag +# tx.do_reput_block Switch deciding if we really block based on flag +# tx.reput_block_duration Setting to define the duration of a block +# +# It may be important to know, that all the other core rules are skipped for +# requests, when it is clear that they carry the blocking flag in question. +# +# Uncomment this rule to use this feature: +# +#SecAction \ +# "id:900960,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.do_reput_block=1" +# +# Uncomment this rule to change the blocking time: +# Default: 300 (5 minutes) +# +#SecAction \ +# "id:900970,\ +# phase:1,\ +# nolog,\ +# pass,\ +# t:none,\ +# setvar:tx.reput_block_duration=300" + + +# +# -- [[ Collection timeout ]] -------------------------------------------------- +# +# Set the SecCollectionTimeout directive from the ModSecurity default (1 hour) +# to a lower setting which is appropriate to most sites. +# This increases performance by cleaning out stale collection (block) entries. +# +# This value should be greater than or equal to: +# tx.reput_block_duration (see section "Blocking Based on IP Reputation") and +# tx.dos_block_timeout (see section "Anti-Automation / DoS Protection"). +# +# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecCollectionTimeout + +# Please keep this directive uncommented. +# Default: 600 (10 minutes) +SecCollectionTimeout 600 # @@ -813,6 +874,4 @@ SecAction \ pass,\ t:none,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:tx.crs_setup_version=460" + setvar:tx.crs_setup_version=337" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/docs/README b/src/common/core/modsecurity/files/coreruleset-v3/docs/README new file mode 100644 index 000000000..281651e7e --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/docs/README @@ -0,0 +1,8 @@ +Welcome to the OWASP Core Rule Set (CRS) documentation. +The OWASP CRS documentation is generated as a Sphinx project and is stored in a separate Github repository. While the documentation is available as part of the CRS project it is provided in the form of a git-submodule. Using a git-submodule allow us to update the documentation without making changes to the main rule repository. + +You can download the documentation using git: + $ git submodule init + $ git submodule update + +Alternatively, the latest version of the documentation is available at https://www.modsecurity.org/CRS/Documentation/ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/docs/README.md b/src/common/core/modsecurity/files/coreruleset-v3/docs/README.md deleted file mode 100644 index 13e798796..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/docs/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Welcome to the OWASP CRS documentation. - -The latest version of the documentation can be read at: -https://coreruleset.org/docs/ - -Documentation is generated by Hugo and is stored -in a separate Github repository: - -https://github.com/coreruleset/documentation/ - diff --git a/src/common/core/modsecurity/files/coreruleset-v3/plugins/README.md b/src/common/core/modsecurity/files/coreruleset-v3/plugins/README.md deleted file mode 100644 index 4c2cc9d4f..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/plugins/README.md +++ /dev/null @@ -1,7 +0,0 @@ -This is the folder where you install CRS plugins. - -See https://github.com/coreruleset/plugin-registry -for a list of registered official and 3rd party plugins. - -Plugins are documented in the CRS INSTALL file and -in also with said plugin registry. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/plugins/empty-after.conf b/src/common/core/modsecurity/files/coreruleset-v3/plugins/empty-after.conf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/common/core/modsecurity/files/coreruleset-v3/plugins/empty-before.conf b/src/common/core/modsecurity/files/coreruleset-v3/plugins/empty-before.conf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/common/core/modsecurity/files/coreruleset-v3/plugins/empty-config.conf b/src/common/core/modsecurity/files/coreruleset-v3/plugins/empty-config.conf deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920100.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920100.ra deleted file mode 100644 index aafa28688..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920100.ra +++ /dev/null @@ -1,23 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! Cover the GET method -##! | Path |--- Query ---| Fragment | -^get /[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?$ - -##! Cover the CONNECT method -##! Meth |----- IPv4 Address ------|- Port -| Protocol | -^connect (?:\d{1,3}\.){3}\d{1,3}\.?(?::\d+)?\s+[\w\./]+$ - -##! Meth |- Host --|Prt| Protocol | -^connect [\w\-\./]+:\d+\s+[\w\./]+$ - -##! Cover the OPTIONS method -##! Meth |*| Protocol | -^options \*\s+[\w\./]+$ - -##! Cover other methods of the form METHOD [[scheme]://[host][:port]]/path[?query][#fragment] protocol -##! Method ---|- Scheme:// -|- Host --|-- Port --| Path |--- Query ---| Fragment | Protocol | -^[a-z]{3,10}\s+(?:\w{3,7}?://[\w\-\./]*(?::\d+)?)?/[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?\s+[\w\./]+$ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920120.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920120.ra deleted file mode 100644 index 4659f6e4b..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920120.ra +++ /dev/null @@ -1,27 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The HTML entities included in the expression are a best guess selection of frequently -##! used entities. Including too many would further reduce the performance of the expression -##! but there may well be additional entities that would make sense to add to the list. -##! The official list of entities is hosted by the WHATWG: -##! https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references - -##!+ i - -##!^ ^ -##!$ *$ - -&[aeiouclnrszg]acute; -&[cdelnrstz]caron; -&[cgklnrst]cedil; -&[aeioucghjswy]circ; -&[aeiou]grave; -&[au]ring; -&[anoi]tilde; -&[aeiouy]uml; -& -' -  -ø -[^'\";=\x5c] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920220-chain1.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920220-chain1.ra deleted file mode 100644 index b53f964c3..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920220-chain1.ra +++ /dev/null @@ -1,15 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - - -##!^ ^ -##!$ $ - -##! grab the path, except for the lat path segment (separate rule) -(.*)/ -##!=> -##! skip the last path segment, if there is one (non-capturing group) -(?:[^?]+)? -##!=> -##! grab the query string, if there is one -(\?.*)? diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920221.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920221.ra deleted file mode 100644 index 47184249d..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920221.ra +++ /dev/null @@ -1,12 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - - -##!^ ^ -##!$ $ - -##! find any percent character -.*%.* -##!=> -##! followed by something that looks like a file extension -\.[^\s.]+ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920260.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920260.ra deleted file mode 100644 index 8bfd4a41c..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920260.ra +++ /dev/null @@ -1,6 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -%uff[0-9a-f]{2} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920521.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920521.ra deleted file mode 100644 index ac81329b1..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920521.ra +++ /dev/null @@ -1,18 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Current Accept-Encoding headers -br -compress -deflate -gzip -identity -\* -^$ -##! Deprecated Accept-Encoding headers -aes128gcm -exi -pack200-gzip -zstd -x-compress -x-gzip diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920600.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920600.ra deleted file mode 100644 index cdc7303ba..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/920600.ra +++ /dev/null @@ -1,4 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!> include charset-specification diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/922110-chain1.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/922110-chain1.ra deleted file mode 100644 index cdc7303ba..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/922110-chain1.ra +++ /dev/null @@ -1,4 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!> include charset-specification diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/930100.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/930100.ra deleted file mode 100644 index 769c9faeb..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/930100.ra +++ /dev/null @@ -1,110 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Source: https://github.com/wireghoul/dotdotpwn/blob/master/DotDotPwn/TraversalEngine.pm -##! Attack description: https://doc.lagout.org/security/McGraw.Hill.HackNotes.Web.Security.Portable.Reference.eBook-DDU.pdf -##! Excerpt: -##! In short, IIS turns %c0%af into -##! the ASCII / character, but parses it at a point where security checks for -##! ‘../’ traversals have already occurred! -##! What has really happened? The attack uses an overlong Unicode -##! representation for a forward or backward slash (/ or \). -##! Unicode permits multibyte encoding of the same character. -##! The fundamental representation can be referred to as a one (character) to one (byte field) -##! representation. The overlong representation is a one (character) to many -##! (bytes) version. -##! Two more valid strings that represent the backward slash are %c1%1c -##! and %c1%9c. The difference between these two hex values is 128. More -##! valid slash representations boil down to a matter of math. For example, -##! %c0%9v works even though %9v isn’t a hexadecimal value. Try adding -##! the value for “9” (57) to “v” (118); if the result is greater than 127, then -##! subtract 128—hint, the final result should be 47. - -##!+ i - -##! slash patterns -##!> assemble - \x5c - ##! URI encoded - %2f - %5c - ##! Hex encoded - 0x2f - 0x5c - ##! Double URI encoded - %252f - %255c - ##! Overlong Unicode sequences (target IIS) - %c0%2f - %c0%af - %c0%5c - %c1%9c - %c1%pc - %c0%9v - %c0%qf - %c1%8s - %c1%1c - %c1%af - %bg%qf - ##! Unicode 16 "alternative" glyphs - %u2215 - %u2216 - ##! Unknown - %uEFC8 - %uF025 - ##! More double encoding and variations on the above - %%32%%66 - %%35%%63 - %e0%80%af - %25c1%259c - %25c0%25af - %f0%80%80%af - %f8%80%80%80%af - %2%46 - %%32%46 - %%32F - %u002f - %1u - / - ##!=< slashes - ##!=> slashes - - ##! dot patterns - ##! These use the same techniques as for slashes to evade the detection of '.' - \. - \.%00 - \.%01 - \.\? - \?\. - \? - %2e - 0x2e - %c0\. - %252e - %c0%2e - %c0%ae - %c0%5e - %c0%ee - %c0%fe - %uff0e - %%32%%65 - %e0%80%ae - %25c0%25ae - %f0%80%80%ae - %f8%80%80%80%ae - %fc%80%80%80%80%ae - %2%45 - %u002e - %uff0e - %u2024 - %%32%45 - %%32E - %c0%6e - ##!=> - - ##! Append {2,3} to the result, as we're looking for two or three dots (e.g. /../, /.../) - {2,3} - ##!=> - - ##!=> slashes -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/931130.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/931130.ra deleted file mode 100644 index 558f5da46..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/931130.ra +++ /dev/null @@ -1,17 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! ATTENTION: The rule files 931130.data and 931131.data are meant to be kept in sync. -##! They should result in the same regular expression used on different targets in different phases. - -##!+ i - -##!> assemble - ##!=> - (?:(?:url|jar):)? - ##!=> - ##!> include url-schemes - ##!=> - ://(?:[^@]+@)?([^/]*) - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/931131.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/931131.ra deleted file mode 100644 index aef8b0ee8..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/931131.ra +++ /dev/null @@ -1,17 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! ATTENTION: The rule files 931129.data and 931131.data are meant to be kept in sync. -##! They should result in the same regular expression used on different targets in different phases. - -##!+ i - -##!> assemble - ##!=> - (?:(?:url|jar):)? - ##!=> - ##!> include url-schemes - ##!=> - ://(?:[^@]+@)?([^/]*) - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932125.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932125.ra deleted file mode 100644 index 2a69987a1..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932125.ra +++ /dev/null @@ -1,235 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932125 (RCE Windows command injection - PowerShell aliases) -##! -##! This list comes from the powershell source code. Can be updated using this oneliner: -##! curl -s https://raw.githubusercontent.com/PowerShell/PowerShell/master/src/System.Management.Automation/engine/InitialSessionState.cs -o - | awk -F\" '/new SessionStateAliasEntry\("/ { print $2; }' -##! To prevent some FP for a command, you can require command parameters -##! after a command. Only do this if the command regularly causes FP and if -##! allowing the bare command (without parameters) is not too dangerous. -##! (Note: due to \b following the regexp, a word boundary is also required -##! further on, so some letter/number is needed for a match). Example: -##! -##! diff@ - -##!+ i - -##! Note: the quoting prefixes are part of the command prefixes, except for ^ -##! which, for unknown reasons, is not part of the expression - -##! extension/switches suffix -##! cmd.com, cmd.exe, etc. -##!$ (?:\.[\"\^]*\w+)? -##! cmd/h -##!$ \b - -##! starting tokens prefix -##!> assemble - ##! ;cmd - ; - ##! {cmd - \{ - ##! |cmd - \| - ##! ||cmd - \|\| - ##! &cmd - & - ##! &&cmd - && - ##! \ncmd - \n - ##! \rcmd - \r - ##! `cmd - ` - ##!=> - - ##! match possible white space between prefix expressions - \s* - ##!=> - - ##! commands prefix - ##!> assemble - ##! (cmd) - \( - ##! ,cmd - , - ##! @cmd - @ - ##! 'cmd' - ' - ##! "cmd" - \" - ##! spacing+cmd - \s - ##!< - ##!=> - - * - ##!=> - - ##! paths prefix - ##!> assemble - ##! /path/cmd - [\w'\"\./]+/ - ##! C:\Program Files\cmd - [\x5c'\"\^]*\w[\x5c'\"\^]*:.*\x5c - ##! \\net\share\dir\cmd - [\^\.\w '\"/\x5c]*\x5c - ##!< - ##!=> - - ?[\"\^]* - ##!=> - - ##!> cmdline windows - - ac@ - asnp@ - cd@ - ##! disabled for FP: cat@ - chdir@ - clc@ - ##! disabled for FP: clear - clhy@ - cli@ - clp@ - cls - clv@ - cnsn - ##! disabled for FP: compare@ - ##! disabled for FP: copy@ - cp@ - cpi@ - cpp@ - cvpa@ - dbp@ - del@ - diff@ - dir@ - dnsn - ebp@ - epal@ - epcsv@ - epsn@ - ##! disabled for FP: erase@ - etsn@ - exsn@ - fc@ - fl@ - foreach@ - ft@ - fw@ - gal@ - gbp@ - gc@ - gci@ - gcm@ - gcs@ - gdr@ - gerr - ghy@ - gi@ - gjb@ - gl@ - gm@ - gmo@ - gp@ - gps@ - gpv - ##! disabled for FP: group - gsn@ - gsnp@ - gsv@ - gu@ - gv@ - gwmi@ - ##! disabled for FP: h - ##! disabled for FP: history - icm@ - iex@ - ihy@ - ii@ - ipal@ - ipcsv@ - ipmo@ - ipsn@ - irm@ - ise@ - iwmi@ - iwr@ - ##! disabled for FP: kill - ls - man@ - md@ - ##! disabled for FP: measure - mi@ - mount@ - ##! disabled for FP: move - mp@ - mv@ - nal@ - ndr@ - ni@ - nmo@ - npssc - nsn@ - nv@ - ogv@ - ##! disabled for FP: oh - popd@ - pushd@ - ##! disabled for FP: pwd - ##! disabled for FP: r - rbp@ - rcjb@ - rcsn - rd@ - rdr@ - ren@ - ri@ - rjb@ - rm@ - rmdir@ - rmo@ - rni@ - rnp@ - rp@ - rsn@ - rsnp@ - rujb - rv@ - rvpa@ - rwmi@ - sajb@ - sal@ - saps@ - sasv@ - sbp@ - sc@ - ##! disabled for FP: select - ##! disabled for FP: set - shcm - si@ - sl@ - ##! disabled for FP: sleep - sls@ - ##! disabled for FP: sort - sp@ - spjb@ - spps@ - spsv@ - ##! disabled for FP: start - sujb - sv@ - swmi@ - ##! disabled for FP: tee - trcm@ - ##! disabled for FP: type - ##! disabled for FP: where - wjb@ - ##! disabled for FP: write@ - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932130.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932130.ra deleted file mode 100644 index bd183fc2a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932130.ra +++ /dev/null @@ -1,4 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!> include 932130 diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932131.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932131.ra deleted file mode 100644 index d769518b1..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932131.ra +++ /dev/null @@ -1,7 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Rule 932131 uses the same regular expression as 932130 on a -##! different target. - -##!> include 932130 diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932175.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932175.ra deleted file mode 100644 index 47fea4980..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932175.ra +++ /dev/null @@ -1,32 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Prevent command aliasing - -##! starting tokens prefix -##!> assemble - \b - ##!=> - ##!> cmdline unix - alias - ##!< - ##!=> - - ##! match white space between command and arguments - \b\s+ - ##!=> - - ##! match flags - (?:[+\-][a-z]+\+?\s+)? - ##!=> - - ##! match the alias name - ##! The '.' and '-' character match payloads like "alias ls-al='ls -al'" and "alias ..='cd ..'" - [.'"\w!%\-,@]+ - ##!=> - - ##! match equals something - =\S - ##!=> - -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932200.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932200.ra deleted file mode 100644 index e2dcc4d84..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932200.ra +++ /dev/null @@ -1,17 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! - bar;cd+/etc;/bin$u/ca*+passwd -##! - foo;ca\t+/et\c/pa\s\swd -##! - foo;c'at'+/etc/pa's'swd -[*?`\x5c'][^/\n]+/ -/[^/]+?[*?`\x5c'] -##! - foo;cat$u+/etc$u/passwd -##! - foo;c$-at+/et$-c/pas$-swd -##! - foo;c$_at+/et$_c/pas$_swd -##! - foo;c$?at+/et$?c/pas$?swd -##! - foo;c$*at+/et$*c/pas$*swd -##! - foo;c$@at+/et$@c/pas$@swd -##! - foo;c$!at+/et$!c/pas$!swd -##! - foo;c$$at+/et$$c/pas$$swd -\$[({\[#@!?*\-_$a-zA-Z0-9] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932205-chain1.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932205-chain1.ra deleted file mode 100644 index 84695af32..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932205-chain1.ra +++ /dev/null @@ -1,29 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Prefix to prevent the first `?` (query string marker -##! in URLs) from matching any of the later expressions. -##! If the URL does not have a query string, then instead -##! look for the first `;`. -##! Prefix and suffix markers also form two capture groups -##! that are used for processing and logging in the rule. -##!^ ^[^.]+\.[^?;]+[?;](.*( -##!$ )) - -##! The following expressions in this file must be identical to the -##! ones in 932200. - -##! - bar;cd+/etc;/bin$u/ca*+passwd -##! - foo;ca\t+/et\c/pa\s\swd -##! - foo;c'at'+/etc/pa's'swd -[*?`\x5c'][^/\n]+/ -/[^/]+?[*?`\x5c'] -##! - foo;cat$u+/etc$u/passwd -##! - foo;c$-at+/et$-c/pas$-swd -##! - foo;c$_at+/et$_c/pas$_swd -##! - foo;c$?at+/et$?c/pas$?swd -##! - foo;c$*at+/et$*c/pas$*swd -##! - foo;c$@at+/et$@c/pas$@swd -##! - foo;c$!at+/et$!c/pas$!swd -##! - foo;c$$at+/et$$c/pas$$swd -\$[({\[#@!?*\-_$a-zA-Z0-9] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932206.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932206.ra deleted file mode 100644 index dce24e55f..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932206.ra +++ /dev/null @@ -1,25 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Prefix to ensure that the rule only matches when the -##! value of the Referer header is not a URL (illegal header -##! value). -##!^ ^[^.]*? - -##! The following expressions in this file must be identical to the -##! ones in 932200. - -##! - bar;cd+/etc;/bin$u/ca*+passwd -##! - foo;ca\t+/et\c/pa\s\swd -##! - foo;c'at'+/etc/pa's'swd -[*?`\x5c'][^/\n]+/ -/[^/]+?[*?`\x5c'] -##! - foo;cat$u+/etc$u/passwd -##! - foo;c$-at+/et$-c/pas$-swd -##! - foo;c$_at+/et$_c/pas$_swd -##! - foo;c$?at+/et$?c/pas$?swd -##! - foo;c$*at+/et$*c/pas$*swd -##! - foo;c$@at+/et$@c/pas$@swd -##! - foo;c$!at+/et$!c/pas$!swd -##! - foo;c$$at+/et$$c/pas$$swd -\$[({\[#@!?*\-_$a-zA-Z0-9] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932210.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932210.ra deleted file mode 100644 index 1d44a1873..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932210.ra +++ /dev/null @@ -1,77 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list can be updated using: -##! curl -ks https://raw.githubusercontent.com/sqlite/sqlite/master/src/shell.c.in | grep -oE '^\s+"(\.[a-z0-9]+)' | cut -f2 -d. - -##!^ ;\s*\.\s*[\"']? - -archive -auth -backup -bail -binary -cd -changes -check -clone -connection -databases -dbconfig -dbinfo -dump -echo -eqp -excel -exit -expert -explain -filectrl -fullschema -headers -help -import -imposter -indexes -iotrace -limit -lint -load -log -mode -nonce -nullvalue -once -open -output -parameter -print -progress -prompt -quit -read -recover -restore -save -scanstats -schema -selftest -separator -session -sh -sha3sum -shell -show -stats -system -tables -testcase -testctrl -timeout -timer -trace -unmodule -vfsinfo -vfslist -vfsname -width diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932220.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932220.ra deleted file mode 100644 index c2bc6307c..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932220.ra +++ /dev/null @@ -1,25 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932220 (RCE Unix command injection) -##! -##! This list comes from (and should be in sync) the `unix-shell.data` file. - -##! Not all of the prefixes for the command words will be legal. -##! We've decided to use the same prefix as in 932100 and 932105 here, -##! because we don't know exactly what things are possible after a pipe and -##! we don't want to overcomplicate things by introducing another prefix variation. -##! Not all of the prefixes matched by the expression will actually be valid. - -##!+ i - -##!^ .\| - -##!> assemble - \s* - ##!> include unix-shell-evasion-prefix - - ##!> cmdline unix - ##!> include-except unix-shell-upto3 unix-shell-fps-pl2 -- @ "" ~ "" - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932230.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932230.ra deleted file mode 100644 index 7b298ea66..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932230.ra +++ /dev/null @@ -1,21 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932230 (RCE for commands of two and three character words) -##! -##! Per discussion in https://github.com/coreruleset/coreruleset/issues/2632, we decided -##! to extend the cmdline evasion regex, so we are applying the evasion to a subset of the -##! original 93210(0|5) rules: the subset of commands from two or three characters that might pose -##! a greater risk of false positives. - -##!+ i - -##!$ \b - -##!> assemble - ##!> include unix-shell-evasion-prefix - - ##!> cmdline unix - ##!> include-except unix-shell-upto3 unix-shell-fps-pl1 - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932231.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932231.ra deleted file mode 100644 index 22b5e8b89..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932231.ra +++ /dev/null @@ -1,21 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932231 (RCE Unix command injection part 3/4) -##! -##! To prevent some FP for a command, you can require command parameters -##! after a command. Only do this if the command regularly causes FP and if -##! allowing the bare command (without parameters) is not too dangerous. -##! (Note: due to \b following the regexp, a word boundary is also required -##! further on, so some letter/number is needed for a match). Example: -##! -##! diff+ - -##! Special regexp case for the '.' (source) command to prevent FP: - - -##!> assemble - ##!> include unix-shell-evasion-prefix - - \.\s.*\b -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932232.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932232.ra deleted file mode 100644 index 50af9d013..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932232.ra +++ /dev/null @@ -1,16 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932232 (RCE Unix command injection part 4/4) - -##!$ \b - -##!> assemble - ##!> include unix-shell-evasion-prefix - - ##!> assemble - ##!> cmdline unix - ##!> include unix-shell-pl3 - ##!< - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932235.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932235.ra deleted file mode 100644 index df2b696e3..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932235.ra +++ /dev/null @@ -1,11 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> include unix-shell-evasion-prefix - -##! These patterns are approximations of the patterns used by the cmdline -##! processor for `@` and `~`. -##! These patterns are used across multiple files, change with care. -##!> include-except unix-shell-4andup unix-shell-fps-pl1-curated -- @ [\s<>&|)] ~ \S diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932236.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932236.ra deleted file mode 100644 index 205a7cdb2..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932236.ra +++ /dev/null @@ -1,15 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> assemble - ##!> include unix-shell-evasion-prefix-start-of-string.ra -##!< -##!=> - -##! These patterns are approximations of the patterns used by the cmdline -##! processor for `@` and `~`. -##! These patterns are used across multiple files, change with care. -##!> include-except unix-shell-upto3 unix-shell-fps-pl2 unix-shell-fps-pl2-start-of-string -- @ [\s<>&|)] ~ \S -##!> include-except unix-shell-4andup unix-shell-fps-pl2 unix-shell-fps-pl2-start-of-string -- @ [\s<>&|)] ~ \S diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932237.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932237.ra deleted file mode 100644 index db57f72d9..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932237.ra +++ /dev/null @@ -1,15 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!^ \b - -##!$ (?:\b|\W) - -##! These patterns are approximations of the patterns used by the cmdline -##! processor for `@` and `~`. -##! These patterns are used across multiple files, change with care. -##!> include-except unix-shell-upto3 unix-shell-fps-useragents -- @ [\s<>&|)] ~ \S -##!> include-except unix-shell-4andup unix-shell-fps-useragents -- @ [\s<>&|)] ~ \S -##!> include-except unix-shell-pl3 unix-shell-fps-useragents -- @ [\s<>&|)] ~ \S diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932238.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932238.ra deleted file mode 100644 index a11509f5a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932238.ra +++ /dev/null @@ -1,15 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> assemble - ##!> include unix-shell-evasion-prefix-start-of-string -##!< -##!=> - -##!> assemble - ##!> cmdline unix - ##!> include unix-shell-pl3 - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932239.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932239.ra deleted file mode 100644 index a37b41ea2..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932239.ra +++ /dev/null @@ -1,15 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> assemble - ##!> include unix-shell-evasion-prefix-start-of-string -##!< -##!=> - -##! These patterns are approximations of the patterns used by the cmdline -##! processor for `@` and `~`. -##! These patterns are used across multiple files, change with care. -##!> include-except unix-shell-upto3 unix-shell-fps-pl2 unix-shell-fps-pl2-start-of-string unix-shell-fps-useragents -- @ [\s<>&|)] ~ \S -##!> include-except unix-shell-4andup unix-shell-fps-pl2 unix-shell-fps-pl2-start-of-string unix-shell-fps-useragents -- @ [\s<>&|)] ~ \S diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932240.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932240.ra deleted file mode 100644 index 12259d781..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932240.ra +++ /dev/null @@ -1,44 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Rule 932240 (Generic RCE Unix command evasion detection) -##! -##! Conceptually, we want to match: -##! - at least one character -##! - at least one character from an evasion technique - -##!+ i - -##! The previous cmdline evasion detection was based on the one from modsecurity: `[\x5c'\"]*` -##! We extended the evasion detection from the cmdline processor with `(?:\$[a-z0-9_@?!#{*-]*)?(?:\x5c)?` to match: -##! - non-existing vars: cu$@rl, una$$me -a, uname$$u -a -##! - vars + spacing: v='u';cu$v\r\l google.com -##! - globbing pattern expansion: {n$u\c$u,-nlvp,777} -##! - globbing: garb=cur[l];$garb+google.com - -##! kill '-'9 -##!> assemble - [a-z0-9_-]+ - ##!=> - \s*['\"][^'\"\s]+['\"] - ##!=> - [a-z0-9_-]+ -##!< - -##!> assemble - [a-z0-9_-]+ - ##!=> - ##! py""thon - ['\"]['\"]+ - [\x5c\[\]]+ - \$+[\x5ca-z0-9_@?!#{*-]+ - ##! process substitution - `` - \$\(\) - <\(\) - >\(\) - ##!=> - - \s*[a-z0-9_-]+ - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932250.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932250.ra deleted file mode 100644 index da48fa621..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932250.ra +++ /dev/null @@ -1,21 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932250 (RCE Unix command injection) - -##!+ i - -##!> assemble - ##!> include unix-shell-evasion-prefix-start-of-string - - ##!> assemble - ##!> cmdline unix - ##!> include-except unix-shell-upto3 unix-shell-fps-pl1 -- @ "" ~ "" - ##!< - ##!=> - ##! This pattern is an approximation of the pattern used by the cmdline - ##! processor for `@`. - ##! This pattern is used across multiple files, change with care. - [\s<>&|)] - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932260.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932260.ra deleted file mode 100644 index d94b7912c..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932260.ra +++ /dev/null @@ -1,15 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932260 (RCE Unix command injection) - -##!+ i - -##!> assemble - ##!> include unix-shell-evasion-prefix-start-of-string - - ##! These patterns are approximations of the patterns used by the cmdline - ##! processor for `@` and `~`. - ##! These patterns are used across multiple files, change with care. - ##!> include-except unix-shell-4andup unix-shell-fps-pl1 -- @ [\s<>&|)] ~ \S -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932270.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932270.ra deleted file mode 100644 index 01e5b271a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932270.ra +++ /dev/null @@ -1,11 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Bash - Tilde Expansion -##! Detects the following patterns which are common in Unix shell scripts and one-liners - -~\+$ -~\+[\d\s]+ -~\-$ -~\-[\d\s]+ -~\d+ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932300.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932300.ra deleted file mode 100644 index 9477717f8..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932300.ra +++ /dev/null @@ -1,18 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!^ (?is)\r\n.*?\b - -##! - SMTP Commands -EHLO [a-zA-Z-\.]{1,255} -HELO [a-zA-Z-\.]{1,255} -MAIL FROM:<.{1,64}@.{1,255}> -RCPT TO:(?:<.{1,64}@.{1,255}>|(?: ))?<.{1,64}> -VRFY (?:.{1,64} <.{1,64}@.{1,255}>|.{1,64}@.{1,255}) -EXPN (?:.{1,64}) -AUTH [A-Z0-9-_]{1,20} (?:=|(?:[\w+/]{4})*(?:[\w+/]{2}==|[\w+/]{3}=)) - -##! - SMTP Commands without params -STARTTLS\b -RSET\b -NOOP\b(?: .{1,255})? diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932301.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932301.ra deleted file mode 100644 index a19c80cc0..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932301.ra +++ /dev/null @@ -1,13 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!^ (?s)\r\n.*?\b - -##! - SMTP Commands without or optional params -DATA -QUIT -HELP(?: .{1,255})? - -##! - SMTP Commands with params - -##! Not covered - X Command (client extensions) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932310.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932310.ra deleted file mode 100644 index 0aaeadcc5..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932310.ra +++ /dev/null @@ -1,22 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! All IMAP4 commands start with a "tag" - -##!+ is -##!^ \r\n\w{1,50}\b[ ] - -##! IMAP4 Commands - PL2 - -##! - IMAP4Rev1 Commands - with params -APPEND (?:[\w\"\.\-\x5c\/%\*&#]+)?(?: \((?:[a-z\x5c\ ])+\))?(?: \"?\d{1,2}-\w{3}-\d{4} \d{2}:\d{2}:\d{2} [+-]\d{4}\"?)? \{\d{1,20}\+?\} -AUTHENTICATE [a-z0-9-_]{1,20}\r\n -LSUB (?:[\w\"~\/\*#\.]+)? (?:[\w\"\.\x5c\/%\*&]+)? -STATUS (?:[\w\"\.\-\x5c\/%\*&]+)? \((?:UNSEEN|UIDNEXT|MESSAGES|UIDVALIDITY|RECENT| )+\) -UID (?:COPY|FETCH|STORE) (?:[0-9,:\*]+)? -##! - IMAP4Rev1 Commands Extensions - with params -DELETEACL (?:[\w\"\.\-\x5c\/%\*&]+)? -GETACL (?:[\w\"\.\-\x5c\/%\*&]+)? -MYRIGHTS (?:[\w\"\.\-\x5c\/%\*&]+)? -LISTRIGHTS (?:[\w\"\.\-\x5c\/%\*&]+)? -SETACL (?:[\w\"\.\-\x5c\/%\*&]+)? [+-][lrswipckdxtea]+? diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932311.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932311.ra deleted file mode 100644 index d1d76f4f9..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932311.ra +++ /dev/null @@ -1,44 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! All IMAP4 commands start with a "tag" - -##! TDB: representing charset and language (if needed) -##!+ is -##!^ \r\n\w{1,50}\b[ ] - -##! - IMAP4 Commands - PL3 - -##! - IMAP4Rev1 Commands - with params -CREATE [\w\"\.\-\x5c\/%\*&#]+ -COPY [0-9,:\*]+ [\w\"\.\-\x5c\/%\*&#]+ -DELETE [\w\"\.\-\x5c%\*&#]+ -EXAMINE [\w\"\.\-\x5c%\*&#]+ -FETCH [0-9,:\*]+ -LIST [\w\"~\-\x5c\/\*#\.]+? [\w\"\.\-\x5c\/%\*&#]+ -LOGIN [a-z0-9-_\.\@]{1,40} .*? -RENAME [\w\"\.\-\x5c\/%\*&#]+? [\w\"\.\-\x5c\/%\*&#]+ -SELECT [\w\"\.\-\x5c\/%\*&#]+ -STORE [0-9,:\*]+? [+-]?FLAGS(?:\.SILENT)? (?:\(\x5c[a-z]{1,20}\))? -SUBSCRIBE [\w\"\.\-\x5c\/%\*&#]+ -UNSUBSCRIBE [\w\"\.\-\x5c\/%\*&#]+ -##! Search has plenty of variants -SEARCH(?: CHARSET [\w\-_\.]{1,40})? (KEYWORD \x5c)?(?:ALL|ANSWERED|BCC|DELETED|DRAFT|FLAGGED|RECENT|SEEN|UNANSWERED|UNDELETED|UNDRAFT|UNFLAGGED|UNSEEN|NEW|OLD) -SEARCH(?: CHARSET [\w\-_\.]{1,40})? (?:BODY|CC|FROM) .{1,255} -SEARCH(?: CHARSET [\w\-_\.]{1,40})? HEADER .{1,100} .{1,255} -SEARCH(?: CHARSET [\w\-_\.]{1,40})? (?:LARGER \d{1,20}|NOT .{1,255}|[0-9,:\*]+) -SEARCH(?: CHARSET [\w\-_\.]{1,40})? (?:BEFORE|ON|SENTBEFORE|SENTON|SENTSINCE|SINCE) \"?\d{1,2}-\w{3}-\d{4}\"? -SEARCH(?: CHARSET [\w\-_\.]{1,40})? (?:OR .{1,255} .{1,255}|SMALLER \d{1,20}|SUBJECT .{1,255}) -SEARCH(?: CHARSET [\w\-_\.]{1,40})? (?:TEXT .{1,255}|TO .{1,255}|UID [0-9,:\*]+?|UNKEYWORD (?:\x5c(Seen|Answered|Flagged|Deleted|Draft|Recent))) - -##! - IMAP4rev1 Commands - without params -CAPABILITY -CHECK -CLOSE -EXPUNGE -LOGOUT -NOOP -STARTTLS -UNAUTHENTICATE - -##! Not covered - X Command (client extensions) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932320.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932320.ra deleted file mode 100644 index f9adf5e94..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932320.ra +++ /dev/null @@ -1,18 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! POP3 Commands - PL2 - -##!+ is -##!^ \r\n.*?\b - -##! POP3 Commands - with args -LIST(?: \d+)? -USER .+? -PASS .+? -RETR \d+? -DELE \d+? -UIDL(?: \d+)? -APOP [\w]+ [a-f0-9]{32} -TOP \d+(?: \d+)? -AUTH [a-z0-9-_]{1,20} (?:=|(?:[\w+/]{4})*(?:[\w+/]{2}==|[\w+/]{3}=)) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932321.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932321.ra deleted file mode 100644 index 8389557b9..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932321.ra +++ /dev/null @@ -1,13 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!^ (?si)\r\n.*?\b - -##! POP3 Commands - PL3 - -##! POP3 Commands - No args -QUIT -STAT -NOOP -RSET -CAPA diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932370.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932370.ra deleted file mode 100644 index 1a0289a11..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932370.ra +++ /dev/null @@ -1,206 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932370 (RCE Windows command injection part 1/2) -##! -##! The list comes from the project LOLBAS. You can get it using the following one-liner: -##! `curl -s -H "Accept: application/vnd.github.v3+json" https://api.github.com/repos/LOLBAS-Project/LOLBAS/git/trees/master\?recursive\=1 | jq -r '.tree[].path ' | grep ^yml/ | cut -f3 -d/ | cut -f1 -d. | tr 'A-Z' 'a-z' | sort | uniq` -##! To prevent some FP for a command, you can require command parameters -##! after a command. Only do this if the command regularly causes FP and if -##! allowing the bare command (without parameters) is not too dangerous. -##! (Note: due to \b following the regexp, a word boundary is also required -##! further on, so some letter/number is needed for a match). Example: -##! -##! diff@ - -##!+ i - -##! extension/switches suffix -##! cmd.com, cmd.exe, etc. -##!$ (?:\.[\"\^]*\w+)? -##! cmd/h -##!$ \b - -##! starting tokens prefix -##!> assemble - ##!> include windows-commands-prefix - - ##!> cmdline windows - - acccheckconsole - adplus - advpack - agentexecutor - appinstaller - appvlp - aspnet_compiler - at@ - atbroker - bash - bginfo - bitsadmin - cdb - certoc - certreq - certutil - cl_invocation - cl_loadassembly - cl_mutexverifiers - cmd - cmdkey - cmdl32 - cmstp - comsvcs - configsecuritypolicy - conhost - control - coregen - createdump - csc - cscript - csi - customshellhost - datasvcutil - defaultpack - desk - desktopimgdownldr - devicecredentialdeployment - devtoolslauncher - dfshim - dfsvc - diantz - diskshadow - dnscmd - dnx - dotnet - dump64 - dxcap - esentutl - eventvwr - excel - expand - explorer - extexport - extrac32 - findstr - finger - fltmc - forfiles - fsi - fsianycpu - fsutil - ftp - gfxdownloadwrapper - gpscript - hh - ie4uinit - ieadvpack - ieexec - ieframe - ilasm - imewdbld - infdefaultinstall - installutil - jsc - launch-vsdevshell - ldifde - makecab - manage-bde - mavinject - mftrace - microsoft - mmc - mpcmdrun - msbuild - msconfig - msdeploy - msdt - mshta - mshtml - msiexec - msohtmed - mspub - msxsl - netsh - ntdsutil - odbcconf - offlinescannershell - onedrivestandaloneupdater - openconsole - pcalua - pcwrun - pcwutl - pester - pktmon - pnputil - powerpnt - presentationhost - print - printbrm - procdump - protocolhandler - psr - pubprn - rasautou - rcsi - rdrleakdiag - reg - regasm - regedit - regini - register-cimprovider - regsvcs - regsvr32 - remote - replace - rpcping - rundll32 - runexehelper - runonce - runscripthelper - sc@ - schtasks - scriptrunner - setres - settingsynchost - setupapi - shdocvw - shell32 - sqldumper - sqlps - sqltoolsps - squirrel - ssh - stordiag - syncappvpublishingserver - syssetup - te@ - tracker - ttdinject - tttracer - unregmp2 - update - url - utilityfunctions - vbc - verclsid - visualuiaverifynative - vsiisexelauncher - vsjitdebugger - wab - wfc - winget - winrm - winword - wlrmdr - wmic - workfolders - wscript - wsl - wsreset - wt@ - wuauclt - xwizard - zipfldr - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932380.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932380.ra deleted file mode 100644 index 3242abdfd..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/932380.ra +++ /dev/null @@ -1,23 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932380 (RCE Windows command injection part 2/2) -##! -##!+ i - -##! extension/switches suffix -##! cmd.com, cmd.exe, etc. -##!$ (?:\.[\"\^]*\w+)? -##! cmd/h -##!$ \b - -##! starting tokens prefix -##!> assemble - ##!> include windows-commands-prefix - - ##!> cmdline windows - - ##!> include-except windows-commands windows-commands-fps - - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933100.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933100.ra deleted file mode 100644 index e5f16482f..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933100.ra +++ /dev/null @@ -1,30 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> assemble - <\? - ##!=> - ##!> assemble - [^x] - x[^m] - xm[^l] - xml[^\s] - ##! With [^a-z] we are looking for `:` as in ` assemble - \[ - ##!=> - ##!> assemble - php\] - /php\] - \x5cphp\] - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933160.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933160.ra deleted file mode 100644 index ce664710d..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933160.ra +++ /dev/null @@ -1,54 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i -##! optional opening parenthesis before command -##!^ \b\(? -##! optional quotes -##!^ ['\"]* - -##! match comments: `/*...*/`, `//...`, `#...` -##!$ (?:/\*.*\*/|//.*|#.* -##! match white space and quotes -##!$ |\s|\")* - -##! optional quotes -##!$ ['\"]* -##! optional closing parenthesis after command -##!$ \)?\s* - -##! mandatory parentheses containing optional parameters -##!$ \(.*\) - -assert -assert_options -chr -create_function -eval -exec -file -filegroup -glob -imagegif -imagejpeg -imagepng -imagewbmp -imagexbm -is_a -md5 -opendir -passthru -popen -readfile -tmpfile -unpack - -##! English words, or potential snippets of them, are added here to perform a regex match. -##! Compared to the parallel match performed by 933150, fewer false positives will be generated. -exp -ord -prev -stat -substr -system -unlink diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933161.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933161.ra deleted file mode 100644 index e6e25f75e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933161.ra +++ /dev/null @@ -1,104 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! File autogenerated by util/php-dictionary-gen with: -a 30 -F 90000 -s ../fp-finder/spell.sh - -##!+ i -##!^ \b -##!$ (?:\s|/\*.*\*/|#.*|//.*)*\(.*\) - -abs -asin -assert -assert_options -basename -checkdate -chr -chroot -compact -constant -copy -cos -cosh -count -create_function -crypt -current -date -decoct -define -defined -dir -end -eval -exec -exp -explode -extract -file -fileatime -filectime -filegroup -fileinode -filemtime -fileowner -fileperms -filesize -filetype -flock -floor -flush -glob -hash -header -idate -imagegif -imagejpeg -imagepng -imagewbmp -imagexbm -implode -is_a -key -link -log -mail -max -md5 -min -name -next -opendir -ord -pack -pass -passthru -pi -popen -pow -prev -rand -range -readfile -rename -reset -round -serialize -shuffle -sin -sleep -sort -stat -substr -symlink -syslog -system -tan -time -tmpfile -touch -trim -ucfirst -unlink -unpack -virtual diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933200.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933200.ra deleted file mode 100644 index a37d8b31b..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933200.ra +++ /dev/null @@ -1,32 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! PHP Wrappers -##! -##! PHP comes with many built-in wrappers for various URL-style protocols for -##! use with the filesystem functions such as fopen(), copy(), file_exists() and -##! filesize(). Abusing of PHP wrappers like phar:// could lead to RCE as -##! describled by Sam Thomas at BlackHat USA 2018 (https://bit.ly/2yaKV5X), even -##! wrappers like zlib://, glob://, rar://, zip://, etc... could lead to LFI and -##! expect:// to RCE. -##! -##! Valid PHP wrappers can be found in the PHP documentation here: -##! https://www.php.net/manual/en/wrappers.php - -##! Suffix marker: all options end with :// -##!$ :// - -bzip2 -expect -glob -ogg -phar -rar -ssh2 -ssh2.shell -ssh2.exec -ssh2.tunnel -ssh2.sftp -ssh2.scp -zip -zlib diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933210.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933210.ra deleted file mode 100644 index 6162369e1..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933210.ra +++ /dev/null @@ -1,31 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Helpers -##!> define single_or_double_quotes ['"] -##!> define string_in_round_brackets \(.+\) - -##!$ ; - -##!> assemble - ##! example payload: (system)(ls); - {{string_in_round_brackets}}{{string_in_round_brackets}} - - ##! example payload: (sys)"tem"(ls); - {{string_in_round_brackets}}{{single_or_double_quotes}}[a-zA-Z-_0-9]+{{single_or_double_quotes}}{{string_in_round_brackets}} - - ##! example payload: a=system&b=$_GET[0](ls); - \[\d+\]{{string_in_round_brackets}} - - ##! example payload: {0}("ls") - \{\d+\}{{string_in_round_brackets}} - - ##! example payload: $a("ls") - \$[^(\),.;\x5c/]+{{string_in_round_brackets}} - - ##! example payload: "system"("ls") - {{single_or_double_quotes}}[a-zA-Z0-9-_\x5c]+{{single_or_double_quotes}}{{string_in_round_brackets}} - - ##! example payload: (string)system("ls") - \([^\)]*string[^\)]*\)[a-zA-Z-_0-9\"'.{}\[\]\s]+\([^\)]*\) -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933211.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933211.ra deleted file mode 100644 index 77a935a24..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/933211.ra +++ /dev/null @@ -1,30 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Helpers -##!> define single_or_double_quotes ['"] -##!> define string_in_round_brackets \(.+\) -##!$ (?:;|$)? - -##!> assemble - ##! example payload: (system)(ls) - {{string_in_round_brackets}}{{string_in_round_brackets}} - - ##! example payload: (sys)"tem"(ls) - {{string_in_round_brackets}}{{single_or_double_quotes}}[a-zA-Z-_0-9]+{{single_or_double_quotes}}{{string_in_round_brackets}} - - ##! example payload: $_GET[0]("ls") - \[\d+\]{{string_in_round_brackets}} - - ##! example payload: {0}("ls") - \{\d+\}{{string_in_round_brackets}} - - ##! example payload: $a("ls") - \$[^(\),.;\x5c/]+{{string_in_round_brackets}} - - ##! example payload: "system"("ls") - {{single_or_double_quotes}}[a-zA-Z0-9-_\x5c]+{{single_or_double_quotes}}{{string_in_round_brackets}} - - ##! example payload: (string)system("ls") - \([^\)]*string[^\)]*\)[a-zA-Z-_0-9\"'.{}\[\]\s]+\([^\)]*\) -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934100.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934100.ra deleted file mode 100644 index 00d76a5cc..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934100.ra +++ /dev/null @@ -1,230 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Note that the rule uses `multiMatch` and `removeWhitespace. -##! The explicit white space matches will be matched before -##! `removeWhitespace` is applied, everything else will be matched -##! after white space removal. - -##!> define js-prop-start \[['\"`] -##!> define js-prop-start-dynamic \[ -##!> define js-prop-finish ['\"`]\] - - -##! node-serialize serialized function flag -_\$\$ND_FUNC\$\$_ -__js_function -\beval\( -String\.fromCharCode -function\(\){ -new\s+Function\s*\( -this\.constructor -module\.exports= -\(\s*\Wchild_process\W\s*\) - - -##!> assemble - \( - \.call\( - ##!=< js-call -##!< - -##! All "process" method names -##! Note that `sync` will be appended optionally to all, as many -##! of the names have a twin with the `sync` suffix. -##!> assemble - access - appendfile - argv - availability - caveats - chmod - chown - close - copyfile - cp - createreadstream - createwritestream - exec - execfile - exists - fchmod - fchown - fdata - ##! yes, fdatasyncsync - fdatasync - fstat - ##! yes, fsyncsync - fsync - futimes - inodes - lchmod - link - lstat - lutimes - mkdir - mkdtemp - open - opendir - read - readdir - readfile - readlink - readv - rename - rm - spawn - spawnfile - stat - symlink - truncate - unlink - unwatchfile - utimes - watchfile - writefile - write - writev - ##!=> - (?:sync)? - ##!=< process-funcs -##!< - -##! All "process" prop names -##!> assemble - binding - constructor - env - global - main - mainModule - process - require - ##!=< process-props -##!< - -##! All "console" method names -##!> assemble - debug - error - info - trace - warn - ##!=< console-funcs -##!< - -##! All "require" method names -##!> assemble - resolve - ##!=< require-funcs -##!< - -##! All "require" property names -##!> assemble - main - extensions - cache - ##!=< require-props -##!< - - -##! "process" payloads -##!> assemble - process - ##!=> - - ##! Match method calls via their usual syntax: foo.bar() - ##!> assemble - \. - ##!=> - ##!=> process-funcs - ##!=> js-call - ##!< - - ##! Match properties via their usual syntax: foo.bar - ##!> assemble - \. - ##!=> - ##!=> process-props - ##!< - - ##! Match properties functions via: foo["bar"] - ##!> assemble - {{js-prop-start}} - ##!=> - ##!> assemble - ##!=> process-funcs - ##!< - ##!> assemble - ##!=> process-props - ##!< - ##!=> - {{js-prop-finish}} - ##!< -##!< - -##! Match dynamic property access: process[req.query.a] -##! Note that we don't require `process` as a prefix here -##!> assemble - ##!=> process-props - {{js-prop-start-dynamic}} -##!< - - -##! "console" payloads -##!> assemble - console - ##!=> - - ##! Match method calls via their usual syntax: foo.bar() - ##!> assemble - \. - ##!=> - ##!=> console-funcs - ##!=> js-call - ##!< - - ##! Match properties and functions via: foo["bar"] - ##!> assemble - {{js-prop-start}} - ##!=> - ##!=> console-funcs - ##!=> - {{js-prop-finish}} - ##!< -##!< - -##! "require" payloads -##!> assemble - require - ##!=> - - ##! Match method calls via their usual syntax: foo.bar() - ##!> assemble - \. - ##!=> - ##!=> require-funcs - ##!=> js-call - ##!< - - ##! Match properties via their usual syntax: foo.bar - ##!> assemble - \. - ##!=> - ##!=> require-props - ##!< - - ##! Match properties and functions via: foo["bar"] - ##!> assemble - {{js-prop-start}} - ##!=> - ##!> assemble - ##!=> require-funcs - ##!< - ##!> assemble - ##!=> require-props - ##!< - ##!=> - {{js-prop-finish}} - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934101.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934101.ra deleted file mode 100644 index a2ac07236..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934101.ra +++ /dev/null @@ -1,14 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!$ \s*\( - -close -exists -fork -open -read -spawn -watch -write -require diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934120.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934120.ra deleted file mode 100644 index 09ff06790..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934120.ra +++ /dev/null @@ -1,187 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Bypasses and techniques here come from: -##! - https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Request%20Forgery -##! - https://github.com/cujanovic/SSRF-Testing - -##!+ i - -##! add capture group -##!^ ( -##!$ ) - -##! This regex starts with a list of all the schemes that can be used to make a request -##!> assemble - ##!> include url-schemes - ##!=> - :// - ##!=> - - ##! http://425.510.425.510/ Dotted decimal with overflow (already covered by RFI rule 931100) - ##! http://2852039166/ Dotless decimal - ##! http://7147006462/ Dotless decimal with overflow - \d{10} - - ##! http://0xA9.0xFE.0xA9.0xFE/ Dotted hexadecimal - (?:0x[a-f0-9]{2}\.){3}0x[a-f0-9]{2} - - ##! http://0xA9FEA9FE/ Dotless hexadecimal - 0x[a-f0-9]{8} - - ##! http://0x41414141A9FEA9FE/ Dotless hexadecimal with overflow - 0x[a-f0-9]{16} - - ##! http://0251.0376.0251.0376/ Dotted octal - ##! http://0251.00376.000251.0000376/ Dotted octal with padding - (?:0{1,4}\d{1,3}\.){3}0{1,4}\d{1,3} - - ##! http://169.254.43518/ - \d{1,3}\.\d{1,3}\.\d{5} - - ##! http://169.16689662/ - \d{1,3}\.\d{8} - - ##! glibc Name Service Switch abuse - ##! http://\\l\\o\\c\\a\\l\\h\\o\\s\\t (while underscore is not valid RFC syntax, it is allowed and might be used) - (?:\x5c\x5c[a-z\d-]\.?_?)+ - - ##! http://[::ffff:a9fe:a9fe] IPV6 Compressed - IPv6 (base regex from https://ihateregex.io/expr/ipv6/, with [0-9] converted to \d and with non-capturing groups (below)) - ##! http://[0:0:0:0:0:ffff:a9fe:a9fe] IPV6 Expanded - ##! http://[fe80::%zone1] link-local unicast with zone ID - ##! http://[0:0:0:0:0:ffff:169.254.169.254] IPV6/IPV4 - ##! http://[::] the unspecified address - - ##! Something that looks like IPv6 in a URL. - ##! Matches full and compressed IPv6, link-local IPv6 with - ##! zone ID, and embedded IPv4. - ##! We could match the IPv6 specification here but that would - ##! decrease performance of the regular expression and would - ##! actually increase the possibility for bypasses. - \[[a-f\d:]+(?:[\d.]+|%\w+)?\] - - - ##! These come from https://github.com/cujanovic/SSRF-Testing - ##! These bypasses work by confusing URL parsers in different languages (e.g., PHP, Python, Ruby, Perl) - ##! and libraries (e.g. cURL). The bypasses are parser specific but will often be combined to break - ##! multiple parsers with one try. The goal is often to get the application to call another library - ##! with the malicious URL, e.g. libcurl or glibc (name resolution via gethostbyname(), see also - ##! Name Service Switch abuse above). - - ##! http://127.88.23.245:22/+&@google.com:80#+@google.com:80/ (already covered by RFI rule 931100) - - ##! http://127.88.23.245:22/?@google.com:80/ (already covered by RFI rule 931100) - - ##! http://127.88.23.245:22/#@www.google.com:80/ (already covered by RFI rule 931100) - - ##! http://google.com:80\\@127.88.23.245:22/ (already covered by RFI rule 931100) - - ##! http://google.com:80+&@127.88.23.245:22/#+@google.com:80/ - ##! http://google.com:80+&@google.com:80#+@127.88.23.245:22/ - - ##! create ip-or-domain for later use - ##!> assemble - (?:\d{1,3}\.){3,3}\d{1,3} - [a-z][\w\-\.]{1,255} - ##!=> - :\d{1,5} - ##!=< ip-or-domain - ##!< - - ##!> assemble - ##! domain + port - [a-z][\w\-\.]{1,255}:\d{1,5} - ##!=> - - ##! at least one of the evasion techniques - ##!> assemble - ##! technique 1 - ##!> assemble - ##! possible white spaces to fool safety checks in URL parsers - \s* - ##!=> - - ##! &@ to confuse URL parsers (& can indicate query parameter, @ indicates user info) - &?@ - ##!=> - - ##! IPv4 + port or domain + port - ##!=> ip-or-domain - - ##! optional forward slash - \/? - ##!=> - ##!< - - ##! technique 2 - ##!> assemble - ##! fragment to confuse URL parsers - # - ##!=> - - ##! possible white spaces to fool safety checks in URL parsers - \s* - ##!=> - - ##! &@ to confuse URL parsers (& can indicate query parameter, @ indicates user info) - &?@ - ##!=> - - ##! IPv4 + port or domain + port - ##!=> ip-or-domain - - ##! optional forward slash - /? - ##!=> - ##!< - ##!< - ##!=> - + - ##!=> - ##!< - - ##! Enclosed alphanumerics are used for evasion (https://en.wikipedia.org/wiki/Enclosed_Alphanumerics). - ##! See also https://github.com/cujanovic/SSRF-Testing. - ##! These will normally sound many alarms, but having them flagged as ssrf attempt makes sense - - ##!> assemble - ##! ⓪,①,②,③,④,⑤,⑥,⑦,⑧,⑨,⑩,⑪,⑫,⑬,⑭,⑮,⑯,⑰,⑱,⑲,⑳ - \xe2\x91[\xaa\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3] - ##! ⑴,⑵,⑶,⑷,⑸,⑹,⑺,⑻,⑼,⑽,⑾,⑿ - \xe2\x91[\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf] - ##! ⒀,⒁,⒂,⒃,⒄,⒅,⒆,⒇ - \xe2\x92[\x80\x81\x82\x83\x84\x85\x86\x87] - ##! ⒈,⒉,⒊,⒋,⒌,⒍,⒎,⒏,⒐,⒑,⒒,⒓,⒔,⒕,⒖,⒗,⒘,⒙,⒚,⒛ - \xe2\x92[\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b] - ##! ⒜,⒝,⒞,⒟,⒠,⒡,⒢,⒣,⒤,⒥,⒦,⒧,⒨,⒩,⒪,⒫,⒬,⒭,⒮,⒯,⒰,⒱,⒲,⒳,⒴,⒵ - \xe2\x92[\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5] - ##! Ⓐ,Ⓑ,Ⓒ,Ⓓ,Ⓔ,Ⓕ,Ⓖ,Ⓗ,Ⓘ,Ⓙ - \xe2\x92[\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf] - ##! Ⓚ,Ⓛ,Ⓜ,Ⓝ,Ⓞ,Ⓟ,Ⓠ,Ⓡ,Ⓢ,Ⓣ,Ⓤ,Ⓥ,Ⓦ,Ⓧ,Ⓨ,Ⓩ - \xe2\x93[\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f] - ##! ⓐ,ⓑ,ⓒ,ⓓ,ⓔ,ⓕ,ⓖ,ⓗ,ⓘ,ⓙ,ⓚ,ⓛ - \xe2\x93[\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b] - ##! ⓜ,ⓝ,ⓞ,ⓟ,ⓠ,ⓡ,ⓢ,ⓣ,ⓤ,ⓥ,ⓦ,ⓧ,ⓨ,ⓩ - \xe2\x93[\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9] - ##! ⓫,⓬,⓭,⓮,⓯,⓰,⓱,⓲,⓳,⓴ - \xe2\x93[\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4] - ##! ⓿,⓵,⓶,⓷,⓸,⓹,⓺,⓻,⓼,⓽,⓾ - \xe2\x93[\xbf\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe] - ##! ideographic full stop: 。 - \xe3\x80\x82 - ##!=< enclosed-alnums - ##!< - - ##! an IP could start with digits and dots - ##!> assemble - [\d.]{0,11} - ##!=> - ##!> assemble - ##!=> enclosed-alnums - ##!< - ##!=> - ##! match all for capture - + - ##!=> - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934140.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934140.ra deleted file mode 100644 index 53505e01a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934140.ra +++ /dev/null @@ -1,15 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The text describes a performance issue with a simple regular expression "@{.*}" used for searching. The problem arises because the ".*" part matches any character zero or more times, which can lead to inefficient searching in some engines. - -##! We want to reduce the possibility of impacting performance by removing the strings we can match before the one we are looking, "@{" -##! This regex avoids the double backtracking problem and ensures it finds the first "@{" efficiently. - -##! The prefix here to prevent backtracking is: -##! - something that is not an '@' -##! - or something that is an '@', but is not followed by '{' - -##!^ ^(?:[^@]|@[^{])* - -@+{.*} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934150.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934150.ra deleted file mode 100644 index 22786be6e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934150.ra +++ /dev/null @@ -1,4 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -Process\s*\.\s*spawn\s*\( diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934160.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934160.ra deleted file mode 100644 index f62d06d9c..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934160.ra +++ /dev/null @@ -1,9 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Match while(true) like loops -##!> assemble -##!^ while\s*\([\s(]* -##!$ .*\) - ##!> include js-truthy-values -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934170.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934170.ra deleted file mode 100644 index 8ea60176c..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/934170.ra +++ /dev/null @@ -1,10 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!^ ^ - -##!> assemble - data: - ##!=> - ##!> include charset-specification-no-anchors -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941130.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941130.ra deleted file mode 100644 index 422c34e66..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941130.ra +++ /dev/null @@ -1,17 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i -##!^ . -##!$ \b - -\bxlink:href -\bxhtml -\bxmlns -!ENTITY\s+(?:\S+|%\s+\S+)\s+SYSTEM -!ENTITY\s+(?:\S+|%\s+\S+)\s+PUBLIC -\bdata:text/html -\bformaction -@import -;base64 -\bpattern\b.*?= diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941160.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941160.ra deleted file mode 100644 index 3d255d92d..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941160.ra +++ /dev/null @@ -1,391 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The regular expressions in this file were copied from version 1 or 2 of the NoScript -##! browser extension. The source code is available here: https://noscript.net/getit. -##! The extension, among other things, looks for "dangerous" tags and doesn't care whether -##! they are valid or actually carry a dangerous payload. Therefore, rule 941160 is rather -##! aggressive in its detection, triggering on strings like ``. - -##!+ i - -##!> assemble - ##! HTML tag opening bracket - < - ##!=> - ##! Quotes, punctuation, brackets, etc. - [^\w<>]* - ##!=> - ##! More or less `\w`, followed by `:`, which would match `xml:base`, together with the - ##! list defined later. - (?:[^<>\"'\s]*:)? - ##!=> - ##! Quotes, punctuation, brackets, etc. - [^\w<>]* - ##!=> - ##! Quotes, punctuation, brackets, etc., angle brackets allowed - \W*? - ##!=< html-tag-prefix -##!< - -##!> assemble - s\W*?c\W*?r\W*?i\W*?p\W*?t - f\W*?o\W*?r\W*?m - d\W*?i\W*?a\W*?l\W*?o\W*?g - s\W*?t\W*?y\W*?l\W*?e - s\W*?v\W*?g - m\W*?a\W*?r\W*?q\W*?u\W*?e\W*?e - l\W*?i\W*?n\W*?k[^>\w] - o\W*?b\W*?j\W*?e\W*?c\W*?t[^>\w] - e\W*?m\W*?b\W*?e\W*?d[^>\w] - a\W*?p\W*?p\W*?l\W*?e\W*?t[^>\w] - p\W*?a\W*?r\W*?a\W*?m[^>\w] - i?\W*?f\W*?r\W*?a\W*?m\W*?e[^>\w] - b\W*?a\W*?s\W*?e[^>\w] - b\W*?o\W*?d\W*?y[^>\w] - m\W*?e\W*?t\W*?a[^>\w] - i\W*?m\W*?a?\W*?g\W*?e?[^>\w] - v\W*?i\W*?d\W*?e\W*?o[^>\w] - a\W*?u\W*?d\W*?i\W*?o[^>\w] - b\W*?i\W*?n\W*?d\W*?i\W*?n\W*?g\W*?s[^>\w] - s\W*?e\W*?t[^>\w] - a\W*?n\W*?i\W*?m\W*?a\W*?t\W*?e[^>\w] - ##!=< dangerous-html-tags -##!< - - -##!> assemble - (?:<\w.*[\s/]|['\"](?:.*[\s/])?) - ##!=< html-properties-prefix -##!< - -##!> assemble - background - formaction - lowsrc - onabort - onactivate - onadapteradded - onaddtrack - onafterprint - onafterscriptexecute - onafterupdate - onalerting - onanimationcancel - onanimationend - onanimationiteration - onanimationstart - onantennastatechange - onappcommand - onaudioend - onaudioprocess - onaudiostart - onauxclick - onbeforeactivate - onbeforecopy - onbeforecut - onbeforedeactivate - onbeforeeditfocus - onbeforeinput - onbeforepaste - onbeforeprint - onbeforescriptexecute - onbeforetoggle - onbeforeunload - onbeforeupdate - onbegin - onbeginEvent - onblocked - onblur - onbounce - onboundary - onbroadcast - onbusy - oncached - oncallschanged - oncanplay - oncanplaythrough - oncardstatechange - oncellchange - oncfstatechange - onchange - onchargingchange - onchargingtimechange - onchecking - onclick - onclose - oncommand - oncommandupdate - oncomplete - oncompositionend - oncompositionstart - oncompositionupdate - onconnected - onconnecting - oncontextmenu - oncontrolselect - oncopy - oncuechange - oncut - ondataavailable - ondatachange - ondataerror - ondatasetchanged - ondatasetcomplete - ondblclick - ondeactivate - ondeliveryerror - ondeliverysuccess - ondevicefound - ondevicelight - ondevicemotion - ondeviceorientation - ondeviceproximity - ondialing - ondisabled - ondischargingtimechange - ondisconnected - ondisconnecting - ondomactivate - ondomattrmodified - ondomcharacterdatamodified - ondomfocusin - ondomfocusout - ondommousescroll - ondomnodeinserted - ondomnodeinsertedintodocument - ondomnoderemoved - ondomnoderemovedfromdocument - ondomsubtreemodified - ondownloading - ondragdrop - ondragend - ondragenter - ondragexit - ondraggesture - ondragleave - ondragover - ondragstart - ondrop - ondurationchange - onemptied - onenabled - onend - onended - onendEvent - onenter - onerror - onerrorupdate - onexit - onfailed - onfilterchange - onfinish - onfocus - onfocusin - onfocusout - onformchange - onforminput - onfullscreenchange - ongamepadaxismove - ongamepadbuttondown - ongamepadbuttonup - ongamepadconnected - ongamepaddisconnected - onget - onhashchange - onheadphoneschange - onheld - onhelp - onholding - onicccardlockerror - oniccinfochange - onincoming - oninput - oninvalid - onkeydown - onkeypress - onkeyup - onlevelchange - onload - onloadeddata - onloadedmetadata - onloadend - onloadstart - onlosecapture - only - onmark - onmessage - onmousedown - onmouseenter - onmouseleave - onmousemove - onmouseout - onmouseover - onmouseup - onmousewheel - onmove - onmoveend - onmovestart - onmozafterpaint - onmozaudioavailable - onmozbeforeresize - onmozedgeuicanceled - onmozedgeuicompleted - onmozedgeuistarted - onmozfullscreenchange - onmozfullscreenerror - onmozmagnifygesture - onmozmagnifygesturestart - onmozmagnifygestureupdate - onmozmousehittest - onmozmousepixelscroll - onmoznetworkdownload - onmoznetworkupload - onmozorientationchange - onmozpointerlockchange - onmozpointerlockerror - onmozpresstapgesture - onmozrotategesture - onmozrotategesturestart - onmozrotategestureupdate - onmozscrolledareachanged - onmozswipegesture - onmozswipegestureend - onmozswipegesturestart - onmozswipegestureupdate - onmoztapgesture - onmoztimechange - onnomatch - onnoupdate - onobsolete - onoffline - ononline - onopen - onoverflow - onoverflowchanged - onpagehide - onpageshow - onpaint - onpaste - onpause - onplay - onplaying - onpointerdown - onpointerenter - onpointerleave - onpointermove - onpointerout - onpointerover - onpointerrawupdate - onpointerup - onpopstate - onpopuphidden - onpopuphiding - onpopupshowing - onpopupshown - onprogress - onpropertychange - onratechange - onreadystatechange - onreceived - onremovetrack - onrepeat - onrepeatEvent - onrequest - onreset - onresize - onresult - onresume - onresuming - onretrieving - onrowenter - onrowexit - onrowsdelete - onrowsinserted - onscroll - onscrollend - onsearch - onseekcomplete - onseeked - onseeking - onselect - onselectionchange - onselectstart - onsending - onsent - onset - onshow - onsoundend - onsoundstart - onspeechend - onspeechstart - onstalled - onstart - onstatechange - onstatuschanged - onstkcommand - onstksessionend - onstop - onsubmit - onsuccess - onsuspend - onsvgabort - onsvgerror - onsvgload - onsvgresize - onsvgscroll - onsvgunload - onsvgzoom - ontext - ontimeout - ontimeupdate - ontoggle - ontouchcancel - ontouchend - ontouchenter - ontouchleave - ontouchmove - ontouchstart - ontransitioncancel - ontransitionend - ontransitionrun - ontransitionstart - onunderflow - onunhandledrejection - onunload - onupdateready - onupgradeneeded - onuserproximity - onussdreceived - onversionchange - onvoicechange - onvolumechange - onwaiting - onwarning - onwebkitanimationend - onwebkitanimationiteration - onwebkitanimationstart - onwebkittransitionend - onwheel - onzoom - ping - src - style - ##!=< html-properties -##!< - -##!> assemble - [\s\x08]*?= - ##!=< html-properties-end -##!< - -##!> assemble - ##!=> html-tag-prefix - ##!=> dangerous-html-tags -##!< - -##!> assemble - ##!=> html-properties-prefix - ##!=> html-properties - ##!=> html-properties-end -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941210.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941210.ra deleted file mode 100644 index 46f9bc667..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941210.ra +++ /dev/null @@ -1,231 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This rule tries to match all the possible ways to write 'javascript' using -##! html entities, and javascript escape sequences. -##! See https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references for examples. -##! And https://www.w3schools.com/charsets/ref_html_ascii.asp for the list of -##! all the possible html entities. - -##!+ i - -##! Matched order is sequential: we first match 'j', then 'a', then 'v', etc. - -##!> define html_entity_hex_prefix �* -##!> define html_entity_dec_prefix �* -##!> define whitespaces [\t\n\r] - -##! html_encoded_whitespace is a list of all the possible ways to write an encoded whitespace -##!> assemble - ##! canonical form - {{whitespaces}} - ##! alternative forms - ##!> assemble - ##! 09 horizontal tab - ##! 10 line feed - ##! 13 carriage return - ##! 0A line feed (hex) - ##! 0D carriage return (hex) - {{html_entity_dec_prefix}}9;? - {{html_entity_dec_prefix}}10;? - {{html_entity_dec_prefix}}13;? - {{html_entity_hex_prefix}}A;? - {{html_entity_hex_prefix}}D;? - &tab; - &newline; - ##!=> - ##!< - ##!=> - * - ##!=< html_encoded_whitespace -##!< - -##! all the possible ways to end the word 'javascript', plus whitespaces -##!> assemble - ##! canonical form - : - ##! alternative forms - ##!> assemble - ##! 58 : colon - ##! 3A : colon (hex) - {{html_entity_dec_prefix}}58;? - {{html_entity_hex_prefix}}3A;? - : - ##!< - ##!=> - . - ##!=< end_javascript -##!< - -##! all the possible ways to write 'j', plus whitespaces -##! canonical form -j -##! alternative forms -##!> assemble - ##! J 74 uppercase J - ##! j 106 lowercase j - ##! J 4A uppercase J (hex) - ##! j 6A lowercase j (hex) - {{html_entity_dec_prefix}}74; - {{html_entity_dec_prefix}}106; - {{html_entity_hex_prefix}}4A; - {{html_entity_hex_prefix}}6A; -##!< -##!=> -##!=> html_encoded_whitespace - -##! all the possible ways to write 'a', plus whitespaces -##!> assemble - ##! canonical form - a - ##! alternative forms - ##!> assemble - ##! A 65 uppercase A - ##! a 97 lowercase a - ##! A 41 uppercase A (hex) - ##! a 61 lowercase a (hex) - {{html_entity_dec_prefix}}65; - {{html_entity_dec_prefix}}97; - {{html_entity_hex_prefix}}41; - {{html_entity_hex_prefix}}61; - ##!< - ##!=> - ##!=> html_encoded_whitespace - ##!=< all_possible_ways_to_write_a -##!< - -##!=> all_possible_ways_to_write_a - -##! all the possible ways to write 'v', plus whitespaces -##! canonical form -v -##! alternative forms -##!> assemble - ##! V 86 uppercase V - ##! V 56 uppercase V (hex) - ##! v 118 lowercase v - ##! v 76 lowercase v (hex) - {{html_entity_dec_prefix}}86; - {{html_entity_hex_prefix}}56; - {{html_entity_dec_prefix}}118; - {{html_entity_hex_prefix}}76; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> all_possible_ways_to_write_a - -##! all the possible ways to write 's', plus whitespaces -##! canonical form -s -##! alternative forms -##!> assemble - ##! s 115 lowercase s - ##! s 73 lowercase s (hex) - ##! S 83 uppercase S - ##! S 53 uppercase S (hex) - {{html_entity_dec_prefix}}115; - {{html_entity_hex_prefix}}73; - {{html_entity_dec_prefix}}83; - {{html_entity_hex_prefix}}53; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'c', plus whitespaces -##! canonical form -c -##! alternative forms -##!> assemble - ##! c 63 lowercase C (hex) - ##! c 99 lowercase c - ##! C 43 uppercase c (hex) - ##! C 67 uppercase C - {{html_entity_hex_prefix}}63; - {{html_entity_dec_prefix}}99; - {{html_entity_hex_prefix}}43; - {{html_entity_dec_prefix}}67; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'r', plus whitespaces -##! canonical form -r -##! alternative forms -##!> assemble - ##! r 72 lowercase R (hex) - ##! r 114 lowercase r - ##! r 52 uppercase r (hex) - ##! R 82 uppercase R - {{html_entity_hex_prefix}}72; - {{html_entity_dec_prefix}}114; - {{html_entity_hex_prefix}}52; - {{html_entity_dec_prefix}}82; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'i', plus whitespaces -##! canonical form -i -##! alternative forms -##!> assemble - ##! i 69 lowercase i (hex) - ##! i 105 lowercase i - ##! I 49 uppercase i (hex) - ##! I 73 uppercase I - {{html_entity_hex_prefix}}69; - {{html_entity_dec_prefix}}105; - {{html_entity_hex_prefix}}49; - {{html_entity_dec_prefix}}73; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'p', plus whitespaces -##! canonical form -p -##! alternative forms -##!> assemble - ##! p 70 lowercase p (hex) - ##! p 112 lowercase p - ##! P 50 uppercase p (hex) - ##! P 80 uppercase P - {{html_entity_hex_prefix}}70; - {{html_entity_dec_prefix}}112; - {{html_entity_hex_prefix}}50; - {{html_entity_dec_prefix}}80; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 't', plus whitespaces -##! canonical form -t -##! alternative forms -##!> assemble - ##! t 74 lowercase t (hex) - ##! t 116 lowercase t - ##! T 54 uppercase t (hex) - ##! T 84 uppercase T - {{html_entity_hex_prefix}}74; - {{html_entity_dec_prefix}}116; - {{html_entity_hex_prefix}}54; - {{html_entity_dec_prefix}}84; -##!< -##!=> -##!=> html_encoded_whitespace -##!=> - -##!=> end_javascript diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941220.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941220.ra deleted file mode 100644 index 36975fc18..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941220.ra +++ /dev/null @@ -1,212 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This rule tries to match all the possible ways to write 'vbscript' using -##! html entities, and javascript escape sequences. -##! See https://html.spec.whatwg.org/multipage/named-characters.html#named-character-references for examples. -##! And https://www.w3schools.com/charsets/ref_html_ascii.asp for the list of -##! all the possible html entities. - -##!+ i - -##! Matched order is sequential: we first match 'v', then 'b', then 's', etc. - -##!> define html_entity_hex_prefix �* -##!> define html_entity_dec_prefix �* -##!> define whitespaces [\t\n\r] - -##! html_encoded_whitespace is a list of all the possible ways to write an encoded whitespace -##!> assemble - ##! canonical form - {{whitespaces}} - ##! alternative forms - ##!> assemble - ##! 09 horizontal tab - ##! 10 line feed - ##! 13 carriage return - ##! 0A line feed (hex) - ##! 0D carriage return (hex) - {{html_entity_dec_prefix}}9;? - {{html_entity_dec_prefix}}10;? - {{html_entity_dec_prefix}}13;? - {{html_entity_hex_prefix}}A;? - {{html_entity_hex_prefix}}D;? - &tab; - &newline; - ##!=> - ##!< - ##!=> - * - ##!=< html_encoded_whitespace -##!< - -##! all the possible ways to end the word 'vbscript', plus whitespaces -##!> assemble - ##! canonical form - : - ##! alternative forms - ##!> assemble - ##! 58 : colon - ##! 3A : colon (hex) - {{html_entity_dec_prefix}}58;? - {{html_entity_hex_prefix}}3A;? - : - ##!< - ##!=> - . - ##!=< end_vbscript -##!< - -##!=> -##! all the possible ways to write 'v', plus whitespaces -##! canonical form -v -##! alternative forms -##!> assemble - ##! v 118 lowercase v - ##! v 76 lowercase v (hex) - ##! V 86 uppercase V - ##! V 56 uppercase V (hex) - {{html_entity_dec_prefix}}118; - {{html_entity_hex_prefix}}76; - {{html_entity_dec_prefix}}86; - {{html_entity_hex_prefix}}56; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'b', plus whitespaces -##! canonical form -b -##! alternative forms -##!> assemble - ##! b 98 lowercase b - ##! b 62 lowercase b (hex) - ##! B 66 uppercase B - ##! B 42 uppercase B (hex) - {{html_entity_dec_prefix}}98; - {{html_entity_hex_prefix}}62; - {{html_entity_dec_prefix}}66; - {{html_entity_hex_prefix}}42; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 's', plus whitespaces -##! canonical form -s -##! alternative forms -##!> assemble - ##! s 115 lowercase s - ##! s 73 lowercase s (hex) - ##! S 83 uppercase S - ##! S 53 uppercase S (hex) - {{html_entity_dec_prefix}}115; - {{html_entity_hex_prefix}}73; - {{html_entity_dec_prefix}}83; - {{html_entity_hex_prefix}}53; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'c', plus whitespaces -##! canonical form -c -##! alternative forms -##!> assemble - ##! c 63 lowercase C (hex) - ##! c 99 lowercase c - ##! C 43 uppercase c (hex) - ##! C 67 uppercase C - {{html_entity_hex_prefix}}63; - {{html_entity_dec_prefix}}99; - {{html_entity_hex_prefix}}43; - {{html_entity_dec_prefix}}67; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'r', plus whitespaces -##! canonical form -r -##! alternative forms -##!> assemble - ##! r 72 lowercase R (hex) - ##! r 114 lowercase r - ##! r 52 uppercase r (hex) - ##! R 82 uppercase R - {{html_entity_hex_prefix}}72; - {{html_entity_dec_prefix}}114; - {{html_entity_hex_prefix}}52; - {{html_entity_dec_prefix}}82; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'i', plus whitespaces -##! canonical form -i -##! alternative forms -##!> assemble - ##! i 69 lowercase i (hex) - ##! i 105 lowercase i - ##! I 49 uppercase i (hex) - ##! I 73 uppercase I - {{html_entity_hex_prefix}}69; - {{html_entity_dec_prefix}}105; - {{html_entity_hex_prefix}}49; - {{html_entity_dec_prefix}}73; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 'p', plus whitespaces -##! canonical form -p -##! alternative forms -##!> assemble - ##! p 70 lowercase p (hex) - ##! p 112 lowercase p - ##! P 50 uppercase p (hex) - ##! P 80 uppercase P - {{html_entity_hex_prefix}}70; - {{html_entity_dec_prefix}}112; - {{html_entity_hex_prefix}}50; - {{html_entity_dec_prefix}}80; -##!< -##!=> -##!=> html_encoded_whitespace - -##!=> - -##! all the possible ways to write 't', plus whitespaces -##! canonical form -t -##! alternative forms -##!> assemble - ##! t 74 lowercase t (hex) - ##! t 116 lowercase t - ##! T 54 uppercase t (hex) - ##! T 84 uppercase T - {{html_entity_hex_prefix}}74; - {{html_entity_dec_prefix}}116; - {{html_entity_hex_prefix}}54; - {{html_entity_dec_prefix}}84; -##!< -##!=> -##!=> html_encoded_whitespace -##!=> - -##!=> end_vbscript diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941390.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941390.ra deleted file mode 100644 index 92288915a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/941390.ra +++ /dev/null @@ -1,16 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i -##!^ \b -##!$ \s*\( - -eval -settimeout -setinterval -new\s+Function -alert -atob -btoa -prompt -confirm diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942120.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942120.ra deleted file mode 100644 index f12014ed1..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942120.ra +++ /dev/null @@ -1,37 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -\!\= -\&\& -\|\| ->> -<< ->= -<= -<> -<=> -\bxor\b -\bregexp\b -regexp\s+binary -\bisnull\b -\brlike\b -rlike\s+binary -not\s+between\s+0\s+and -not\s+between\s+(?:(?:'[^']*')|(?:\"[^\"]*\"))\s+and\s+(?:(?:'[^']*')|(?:\"[^\"]*\")) -is\s+null -like\s+null -^in[+\s]*\([\s\d\"]+[^()]*\) -\Win[+\s]*\([\s\d\"]+[^()]*\) -<>\s+binary -\bcollate\W*?(?:U&)?[\"'`] -\bcollate\W+(?:binary|nocase|rtrim)\b -\bcollate\W+\w*?_ -\bnotnull\b -like\s+[\w]+\s+escape\b -\bilike\b -[<>=!]{1,2}\s*all\b -\blikelihood\s*\( -\bunlikely\s*\( -\blikely\s*\( diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942130.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942130.ra deleted file mode 100644 index 66beb373e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942130.ra +++ /dev/null @@ -1,42 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! General comments: -##! -##! The idea behind this expressions is to capture simple logic based (un)equalities that -##! are used to quickly test SQL Logic that always returns TRUE (hence the term "SQL Tautology"). - -##! We also want to capture the left and right side, and compare for equality. -##! That's why you see below that some of the patterns include grouping explicitly - -##! Prefix: captures the initial part that will be matched on the right hand side of the logical construct. - -##!^ [\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*? - -##! These expressions try to match the logic using the operator, -##! so when the operator targets a TRUE operation, the initial match -##! should be present after the operator, logically meaning TRUE -##! -##! Examples: -##! '1' = '1' -##! 'f' like 'f' - -##! This one will also match the "equal" part of '<=' and '>=' -=[\s'\"`()]*?\b([\d\w]+)\b - -##! <=> NULL-safe equal to operator in MySQL -<=>[\s'\"`()]*?\b([\d\w]+)\b - -##! Like queries allow you to use wilcards: '%' - -like[\s'\"`()]*?\b([\d\w]+)\b -sounds\s+like[\s'\"`()]*?\b([\d\w]+)\b - -##! GLOB operator is used to match text values against a pattern -glob[\s'\"`()]*?\b([\d\w]+)\b - -##! String based regexp. These don't use % as wildcard. -rlike[\s'\"`()]*?\b([\d\w]+)\b -regexp[\s'\"`()]*?\b([\d\w]+)\b diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942131.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942131.ra deleted file mode 100644 index d4ebdfd92..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942131.ra +++ /dev/null @@ -1,42 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - - -##! General comments: -##! -##! The idea behind this expressions is to capture simple logic based (un)equalities that -##! are used to quickly test SQL Logic that always returns FALSE. - -##! Prefix: captures the initial part that will be unmatched on the right hand side of the logical construct. - -##!^ [\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*? - -##!+ i - -##! These expressions try to match the logic using the negative operator, -##! so when the operator targets a false operation, the initial match -##! should *not* be present after the operator, effectively meaning TRUE. -##! -##! Examples: -##! '1' <= '2' -##! 'a' not like 'b' -##! -##! SQL Comparison Operators: !=, <=, >=, <>, <, >, !>, !<, ^ - -\!=[\s'\"`()]*?\b([\d\w]+)\b -<>[\s'\"`()]*?\b([\d\w]+)\b -<[\s'\"`()]*?\b([\d\w]+)\b -\!<[\s'\"`()]*?\b([\d\w]+)\b ->[\s'\"`()]*?\b([\d\w]+)\b -\!>[\s'\"`()]*?\b([\d\w]+)\b -<=[\s'\"`()]*?\b([\d\w]+)\b ->=[\s'\"`()]*?\b([\d\w]+)\b -\^[\s'\"`()]*?\b([\d\w]+)\b - -is\s+not[\s'\"`()]*?\b([\d\w]+)\b -not\s+like[\s'\"`()]*?\b([\d\w]+)\b - -##! String based regexp. - -not\s+rlike[\s'\"`()]*?\b([\d\w]+)\b -not\s+regexp[\s'\"`()]*?\b([\d\w]+)\b diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942150.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942150.ra deleted file mode 100644 index aaaf7ce8f..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942150.ra +++ /dev/null @@ -1,146 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i -##!^ \b -##!$ \W*\( - -##! SQLite specific functions -json -json_[\w]+ -##! Extracted from docs with: -##! paths=("lang_corefunc.html" "lang_mathfunc.html" "lang_aggfunc.html"); declare items; for path in "${paths[@]}"; do items+=$(curl https://www.sqlite.org/$path -s | xmllint --html --xpath "//a[contains(@href,'func.html')]/text()" - 2>/dev/null | grep --color=never -Po "^[\w]+(?=\()"); done; echo "$items" | sort | uniq -abs -acos -acosh -asin -asinh -atan -atan2 -atanh -ceil -ceiling -changes -char -coalesce -cos -cosh -count -degrees -exp -floor -flooravg -format -glob -group_concat -hex -ifnull -iif -instr -last_insert_rowid -length -like -likelihood -likely -ln -load_extension -log -log10 -log2 -lower -lowerpi -ltrim -max -min -mod -nullif -pi -pow -power -printf -quote -radians -random -randomblob -replace -round -rtrim -sign -sin -sinh -soundex -sqlite_compileoption_get -sqlite_compileoption_used -sqlite_offset -sqlite_source_id -sqlite_version -sqrt -substr -substring -sum -tan -tanh -total -total_changes -trim -trunc -typeof -unicode -unlikely -upper -zeroblob - -##! Generic SQL functions -##! -##! Note: May contain overlap with the generated DBMS specific lists, but this guarantees -##! A minimum level of protection, even if one of the one-liners creates an unusual set. -##! Duplicates do not effect the final result of regexp-assemble. -abs -acos -avg -bin -cast -count -date -day -default -field -floor -format -hour -char -charset -chr -if -in -last -length -ln -local -log -max -min -minute -mod -month -now -password -pi -power -repeat -replace -reverse -right -round -second -sign -sleep -sum -tan -time -upper -user -values -version -week -year diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942151.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942151.ra deleted file mode 100644 index 611a28a1e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942151.ra +++ /dev/null @@ -1,6 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> include sql-injection-function-names diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942152.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942152.ra deleted file mode 100644 index 611a28a1e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942152.ra +++ /dev/null @@ -1,6 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> include sql-injection-function-names diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942170.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942170.ra deleted file mode 100644 index 6a24a4849..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942170.ra +++ /dev/null @@ -1,25 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> define one_or_more_whitespace \s+ -##!> define select_or_terminate (?:select|;){{one_or_more_whitespace}} - -##!> assemble - - ##! benchmark may be used to time how quickly MySQL processes the expression - {{select_or_terminate}}benchmark - - ##! conditional select - {{select_or_terminate}}if - - ##! sleep function - {{select_or_terminate}}sleep - ##!=> - - ##! function parameters - \s*?\(\s*?\(?\s*?\w+ - - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942180.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942180.ra deleted file mode 100644 index d684e706d..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942180.ra +++ /dev/null @@ -1,62 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> define open-comment (?:/\*) -##!> define quotes [\"'`] -##!> define quotes-plus-digits [\d\"'`] -##!> define comment-suffix (?:--|#|{{open-comment}}|\{) -##! PB: Should comment-suffix also include "\*/" ? - -##!> define logical-operators or|xor|and -##!> define math-operators div -##!> define comparison-operators like|between -##!> define math-symbols [+<>=(),-] - -{{open-comment}}+{{quotes}}+\s?{{comment-suffix}}? - -##!> assemble - {{quotes}}\s* - ##!=> - ##! logical operators - or - xor - and - - ##! math operators - div - - ##! comparison operators - like - between - ##!=> - [\w\s-]+{{math-symbols}}\s*{{quotes-plus-digits}} - ##!=> -##!< - - -##!> assemble - {{quotes}} - ##!=> - [<>~]+ - \s*[^\w\s]?=\s* - \W*?[+=]+\W*? - ##!=> - {{quotes}} -##!< - -##!> assemble - {{quotes}} - ##!=> - \s*[!=|][\d\s!=+-]+.*?[\"'`(].*?$ - \s*[!=|][\d\s!=]+.*?\d+$ - \s*(?:like|print)\W+[\w\"'`(] - \s*; -##!< - -\d{{quotes}}\s+{{quotes}}\s+\d -^admin\s*?{{quotes}} -[\"'`\(\s]\s*?glob\W+[\w\"'`(] -\sis\s*?0\W -where\s[\s\w\.,-]+\s= diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942190.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942190.ra deleted file mode 100644 index 9353b13d6..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942190.ra +++ /dev/null @@ -1,61 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> define quotes [\"'`] - -##!> assemble - {{quotes}} - ##!=> - \s*!\s*[\"'`\w] - ##!> assemble - ;?\s* - ##!=> - having - select - ##!> assemble - union\b\s* - ##!=> - all - distinct - select - ##!< - ##!=> - \b\s*[^\s] - ##!< -##!< - -##!> assemble - \b - ##!=> - ##!> assemble - connection_id - current_user - database - schema - user - ##!=> - \s*?\( - ##!< - - exec\s+master\. - execute\s+master\. - from\W+information_schema\W - ##!> assemble - into[\s+]+ - ##!=> - dumpfile - outfile - ##!=> - \s*?{{quotes}} - ##!< - - select.*?\w?user\( - union\sselect\s@ - union[\w(\s]*?select -##!< - -\s*?exec.*?\Wxp_cmdshell -\s*?execute.*?\Wxp_cmdshell -\Wiif\s*?\( diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942200.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942200.ra deleted file mode 100644 index 0d0c35dd2..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942200.ra +++ /dev/null @@ -1,40 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! Helpers -##!> define punctuation-hexnumbers ,.*?[)\da-f\"'`] - -##!> define ticks [\"'`] - -##!> define spaces \s*?\(\s*?space\s*?\( - -##! Main assembly -##!> assemble - {{punctuation-hexnumbers}}{{ticks}} - ##!=> - {{ticks}}.*?{{ticks}} - (?:\r?\n)?\z - [^\"'`]+ - ##!=> -##!< - -\Wselect.+\W*?from - -##!> assemble - alter - create - delete - desc - drop - insert - load - rename - select - truncate - update - ##!=> - {{spaces}} - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942210.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942210.ra deleted file mode 100644 index dfad32663..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942210.ra +++ /dev/null @@ -1,109 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! Looking for patterns like: -##! between[\s(]+\w+[\s)]*?[!=+]+[\s\d]*?[\"'`=()] - -##!> assemble - && - \|\| - and - between - div - like - nand - not - or - xor - xxor - ##!=> - - [\s(]+\w+[\s)]*?[!=+]+[\s\d]*?[\"'`=()] -##!< - - -##! Looking for patterns like: -##! \d\s*?between\s*?\d+\s*?[\-+] - -##!> assemble - \d\s*? - ##!=> - - and - between - div - like - or - xor - ##!=> - - \s*?\d+\s*?[\-+] -##!< - -##! Looking for a variation of the pattern above: -\d\s+group\s+by.+\( - - -##! Looking for patterns like: -##! \/\w+;?\s+between\W - -##!> assemble - \/\w+;?\s+ - ##!=> - - and - between - div - having - like - or - select - xor - ##!=> - - \W -##!< - - -##! Looking for patterns like: -##! ;\s*?drop -##! #\s*?alter -##! --\s*?drop - -##!> assemble - ;\s*? - #\s*? - --\s*? - ##!=> - - alter - drop - ##!=> -##!< - - -##! Looking for patterns like: -##! ;\s*?update\s*?\w{2,} -##! #\s*?insert\s*?\w{2,} -##! --\s*?update\s*?\w{2,} - -##!> assemble - ;\s*? - #\s*? - --\s*? - ##!=> - - insert - update - ##!=> - - \s*?\w{2,} - ##!=> -##!< - - -##! Looking for these unique patterns: -@.+=\s*?\(\s*?select -[^\w]SET\s*?@\w+ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942230.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942230.ra deleted file mode 100644 index 7c0dafd04..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942230.ra +++ /dev/null @@ -1,9 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -[\s()]case\s+when.*?then -\)\s*?like\s*?\( -select.*?having\s*?[^\s]+\s*?[^\w\s] -if\s?\(\w+\s*?[=<>~] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942240.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942240.ra deleted file mode 100644 index fd42ddd10..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942240.ra +++ /dev/null @@ -1,32 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! Helpers -##!> define alter alter\s*?\w+.*? - -##!> define set \s+set\s+\w+ - -##!> define ticks [\"'`] - -##!> define waitfor \s*?waitfor\s+ - -##! Main assembly -##!> assemble - {{alter}} - ##!=> - char - character - ##!=> - {{set}} -##!< - -##!> assemble - {{ticks}} - ##!=> - ;*?{{waitfor}}time\s+[\"'`] - ;*?{{waitfor}}delay\s+[\"'`] - ;.*?:\s*?goto - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942260.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942260.ra deleted file mode 100644 index 10fa4766d..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942260.ra +++ /dev/null @@ -1,31 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> define quotes [\"'`] - - -##!> assemble - {{quotes}}\s*? - ##!=> - and - nand - or - xor - xxor - div - like - between - not - \|\| - && - ##!=> - \s+[\s\w]+=\s*?\w+\s*?having\s+ - ##!=> -##!< - -\w\s+like\s+{{quotes}} -like\s*?{{quotes}}\% -{{quotes}}\s*?like\W*?[\"'`\d] -select\s+?[\[\]()\s\w\.,\"'`-]+from\s+ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942280.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942280.ra deleted file mode 100644 index 0d07e85b7..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942280.ra +++ /dev/null @@ -1,20 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> define optional_whitespace \s*? - -##! The following part is going to be appended -##! to match the end of a query or a comment syntax -##!> define terminators (?:[#;{]|\/\*|--) - -##! In PostgreSQL, you can use the pg_sleep() function -##! to delay execution for a given number of seconds -select{{optional_whitespace}}pg_sleep - -##! WAITFOR DELAY blocks the execution until a time interval elapses -waitfor{{optional_whitespace}}delay\s?[\"'`]+\s?\d - -##! SHUTDOWN immediately stops SQL Server -;{{optional_whitespace}}shutdown{{optional_whitespace}}{{terminators}} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942290.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942290.ra deleted file mode 100644 index 2966c2ee7..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942290.ra +++ /dev/null @@ -1,41 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> define operator_syntax_start \[?\$ -##!> define operator_syntax_end \]? - -##!> assemble - {{operator_syntax_start}} - ##!=> - ne - eq - lt - lte - ni - nin - mod - all - size - exists - type - slice - or - xor - nor - div - like - between - and - nor - not - regex - text - where - jsonSchema - elemMatch - ##!=> - {{operator_syntax_end}} - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942300.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942300.ra deleted file mode 100644 index bf4275210..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942300.ra +++ /dev/null @@ -1,60 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> define required-spaces-plus-sql-function-call \s+\w+\( -##!> define quotes [\"'`] -##!> define start-comment \/\*! -##!> define lazy-optional-spaces \s*? -##!> define lazy-optional-spaces-with-numbers {{lazy-optional-spaces}}\d+{{lazy-optional-spaces}} -##!> define lazy-optional-spaces-numeric-function-call {{lazy-optional-spaces}}\({{lazy-optional-spaces}}\d -##!> define lazy-optional-spaces-plus-sql-function-call {{lazy-optional-spaces}}\w+\( - -\){{lazy-optional-spaces}}when{{lazy-optional-spaces-with-numbers}}then - -##!> assemble - {{quotes}}{{lazy-optional-spaces}} - ##!=> - # - -- - { -##!< - -{{start-comment}}\s?\d+ - -##!> assemble - \b - ##!=> - - ##!> assemble - binary - char - chr - ##!=> - {{lazy-optional-spaces-numeric-function-call}} - ##!< - - ##!> assemble - and - nand - or - xor - xxor - div - like - between - not - regexp - rlike - ##!=> - {{required-spaces-plus-sql-function-call}} - ##!< -##!< - -##!> assemble - \|\| - && - ##!=> - {{lazy-optional-spaces-plus-sql-function-call}} -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942320.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942320.ra deleted file mode 100644 index c19b5fa7d..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942320.ra +++ /dev/null @@ -1,6 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> include sql-injection-mysql-postgresql-procedures-functions.ra diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942321.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942321.ra deleted file mode 100644 index c19b5fa7d..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942321.ra +++ /dev/null @@ -1,6 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##!> include sql-injection-mysql-postgresql-procedures-functions.ra diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942330.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942330.ra deleted file mode 100644 index f1e2ec9df..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942330.ra +++ /dev/null @@ -1,51 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -[\"'`]\s*?\bor\b\s*?[\"'`]?\d -[\"'`]\s*?\bxor\b\s*?[\"'`]?\d -[\"'`]\s*?\bdiv\b\s*?[\"'`]?\d -[\"'`]\s*?\blike\b\s*?[\"'`]?\d -[\"'`]\s*?\bbetween\b\s*?[\"'`]?\d -[\"'`]\s*?\band\b\s*?[\"'`]?\d -\x5cx(?:23|27|3d) -^.?[\"'`]$ -^[\"'`\x5c]*?[\d\"'`]+\s*?\band\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\bnand\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\bor\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\bxor\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\bxxor\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\bdiv\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\blike\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\bbetween\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\bnot\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\b\|\|\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[\d\"'`]+\s*?\b\&\&\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\band\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\bnand\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\bor\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\bxor\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\bxxor\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\bdiv\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\blike\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\bbetween\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\bnot\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\b\|\|\b\s*?[\w\"'`][+&!@(),.-] -^[\"'`\x5c]*?[^\"'`]+[\"'`]\s*?\b\&\&\b\s*?[\w\"'`][+&!@(),.-] -[^\w\s]\w+\s*?[|-]\s*?[\"'`]\s*?\w -@\w+\s+and\b\s*?[\"'`\d]+ -@\w+\s+or\b\s*?[\"'`\d]+ -@\w+\s+xor\b\s*?[\"'`\d]+ -@\w+\s+div\b\s*?[\"'`\d]+ -@\w+\s+like\b\s*?[\"'`\d]+ -@\w+\s+between\b\s*?[\"'`\d]+ -@[\w-]+\sand\b\s*?[^\w\s] -@[\w-]+\sor\b\s*?[^\w\s] -@[\w-]+\sxor\b\s*?[^\w\s] -@[\w-]+\sdiv\b\s*?[^\w\s] -@[\w-]+\slike\b\s*?[^\w\s] -@[\w-]+\sbetween\b\s*?[^\w\s] -[^\w\s:]\s*?\d\W+[^\w\s]\s*?[\"'`]. -\Winformation_schema -table_name\W diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942340.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942340.ra deleted file mode 100644 index 385bd8443..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942340.ra +++ /dev/null @@ -1,28 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -in\s*?\(+\s*?select -(?i:(?:n?and|x?x?or|div|like|between|not)\s+|(?:\|\||\&\&)\s*)[\s\w+]+regexp\s*?\( -(?i:(?:n?and|x?x?or|div|like|between|not)\s+|(?:\|\||\&\&)\s*)[\s\w+]+sounds\s+like\s*?[\"'`] -(?i:(?:n?and|x?x?or|div|like|between|not)\s+|(?:\|\||\&\&)\s*)[\s\w+]+[=\d]+x -[\"'`]\s*?\d\s*?-- -[\"'`]\s*?\d\s*?# -[\"'`][\%&<>^=]+\d\s*?= -[\"'`][\%&<>^=]+\d\s*?or -[\"'`][\%&<>^=]+\d\s*?xor -[\"'`][\%&<>^=]+\d\s*?div -[\"'`][\%&<>^=]+\d\s*?like -[\"'`][\%&<>^=]+\d\s*?between -[\"'`][\%&<>^=]+\d\s*?and -[\"'`]\W+[\w+-]+\s*?=\s*?\d\W+[\"'`] -[\"'`]\s*?is\s*?\d.+[\"'`]?\w -[\"'`]\|?[\w-]{3,}[^\w\s.,]+[\"'`] -[\"'`]\s*?is\s*?[\d.]+\s*?\W.*?[\"'`] -\bexcept\s+select\b -\bexcept\s+values\s*?\( -[\"'`]\s*(?i:(?:n?and|x?x?or|div|like|between|not)\s+|(?:\|\||\&\&)\s*)array\s*\[ -[\"'`]\s*(?i:(?:n?and|x?x?or|div|like|between|not)\s+|(?:\|\||\&\&)\s*)[\w]+\s*!?~ -[\"'`]\s*(?i:(?:n?and|x?x?or|div|like|between|not)\s+|(?:\|\||\&\&)\s*)[\w]+\s+(?:not\s+)?similar\s+to\s+ -[\"'`]\s*(?i:(?:n?and|x?x?or|div|like|between|not)\s+|(?:\|\||\&\&)\s*)(?:true|false)\b diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942350.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942350.ra deleted file mode 100644 index 170fbd397..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942350.ra +++ /dev/null @@ -1,30 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -create\s+function\s.+\sreturns - -##!> assemble - - ##! matching the injection start - ;\s*? - - ##!=> - alter - create - delete - desc - drop - insert - load - rename - select - truncate - update - ##!=> - - ##! matching function/object parameters syntax - \b\s*?[\[(]?\w{2,} - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942362.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942362.ra deleted file mode 100644 index f0461e333..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942362.ra +++ /dev/null @@ -1,171 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! Helpers - -##!> define nonword_number ^[\W\d]+\s*? - -##!> define cmd_alter alter -##!> define cmd_create create -##!> define cmd_delete delete -##!> define cmd_desc desc -##!> define cmd_insert insert -##!> define cmd_load load -##!> define cmd_rename rename -##!> define cmd_select select -##!> define cmd_truncate truncate -##!> define cmd_update update -##!> define cmd_drop drop -##!> define cmd_union union - -##!> define seq_char \s+char\s?\(? -##!> define seq_group_concat \s+group_concat\s?\(? -##!> define seq_load_file \s+load_file\s?\(? - -##! Main assembly -##!> assemble - ##!> assemble - {{cmd_alter}} - {{cmd_create}} - {{cmd_delete}} - {{cmd_desc}} - {{cmd_insert}} - {{cmd_load}} - {{cmd_rename}} - {{cmd_select}} - {{cmd_truncate}} - {{cmd_update}} - ##!=> - {{seq_char}} - {{seq_group_concat}} - {{seq_load_file}} - ##!< - - end\s*?\); - [\s(]load_file\s*?\( - [\"'`]\s+regexp\W - [\d\W]\s+as\b\s*[\"'`\w]+\s*\bfrom - - ##!> assemble - {{nonword_number}} - ##!=> - {{cmd_create}}\s+\w+ - {{cmd_delete}}\b - {{cmd_desc}}\b - {{cmd_drop}}\b - {{cmd_insert}}\b - {{cmd_load}}\b - {{cmd_rename}}\b - {{cmd_select}}\b - {{cmd_truncate}}\b - {{cmd_update}}\b - ##!> assemble - {{cmd_alter}}\s* - ##!=> - aggregate - application\s*role - assembly - asymmetric\s*key - audit - authorization - availability\s*group - broker\s*priority - bufferpool - certificate - cluster - collation - column - conversion - credential - cryptographic\s*provider - database - default - dimension - diskgroup - domain - endpoint - extension - external - event - flashback - foreign - fulltext - function - hierarchy - group - histogram - index - indextype - inmemory - instance - java - language - large - library - lockdown - logfile\s*group - login - mask - master\s*key - materialized - message\s*type - method - module - nickname - operator - outline - package - partition - permission - procedure - profile - queue - remote - resource - role - rollback - route - schema - search - security - server - service - sequence - session - symmetric\s*key - synonym - stogroup - table - tablespace - text - threshold - trigger - trusted - type - usage - user - view - work - workload - wrapper - xml\s*schema - xsrobject - ##!=> - \b - ##!=> - ##!< - - ##!> assemble - {{cmd_union}}\s* - ##!=> - all - select - distinct - ##!=> - \b - ##!=> - ##!< - ##!< -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942370.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942370.ra deleted file mode 100644 index e8253dc4e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942370.ra +++ /dev/null @@ -1,51 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! Helpers -##!> define quotes [\"'`] - -##!> assemble - or - xor - div - like - between - and - ##!=< operators -##!< - -##! Main assembly -##!> assemble - {{quotes}}\s*? - ##!=> - ##!> assemble - \*.+ - ##!=> - ##!> assemble - ##!> assemble - ##!=> operators - ##!< - id - ##!=> - ##!< - ##!=> - \W*?{{quotes}}\d - ##!=> - ##!< - [^\w\s?]+\s*?[^\w\s]+\s*?{{quotes}} - [^\w\s]+\s*?[\W\d].*?# - [^\w\s]+\s*?[\W\d].*?-- - ##!> assemble - ##!> assemble - ##!=> operators - ##!< - ##!=> - \s[^\d]+[\w-]+.*?\d - ##!< -##!< - -\^{{quotes}} -{{quotes}}.*?\*\s*?\d -[()\*<>%+-][\w-]+[^\w\s]+{{quotes}}[^,] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942380.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942380.ra deleted file mode 100644 index 7c435bce6..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942380.ra +++ /dev/null @@ -1,25 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -\bhaving\b\s+\d{1,10}\s*?[=<>] -\bhaving\b\s+'[^=]{1,10}'\s*?[=<>] -\bexecute\( -\bexecute\s{1,5}[\w\.$]{1,5}\s{0,3} -\bhaving\b ?\d{1,10} ?[=<>]+ -\bhaving\b ?[\'\"][^=]{1,10}[\'\" ?[=<>]+ -\bcreate\s+?table.{0,20}?\( -\blike\W*?char\W*?\( -select.*?case -from.*?limit -order\sby -exists\s\sselect -exists\sselect\Sif\s\( -exists\sselect\Sifnull\s\( -exists\sselect\Stop -exists\sselect\Sconcat -exists\ssystem\s\( -exists\s\bhaving\b\s+\d{1,10} -exists\s'[^=]{1,10}' -\bexists\s*?\(\s*?select\b diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942390.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942390.ra deleted file mode 100644 index b13dab49f..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942390.ra +++ /dev/null @@ -1,17 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -\bor\b\s?\d{1,10}\s?[=<>]+ -\bor\b\s?[\'\"][^=]{1,10}[\'\"]\s?[=<>]+ -'\s+or\s+.{1,20}[+\-!<>=] -'\s+xor\s+.{1,20}[+\-!<>=] -\bor\b\s+\d{1,10} -\bor\b\s+'[^=]{1,10}' -\bxor\b\s+\d{1,10} -\bxor\b\s+'[^=]{1,10}' -\bor\b\s+\d{1,10}\s*?[=<>] -\bxor\b\s+\d{1,10}\s*?[=<>] -\bor\b\s+'[^=]{1,10}'\s*?[=<>] -\bxor\b\s+'[^=]{1,10}'\s*?[=<>] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942440-chain1.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942440-chain1.ra deleted file mode 100644 index 1592b5b1b..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942440-chain1.ra +++ /dev/null @@ -1,25 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This chained rule is used to match on JWT base64-urlencoded tokens. -##! See https://www.rfc-editor.org/rfc/rfc4648#section-5 for details. - -##! JWTs consist of base64-urlencoded encoded JSON, and a JSON structure -##! just starts with '{"', which becomes 'ey' when encoded with a base64-urlencoded encoder. - -##!> define base64-urlencoded-charset [a-zA-Z0-9_-]+ -##!> define dot [.] - -##!^ ^ey - -{{base64-urlencoded-charset}} - -##!=> - -{{dot}}ey{{base64-urlencoded-charset}} - -##!=> - -{{dot}}{{base64-urlencoded-charset}} - -##!$ $ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942440.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942440.ra deleted file mode 100644 index 4d790510a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942440.ra +++ /dev/null @@ -1,10 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -/\*!? -\*/ -[';]-- ---\s ---[^-]*?- -[^&-]#.*?\s -;?\x00 diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942500.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942500.ra deleted file mode 100644 index 99a142dcd..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942500.ra +++ /dev/null @@ -1,9 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!> define comment-contents (?:[\w\s=_\-()]+) -##!> define c-style-modifiers \s*?[!+] - -##!+ i - -/\*{{c-style-modifiers}}{{comment-contents}}?\*/ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942520.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942520.ra deleted file mode 100644 index 05ae95b3b..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942520.ra +++ /dev/null @@ -1,18 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - - -##!^ [\"'`]\s*? - -##! All tests below are prefixed with [\"'`]\s*? - -is\s+not\b -##! all sqlite not smth from https://www.sqlite.org/lang_expr.html -not\s+(?:like|glob|between|null|in|regexp|match)\b -##! sql operators -[|&<>*\/%=^+-] -##! common operators that can't be added to 942120.data -(?:mod|div)\b -sounds\s+like\b diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942521.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942521.ra deleted file mode 100644 index de2ab1961..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942521.ra +++ /dev/null @@ -1,10 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!^ ^ -##!+ i - -##! Regex for detecting first word after an odd number of quotes -[^']*?(?:'[^']*?'[^']*?)*?'\s*(\w+)\b -[^\"]*?(?:\"[^\"]*?\"[^\"]*?)*?\"\s*(\w+)\b -[^`]*?(?:`[^`]*?`[^`]*?)*?`\s*(\w+)\b diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942540.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942540.ra deleted file mode 100644 index 248fdfcc6..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942540.ra +++ /dev/null @@ -1,8 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! These expressions look for an ending '; pattern, but won't match if the quotes -##! are balanced. -^[^']*'\s*; -^[^"]*"\s*; -^[^`]*`\s*; diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942550.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942550.ra deleted file mode 100644 index bf65e63cf..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942550.ra +++ /dev/null @@ -1,30 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Referring to https://claroty.com/team82/research/js-on-security-off-abusing-json-based-sql-to-bypass-waf -##! this rule tries to match the following payloads: -##! -##! PostgreSQL: '{"b":2}'::jsonb <@ '{"a":1, "b":2}'::jsonb -##! PostgreSQL: '{"b":2}'::jsonb @> '{"a":1, "b":2}'::jsonb -##! PostgreSQL: '{"b":2}'::jsonb @ '{"a":1, "b":2}'::jsonb -##! PostgreSQL: '{"b":2}'::jsonb < '{"a":1, "b":2}'::jsonb -##! PostgreSQL: '{"b":2}'::jsonb > '{"a":1, "b":2}'::jsonb -##! SQLite: '{"a":2,"c":[4,5,{"f":7}]}' -> '$.c[2].f' = 7 -##! SQLite: '{"a":2,"c":[4,5,{"f":7}]}' <- '$.c[2].f' = 7 -##! SQLite: '{"a":2,"c":[4,5,{"f":7}]}' < '$.c[2].f' = 7 -##! SQLite: '{"a":2,"c":[4,5,{"f":7}]}' > '$.c[2].f' = 7 -##! MySQL: JSON_EXTRACT('{"id": 14, "name": "Aztalan"}', '$.name') = 'Aztalan' - -##!> define quotes [\"'`] -##!> define operators (?:@>|<@|\?|\?\||\?&|#>|#>>|->>|<|>|->|<-) -##!> define json_ending_brackets [\]\}] -##!> define json_starting_brackets [\[\{] - -##!> assemble - ##! https://regex101.com/r/mzG5Fg/1 - {{quotes}}{{json_starting_brackets}}.*{{json_ending_brackets}}{{quotes}}.*(::.*jsonb?)?.*{{operators}} - {{operators}}{{quotes}}{{json_starting_brackets}}.*{{json_ending_brackets}}{{quotes}} - - ##! example: SELECT id FROM users WHERE id=JsoN_EXTraCT/**/(/**/' {"a":1} '/**/,/**/' $.a '/**/); - json_extract.*\(.*\) -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942560.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942560.ra deleted file mode 100644 index cb40cfa9e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/942560.ra +++ /dev/null @@ -1,8 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -1\.e, -1\.e\( -1\.e\) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944150.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944150.ra deleted file mode 100644 index 523aebf5a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944150.ra +++ /dev/null @@ -1,23 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The following is an expansion of -##! (?:\${[^}]{0,15}\${|\${(?:jndi|ctx)) -##! where every character also matches the equivalent named HTML entity. -##! It is a workaround for the shortcomings of `htmlEntityDecode`, which -##! handles numerical HTML entities well but only handles 5 named -##! entities. The official list of named entities can be found here: -##! https://html.spec.whatwg.org/multipage/named-characters.html. -##! -##! Note: -##! - We don't match `}` or `}` because it would enable more -##! evasions while also increasing the number of potential false positives. -##! The risk of false negatives in this case is acceptable. -##! - Omitting the terminating semi-colon can be used as an evasion with lenient -##! parsers. We catch those by making the semi-colon optional. - - -##!+ i - -(?:\$|$?)(?:\{|&(?:lbrace|lcub);?)[^}]{0,15}(?:\$|$?)(?:\{|&(?:lbrace|lcub);?) -(?:\$|$?)(?:\{|&(?:lbrace|lcub);?)(?:jndi|ctx) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944151.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944151.ra deleted file mode 100644 index a8174bacd..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944151.ra +++ /dev/null @@ -1,22 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The following is an expansion of -##! (?:\$\{[^}]*\$\{|\$\{(?:jndi|ctx)) -##! where every character also matches the equivalent named HTML entity. -##! It is a workaround for the shortcomings of `htmlEntityDecode`, which -##! handles numerical HTML entities well but only handles 5 named -##! entities. The official list of named entities can be found here: -##! https://html.spec.whatwg.org/multipage/named-characters.html. -##! -##! Note: -##! - We don't match `}` or `}` because it would enable more -##! evasions while also increasing the number of potential false positives. -##! The risk of false negatives in this case is acceptable. -##! - Omitting the terminating semi-colon can be used as an evasion with lenient -##! parsers. We catch those by making the semi-colon optional. - -##!+ i - -(?:\$|$?)(?:\{|&(?:lbrace|lcub);?)[^}]*(?:\$|$?)(?:\{|&(?:lbrace|lcub);?) -(?:\$|$?)(?:\{|&(?:lbrace|lcub);?)(?:jndi|ctx) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944152.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944152.ra deleted file mode 100644 index 158445dec..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/944152.ra +++ /dev/null @@ -1,18 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The following is an expansion of -##! (?:\${[^}]{0,15}\${|\${(?:jndi|ctx)) -##! where every character also matches the equivalent named HTML entity. -##! It is a workaround for the shortcomings of `htmlEntityDecode`, which -##! handles numerical HTML entities well but only handles 5 named -##! entities. The official list of named entities can be found here: -##! https://html.spec.whatwg.org/multipage/named-characters.html. -##! -##! - Omitting the terminating semi-colon can be used as an evasion with lenient -##! parsers. We catch those by making the semi-colon optional. - - -##!+ i - -(?:\$|$?)(?:\{|&(?:lbrace|lcub);?) diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951120.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951120.ra deleted file mode 100644 index 12e5214d0..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951120.ra +++ /dev/null @@ -1,17 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -##! ORA-04021: timeout occurred while waiting to lock object SYS.: oci_connect(): ... -Warning.{1,10}oci_.{1,30} -##! Warning: ora_logon(): ... -Warning.{1,10}ora_.{1,20} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951230.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951230.ra deleted file mode 100644 index a96b6f9cc..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951230.ra +++ /dev/null @@ -1,22 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -supplied argument is not a valid MySQL -Column count doesn't match value count at row -mysql_fetch_array\(\) -on MySQL result index -You have an error in your SQL syntax; -You have an error in your SQL syntax near -MySQL server version for the right syntax to use -\[MySQL\]\[ODBC -Column count doesn't match -Table '[^']+' doesn't exist -SQL syntax.*MySQL -##! Because of the bug in RE2 (golang), we cannot use {0,n} (a range started at 0), so it was replaced with (?:...{1,n})? -Warning.{1,10}mysql_(?:[a-z_()]{1,26})? -valid MySQL result -MySqlClient\. -ERROR [0-9]{4} \([a-z0-9]{5}\): -XPATH syntax error: diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951240.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951240.ra deleted file mode 100644 index 44f23c48e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/951240.ra +++ /dev/null @@ -1,18 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##!+ i - -PostgreSQL query failed: -pg_query\(\) \[: -pg_exec\(\) \[: -PostgreSQL.{1,20}ERROR -##! Example match: Warning: pg_fetch_array(): 3 is not a valid PostgreSQL result resource -Warning.{1,20}\bpg_.* -valid PostgreSQL result -Npgsql\. -PG::[a-z]*Error -Supplied argument is not a valid PostgreSQL .*? resource -Unable to connect to PostgreSQL server -invalid input syntax for integer -org\.postgresql\.util\.PSQLException: diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl1-curated.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl1-curated.ra deleted file mode 100644 index 395046285..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl1-curated.ra +++ /dev/null @@ -1,21 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list excludes command words that are prone to cause false -##! positives from the following include files: -##! - unix-shell-upto3.ra and -##! - unix-shell-4andup.ra - -##! To reduce complexity, this file simply lists all possible -##! variants of a word, so when a word would be changed from, e.g., -##! `awk@` to `awk~`, this list would not have to be updated. - -##! This list contains a subset of commands extracted from the file unix-shell-fps-pl1.ra -##! It specifically includes commands for which false positive reports were received. - -more -more@ -more~ -time -time@ -time~ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl1.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl1.ra deleted file mode 100644 index 5fa6bb130..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl1.ra +++ /dev/null @@ -1,823 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list excludes command words that are prone to cause false -##! positives from the following include files: -##! - unix-shell-upto3.ra and -##! - unix-shell-4andup.ra - -##! To reduce complexity, this file simply lists all possible -##! variants of a word, so when a word would be changed from, e.g., -##! `awk@` to `awk~`, this list would not have to be updated. - -##! To automatically add exclusions for English words from the sources, run the following: -##! NL=$'\n' -##! original="$(grep -vE '^[#$]' regex-assembly/exclude/unix-shell-fps-pl1.ra)" -##! upto3="$(grep -vE '^[#$]' regex-assembly/include/unix-shell-upto3.ra)" -##! rest="$(grep -vE '^[#$]' regex-assembly/include/unix-shell-4andup.ra)" -##! english_upto3="$(util/fp-finder/spell.sh -m -e regex-assembly/include/unix-shell-upto3.ra)" -##! # strip suffixes from words so that spell.sh works -##! english_rest="$(util/fp-finder/spell.sh -m -e -s '[@~]' regex-assembly/include/unix-shell-4andup.ra)" -##! result="" -##! function update_existing { -##! if [ -z "${1}" ]; then -##! return -##! fi -##! while read -r oword; do -##! found=0 -##! while read -r eword; do -##! if grep -qE "^${eword}[@~]?" <<<"${oword}"; then -##! result="${result}${eword}${NL}" -##! result="${result}${eword}@${NL}" -##! result="${result}${eword}~${NL}" -##! found=1 -##! break -##! fi -##! done <<<"${1}" -##! if [ ${found} -eq 0 ]; then -##! result="${result}${oword}${NL}" -##! fi -##! done <<<"${original}" -##! } -##! function add_new { -##! if [ -z "${1}" ]; then -##! return -##! fi -##! while read -r eword; do -##! if ! grep -qE "^${eword}[@~]?" <<<"${original}"; then -##! result="${result}${eword}${NL}" -##! result="${result}${eword}@${NL}" -##! result="${result}${eword}~${NL}" -##! fi -##! done <<<"${1}" -##! } -##! update_existing "${english_upto3}" -##! update_existing "${english_rest}" -##! add_new "${english_upto3}" -##! add_new "${english_rest}" - -##! body_start=$(grep -n -E -m 1 '^[^#$]' regex-assembly/exclude/unix-shell-fps-pl1.ra | cut -d: -f1) -##! ed -s regex-assembly/exclude/unix-shell-fps-pl1.ra <> regex-assembly/exclude/unix-shell-fps-pl1.ra - -GET -GET@ -GET~ -HEAD -HEAD@ -HEAD~ -POST -POST@ -POST~ -ab -ab@ -ab~ -adduser -agetty -alias -alias@ -alias~ -alpine -alpine@ -alpine~ -ansible-playbook -apt -apt-get -apt@ -aptitude -aptitude@ -aptitude~ -apt~ -ar -ar@ -arch -arch@ -arch~ -aria2c -arj -arp -arp@ -arp~ -ar~ -as -as@ -ascii-xfr -ascii85 -ash -ash@ -ash~ -aspell -as~ -at -at@ -atobm -at~ -awk -awk@ -aws -aws@ -axel -axel@ -axel~ -basename -basename@ -basename~ -bash -bash@ -bash~ -batch -batch@ -batch~ -bpftrace -breaksw -bridge -bridge@ -bridge~ -bundler@ -busctl -byebug -c89 -c99 -cancel -cancel@ -cancel~ -capsh@ -cat -cat@ -cat~ -cc -cc@ -cc~ -certbot -chattr -chdir@ -check_by_ssh -check_cups -check_log -check_memory -check_raid -check_ssl_cert -check_statusfile -chflags -chmod -choom -chown -chroot -chroot@ -chroot~ -clang -clang@ -clang~ -cmp -cobc -column -column@ -column~ -comm -command -command@ -command~ -composer -composer@ -composer~ -compress -compress@ -compress~ -cowsay -cowthink -cp -cp@ -cpan -cpio -cpulimit -crash -crash@ -crash~ -crontab -csplit -csvtool -cupsfilter -curl -curl@ -curl~ -cut -cut@ -cut~ -dash -dash@ -dash~ -date -date@ -date~ -dd -dd@ -dd~ -dhclient -dialog -dialog@ -dialog~ -dig -dig@ -dig~ -dir -dir@ -dir~ -dmidecode -dmsetup -dnf -docker -docker@ -docker~ -done -done@ -done~ -dosbox -dpkg -du -du@ -dvips -easy_install -eb -eb@ -eb~ -echo -echo@ -echo~ -ed -ed@ -ed~ -efax -emacs -endif -endsw -env-update -eqn -es -es@ -esac -es~ -eval -eval@ -eval~ -ex -ex@ -exec -exec@ -exec~ -exiftool -expand -expand@ -expand~ -expect -expect@ -expect~ -export -export@ -export~ -expr -ex~ -facter -fc -fc@ -fetch -fetch@ -fetch~ -fi -fi@ -file -file@ -file~ -find -find@ -find~ -finger -finger@ -finger~ -fish -fish@ -fish~ -fi~ -flock -flock@ -flock~ -fmt -fold -fold@ -fold~ -foreach -fping -ftp -ftp@ -ftp~ -function -function@ -function~ -gawk -gawk@ -gawk~ -gcore -gdb -gem -gem@ -gem~ -genie -genie@ -genie~ -genisoimage -getfacl@ -ghc -ghci -gimp -gimp@ -gimp~ -ginsh -git -git@ -git~ -go -go@ -go~ -grc -group -group@ -group~ -gtester -hash -hash@ -hash~ -hd -hd@ -head -head@ -head~ -hexdump -highlight -highlight@ -highlight~ -history -history@ -history~ -hostid -hostname -hping3 -htdigest -htpasswd -iconv -id -id@ -id~ -ifconfig -iftop -install -install@ -install~ -ionice -ip -ip6tables -ip@ -ipconfig -iptables -ip~ -ispell -java -java@ -java~ -jexec -jjs -jobs -jobs@ -jobs~ -join -join@ -join~ -journalctl -jq -jrunscript -kill -kill@ -killall -kill~ -knife -knife@ -knife~ -ksshell -last -last@ -last~ -latex -latex@ -latex~ -ld -ld@ -ldconfig -ldd -ldd@ -less -less@ -less~ -links -links@ -links~ -ln -ln@ -local -local@ -local~ -locate -locate@ -locate~ -loginctl -logname -logsave -look -look@ -look~ -lp -lp@ -lp~ -lshw -ltrace -lua -lua@ -lualatex -luatex -lwp-dump -lwp-mirror -lwp-request -lynx -lynx@ -lynx~ -mail -mail@ -mailx@ -mail~ -make -make@ -make~ -man -man@ -man~ -mawk -mkdir@ -more -more@ -more~ -mosquitto -mount -mount@ -mount~ -msgattrib -msgcat -msgconv -msgfilter -msgmerge -msguniq -mtr -mutt -mutt@ -mutt~ -mv -mv@ -mv~ -mysql -nano@ -nasm -nawk -nc -nc@ -nc~ -neofetch -net -net@ -net~ -nice -nice@ -nice~ -nl -nl@ -nm -nm@ -nmap -nm~ -node -node@ -node~ -npm -npm@ -nroff -nsenter -nslookup -null -null@ -null~ -octave -octave@ -octave~ -od -od@ -od~ -openssl -openvpn -openvt -opkg -pacman@ -parted -parted@ -parted~ -passwd -paste -paste@ -paste~ -patch -patch@ -patch~ -pax -pax@ -pax~ -pdb -pdflatex -pdftex -perf -perlsh -perms -perms@ -perms~ -pf -pf@ -pg -pic -pic@ -pico@ -pic~ -pidstat -ping -ping@ -ping~ -pip -pip@ -pip~ -pkg -pkg_info -pkginfo -pr -pr@ -pry -pry@ -pry~ -pr~ -ps -ps@ -psftp -psql -ps~ -ptx -puppet -puppet@ -puppet~ -pushd -python -python@ -python~ -rake -rake@ -rake~ -raku -rar -rar@ -readelf -red -red@ -redcarpet@ -red~ -rename -rename@ -rename~ -repeat -repeat@ -repeat~ -replace -replace@ -replace~ -restic -rev -rev@ -rev~ -rlogin -rlwrap -rm -rm@ -route -route@ -route~ -rpm -rpm@ -rpmdb -rpmquery -rpmverify -rpm~ -ruby -ruby@ -ruby~ -run-mailcap -run-parts -rview -rvim -sash -sash@ -sash~ -sched -sched@ -sched~ -screen -screen@ -screen~ -script -script@ -script~ -self -self@ -self~ -service -service@ -service~ -set -set@ -setarch -setfacl@ -set~ -sg -sg@ -sg~ -shadow -shadow@ -shadow~ -shells -shells@ -shells~ -shuf -shutdown -shutdown@ -shutdown~ -sleep -sleep@ -sleep~ -slsh -smbclient -snap -snap@ -snap~ -soelim -sort -sort@ -sort~ -source -source@ -source~ -split -split@ -split~ -sqlite3 -ss -ss@ -ssh-keygen -ssh-keyscan -sshpass -ss~ -start-stop-daemon -stdbuf -strace -strings -strings@ -strings~ -su -su@ -systemctl -systemd-resolve -tac -tail -tail@ -tail~ -tar -tar@ -tar~ -task -task@ -taskset -task~ -tbl -tclsh -tcp -tcp@ -tcpdump -tcp~ -tee -tee@ -tee~ -tex -tex@ -tex~ -tftp -tic -tic@ -tic~ -time -time@ -timedatectl -time~ -tmux -top -top@ -top~ -touch -touch@ -touch~ -troff -tshark -ul -ul@ -ulimit@ -uncompress -uncompress@ -uncompress~ -unexpand -uniq -unlink -unlink@ -unlink~ -unset -unset@ -unset~ -unshare@ -unzip -unzip@ -unzip~ -up2date@ -update-alternatives -uudecode -uuencode -valgrind -vi -vi@ -view -view@ -view~ -vim -vim@ -vimdiff -vim~ -virsh -vi~ -volatility -volatility@ -volatility~ -w -w@ -wall -wall@ -wall~ -watch -watch@ -watch~ -wc -whiptail -whiptail@ -whiptail~ -who -who@ -whois -who~ -wireshark -wish -wish@ -wish~ -w~ -xelatex -xetex -xmodmap -xmore -xpad -xterm -xxd -yarn -yarn@ -yarn~ -yelp -yelp@ -yelp~ -yes -yes@ -yes~ -yum -zathura -zero -zero@ -zero~ -zip -zip@ -zip~ -zsoelim -zypper diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl2-start-of-string.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl2-start-of-string.ra deleted file mode 100644 index 257ac227a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl2-start-of-string.ra +++ /dev/null @@ -1,19 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list excludes command words that are prone to cause false -##! positives from the following include files: -##! - unix-shell-upto3.ra -##! - unix-shell-4andup.ra - -##! To reduce complexity, this file simply lists all possible -##! variants of a word, so when a word would be changed from, e.g., -##! `awk@` to `awk~`, this list would not have to be updated. -##! See also unix-shell-fps-pl1.ra. - -as -as@ -as~ -at -at@ -at~ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl2.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl2.ra deleted file mode 100644 index d55b11dd7..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-pl2.ra +++ /dev/null @@ -1,43 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list excludes command words that are prone to cause false -##! positives from the following include files: -##! - unix-shell-upto3.ra -##! - unix-shell-4andup.ra - -##! To reduce complexity, this file simply lists all possible -##! variants of a word, so when a word would be changed from, e.g., -##! `awk@` to `awk~`, this list would not have to be updated. -##! See also unix-shell-fps-pl1.ra. - -aptitude -aptitude@ -aptitude~ -dnf -dnf@ -dnf~ -more -more@ -more~ -pacman -pacman@ -pacman~ -ps -ps@ -ps~ -time -time@ -time~ -up2date -up2date@ -up2date~ -vi -vi@ -vi~ -who -who@ -who~ -w -w@ -w~ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-useragents.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-useragents.ra deleted file mode 100644 index 9cbd3f554..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/unix-shell-fps-useragents.ra +++ /dev/null @@ -1,47 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list excludes command words that are prone to cause false -##! positives from the following include files: -##! -##! - unix-shell-upto3.ra -##! - unix-shell-4andup.ra -##! - unix-shell-pl3.ra - -##! This list is managed manually and contains known user-agents causing false positives -##! in rules checking for RCE in User-Agent and Referer request header. - -##! To reduce complexity, this file simply lists all possible -##! variants of a word, so when a word would be changed from, e.g., -##! `curl@` to `curl~`, this list would not have to be updated. -##! See also unix-shell-fps-pl1.ra. - -# CPanel client (https://cpanel.net): Cpanel-HTTP-Client/1.0 -cpan -cpan@ -cpan~ -# curl (https://curl.se): curl/8.1.2 -curl -curl@ -curl~ -# Links browser (https://en.wikipedia.org/wiki/Links_(web_browser)): Links (2.3pre1; Linux 2.6.38-8-generic x86_64; 170x48) -links -links@ -links~ -# Requests (https://docs.python-requests.org/en/latest/index.html): python-requests/2.31.0 -# urllib (https://docs.python.org/3/library/urllib.html): Python-urllib/3.9 -python -python@ -python~ -# Snapchat URL Preview Service (https://developers.snap.com/robots): Snap URL Preview Service; bot; snapchat; https://developers.snap.com/robots -snap -snap@ -snap~ -# w3m browser (https://en.wikipedia.org/wiki/W3m): w3m/0.5.1 -w3m -w3m@ -w3m~ -# wget (https://www.gnu.org/software/wget/): wget -wget -wget@ -wget~ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/windows-commands-fps.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/windows-commands-fps.ra deleted file mode 100644 index a1d77375c..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/exclude/windows-commands-fps.ra +++ /dev/null @@ -1,89 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list excludes command words that are prone to cause false -##! because they're common English words. -##! -##! This list can be generated with: -##! util/fp-finder/spell.sh -m regex-assembly/include/windows-commands.ra - -active -add -append -arp -assign -at -attributes -break -call -cd -change -choice -cipher -clean -clip -cls -color -comp -compact -convert -copy -create -date -delete -detail -echo -edit -erase -exec -exit -expand -expose -extend -extract -find -finger -fondue -format -ftp -help -inactive -label -list -md -mode -more -mount -move -msg -online -path -pause -ping -print -prompt -query -recover -rem -remove -rename -repair -replace -reset -retain -revert -select -shadow -shift -shrink -shutdown -sort -start -time -title -tree -type -ver -verifier -verify -writer diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/932130.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/932130.ra deleted file mode 100644 index b04b7021a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/932130.ra +++ /dev/null @@ -1,16 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -\$\(.*\) -\$\{.*\} -<\(.*\) ->\(.*\) -##! arithmetic expansion -\$\(\(.*\)\) -##! arithmetic expansion (deprecated in bash, but exists in other shells, like zsh) -\$\[.*\] - -##! Find wordlist bypasses using [ ] glob characters, like: /e[t]c -##! Require a / in front to prevent false positives like [text in brackets] -/\w*\[!.+\] -/\w*\[.+\] diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/charset-specification-no-anchors.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/charset-specification-no-anchors.ra deleted file mode 100644 index 2cad0b73a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/charset-specification-no-anchors.ra +++ /dev/null @@ -1,112 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The expression generated from this file matches a full HTTP -##! `Accept` header by following the specification as far as -##! necessary, while restricting the `charset` parameter -##! to a list of explicitly allowed values. -##! Where possible, the expression matches tokens "loosely", -##! to reduce complexity and the risk of false positives. - -##! As this specification is used by several rules, we now -##! store it as an include file. - -##! Specifications: -##! https://httpwg.org/specs/rfc7231.html#request.conneg -##! https://httpwg.org/specs/rfc7230.html - -##! Helpers -##!> define non-token-without-dquote-chars (),/:;<=>?![\x5c\]{} - -##!> define non-token-chars \"{{non-token-without-dquote-chars}} - -##!> define token-chars [^{{non-token-chars}}] - -##!> define token-with-dquote-chars [^{{non-token-without-dquote-chars}}] - -##!> define type-subtype (?:\*|{{token-chars}}+) - -##! The specification does not allow `*` in place of `*/*` but -##! enough clients use `*` for it to be an issue. Thus, it is -##! explicitly allowed here. -##!> define media-type (?:(?:{{type-subtype}}/{{type-subtype}})|\*) - -##! list of allowed charsets -##!> assemble - (?:"? - ##!=> - ##!> include allowed-charsets - ##!=> - \b"?)) - ##!=< allowed-charsets -##!< - - -##! Main assembly -##!> assemble - (?:{{media-type}}) - ##!=> - (?:\s*;\s* - ##!=> - (?:(?:charset\s*=\s* - ##!=> - ##!=> allowed-charsets - - ##! If the first part wasn't a "charset", then - ##! anything is allowed here that is not "charset". - ##! Note that this doesn't follow the RFC strictly. - |(?: - ##!=> - ##! Do not match space, otherwise the following would be possible: - ##! "text/html; charset=invalid" - ##! `charset` would be matched by `{{token-chars}}` - [^c\s{{non-token-chars}}]{{token-chars}}* - c[^h{{non-token-chars}}]{{token-chars}}* - ch[^a{{non-token-chars}}]{{token-chars}}* - cha[^r{{non-token-chars}}]{{token-chars}}* - char[^s{{non-token-chars}}]{{token-chars}}* - chars[^e{{non-token-chars}}]{{token-chars}}* - charse[^t{{non-token-chars}}]{{token-chars}}* - ##!=> - )\s*=\s*{{token-with-dquote-chars}}+) - ##!=> - ##! Clients like to violate the RFC, be lenient with - ##! terminating semi-colons. - ;? - ##!=> - )* - ##!=> - - ##! Multiple "media-range" expressions can be - ##! specified, comma separated. - (?:\s*,\s* - ##!=> - (?:{{media-type}}) - ##!=> - (?:\s*;\s* - ##!=> - (?:(?:charset\s*=\s* - ##!=> - ##!=> allowed-charsets - |(?: - ##!=> - ##! Do not match space, otherwise the following would be possible: - ##! "text/html; charset=invalid" - ##! `charset` would be matched by `{{token-chars}}` - [^c\s{{non-token-chars}}]{{token-chars}}* - c[^h{{non-token-chars}}]{{token-chars}}* - ch[^a{{non-token-chars}}]{{token-chars}}* - cha[^r{{non-token-chars}}]{{token-chars}}* - char[^s{{non-token-chars}}]{{token-chars}}* - chars[^e{{non-token-chars}}]{{token-chars}}* - charse[^t{{non-token-chars}}]{{token-chars}}* - ##!=> - )\s*=\s*{{token-with-dquote-chars}}+) - ##!=> - ##! Clients like to violate the RFC, be lenient with - ##! terminating semi-colons. - ;? - ##!=> - )*)* - ##!=> -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/charset-specification.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/charset-specification.ra deleted file mode 100644 index 24f2127d4..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/charset-specification.ra +++ /dev/null @@ -1,21 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! The expression generated from this file matches a full HTTP -##! `Accept` header by following the specification as far as -##! necessary, while restricting the `charset` parameter -##! to a list of explicitly allowed values. -##! Where possible, the expression matches tokens "loosely", -##! to reduce complexity and the risk of false positives. - -##! As this specification is used by several rules, we now -##! store it as an include file. - -##! Specifications: -##! https://httpwg.org/specs/rfc7231.html#request.conneg -##! https://httpwg.org/specs/rfc7230.html - -##!^ ^ -##!$ $ - -##!> include charset-specification-no-anchors diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/js-truthy-values.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/js-truthy-values.ra deleted file mode 100644 index 5e229bb9a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/js-truthy-values.ra +++ /dev/null @@ -1,49 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Falsy and negations -##!> assemble - !+ - ##!=> - false - null - undefined - NaN - [-+]?0 - "{2} - '{2} - `{2} -##!< - -##! Truthy and double negations (word boundary) -##!> assemble - (?:!!)* - ##!=> - true - [-+]?Infinity - [-+]?[1-9]\d* - new [a-zA-Z]\w* - this - window - String - Boolean - Object - Array - Function - ##!=> - \b - ##!=> -##!< - - -##! Truthy and double negations (no word boundary: anything that ends -##! with a special character) -##!> assemble - (?:!!)* - ##!=> - \{.*\} - \[.*\] - "[^"]+" - '[^']+' - `[^`]+` -##!< diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/sql-injection-mysql-postgresql-procedures-functions.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/sql-injection-mysql-postgresql-procedures-functions.ra deleted file mode 100644 index a58f2c427..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/sql-injection-mysql-postgresql-procedures-functions.ra +++ /dev/null @@ -1,23 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -create\s+function\s*?\w+\s*?\(\s*?\)\s*?- -create\s+procedure\s*?\w+\s*?\(\s*?\)\s*?- -declare[^\w]+[@#]\s*?\w+ -div\s*?\([+-]*[\d.\s]+,[+-]*[\d.\s]+\) -exec\s*?\(\s*?@ -lo_import\s*?\( -lo_get\s*?\( -procedure\s+analyse\s*?\( -;\s*?declare\s+[\w-]+ -;\s*?open\s+[\w-]+ -::bigint -::bool -::double\s+precision -::int -::integer -::numeric -::oid -::real -::text -::smallint diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-4andup.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-4andup.ra deleted file mode 100644 index f69c1e9a0..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-4andup.ra +++ /dev/null @@ -1,580 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list was generated from the original lists with the following command: -##! awk '/^([a-z0-9_-]+)/ { x = $0; gsub(/[@~]/, "", x); if (length(x) > 3) print }' 93210{0,5}.data - -##! Note that the suffixes must be added manually to new entries. -##! To regenerate this list from unix-shell.data, run the following: -##! NL=$'\n' -##! original="$(grep -vE '^[#$]' regex-assembly/include/unix-shell-4andup.ra)" -##! source="$(awk '/^[^#$]/ {split($0,x,"/"); y=x[length(x)]} length(y) > 3 {print y}' \ -##! rules/unix-shell.data | \ -##! sort | uniq)" -##! result="" -##! # retain all unmodified entries in this list and skip removed ones; ignore the manually added suffixes -##! while read -r oword; do -##! # strip suffixes from end of words -##! oword_raw="${oword/%@/}" -##! oword_raw="${oword_raw/%~/}" -##! while read -r sword; do -##! # handle "clang++" -##! sword="${sword//++/\+\+}" -##! # handle "." in commands -##! sword="${sword//./\.}" -##! if [ "${oword_raw}" = "${sword}" ]; then -##! result="${result}${oword}${NL}" -##! break -##! fi -##! done <<<"${source}" -##! done <<<"${original}" - -##! # add new entries to this list -##! while read -r sword; do -##! # handle "clang++" -##! sword="${sword/%++/\+\+}" -##! # handle "." in commands -##! sword="${sword//./\.}" -##! found=0 -##! while read -r oword; do -##! # strip suffixes from end of words -##! oword_raw="${oword/%@/}" -##! oword_raw="${oword_raw/%~/}" -##! if [ "${oword_raw}" = "${sword}" ]; then -##! found=1 -##! break -##! fi -##! done <<<"${original}" -##! if [ ${found} -eq 0 ]; then -##! result="${result}${sword}${NL}" -##! fi -##! done <<<"${source}" - -##! # check entries for English words and suffix those -##! original="${result}" -##! english="$(util/fp-finder/spell.sh -m -e - <<<"${result}")" -##! result="" -##! while read -r oword; do -##! found=0 -##! while read -r eword; do -##! if [ "${oword}" = "${eword}" ] && [ -n "${oword}" ]; then -##! result="${result}${oword}@${NL}" -##! found=1 -##! break -##! fi -##! done <<<"${english}" -##! if [ ${found} -eq 0 ]; then -##! result="${result}${oword}${NL}" -##! fi -##! done <<<"${original}" - -##! body_start=$(grep -n -E -m 1 '^[^#$]' regex-assembly/include/unix-shell-4andup.ra | cut -d: -f1) -##! ed -s regex-assembly/include/unix-shell-4andup.ra <> regex-assembly/include/unix-shell-4andup.ra - -HEAD@ -POST@ -addgroup -adduser -agetty -alias@ -alpine@ -ansible -apt-get -aptitude@ -arch@ -aria2c -ascii-xfr -ascii85 -aspell -atobm -axel@ -base32 -base64 -basename@ -basenc -bash@ -batch@ -blkid -bpftrace -breaksw -bridge@ -bsdcat -bsdiff -bsdtar -builtin -bundler@ -bunzip2 -busctl -busybox -byebug -byobu -bzcat -bzcmp -bzdiff -bzegrep -bzexe -bzfgrep -bzgrep -bzip2 -bzip2recover -bzless -bzmore -cancel@ -capsh@ -certbot -chattr -chdir@ -check_by_ssh -check_cups -check_log -check_memory -check_raid -check_ssl_cert -check_statusfile -chef@ -chef- -chflags -chgpasswd -chgrp -chmod -choom -chown -chpass -chroot@ -chsh -clang@ -clang\+\+ -cobc -column@ -comm@ -command@ -composer@ -compress@ -coproc -cowsay -cowthink -cpan -cpio -cpulimit -crash@ -cron@ -crontab -cscli@ -csplit -csvtool -cupsfilter -curl@ -dash@ -date@ -dhclient -dialog@ -diff@ -dmesg -dmidecode -dmsetup -doas -docker@ -done@ -dosbox -dpkg -dvips -e2fsck -easy_install -echo@ -efax -egrep -emacs -endif -endsw -env-update -esac -eval -exec@ -exiftool -expand@ -expect@ -export@ -expr -facter -fetch@ -fgrep -file@ -filetest -find@ -finger@ -fish@ -flock@ -fold@ -foreach -fping -ftpstats -ftpwho -function@ -gawk@ -gcore -genie@ -genisoimage -getfacl@ -ghci -gimp@ -ginsh -grep@ -group@ -groupmod -gtester -gunzip -gzcat -gzexe -gzip -hash@ -head@ -hexdump -highlight@ -history@ -hostid -hostname -hping3 -htdigest -htop -htpasswd -iconv -ifconfig -iftop -install@ -ionice -ip6tables -ipconfig -iptables -ispell -java@ -jexec -jobs@ -join@ -journalctl -jrunscript -kill@ -killall -knife@ -ksshell -last@ -lastcomm -lastlog -lastlogin -latex@ -ldconfig -less@ -lessecho -lessfile -lesspipe -lftp -lftpget -links@ -local@ -locate@ -loginctl -logname -logsave -look@ -losetup -ls-F -lsb_release -lscpu -lshw -lsmod -lsof -lspci -lsusb -ltrace -lualatex -luatex -lwp-download -lwp-dump -lwp-mirror -lwp-request -lynx@ -lz4c -lz4cat -lzcat -lzcmp -lzdiff -lzegrep -lzfgrep -lzgrep -lzless -lzma -lzmadec -lzmainfo -lzmore -mail@ -mailq -mailx@ -make@ -master\.passwd -mawk -mkdir@ -mkfifo -mknod -mktemp -mlocate -more@ -mosquitto -mount@ -msgattrib -msgcat -msgconv -msgfilter -msgmerge -msguniq -mutt@ -mysql -mysqladmin -mysqldump -mysqldumpslow -mysqlhotcopy -mysqlshow -nano@ -nasm -nawk -nc\.openbsd -nc\.traditional -ncat -neofetch -netcat -netkit-ftp -netplan -netstat -nice@ -nmap -node@ -nohup -nping -nroff -nsenter -nslookup -nstat -null@ -octave@ -onintr -openssl -openvpn -openvt -opkg -pacman@ -parted@ -passwd -paste@ -patch@ -pdflatex -pdftex -pdksh -perf@ -perl@ -perl5 -perlsh -perms@ -pftp -pgrep -php-cgi -php5 -php7 -pico@ -pidstat -pigz -ping@ -pkexec -pkg_info -pkginfo -pkill -popd -printenv -printf@ -psed -psftp -psql -ptar -ptardiff -ptargrep -puppet@ -pushd -pwd\.db -python2 -python3 -python~ -pyversions -py3versions -rake@ -raku -rbash -readelf -realpath -redcarpet@ -rename@ -repeat@ -replace@ -restic -rlogin -rlwrap -rmdir@ -rmuser -rnano -route@ -rpmdb -rpmquery -rpmverify -rsync -ruby~ -run-mailcap -run-parts -rview -rvim -sash@ -sched@ -screen@ -script@ -sdiff -self@ -sendmail -service@ -setarch -setenv -setfacl@ -setsid -sftp -sh\.distrib -shadow@ -shells@ -shuf -shutdown@ -sleep@ -slsh -smbclient -snap@ -socat -soelim -sort@ -source@ -split@ -spwd\.db -sqlite3 -ssh-keygen -ssh-keyscan -sshpass -start-stop-daemon -stdbuf -stderr -stdin -stdout -strace -strings@ -sudo -sysctl -systemctl -systemd-resolve -tail@ -tailf -task@ -taskset -tclsh -tcpdump -tcping -tcptraceroute -tcsh -telnet -tftp -time@ -timedatectl -timeout@ -tmux -touch@ -traceroute -traceroute6 -troff -tshark -ulimit@ -uname -uncompress@ -unexpand -uniq -unlink@ -unlz4 -unlzma -unpigz -unrar -unset@ -unshare@ -unxz -unzip@ -unzstd -up2date@ -update-alternatives -useradd -userdel -usermod -uudecode -uuencode -valgrind -view@ -vigr -vimdiff -vipw -virsh -visudo -volatility@ -wall@ -watch@ -wget -whiptail@ -whoami -whois -wireshark -wish@ -xargs -xelatex -xetex -xmodmap -xmore -xpad -xterm -xzcat -xzcmp -xzdec -xzdiff -xzegrep -xzfgrep -xzgrep -xzless -xzmore -yarn@ -yelp@ -zathura -zcat -zcmp -zdiff -zegrep -zero@ -zfgrep -zgrep -zipcloak -zipcmp -zipdetails -zipgrep -zipinfo -zipmerge -zipnote -zipsplit -ziptool -zless -zmore -zrun -zsoelim -zstd -zstdcat -zstdgrep -zstdless -zstdmt -zypper diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-evasion-prefix-start-of-string.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-evasion-prefix-start-of-string.ra deleted file mode 100644 index dc951a296..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-evasion-prefix-start-of-string.ra +++ /dev/null @@ -1,6 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! ifconfig (start of string) -^ -##!> include unix-shell-evasion-prefix.ra diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-evasion-prefix.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-evasion-prefix.ra deleted file mode 100644 index c9d5baa62..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-evasion-prefix.ra +++ /dev/null @@ -1,100 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This assembly file generates a prefix match for unix shell RCE -##! evasions. Command words, in this case, must folow the prefix. -##! Separate rules target commands that do not follow this prefix, -##! as the chance of false positives is higher without a prefix match. - -##! ifconfig -##!> cmdline unix - busybox - command - env - eval - ltrace - nohup - strace - time - timeout - watch -##!< -##! ;ifconfig -; -##! =ifconfig -= -##! {ifconfig} -\{ -##! |ifconfig -\| -##! ||ifconfig -\|\| -##! &ifconfig -& -##! & &ifconfig -&& -##! ;\nifconfig -\n -##! ;\rifconfig -\r -##! $(ifconfig) -\$\( -##! $((1+2)) arithmetic expansion -\$\(\( -##! $[1+2] arithmetic expansion (deprecated in bash, but exists in other shells, like zsh) -\$\[ -##! `ifconfig` -` -##! ${ifconfig} -\${ -##! <( ifconfig ) -<\( -##! >( ifconfig ) ->\( -##! a() ( ifconfig; ); a -\(\s*\) -##! `cat<< - -##! match possible white space between prefix expressions -\s* -##!=> - -##! commands prefix -##!> assemble - ##! { ifconfig } - \{ - ##! ( ifconfig ) - \s*\(\s* - ##! VARNAME=xyz ifconfig - \w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+ - ##! ! ifconfig - !\s* - ##! $ifconfig - \$ -##!< -##!=> - -* -##!=> - -##! match possible white space between prefix expressions -\s* -##!=> - -##! quoting prefix -##!> assemble - ##! 'ifconfig' - ' - ##! "ifconfig" - \" -##!< -##!=> - -* -##!=> - -##! paths prefix (+ evasion prevention suffix [\x5c'\"]*) -(?:[\?\*\[\]\(\)\-\|+\w'\"\./\x5c]+/)?[\x5c'\"]* -##!=> diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-pl3.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-pl3.ra deleted file mode 100644 index c17b75154..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-pl3.ra +++ /dev/null @@ -1,27 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This list contains terms that are only searched for at PL 3. -##! Note that the equivalent could be achieved by using -##! `include` processors with both <= 3 and > 3 but that would -##! make the rule almost identical to its PL 1 counterparts, -##! artificially doubling the critiality of hits and adding -##! unnecessary overhead. - -##! Note that this list is arbitrary. We do not have criteria -##! for inclusion in this list apart from false positive -##! reports. - -##! This list must be in sync with: -##! - unix-shell-upto3.ra -##! - unix-shell-4andup.ra -##! - unix-shell-pl3.ra - -aptitude@ -dnf -pacman@ -ps -up2date@ -vi@ -who -w@ diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-upto3.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-upto3.ra deleted file mode 100644 index 874e5983f..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/unix-shell-upto3.ra +++ /dev/null @@ -1,198 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Note that the suffixes @ / ~ must be added manually to new entries. -##! To regenerate this list from unix-shell.data, run the following: -##! NL=$'\n' -##! # select words of length <= 3 -##! original="$(grep -vE '^[#$]' regex-assembly/include/unix-shell-upto3.ra)" -##! source=$(awk '/^[^#$]/ {split($0,x,"/"); y=x[length(x)]} length(y) <= 3 {print y}' \ -##! rules/unix-shell.data | \ -##! sort | uniq) -##! result="" -##! # retain all unmodified entries in this list and skip removed ones; ignore the manually added suffixes -##! while read -r oword; do -##! # strip @ and ~ from end of words -##! oword_raw="${oword/%@/}" -##! oword_raw="${oword_raw/%\~/}" -##! while read -r sword; do -##! if [ "${oword_raw}" = "${sword}" ]; then -##! result="${result}${oword}${NL}" -##! break -##! fi -##! done <<<"${source}" -##! done <<<"${original}" - -##! # add new entries to this list -##! while read -r sword; do -##! found=0 -##! while read -r oword; do -##! # strip @ and ~ from end of words -##! oword_raw="${oword/%@/}" -##! oword_raw="${oword_raw/%\~/}" -##! if [ "${oword_raw}" = "${sword}" ]; then -##! found=1 -##! break -##! fi -##! done <<<"${original}" -##! if [ ${found} -eq 0 ]; then -##! result="${result}${sword}${NL}" -##! fi -##! done <<<"${source}" - -##! # check entries for English words and suffix those -##! original="$(grep -vE '^[#$]' regex-assembly/include/unix-shell-upto3.ra)" -##! english="$(util/fp-finder/spell.sh -m -e regex-assembly/include/unix-shell-upto3.ra)" -##! # do not suffix the following words: -##! english="$(grep -vE 'ip|id|top|set' <<< "${english}")" -##! result="" -##! while read -r oword; do -##! found=0 -##! while read -r eword; do -##! if [ "${oword}" = "${eword}" ] && [ -n "${oword}" ]; then -##! result="${result}${oword}@${NL}" -##! found=1 -##! break -##! fi -##! done <<<"${english}" -##! if [ ${found} -eq 0 ]; then -##! result="${result}${oword}${NL}" -##! fi -##! done <<<"${original}" - -##! body_start=$(grep -n -E -m 1 '^[^#$]' regex-assembly/include/unix-shell-upto3.ra | cut -d: -f1) -##! ed -s regex-assembly/include/unix-shell-upto3.ra <> regex-assembly/include/unix-shell-upto3.ra - -7z -7za -7zr -7zx -GET@ -ab@ -apt@ -ar@ -arj -arp@ -as@ -ash@ -at@ -awk@ -aws@ -bzz@ -c89 -c99 -cat@ -cc@ -cmp -cp@ -csh -cut@ -dd@ -df -dig@ -dir@ -dnf -du@ -eb@ -ed@ -env@ -eqn -es@ -esh -ex@ -fc@ -fd -fg -fi@ -fmt -ftp@ -gcc~ -gdb -gem@ -ghc -git@ -go@ -gpg -grc -hd@ -hup@ -id -ip -irb -jjs -jq -ksh -ld@ -ldd@ -ln@ -lp@ -ls -lua@ -lz4 -lz@ -man@ -mtr -mv@ -nc@ -net@ -nl@ -nm@ -npm@ -od@ -pax@ -pdb -pf@ -pg -php@ -pic@ -pip~ -pkg -pr@ -pry@ -ps@ -ptx -pwd -pxz -rar@ -rc -rcp@ -red@ -rev@ -rm@ -rpm@ -scp -sed@ -set@ -sg@ -sh@ -ss@ -ssh@ -su@ -svn -tac -tar@ -tbl -tcp@ -tee@ -tex@ -tic@ -top -udp -ul@ -vi@ -vim@ -w3m -w@ -wc -who@ -xxd -xz@ -yes@ -yum -zip@ -zsh diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/url-schemes.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/url-schemes.ra deleted file mode 100644 index 136606e22..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/url-schemes.ra +++ /dev/null @@ -1,120 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This is a list of schemes that can be used for RFI/SSRF (from https://en.wikipedia.org/wiki/List_of_URI_schemes): - -acap -afp -afs -attachment -beshare -bitcoin -blob -callto -cap -cid -cvs -dav -data -dict -dns -dntp -ed2k -expect -fd -feed -file -finger -fish -ftp -ftps -git -go -gopher -h323 -http -https -iax -icap -imap -imaps -ipp -ipps -irc -irc6 -ircs -jabber -jar -ldap -ldapi -ldaps -local_file -mailto -maven -mms -mumble -netdoc -news -nfs -nntp -nntps -ogg -paparazzi -phar -pop2 -pop3 -pop3s -pres -proxy -psyc -rmi -rsync -rtm -rtmfp -rtmp -s3 -sftp -sip -sips -smb -smtp -smtps -sms -snews -snmp -ssh -ssh2 -svn -svn\+ssh -teamspeak -telnet -tftp -turn -turns -udp -unreal -ut2004 -ventrilo -view-source -vnc -webcal -ws -wss -xmpp -xri - -##! Adding also the list of PHP (sub)schemes that can be used for RFI/SSRF (from https://www.php.net/manual/en/wrappers.php): - -ssh2.shell -ssh2.exec -ssh2.tunnel -ssh2.sftp -ssh2.scp -compress.zlib -compress.bzip2 -zip -glob -rar -ogg -expect -php diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/windows-commands-prefix.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/windows-commands-prefix.ra deleted file mode 100644 index b59b4bb4e..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/windows-commands-prefix.ra +++ /dev/null @@ -1,68 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! This assembly file generates a prefix match for windows commands. -##! Command words, in this case, must follow the prefix. -##! Separate rules target commands that do not follow this prefix, -##! as the chance of false positives is higher without a prefix match. - -##! Note: the quoting prefixes are part of the command prefixes, except for ^ -##! which, for unknown reasons, is not part of the expression - -##! ;cmd -; -##! {cmd -\{ -##! |cmd -\| -##! ||cmd -\|\| -##! &cmd -& -##! &&cmd -&& -##! \ncmd -\n -##! \rcmd -\r -##! `cmd -` -##!=> - -##! match possible white space between prefix expressions -\s* -##!=> - -##! commands prefix -##!> assemble - ##! (cmd) - \( - ##! ,cmd - , - ##! @cmd - @ - ##! 'cmd' - ' - ##! "cmd" - \" - ##! spacing+cmd - \s -##!< -##!=> - -* -##!=> - -##! paths prefix -##!> assemble - ##! /path/cmd - [\w'\"\./]+/ - ##! C:\Program Files\cmd - [\x5c'\"\^]*\w[\x5c'\"\^]*:.*\x5c - ##! \\net\share\dir\cmd - [\^\.\w '\"/\x5c]*\x5c -##!< -##!=> - -?[\"\^]* -##!=> diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/windows-commands.ra b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/windows-commands.ra deleted file mode 100644 index 5e36d81b9..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/include/windows-commands.ra +++ /dev/null @@ -1,299 +0,0 @@ -##! Please refer to the documentation at -##! https://coreruleset.org/docs/development/regex_assembly/. - -##! Word list for rule 932380 (RCE Windows command injection part 2/2) -##! -##! The list comes from the Microsoft Windows Server documentation. -##! You can get it using the following one-liner: -##! `curl https://raw.githubusercontent.com/MicrosoftDocs/windowsserverdocs/main/WindowsServerDocs/administration/windows-commands/windows-commands.md | grep -oE '^-\s\[\w+\]' | cut -f2 -d[ | cut -f1 -d]` - -active -add -append -arp -assign -assoc -at -atmadm -attrib -attributes -auditpol -autochk -autoconv -autofmt -automount -bcdboot -bcdedit -bdehdcfg -bitsadmin -bootcfg -break -cacls -call -cd -certreq -certutil -change -chcp -chdir -chglogon -chgport -chgusr -chkdsk -chkntfs -choice -cipher -clean -cleanmgr -clip -cls -cmd -cmdkey -cmstp -color -comp -compact -convert -copy -create -cscript -date -dcdiag -dcgpofix -defrag -del -delete -detail -dfsdiag -dfsrmig -diantz -dir -diskcomp -diskcopy -diskpart -diskperf -diskraid -diskshadow -dispdiag -dnscmd -doskey -driverquery -echo -edit -endlocal -erase -eventcreate -Evntcmd -exec -exit -expand -expose -extend -extract -fc -filesystems -find -findstr -finger -flattemp -fondue -for -forfiles -format -freedisk -fsutil -ftp -ftype -fveupdate -getmac -gettype -goto -gpfixup -gpresult -gpt -gpupdate -graftabl -help -helpctr -hostname -icacls -if -inactive -ipconfig -ipxroute -irftp -jetpack -klist -ksetup -ktmutil -ktpass -label -list -lodctr -logman -logoff -lpq -lpr -macfile -makecab -mapadmin -md -mkdir -mklink -mmc -mode -more -mount -mountvol -move -mqbkup -mqsvc -mqtgsvc -msdt -msg -msiexec -msinfo32 -mstsc -nbtstat -netcfg -netdom -netsh -netstat -nfsadmin -nfsshare -nfsstat -nlbmgr -nltest -nslookup -ntbackup -ntcmdprompt -ntfrsutl -offline -online -openfiles -pagefileconfig -path -pathping -pause -pbadmin -pentnt -perfmon -ping -pktmon -pnpunattend -pnputil -popd -powershell -print -prncnfg -prndrvr -prnjobs -prnmngr -prnport -prnqctl -prompt -pubprn -pushd -pushprinterconnections -pwlauncher -pwsh -qappsrv -qprocess -query -quser -qwinsta -rd -rdpsign -recover -refsutil -reg -regini -regsvr32 -relog -rem -remove -ren -rename -repadmin -repair -replace -rescan -reset -retain -revert -rexec -risetup -rmdir -robocopy -rpcinfo -rpcping -rsh -rundll32 -rwinsta -san -schtasks -scwcmd -secedit -select -serverceipoptin -servermanagercmd -serverweroptin -setx -sfc -shadow -shift -showmount -shrink -shutdown -sort -start -subst -sxstrace -sysocmgr -systeminfo -takeown -tapicfg -taskkill -tasklist -tcmsetup -telnet -tftp -time -timeout -title -tlntadmn -tpmtool -tpmvscmgr -tracerpt -tracert -tree -tscon -tsdiscon -tsecimp -tskill -tsprof -type -typeperf -tzutil -unexpose -uniqueid -unlodctr -ver -verifier -verify -vol -vssadmin -waitfor -wbadmin -wdsutil -wecutil -wevtutil -where -whoami -winnt -winnt32 -winrs -wmic -writer -wscript -xcopy diff --git a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/toolchain.yaml b/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/toolchain.yaml deleted file mode 100644 index d921b799b..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/regex-assembly/toolchain.yaml +++ /dev/null @@ -1,46 +0,0 @@ -# # # # # # # # # # # # # # # # # # # # -# configuration file for crs-toolchain -# # # # # # # # # # # # # # # # # # # # -patterns: - # The Unix evasion patterns, were extended per decision in https://github.com/coreruleset/coreruleset/issues/2632. - anti_evasion: - # - [\x5c'\"\[)]: common evasion tokens and path expansion, e.g., `/bin/[c]''a""\t` - # - (?:\|\||&&)\s*: hiding of empty variables through logial operators, e.g., `nc&&$u -p 777` - # - \$[a-z0-9_@?!#{(*-]*: empty variable evasion, e.g., `n\$uc -p 777` - # - [\x5c'\"\[)], \$[a-z0-9_@?!#{(*-]*: arithmetic expansion evasion, e.g., `c$((9))9` - unix: | - [\x5c'\"\[)]*(?:(?:(?:\|\||&&)\s*)?\$[a-z0-9_@?!#{(*-]*)?\x5c? - windows: | - [\"\^]* - anti_evasion_suffix: - # - <>: redirection, e.g., `cat,&|)].* - # "more foo", "more,foo", "more;foo", "more.com", "more/e", - # "morefoo" - windows: | - [\s,;./<>].* - # Same as above but does not allow any white space as the next token. - # This is useful for words like `python3`, where `python@` would - # create too many false positives because it would match `python `. - anti_evasion_no_space_suffix: - # This will match: - # - # python<<,&|]|(?:[\w\d._-][\x5c'\"\[]*(?:(?:(?:\|\||&&)\s*)?\$[a-z0-9_@?!#{*-]*)?\x5c?)+[\s<>,&|]).* - # This will match: - # - # python,foo - # python2 foo - # - # It will _not_ match: - # python foo - windows: | - (?:[,;./<>]|(?:[\w\d._-][\"\^]*)+[\s,;./<>]).* diff --git a/src/common/core/modsecurity/files/coreruleset-v3/renovate.json b/src/common/core/modsecurity/files/coreruleset-v3/renovate.json deleted file mode 100644 index 26f58fa20..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/renovate.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "local>coreruleset/renovate-config", - "schedule:weekly" - ], - "enabledManagers": [ - "docker-compose" - ] -} diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example index b58c889e9..371700fc0 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -82,9 +82,9 @@ # This ruleset allows you to control how ModSecurity will handle traffic # originating from Authorized Vulnerability Scanning (AVS) sources. See # related blog post - -# https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/updated-advanced-topic-of-the-week-handling-authorized-scanning-traffic/ +# http://blog.spiderlabs.com/2010/12/advanced-topic-of-the-week-handling-authorized-scanning-traffic.html # -# Allow List ASV network block (no blocking or logging of AVS traffic) Update +# White-list ASV network block (no blocking or logging of AVS traffic) Update # IP network block as appropriate for your AVS traffic # # ModSec Rule Exclusion: Disable Rule Engine for known ASV IP @@ -130,7 +130,7 @@ # Example Exclusion Rule: Removing a specific ARGS parameter from inspection # for all CRS rules # -# This rule illustrates that we can use tagging very effectively to allow list a +# This rule illustrates that we can use tagging very effectively to whitelist a # common false positive across an entire ModSecurity instance. This can be done # because every rule in OWASP_CRS is tagged with OWASP_CRS. This will NOT # affect custom rules. @@ -150,10 +150,6 @@ # This rule illustrates that we can remove a rule range via a ctl action. # This uses the fact, that rules are grouped by topic in rule files covering # a certain id range. -# IMPORTANT: ModSecurity v3, aka libModSecurity, does not currently support the -# use of rule ranges in a ruleRemoveById ctl action (this feature has been -# planned for v3.1). Consider using ruleRemoveByTag as a workaround, if -# appropriate. # # ModSecurity Rule Exclusion: Disable all SQLi and XSS rules # SecRule REQUEST_FILENAME "@beginsWith /admin" \ @@ -164,37 +160,7 @@ # ctl:ruleRemoveById=941000-942999" # # -# The application-specific rule exclusion plugins -# (see: https://github.com/coreruleset/plugin-registry) -# provide additional examples which can be useful then tuning a service. - - -# -# Example Rule: Allow monitoring tools and scripts -# -# Uncomment this rule to allow all requests from trusted IPs and User-Agent. -# This can be useful for monitoring tools like Monit, Nagios, or other agents. -# For example, if you're using AWS Load Balancer, you may need to trust all -# requests from "10.0.0.0/8" subnet that come with the user-agent -# "ELB-HealthChecker/2.0". By doing this, all requests that match these -# conditions will not be matched against the following rules: -# -# - id: 911100 (allowed methods) -# - id: 913100 (scan detection) -# - id: 920280 (missing/empty host header) -# - id: 920350 (IP address in host header) -# - tag: attack-disclosure (all RESPONSE-*-DATA-LEAKAGES rules) -# -# SecRule REMOTE_ADDR "@ipMatch 10.0.0.0/8" \ -# "id:1005,\ -# phase:1,\ -# pass,\ -# nolog,\ -# chain" -# SecRule REQUEST_METHOD "@pm GET HEAD" "chain" -# SecRule REQUEST_HEADERS:User-Agent "@pm ELB-HealthChecker" \ -# "ctl:ruleRemoveById=911100,\ -# ctl:ruleRemoveById=913100,\ -# ctl:ruleRemoveById=920280,\ -# ctl:ruleRemoveById=920350,\ -# ctl:ruleRemoveByTag=attack-disclosure" +# The application specific rule exclusion files +# REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf +# REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf +# bring additional examples which can be useful then tuning a service. diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-901-INITIALIZATION.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-901-INITIALIZATION.conf index 1571c4807..539ebe3d5 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-901-INITIALIZATION.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-901-INITIALIZATION.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -12,7 +12,7 @@ # This file REQUEST-901-INITIALIZATION.conf initializes the Core Rules # and performs preparatory actions. It also fixes errors and omissions # of variable definitions in the file crs-setup.conf. -# The crs-setup.conf can and should be edited by the user, this file +# The setup.conf can and should be edited by the user, this file # is part of the CRS installation and should not be altered. # @@ -24,9 +24,9 @@ # # - Producer: ModSecurity for Apache/2.9.1 (http://www.modsecurity.org/); OWASP_CRS/3.1.0. # -# Ref: https://github.com/owasp-modsecurity/ModSecurity/wiki/Reference-Manual-(v2.x)#seccomponentsignature +# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecComponentSignature # -SecComponentSignature "OWASP_CRS/4.6.0" +SecComponentSignature "OWASP_CRS/3.3.7" # # -=[ Default setup values ]=- @@ -58,9 +58,8 @@ SecRule &TX:crs_setup_version "@eq 0" \ status:500,\ log,\ auditlog,\ - msg:'ModSecurity CRS is deployed without configuration! Please copy the crs-setup.conf.example template to crs-setup.conf, and include the crs-setup.conf file in your webserver configuration before including the CRS rules. See the INSTALL file in the CRS directory for detailed instructions',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + msg:'ModSecurity Core Rule Set is deployed without configuration! Please copy the crs-setup.conf.example template to crs-setup.conf, and include the crs-setup.conf file in your webserver configuration before including the CRS rules. See the INSTALL file in the CRS directory for detailed instructions',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL'" @@ -68,88 +67,62 @@ SecRule &TX:crs_setup_version "@eq 0" \ # -=[ Default setup values ]=- # # Some constructs or individual rules will fail if certain parameters -# are not set in the crs-setup.conf file. The following rules will catch +# are not set in the setup.conf file. The following rules will catch # these cases and assign sane default values. # -# Default Inbound Anomaly Threshold Level (rule 900110 in crs-setup.conf) +# Default Inbound Anomaly Threshold Level (rule 900110 in setup.conf) SecRule &TX:inbound_anomaly_score_threshold "@eq 0" \ "id:901100,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.inbound_anomaly_score_threshold=5'" -# Default Outbound Anomaly Threshold Level (rule 900110 in crs-setup.conf) +# Default Outbound Anomaly Threshold Level (rule 900110 in setup.conf) SecRule &TX:outbound_anomaly_score_threshold "@eq 0" \ "id:901110,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.outbound_anomaly_score_threshold=4'" -# Default Reporting Level (rule 900115 in crs-setup.conf) -SecRule &TX:reporting_level "@eq 0" \ - "id:901111,\ - phase:1,\ - pass,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.reporting_level=4'" - -# Default Early Blocking (rule 900120 in crs-setup.conf) -SecRule &TX:early_blocking "@eq 0" \ - "id:901115,\ - phase:1,\ - pass,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.early_blocking=0'" - -# Default Blocking Paranoia Level (rule 900000 in crs-setup.conf) -SecRule &TX:blocking_paranoia_level "@eq 0" \ +# Default Paranoia Level (rule 900000 in setup.conf) +SecRule &TX:paranoia_level "@eq 0" \ "id:901120,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_paranoia_level=1'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.paranoia_level=1'" -# Default Detection Paranoia Level (rule 900001 in crs-setup.conf) -SecRule &TX:detection_paranoia_level "@eq 0" \ +# Default Executing Paranoia Level (rule 900000 in setup.conf) +SecRule &TX:executing_paranoia_level "@eq 0" \ "id:901125,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_paranoia_level=%{TX.blocking_paranoia_level}'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.executing_paranoia_level=%{TX.PARANOIA_LEVEL}'" -# Default Sampling Percentage (rule 900400 in crs-setup.conf) +# Default Sampling Percentage (rule 900400 in setup.conf) SecRule &TX:sampling_percentage "@eq 0" \ "id:901130,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.sampling_percentage=100'" -# Default Anomaly Scores (rule 900100 in crs-setup.conf) +# Default Anomaly Scores (rule 900100 in setup.conf) SecRule &TX:critical_anomaly_score "@eq 0" \ "id:901140,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.critical_anomaly_score=5'" SecRule &TX:error_anomaly_score "@eq 0" \ @@ -157,8 +130,7 @@ SecRule &TX:error_anomaly_score "@eq 0" \ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.error_anomaly_score=4'" SecRule &TX:warning_anomaly_score "@eq 0" \ @@ -166,8 +138,7 @@ SecRule &TX:warning_anomaly_score "@eq 0" \ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.warning_anomaly_score=3'" SecRule &TX:notice_anomaly_score "@eq 0" \ @@ -175,100 +146,117 @@ SecRule &TX:notice_anomaly_score "@eq 0" \ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.notice_anomaly_score=2'" -# Default HTTP policy: allowed_methods (rule 900200 in crs-setup.conf) +# Default do_reput_block +SecRule &TX:do_reput_block "@eq 0" \ + "id:901150,\ + phase:1,\ + pass,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.do_reput_block=0'" + +# Default block duration +SecRule &TX:reput_block_duration "@eq 0" \ + "id:901152,\ + phase:1,\ + pass,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.reput_block_duration=300'" + +# Default HTTP policy: allowed_methods (rule 900200) SecRule &TX:allowed_methods "@eq 0" \ "id:901160,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'" -# Default HTTP policy: allowed_request_content_type (rule 900220 in crs-setup.conf) +# Default HTTP policy: allowed_request_content_type (rule 900220) SecRule &TX:allowed_request_content_type "@eq 0" \ "id:901162,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |multipart/related| |text/xml| |application/xml| |application/soap+xml| |application/json| |application/cloudevents+json| |application/cloudevents-batch+json|'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_request_content_type=|application/x-www-form-urlencoded| |multipart/form-data| |text/xml| |application/xml| |application/soap+xml| |application/json|'" -# Default HTTP policy: allowed_request_content_type_charset (rule 900280 in crs-setup.conf) +# Default HTTP policy: allowed_request_content_type_charset (rule 900270) SecRule &TX:allowed_request_content_type_charset "@eq 0" \ "id:901168,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.allowed_request_content_type_charset=|utf-8| |iso-8859-1| |iso-8859-15| |windows-1252|'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_request_content_type_charset=utf-8|iso-8859-1|iso-8859-15|windows-1252'" -# Default HTTP policy: allowed_http_versions (rule 900230 in crs-setup.conf) +# Default HTTP policy: allowed_http_versions (rule 900230) SecRule &TX:allowed_http_versions "@eq 0" \ "id:901163,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0 HTTP/3 HTTP/3.0'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_http_versions=HTTP/1.0 HTTP/1.1 HTTP/2 HTTP/2.0'" -# Default HTTP policy: restricted_extensions (rule 900240 in crs-setup.conf) +# Default HTTP policy: restricted_extensions (rule 900240) SecRule &TX:restricted_extensions "@eq 0" \ "id:901164,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pem/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.restricted_extensions=.asa/ .asax/ .ascx/ .axd/ .backup/ .bak/ .bat/ .cdx/ .cer/ .cfg/ .cmd/ .com/ .config/ .conf/ .cs/ .csproj/ .csr/ .dat/ .db/ .dbf/ .dll/ .dos/ .htr/ .htw/ .ida/ .idc/ .idq/ .inc/ .ini/ .key/ .licx/ .lnk/ .log/ .mdb/ .old/ .pass/ .pdb/ .pol/ .printer/ .pwd/ .rdb/ .resources/ .resx/ .sql/ .swp/ .sys/ .vb/ .vbs/ .vbproj/ .vsdisco/ .webinfo/ .xsd/ .xsx/'" -# Default HTTP policy: restricted_headers_basic (rule 900250 in crs-setup.conf) -SecRule &TX:restricted_headers_basic "@eq 0" \ +# Default HTTP policy: restricted_headers (rule 900250) +SecRule &TX:restricted_headers "@eq 0" \ "id:901165,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.restricted_headers_basic=/content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.restricted_headers=/accept-charset/ /content-encoding/ /proxy/ /lock-token/ /content-range/ /if/'" -# Default HTTP policy: restricted_headers_extended (rule 900255 in crs-setup.conf) -SecRule &TX:restricted_headers_extended "@eq 0" \ - "id:901171,\ +# Default HTTP policy: static_extensions (rule 900260) +SecRule &TX:static_extensions "@eq 0" \ + "id:901166,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.restricted_headers_extended=/accept-charset/'" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.static_extensions=/.jpg/ /.jpeg/ /.png/ /.gif/ /.js/ /.css/ /.ico/ /.svg/ /.webp/'" -# Default enforcing of body processor URLENCODED (rule 900010 in crs-setup.conf) +# Default enforcing of body processor URLENCODED SecRule &TX:enforce_bodyproc_urlencoded "@eq 0" \ "id:901167,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.enforce_bodyproc_urlencoded=0'" -# Default check for UTF8 encoding validation (rule 900950 in crs-setup.conf) +# Default check for UTF8 encoding validation SecRule &TX:crs_validate_utf8_encoding "@eq 0" \ "id:901169,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'tx.crs_validate_utf8_encoding=0'" +# Default monitor_anomaly_score value +SecRule &TX:monitor_anomaly_score "@eq 0" \ + "id:901170,\ + phase:1,\ + pass,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.monitor_anomaly_score=0'" + # # -=[ Initialize internal variables ]=- # @@ -276,6 +264,7 @@ SecRule &TX:crs_validate_utf8_encoding "@eq 0" \ # Initialize anomaly scoring variables. # All _score variables start at 0, and are incremented by the various rules # upon detection of a possible attack. +# sql_error_match is used for shortcutting rules for performance reasons. SecAction \ "id:901200,\ @@ -283,14 +272,12 @@ SecAction \ pass,\ t:none,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=0',\ - setvar:'tx.detection_inbound_anomaly_score=0',\ - setvar:'tx.inbound_anomaly_score_pl1=0',\ - setvar:'tx.inbound_anomaly_score_pl2=0',\ - setvar:'tx.inbound_anomaly_score_pl3=0',\ - setvar:'tx.inbound_anomaly_score_pl4=0',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.anomaly_score=0',\ + setvar:'tx.anomaly_score_pl1=0',\ + setvar:'tx.anomaly_score_pl2=0',\ + setvar:'tx.anomaly_score_pl3=0',\ + setvar:'tx.anomaly_score_pl4=0',\ setvar:'tx.sql_injection_score=0',\ setvar:'tx.xss_score=0',\ setvar:'tx.rfi_score=0',\ @@ -299,40 +286,42 @@ SecAction \ setvar:'tx.php_injection_score=0',\ setvar:'tx.http_violation_score=0',\ setvar:'tx.session_fixation_score=0',\ - setvar:'tx.blocking_outbound_anomaly_score=0',\ - setvar:'tx.detection_outbound_anomaly_score=0',\ + setvar:'tx.inbound_anomaly_score=0',\ + setvar:'tx.outbound_anomaly_score=0',\ setvar:'tx.outbound_anomaly_score_pl1=0',\ setvar:'tx.outbound_anomaly_score_pl2=0',\ setvar:'tx.outbound_anomaly_score_pl3=0',\ setvar:'tx.outbound_anomaly_score_pl4=0',\ - setvar:'tx.anomaly_score=0'" + setvar:'tx.sql_error_match=0'" # # -=[ Initialize collections ]=- # # Create both Global and IP collections for rules to use. -# Some plugins assume that these two collections have already -# been initialized. -# IP collection is initialized with the IP address concatened with the hashed user agent. +# There are some CRS rules that assume that these two collections +# have already been initiated. +# -# Disable collection initialization by default (see rule 900130 in crs-setup.conf) -# The creation of the IP and the GLOBAL collection is not being tested as -# of this writing due to limits in ftw and our testing setup. -# Proper testing would involve the checking of a variable in the said collections. -SecRule TX:ENABLE_DEFAULT_COLLECTIONS "@eq 1" \ - "id:901320,\ +SecRule REQUEST_HEADERS:User-Agent "@rx ^.*$" \ + "id:901318,\ phase:1,\ pass,\ + t:none,t:sha1,t:hexEncode,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.ua_hash=%{REQUEST_HEADERS.User-Agent}',\ - chain" - SecRule TX:ua_hash "@unconditionalMatch" \ - "t:none,t:sha1,t:hexEncode,\ - initcol:global=global,\ - initcol:ip=%{remote_addr}_%{MATCHED_VAR}" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.ua_hash=%{MATCHED_VAR}'" + +SecAction \ + "id:901321,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + initcol:global=global,\ + initcol:ip=%{remote_addr}_%{tx.ua_hash},\ + setvar:'tx.real_ip=%{remote_addr}'" # # -=[ Initialize Correct Body Processing ]=- @@ -348,9 +337,8 @@ SecRule REQBODY_PROCESSOR "!@rx (?:URLENCODED|MULTIPART|XML|JSON)" \ nolog,\ noauditlog,\ msg:'Enabling body inspection',\ - tag:'OWASP_CRS',\ ctl:forceRequestBodyVariable=On,\ - ver:'OWASP_CRS/4.6.0'" + ver:'OWASP_CRS/3.3.7'" # Force body processor URLENCODED SecRule TX:enforce_bodyproc_urlencoded "@eq 1" \ @@ -361,8 +349,7 @@ SecRule TX:enforce_bodyproc_urlencoded "@eq 1" \ nolog,\ noauditlog,\ msg:'Enabling forced body inspection for ASCII content',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ chain" SecRule REQBODY_PROCESSOR "!@rx (?:URLENCODED|MULTIPART|XML|JSON)" \ "ctl:requestBodyProcessor=URLENCODED" @@ -390,32 +377,57 @@ SecRule TX:enforce_bodyproc_urlencoded "@eq 1" \ # # We take the entropy contained in the UNIQUE_ID. We hash that variable and # take the first integer numbers out of it. Theoretically, it is possible -# but highly improbable that there are no integers in a hexEncoded sha1 hash. -# In the very rare event that two integers are not matched (due to only being -# a-f in all, or all but one positions) 901450 will not be triggered. -# Leading zeros are not removed from the two-digit random number, and are -# handled gracefullly by 901450 +# there are no integers in a sha1 hash. We make sure we get two +# integer numbers by taking the last two digits from the DURATION counter +# (in microseconds). +# Finally, leading zeros are removed from the two-digit random number. +# SecRule TX:sampling_percentage "@eq 100" \ "id:901400,\ phase:1,\ pass,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ skipAfter:END-SAMPLING" -SecRule UNIQUE_ID "@rx ^[a-f]*([0-9])[a-f]*([0-9])" \ +SecRule UNIQUE_ID "@rx ^." \ "id:901410,\ phase:1,\ pass,\ - capture,\ t:sha1,t:hexEncode,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'TX.sampling_rnd100=%{MATCHED_VAR}'" + +SecRule DURATION "@rx (..)$" \ + "id:901420,\ + phase:1,\ + pass,\ + capture,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'TX.sampling_rnd100=%{TX.sampling_rnd100}%{TX.1}'" + +SecRule TX:sampling_rnd100 "@rx ^[a-f]*([0-9])[a-f]*([0-9])" \ + "id:901430,\ + phase:1,\ + pass,\ + capture,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ setvar:'TX.sampling_rnd100=%{TX.1}%{TX.2}'" +SecRule TX:sampling_rnd100 "@rx ^0([0-9])" \ + "id:901440,\ + phase:1,\ + pass,\ + capture,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'TX.sampling_rnd100=%{TX.1}'" + + # # Sampling decision # @@ -436,9 +448,8 @@ SecRule TX:sampling_rnd100 "!@lt %{tx.sampling_percentage}" \ log,\ noauditlog,\ msg:'Sampling: Disable the rule engine based on sampling_percentage %{TX.sampling_percentage} and random number %{TX.sampling_rnd100}',\ - tag:'OWASP_CRS',\ - ctl:ruleRemoveByTag=OWASP_CRS,\ - ver:'OWASP_CRS/4.6.0'" + ctl:ruleEngine=Off,\ + ver:'OWASP_CRS/3.3.7'" SecMarker "END-SAMPLING" @@ -447,14 +458,13 @@ SecMarker "END-SAMPLING" # Configuration Plausibility Checks # -# Make sure detection paranoia level is not lower than paranoia level -SecRule TX:detection_paranoia_level "@lt %{tx.blocking_paranoia_level}" \ +# Make sure executing paranoia level is not lower than paranoia level +SecRule TX:executing_paranoia_level "@lt %{tx.paranoia_level}" \ "id:901500,\ phase:1,\ deny,\ status:500,\ t:none,\ log,\ - msg:'Detection paranoia level configured is lower than the paranoia level itself. This is illegal. Blocking request. Aborting',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0'" + msg:'Executing paranoia level configured is lower than the paranoia level itself. This is illegal. Blocking request. Aborting',\ + ver:'OWASP_CRS/3.3.7'" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf new file mode 100644 index 000000000..be5faa046 --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9001-DRUPAL-EXCLUSION-RULES.conf @@ -0,0 +1,423 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# These exclusions remedy false positives in a default Drupal install. +# The exclusions are only active if crs_exclusions_drupal=1 is set. +# See rule 900130 in crs-setup.conf.example for instructions. + +# +# [ POLICY ] +# +# Drupal is a complex application that is hard to secure with the CRS. This set +# of exclusion rules aims to sanitise the CRS in a way that allows a default +# Drupal setup to be installed and configured without much hassle as far as +# ModSecurity and the CRS are concerned. +# +# The exclusion rules are fairly straight forward in the sense that they +# disable CRS on a set of well-known parameter fields that are often the source +# of false positives / false alarms of the CRS. This includes namely the +# session cookie, the password fields and article/node bodies. +# +# This is based on two assumptions: - You have a basic trust in your +# authenticated users who are allowed to edit nodes. - Drupal allows html +# content in nodes and it protects your users from attacks via these fields. +# +# If you think these assumptions are wrong or if you would prefer a more +# careful/secure approach, you can disable the exclusion rules handling of said +# node body false positives. Do this by placing the following directive in +# RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf. +# +# SecRuleRemoveById 9001200-9001299 +# +# This will mean the CRS remain intact for the editing of node bodies. +# +# The exclusion rules in this file work without the need to define a Drupal +# installation path prefix. Instead they look at the URI from the end - or +# they use regular expressions when targeting dynamic URL. This is all not +# totally foolproof. In some cases, an advanced attacker might be able to +# doctor a request in a way that one of these exclusion rules is triggered +# and the request will bypass all further inspection despite not being a +# Drupal request at all. These exclusion rules could thus be leveraged to +# disable the CRS completely. This is why these rules are off by default. +# +# The CRS rules covered by this ruleset are the rules with Paranoia Level 1 and +# 2. If you chose to run Paranoia Level 3 or 4, you will be facing additional +# false positives which you need to handle yourself. +# +# This set of exclusion rules does not cover any additional Drupal modules +# outside of core. +# +# The exclusion rules are based on Drupal 8.1.10. +# +# And finally: This set of exclusion rules is in an experimental state. If you +# encounter false positives with the basic Drupal functionality and they are +# not covered by this rule file, then please report them. The aim is to be able +# to install and run Drupal core in a seamless manner protected by +# ModSecurity / CRS up to the paranoia level 2. + + +SecRule &TX:crs_exclusions_drupal|TX:crs_exclusions_drupal "@eq 0" \ + "id:9001000,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-DRUPAL-RULE-EXCLUSIONS" + +SecRule &TX:crs_exclusions_drupal|TX:crs_exclusions_drupal "@eq 0" \ + "id:9001001,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-DRUPAL-RULE-EXCLUSIONS" + + +# [ Table of Contents ] +# +# 9001100 Session Cookie +# 9001110 Password +# 9001120 FREE for use +# 9001130 FREE for use +# 9001140 Content and Descriptions +# 9001150 FREE for use +# 9001160 Form Token +# 9001170 Text Formats and Editors +# 9001180 WYSIWYG/CKEditor Assets and Upload +# 9001190 FREE for use +# 9001200 Content and Descriptions +# +# The rule id range from 9001200 to 9001999 is reserved for future +# use (Drupal plugins / modules). + + +# [ Session Cookie ] +# +# Giving the session cookie a dynamic name is most unfortunate +# from a ModSecurity perspective. The rule language does not allow +# us to disable rules in a granular way for individual cookies with +# dynamic names. So we need to disable rule causing false positives +# for all cookies and their names. +# +# Rule Exclusion Session Cookie: 942450 SQL Hex Encoding Identified +# +SecAction "id:9001100,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetById=942450;REQUEST_COOKIES_NAMES,\ + ctl:ruleRemoveTargetById=942450;REQUEST_COOKIES,\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Password ] +# +# Disable the CRS completely for all occurrences of passwords. +# +SecRule REQUEST_FILENAME "@endsWith /core/install.php" \ + "id:9001110,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:account[pass][pass1],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:account[pass][pass2],\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /user/login" \ + "id:9001112,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /admin/people/create" \ + "id:9001114,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass[pass1],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass[pass2],\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@rx /user/[0-9]+/edit$" \ + "id:9001116,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:current_pass,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass[pass1],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass[pass2],\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Admin Settings (general) ] +# +# Disable known false positives for various fields used on admin pages. +# +# Rule Exclusion: 920271 Invalid character in request on multiple fields/paths +# Rule Exclusion: 942430 Restricted SQL Character Anomaly Detection (args) +# Disabled completely for admin/config pages +# For the people/accounts page, we disable the CRS completely for a number of +# freeform text fields. +# +SecRule REQUEST_FILENAME "@contains /admin/config/" \ + "id:9001122,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveById=942430,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /admin/config/people/accounts" \ + "id:9001124,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveById=920271,\ + ctl:ruleRemoveById=942440,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_cancel_confirm_body,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_password_reset_body,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_register_admin_created_body,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_register_no_approval_required_body,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_register_pending_approval_body,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_status_activated_body,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_status_blocked_body,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:user_mail_status_canceled_body,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /admin/config/development/configuration/single/import" \ + "id:9001126,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveById=920271,\ + ctl:ruleRemoveById=942440,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /admin/config/development/maintenance" \ + "id:9001128,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveById=942440,\ + ver:'OWASP_CRS/3.3.7'" + + +# +# +# [ Content and Descriptions ] +# +# Disable known false positives for field "ids[]". +# +# Rule Exclusion: 942130 SQL Injection Attack: SQL Tautology Detected +# +SecRule REQUEST_FILENAME "@endsWith /contextual/render" \ + "id:9001140,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetById=942130;ARGS:ids[],\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Form Token / Build ID ] +# +# Rule Exclusion for form_build_id: 942440 SQL Comment Sequence Detected on ... +# Rule Exclusion for form_token: 942450 SQL Hex Encoding +# Rule Exclusion for form_build_id: 942450 SQL Hex Encoding +# +# This is applied site-wide. +# +SecAction "id:9001160,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetById=942440;ARGS:form_build_id,\ + ctl:ruleRemoveTargetById=942450;ARGS:form_token,\ + ctl:ruleRemoveTargetById=942450;ARGS:form_build_id,\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Text Formats and Editors ] +# +# Disable the CRS completely for two fields triggering many, many rules +# +# Rule Exclusion for two fields: 942440 SQL Comment Sequence Detected +# +SecRule REQUEST_FILENAME "@endsWith /admin/config/content/formats/manage/full_html" \ + "id:9001170,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:editor[settings][toolbar][button_groups],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:filters[filter_html][settings][allowed_html],\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ WYSIWYG/CKEditor Assets and Upload ] +# +# Disable the unnecessary requestBodyAccess and for binary uploads +# bigger than an arbitrary limit of 31486341 bytes. +# +# Extensive checks make sure these uploads are really legitimate. +# +# Rule 9001180 was commented out in 2021 in order to fight CVE-2021-35368. +# +#SecRule REQUEST_METHOD "@streq POST" \ +# "id:9001180,\ +# phase:1,\ +# pass,\ +# t:none,\ +# nolog,\ +# noauditlog,\ +# ver:'OWASP_CRS/3.3.7',\ +# chain" +# SecRule REQUEST_FILENAME "@rx /admin/content/assets/add/[a-z]+$" \ +# "chain" +# SecRule REQUEST_COOKIES:/S?SESS[a-f0-9]+/ "@rx ^[a-zA-Z0-9_-]+" \ +# "ctl:requestBodyAccess=Off" + +# Rule 9001182 was commented out in 2021 in order to fight CVE-2021-35368. +# +#SecRule REQUEST_METHOD "@streq POST" \ +# "id:9001182,\ +# phase:1,\ +# pass,\ +# t:none,\ +# nolog,\ +# noauditlog,\ +# ver:'OWASP_CRS/3.3.7',\ +# chain" +# SecRule REQUEST_FILENAME "@rx /admin/content/assets/manage/[0-9]+$" \ +# "chain" +# SecRule ARGS:destination "@streq admin/content/assets" \ +# "chain" +# SecRule REQUEST_HEADERS:Content-Length "@gt 31486341" \ +# "chain" +# SecRule REQUEST_COOKIES:/S?SESS[a-f0-9]+/ "@rx ^[a-zA-Z0-9_-]+" \ +# "ctl:requestBodyAccess=Off" + +# Rule 9001184 was commented out in 2021 in order to fight CVE-2021-35368. +# +#SecRule REQUEST_METHOD "@streq POST" \ +# "id:9001184,\ +# phase:1,\ +# pass,\ +# t:none,\ +# nolog,\ +# noauditlog,\ +# ver:'OWASP_CRS/3.3.7',\ +# chain" +# SecRule REQUEST_FILENAME "@rx /file/ajax/field_asset_[a-z0-9_]+/[ua]nd/0/form-[a-z0-9A-Z_-]+$" \ +# "chain" +# SecRule REQUEST_HEADERS:Content-Length "@gt 31486341" \ +# "chain" +# SecRule REQUEST_HEADERS:Content-Type "@rx ^(?i)multipart/form-data" \ +# "chain" +# SecRule REQUEST_COOKIES:/S?SESS[a-f0-9]+/ "@rx ^[a-zA-Z0-9_-]+" \ +# "ctl:requestBodyAccess=Off" + + +# +# [ Content and Descriptions ] +# +# Disable the CRS completely for node bodies and other free text fields. +# Other rules are disabled individually. +# +# Rule Exclusion for ARGS:uid[0][target_id]: 942410 SQL Injection Attack +# Rule Exclusion for ARGS:destination: 932110 RCE: Windows Command Inj. +# +SecRule REQUEST_FILENAME "@endsWith /node/add/article" \ + "id:9001200,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:body[0][value],\ + ctl:ruleRemoveTargetById=942410;ARGS:uid[0][target_id],\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /node/add/page" \ + "id:9001202,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:body[0][value],\ + ctl:ruleRemoveTargetById=942410;ARGS:uid[0][target_id],\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@rx /node/[0-9]+/edit$" \ + "id:9001204,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:body[0][value],\ + ctl:ruleRemoveTargetById=942410;ARGS:uid[0][target_id],\ + ctl:ruleRemoveTargetById=932110;ARGS:destination,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /block/add" \ + "id:9001206,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:body[0][value],\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /admin/structure/block/block-content/manage/basic" \ + "id:9001208,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:description,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@rx /editor/filter_xss/(?:full|basic)_html$" \ + "id:9001210,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:value,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@rx /user/[0-9]+/contact$" \ + "id:9001212,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message[0][value],\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /admin/config/development/maintenance" \ + "id:9001214,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:maintenance_mode_message,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@endsWith /admin/config/services/rss-publishing" \ + "id:9001216,\ + phase:2,\ + pass,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:feed_description,\ + ver:'OWASP_CRS/3.3.7'" + + +SecMarker "END-DRUPAL-RULE-EXCLUSIONS" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf new file mode 100644 index 000000000..b72283af3 --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9002-WORDPRESS-EXCLUSION-RULES.conf @@ -0,0 +1,760 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# These exclusions remedy false positives in a default WordPress install. +# The exclusions are only active if crs_exclusions_wordpress=1 is set. +# See rule 900130 in crs-setup.conf.example for instructions. +# +# Note that the WordPress comment field itself is currently NOT excluded +# from checking. The reason is that malicious content is regularly being +# posted to WordPress comment forms, and there have been various cases +# of XSS and even RCE vulnerabilities exploited by WordPress comments. + +SecRule &TX:crs_exclusions_wordpress|TX:crs_exclusions_wordpress "@eq 0" \ + "id:9002000,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-WORDPRESS" + +SecRule &TX:crs_exclusions_wordpress|TX:crs_exclusions_wordpress "@eq 0" \ + "id:9002001,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-WORDPRESS" + + +# +# -=[ WordPress Front-End ]=- +# + + +# +# [ Login form ] +# + +# User login password +SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \ + "id:9002100,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pwd,\ + ver:'OWASP_CRS/3.3.7'" + +# Reset password +SecRule REQUEST_FILENAME "@endsWith /wp-login.php" \ + "id:9002120,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq resetpass" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass2" + + +# +# [ Comments ] +# + +# Post comment +SecRule REQUEST_FILENAME "@endsWith /wp-comments-post.php" \ + "id:9002130,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=931130;ARGS:url,\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Gutenberg Editor ] +# Used when a user (auto)saves a post/page with Gutenberg. +# + +# Gutenberg +SecRule REQUEST_FILENAME "@rx /wp-json/wp/v[0-9]+/(?:posts|pages)" \ + "id:9002140,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:content,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:json.content,\ + ver:'OWASP_CRS/3.3.7'" + +# Gutenberg via rest_route for sites without pretty permalinks +SecRule REQUEST_FILENAME "@endsWith /index.php" \ + "id:9002141,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule &ARGS:rest_route "@eq 1" \ + "t:none,\ + nolog,\ + chain" + SecRule ARGS:rest_route "@rx ^/wp/v[0-9]+/(?:posts|pages)" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:content,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:json.content" + +# Gutenberg upload image/media +SecRule REQUEST_FILENAME "@rx /wp-json/wp/v[0-9]+/media" \ + "id:9002142,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=200002,\ + ctl:ruleRemoveById=200003,\ + ver:'OWASP_CRS/3.3.7'" + +# Gutenberg upload image/media via rest_route for sites without pretty permalinks +SecRule REQUEST_FILENAME "@endsWith /index.php" \ + "id:9002143,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule &ARGS:rest_route "@eq 1" \ + "t:none,\ + nolog,\ + chain" + SecRule ARGS:rest_route "@rx ^/wp/v[0-9]+/media" \ + "t:none,\ + ctl:ruleRemoveById=200002,\ + ctl:ruleRemoveById=200003" + +# +# [ Live preview ] +# Used when an administrator customizes the site and previews the result +# as a normal user. +# + +# Theme select +# Example: wp_customize=on&theme=twentyfifteen&customized= +# {"old_sidebars_widgets_data":{"wp_inactive_widgets":[], +# "sidebar-1":["search-2","recent-posts-2","recent-comments-2", +# "archives-2","categories-2","meta-2"]}}&nonce=XXX& +# customize_messenger_channel=preview-0 +SecRule ARGS:wp_customize "@streq on" \ + "id:9002150,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule &ARGS:action "@eq 0" \ + "t:none,\ + ctl:ruleRemoveTargetById=942200;ARGS:customized,\ + ctl:ruleRemoveTargetById=942260;ARGS:customized,\ + ctl:ruleRemoveTargetById=942300;ARGS:customized,\ + ctl:ruleRemoveTargetById=942330;ARGS:customized,\ + ctl:ruleRemoveTargetById=942340;ARGS:customized,\ + ctl:ruleRemoveTargetById=942370;ARGS:customized,\ + ctl:ruleRemoveTargetById=942430;ARGS:customized,\ + ctl:ruleRemoveTargetById=942431;ARGS:customized,\ + ctl:ruleRemoveTargetById=942460;ARGS:customized" + +# Appearance -> Widgets -> Live Preview +SecRule ARGS:wp_customize "@streq on" \ + "id:9002160,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@rx ^(?:|customize_save|update-widget)$" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=942200;ARGS:customized,\ + ctl:ruleRemoveTargetById=942260;ARGS:customized,\ + ctl:ruleRemoveTargetById=942300;ARGS:customized,\ + ctl:ruleRemoveTargetById=942330;ARGS:customized,\ + ctl:ruleRemoveTargetById=942340;ARGS:customized,\ + ctl:ruleRemoveTargetById=942370;ARGS:customized,\ + ctl:ruleRemoveTargetById=942430;ARGS:customized,\ + ctl:ruleRemoveTargetById=942431;ARGS:customized,\ + ctl:ruleRemoveTargetById=942460;ARGS:customized,\ + ctl:ruleRemoveTargetById=920230;ARGS:partials,\ + ctl:ruleRemoveTargetById=941320;ARGS:partials,\ + ctl:ruleRemoveTargetById=942180;ARGS:partials,\ + ctl:ruleRemoveTargetById=942200;ARGS:partials,\ + ctl:ruleRemoveTargetById=942260;ARGS:partials,\ + ctl:ruleRemoveTargetById=942330;ARGS:partials,\ + ctl:ruleRemoveTargetById=942340;ARGS:partials,\ + ctl:ruleRemoveTargetById=942370;ARGS:partials,\ + ctl:ruleRemoveTargetById=942430;ARGS:partials,\ + ctl:ruleRemoveTargetById=942431;ARGS:partials,\ + ctl:ruleRemoveTargetById=942460;ARGS:partials" + + + +# Self calls to wp-cron.php?doing_wp_cron=[timestamp] +# These requests may be missing Accept, Content-Length headers. +# This rule must run in phase:1. +SecRule REQUEST_FILENAME "@endsWith /wp-cron.php" \ + "id:9002200,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=920180,\ + ctl:ruleRemoveById=920300,\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Cookies ] + +# WP Session Manager +# Cookie: _wp_session=[hex]||[timestamp]||[timestamp] +# detected SQLi using libinjection with fingerprint 'n&1' +SecRule REQUEST_COOKIES:_wp_session "@rx ^[0-9a-f]+\|\|\d+\|\|\d+$" \ + "id:9002300,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule &REQUEST_COOKIES:_wp_session "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=942100;REQUEST_COOKIES:_wp_session" + + +# +# -=[ WordPress Administration Back-End (wp-admin) ]=- +# + +# Skip this section for performance unless /wp-admin/ is in filename + +SecRule REQUEST_FILENAME "!@contains /wp-admin/" \ + "id:9002400,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-WORDPRESS-ADMIN" + +SecRule REQUEST_FILENAME "!@contains /wp-admin/" \ + "id:9002401,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-WORDPRESS-ADMIN" + + +# +# [ Installation ] +# + +# WordPress installation: exclude database password +SecRule REQUEST_FILENAME "@endsWith /wp-admin/setup-config.php" \ + "id:9002410,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:step "@streq 2" \ + "t:none,\ + chain" + SecRule &ARGS:step "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pwd" + +# WordPress installation: exclude admin password +SecRule REQUEST_FILENAME "@endsWith /wp-admin/install.php" \ + "id:9002420,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:step "@streq 2" \ + "t:none,\ + chain" + SecRule &ARGS:step "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:admin_password,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:admin_password2,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text" + + +# +# [ User management ] +# + +# Edit logged-in user +SecRule REQUEST_FILENAME "@endsWith /wp-admin/profile.php" \ + "id:9002520,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq update" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=931130;ARGS:url,\ + ctl:ruleRemoveTargetById=931130;ARGS:facebook,\ + ctl:ruleRemoveTargetById=931130;ARGS:instagram,\ + ctl:ruleRemoveTargetById=931130;ARGS:linkedin,\ + ctl:ruleRemoveTargetById=931130;ARGS:myspace,\ + ctl:ruleRemoveTargetById=931130;ARGS:pinterest,\ + ctl:ruleRemoveTargetById=931130;ARGS:soundcloud,\ + ctl:ruleRemoveTargetById=931130;ARGS:tumblr,\ + ctl:ruleRemoveTargetById=931130;ARGS:youtube,\ + ctl:ruleRemoveTargetById=931130;ARGS:wikipedia,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass2" + +# Edit user +SecRule REQUEST_FILENAME "@endsWith /wp-admin/user-edit.php" \ + "id:9002530,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq update" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=931130;ARGS:url,\ + ctl:ruleRemoveTargetById=931130;ARGS:url,\ + ctl:ruleRemoveTargetById=931130;ARGS:facebook,\ + ctl:ruleRemoveTargetById=931130;ARGS:instagram,\ + ctl:ruleRemoveTargetById=931130;ARGS:linkedin,\ + ctl:ruleRemoveTargetById=931130;ARGS:myspace,\ + ctl:ruleRemoveTargetById=931130;ARGS:pinterest,\ + ctl:ruleRemoveTargetById=931130;ARGS:soundcloud,\ + ctl:ruleRemoveTargetById=931130;ARGS:tumblr,\ + ctl:ruleRemoveTargetById=931130;ARGS:youtube,\ + ctl:ruleRemoveTargetById=931130;ARGS:wikipedia,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass2" + +# Create user +SecRule REQUEST_FILENAME "@endsWith /wp-admin/user-new.php" \ + "id:9002540,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq createuser" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=931130;ARGS:url,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass2" + + +# +# [ General exclusions ] +# + +# _wp_http_referer and wp_http_referer are passed on a lot of wp-admin pages +SecAction \ + "id:9002600,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=920230;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=931130;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=932150;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=941100;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=942130;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=942200;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=942260;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=942431;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=942440;ARGS:_wp_http_referer,\ + ctl:ruleRemoveTargetById=920230;ARGS:wp_http_referer,\ + ctl:ruleRemoveTargetById=931130;ARGS:wp_http_referer,\ + ctl:ruleRemoveTargetById=932150;ARGS:wp_http_referer,\ + ctl:ruleRemoveTargetById=941100;ARGS:wp_http_referer,\ + ctl:ruleRemoveTargetById=942130;ARGS:wp_http_referer,\ + ctl:ruleRemoveTargetById=942200;ARGS:wp_http_referer,\ + ctl:ruleRemoveTargetById=942260;ARGS:wp_http_referer,\ + ctl:ruleRemoveTargetById=942431;ARGS:wp_http_referer,\ + ver:'OWASP_CRS/3.3.7'" + +# +# [ Content editing ] +# + +# Edit posts and pages +# /wp-admin/post.php, /wp-admin/post.php?t=[timestamp] +# - Themes do not properly escape post_title in HTML, so beware of XSS +# and be conservative in excluding this parameter. +# - Parameter _wp_http_referer can appear multiple times. +SecRule REQUEST_FILENAME "@endsWith /wp-admin/post.php" \ + "id:9002700,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@rx ^(?:edit|editpost)$" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:post_title,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:content,\ + ctl:ruleRemoveById=920272,\ + ctl:ruleRemoveById=921180" + +# Autosave posts and pages +# ARGS_NAMES:data[wp-check-locked-posts][] can appear multiple times +SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ + "id:9002710,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq heartbeat" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:data[wp_autosave][post_title],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:data[wp_autosave][content],\ + ctl:ruleRemoveTargetById=942431;ARGS_NAMES:data[wp-refresh-post-lock][post_id],\ + ctl:ruleRemoveTargetById=942431;ARGS_NAMES:data[wp-refresh-post-lock][lock],\ + ctl:ruleRemoveTargetById=942431;ARGS_NAMES:data[wp-check-locked-posts][],\ + ctl:ruleRemoveById=921180,\ + ctl:ruleRemoveById=920272" + +# Edit menus +SecRule REQUEST_FILENAME "@endsWith /wp-admin/nav-menus.php" \ + "id:9002720,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq update" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=942460;ARGS:menu-name,\ + ctl:ruleRemoveTargetById=941330;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=941340;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=942200;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=942260;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=942330;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=942340;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=942430;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=942431;ARGS:nav-menu-data,\ + ctl:ruleRemoveTargetById=942460;ARGS:nav-menu-data" + +# Edit text widgets (can contain custom HTML) +SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ + "id:9002730,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@rx ^(?:save-widget|update-widget)$" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[0][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[1][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[2][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[3][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[4][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[5][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[6][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[7][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[8][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[9][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[10][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[11][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[12][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[13][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[14][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[15][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[16][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[17][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[18][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[19][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[20][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[21][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[22][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[23][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[24][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[25][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[26][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[27][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[28][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[29][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[30][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[31][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[32][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[33][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[34][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[35][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[36][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[37][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[38][text],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:widget-text[39][text]" + +# Reorder widgets +SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ + "id:9002740,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq widgets-order" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-1],\ + ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-1],\ + ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-2],\ + ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-2],\ + ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-3],\ + ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-3],\ + ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-4],\ + ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-4],\ + ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-5],\ + ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-5],\ + ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-6],\ + ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-6],\ + ctl:ruleRemoveTargetById=942430;ARGS:sidebars[sidebar-7],\ + ctl:ruleRemoveTargetById=942431;ARGS:sidebars[sidebar-7]" + +# Create permalink sample for new post +SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ + "id:9002750,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq sample-permalink" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=attack-sqli;ARGS:new_title" + +# Add external link to menu +SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ + "id:9002760,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq add-menu-item" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=931130;ARGS:menu-item[-1][menu-item-url]" + +# Editor: Add Media, Insert Media, Insert into page +SecRule REQUEST_FILENAME "@endsWith /wp-admin/admin-ajax.php" \ + "id:9002770,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq send-attachment-to-editor" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:html" + + +# +# [ Options and Settings ] +# + +# Change site URL +SecRule REQUEST_FILENAME "@endsWith /wp-admin/options.php" \ + "id:9002800,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:option_page "@streq general" \ + "t:none,\ + chain" + SecRule &ARGS:option_page "@eq 1" \ + "t:none,\ + chain" + SecRule ARGS:action "@streq update" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetById=931130;ARGS:home,\ + ctl:ruleRemoveTargetById=931130;ARGS:siteurl" + +# Permalink settings +# permalink_structure=/index.php/%year%/%monthnum%/%day%/%postname%/ +SecRule REQUEST_FILENAME "@endsWith /wp-admin/options-permalink.php" \ + "id:9002810,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=920230;ARGS:selection,\ + ctl:ruleRemoveTargetById=920272;ARGS:selection,\ + ctl:ruleRemoveTargetById=942431;ARGS:selection,\ + ctl:ruleRemoveTargetById=920230;ARGS:permalink_structure,\ + ctl:ruleRemoveTargetById=920272;ARGS:permalink_structure,\ + ctl:ruleRemoveTargetById=942431;ARGS:permalink_structure,\ + ctl:ruleRemoveTargetById=920272;REQUEST_BODY,\ + ver:'OWASP_CRS/3.3.7'" + +# Comments blacklist and moderation list +SecRule REQUEST_FILENAME "@endsWith /wp-admin/options.php" \ + "id:9002820,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:option_page "@streq discussion" \ + "t:none,\ + chain" + SecRule &ARGS:option_page "@eq 1" \ + "t:none,\ + chain" + SecRule ARGS:action "@streq update" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:blacklist_keys,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:moderation_keys" + +# Posts/pages overview search +SecRule REQUEST_FILENAME "@endsWith /wp-admin/edit.php" \ + "id:9002830,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:s,\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Helpers ] +# + +# /wp-admin/load-scripts.php?c=0&load%5B%5D=hoverIntent,common, +# admin-bar,wp-ajax-response,jquery-color,wp-lists,quicktags, +# jquery-query,admin-comments,svg-painter,heartbeat,&load%5B%5D= +# wp-auth-check,wp-a11y,wplink,jquery-ui-core,jquery-ui-widget, +# jquery-ui-position,jquery-ui-menu,jquery-ui-autocomplete&ver=4.6.1 +# +# /wp-admin/load-styles.php?c=0&dir=ltr&load%5B%5D=dashicons, +# admin-bar,buttons,media-views,common,forms,admin-menu,dashboard, +# list-tables,edit,revisions,media,themes,about,nav-menu&load%5B%5D= +# s,widgets,site-icon,l10n,wp-auth-check&ver=4.6.1 +# +# /wp-admin/load-scripts.php?c=0&load%5B%5D=hoverIntent,common, +# admin-bar,jquery-ui-widget,jquery-ui-position,wp-pointer, +# wp-ajax-response,jquery-color,wp-lists,quicktags, +# jqu&load%5B%5D=ery-query,admin-comments,jquery-ui-core, +# jquery-ui-mouse,jquery-ui-sortable,postbox,dashboard,underscore, +# customize-base,customize&load%5B%5D=-loader,thickbox,plugin-install, +# wp-util,wp-a11y,updates,shortcode,media-upload,svg-painter, +# jquery-ui-accordion&ver=3f9999390861a0133beda3ee8acf152e +SecRule REQUEST_FILENAME "@rx /wp-admin/load-(?:scripts|styles)\.php$" \ + "id:9002900,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=921180,\ + ctl:ruleRemoveTargetById=920273;ARGS_NAMES:load[],\ + ctl:ruleRemoveTargetById=942432;ARGS_NAMES:load[],\ + ctl:ruleRemoveTargetById=942360;ARGS:load[],\ + ctl:ruleRemoveTargetById=942430;ARGS:load[],\ + ctl:ruleRemoveTargetById=942431;ARGS:load[],\ + ctl:ruleRemoveTargetById=942432;ARGS:load[],\ + ver:'OWASP_CRS/3.3.7'" + + +SecMarker "END-WORDPRESS-ADMIN" + + +SecMarker "END-WORDPRESS" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf new file mode 100644 index 000000000..a071a2756 --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9003-NEXTCLOUD-EXCLUSION-RULES.conf @@ -0,0 +1,416 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# +# ------------------------------------------------------------------------ + +# These exclusions remedy false positives in a default NextCloud install. +# They will likely work with OwnCloud too, but you may have to modify them. +# The exclusions are only active if crs_exclusions_nextcloud=1 is set. +# See rule 900130 in crs-setup.conf.example for instructions. +# +# To relax upload restrictions for only the php files that need it, +# you put something like this in crs-setup.conf: +# +# SecRule REQUEST_FILENAME "@rx /(?:remote.php|index.php)/" \ +# "id:9003330,\ +# phase:1,\ +# t:none,\ +# nolog,\ +# pass,\ +# tx.restricted_extensions='.bak/ .config/ .conf/'" +# +# Large uploads can be modified with SecRequestBodyLimit. Or they +# can be more controlled by using the following: +# +# SecRule REQUEST_URI "@endsWith /index.php/apps/files/ajax/upload.php" \ +# "id:9003610,\ +# phase:1,\ +# t:none,\ +# nolog,\ +# ctl:requestBodyLimit=1073741824" +# +# --------------------- + + +SecRule &TX:crs_exclusions_nextcloud|TX:crs_exclusions_nextcloud "@eq 0" \ + "id:9003000,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-NEXTCLOUD" + +SecRule &TX:crs_exclusions_nextcloud|TX:crs_exclusions_nextcloud "@eq 0" \ + "id:9003001,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-NEXTCLOUD" + + +# +# [ File Manager ] +# +# +# The web interface uploads files, and interacts with the user. + +SecRule REQUEST_FILENAME "@contains /remote.php/webdav" \ + "id:9003100,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveByTag=attack-injection-php,\ + ctl:ruleRemoveById=941000-942999,\ + ctl:ruleRemoveById=951000-951999,\ + ctl:ruleRemoveById=953100-953130,\ + ctl:ruleRemoveById=920420,\ + ctl:ruleRemoveById=920440,\ + ver:'OWASP_CRS/3.3.7'" + +# Skip PUT parsing for invalid encoding / protocol violations in binary files. + +SecRule REQUEST_METHOD "@streq PUT" \ + "id:9003105,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule REQUEST_FILENAME "@contains /remote.php/webdav" \ + "t:none,\ + ctl:ruleRemoveById=920000-920999,\ + ctl:ruleRemoveById=932000-932999,\ + ctl:ruleRemoveById=921150,\ + ctl:ruleRemoveById=930110,\ + ctl:ruleRemoveById=930120" + +# Allow the data type 'text/vcard' + +SecRule REQUEST_FILENAME "@contains /remote.php/dav/files/" \ + "id:9003110,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type} |text/vcard|'" + +# Allow the data type 'application/octet-stream' + +SecRule REQUEST_METHOD "@rx ^(?:PUT|MOVE)$" \ + "id:9003115,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule REQUEST_FILENAME "@rx /remote\.php/dav/(?:files|uploads)/" \ + "setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type} |application/octet-stream|'" + +# Allow data types like video/mp4 + +SecRule REQUEST_METHOD "@streq PUT" \ + "id:9003116,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule REQUEST_FILENAME "@rx (?:/public\.php/webdav/|/remote\.php/dav/uploads/)" \ + "ctl:ruleRemoveById=920340,\ + ctl:ruleRemoveById=920420" + + +# Allow characters like /../ in files. +# Allow all kind of filetypes. +# Allow source code. + +SecRule REQUEST_FILENAME "@contains /remote.php/dav/files/" \ + "id:9003120,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=930100-930110,\ + ctl:ruleRemoveById=951000-951999,\ + ctl:ruleRemoveById=953100-953130,\ + ctl:ruleRemoveById=920440,\ + ver:'OWASP_CRS/3.3.7'" + +# Allow REPORT requests without Content-Type header (at least the iOS app does this) + +SecRule REQUEST_METHOD "@streq REPORT" \ + "id:9003121,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + chain" + SecRule REQUEST_FILENAME "@contains /remote.php/dav/files/" \ + "t:none,\ + ctl:ruleRemoveById=920340" + + +# [ Searchengine ] +# +# NexCloud uses a search field for filename or content queries. + +SecRule REQUEST_FILENAME "@contains /index.php/core/search" \ + "id:9003125,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=attack-injection-php;ARGS:query,\ + ctl:ruleRemoveTargetById=941000-942999;ARGS:query,\ + ctl:ruleRemoveTargetById=932000-932999;ARGS:query,\ + ver:'OWASP_CRS/3.3.7'" + + +# [ DAV ] +# +# NextCloud uses DAV methods with index.php and remote.php to do many things +# The default ones in ModSecurity are: GET HEAD POST OPTIONS +# +# Looking through the code, and via testing, I found these: +# +# File manager: PUT DELETE MOVE PROPFIND PROPPATCH +# Calendars: REPORT +# Others in the code or js files: PATCH MKCOL MOVE TRACE +# Others that I added just in case, and they seem related: +# CHECKOUT COPY LOCK MERGE MKACTIVITY UNLOCK. + +SecRule REQUEST_FILENAME "@rx /(?:remote|index|public)\.php/" \ + "id:9003130,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_methods=%{tx.allowed_methods} PUT PATCH CHECKOUT COPY DELETE LOCK MERGE MKACTIVITY MKCOL MOVE PROPFIND PROPPATCH UNLOCK REPORT TRACE jsonp'" + + +# We need to allow DAV methods for sharing files, and removing shares +# DELETE - when the share is removed +# PUT - when setting a password / expiration time + +SecRule REQUEST_FILENAME "@rx /ocs/v[0-9]+\.php/apps/files_sharing/" \ + "id:9003140,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_methods=%{tx.allowed_methods} PUT DELETE'" + + +# [ Preview and Thumbnails ] + +SecRule REQUEST_FILENAME "@contains /index.php/core/preview.png" \ + "id:9003150,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=932150;ARGS:file,\ + ver:'OWASP_CRS/3.3.7'" + +# Filepreview for trashbin + +SecRule REQUEST_FILENAME "@contains /index.php/apps/files_trashbin/ajax/preview.php" \ + "id:9003155,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=932150;ARGS:file,\ + ctl:ruleRemoveTargetById=942190;ARGS:file,\ + ver:'OWASP_CRS/3.3.7'" + +SecRule REQUEST_FILENAME "@rx /index\.php/(?:apps/gallery/thumbnails|logout$)" \ + "id:9003160,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=941120;ARGS:requesttoken,\ + ver:'OWASP_CRS/3.3.7'" + + +# [ Ownnote ] + +SecRule REQUEST_FILENAME "@contains /index.php/apps/ownnote/" \ + "id:9003300,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=941150,\ + ver:'OWASP_CRS/3.3.7'" + + +# [ Text Editor ] +# +# This file can save anything, and it's name could be lots of things. + +SecRule REQUEST_FILENAME "@contains /index.php/apps/files_texteditor/" \ + "id:9003310,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:filecontents,\ + ctl:ruleRemoveTargetById=921110-921160;ARGS:filecontents,\ + ctl:ruleRemoveTargetById=932150;ARGS:filename,\ + ctl:ruleRemoveTargetById=920370-920390;ARGS:filecontents,\ + ctl:ruleRemoveTargetById=920370-920390;ARGS_COMBINED_SIZE,\ + ver:'OWASP_CRS/3.3.7'" + + +# [ Address Book ] +# +# Allow the data type 'text/vcard' + +SecRule REQUEST_FILENAME "@contains /remote.php/dav/addressbooks/" \ + "id:9003320,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type} |text/vcard|'" + +# Allow modifying contacts via the web interface +SecRule REQUEST_METHOD "@streq PUT" \ + "id:9003321,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + chain" + SecRule REQUEST_FILENAME "@contains /remote.php/dav/addressbooks/" \ + "t:none,\ + ctl:ruleRemoveById=200002" + + +# [ Calendar ] +# +# Allow the data type 'text/calendar' + +SecRule REQUEST_FILENAME "@contains /remote.php/dav/calendars/" \ + "id:9003330,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type} |text/calendar|'" + +# Allow modifying calendar events via the web interface +SecRule REQUEST_METHOD "@streq PUT" \ + "id:9003331,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + chain" + SecRule REQUEST_FILENAME "@contains /remote.php/dav/calendars/" \ + "t:none,\ + ctl:ruleRemoveById=200002" + + +# [ Notes ] +# +# We want to allow a lot of things as the user is +# allowed to note on anything. + +SecRule REQUEST_FILENAME "@contains /index.php/apps/notes/" \ + "id:9003340,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveByTag=attack-injection-php,\ + ver:'OWASP_CRS/3.3.7'" + + +# [ Bookmarks ] +# +# Allow urls in data. + +SecRule REQUEST_FILENAME "@contains /index.php/apps/bookmarks/" \ + "id:9003350,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=931130,\ + ver:'OWASP_CRS/3.3.7'" + + +# +# [ Login forms ] +# + +# This removes checks on the 'password' and related fields: + +# User login password. + +SecRule REQUEST_FILENAME "@contains /index.php/login" \ + "id:9003400,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=941100;ARGS:requesttoken,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:password,\ + ver:'OWASP_CRS/3.3.7'" + +# Reset password. + +SecRule REQUEST_FILENAME "@endsWith /index.php/login" \ + "id:9003410,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:action "@streq resetpass" \ + "t:none,\ + chain" + SecRule &ARGS:action "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass2" + +# Change Password and Setting up a new user/password + +SecRule REQUEST_FILENAME "@endsWith /index.php/settings/users" \ + "id:9003500,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:newuserpassword,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:password,\ + ver:'OWASP_CRS/3.3.7'" + + +SecMarker "END-NEXTCLOUD-ADMIN" + +SecMarker "END-NEXTCLOUD" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf new file mode 100644 index 000000000..e9da034de --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9004-DOKUWIKI-EXCLUSION-RULES.conf @@ -0,0 +1,273 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# +# ------------------------------------------------------------------------ + +# These exclusions remedy false positives in a default Dokuwiki install. +# The exclusions are only active if crs_exclusions_dokuwiki=1 is set. +# See rule 900130 in crs-setup.conf.example for instructions. +# +# Note, if you want to relax the upload restrictions, +# see rule 900240. For Dokuwiki you can limit the exception +# to the ajax.php file: +# +# SecRule REQUEST_FILENAME "@endsWith /lib/exe/ajax.php" ... +# + + +SecRule &TX:crs_exclusions_dokuwiki|TX:crs_exclusions_dokuwiki "@eq 0" \ + "id:9004000,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-DOKUWIKI" + +SecRule &TX:crs_exclusions_dokuwiki|TX:crs_exclusions_dokuwiki "@eq 0" \ + "id:9004001,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-DOKUWIKI" + + +# +# -=[ Dokuwiki Front-End ]=- +# +# Note on files specified: +# /doku.php: shows pages, saves, edits, admin +# /lib/exe/ajax.php: autosave, uploads +# +# Allow pages to be edited, and ajax to save drafts. +# +# ARGS 'wikitext', 'suffix', and 'prefix' must allow the same things, +# as the page (in part or whole) is passed via 'suffix/prefix' at times. +# attack-protocol (921110-921160/920230): Allows odd characters on the page. +# CRS: (still need attack-protocol specified.) +# attack-injection-php (930000-933999): Allows code on page. +# attack-sqli (940000-942999): Allows SQL expressions on page. +# +# Others: +# 930100-930110;REQUEST_BODY: if there's a /../ in the text. +# +# ARGS:summary (the text in the 'summary' box on page edits.): +# Allowing 930120-930130 lets user save summaries with +# system file names. This should not be needed in normal +# use. But leaving a note here of how to allow in rule below: +# ctl:ruleRemoveTargetById=930120;ARGS:summary +# ctl:ruleRemoveTargetById=930130;ARGS:summary +# +# Also, can't specify: +# SecRule ARGS:do "@streq edit" \ +# SecRule REQUEST_FILENAME "@endsWith /lib/exe/ajax.php"\ +# because at times the do=edit can get dropped, so if we use +# above the edit will get blocked when the page is saved. + +# Hint: those using .htaccess rewrites can remove/replace +# this first 'SecRule...' line with 'SecAction \' (unsupported). + +SecRule REQUEST_FILENAME "@rx (?:/doku.php|/lib/exe/ajax.php)$" \ + "id:9004100,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule REQUEST_METHOD "@streq POST" \ + "t:none,\ + chain" + SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=attack-protocol;ARGS:wikitext,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:wikitext,\ + ctl:ruleRemoveTargetByTag=attack-protocol;ARGS:suffix,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:suffix,\ + ctl:ruleRemoveTargetByTag=attack-protocol;ARGS:prefix,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:prefix,\ + ctl:ruleRemoveTargetById=930100-930110;REQUEST_BODY" + + +# Allow it to upload files. But check for cookies just to make sure. + +SecRule REQUEST_FILENAME "@endsWith /lib/exe/ajax.php" \ + "id:9004110,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + noauditlog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule REQUEST_METHOD "@streq POST" \ + "t:none,\ + chain" + SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \ + "t:none,\ + setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type}|application/octet-stream'" + + +# Show the index, even if things like "postgresql" or other things show up. + +SecRule REQUEST_FILENAME "@endsWith /doku.php" \ + "id:9004130,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + noauditlog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:do "@streq index" \ + "t:none,\ + chain" + SecRule &ARGS:do "@eq 1" \ + "t:none,\ + ctl:ruleRemoveById=951240,\ + ctl:ruleRemoveById=953110" + + +# +# [ Login form ] +# + +# Turn off checks for password. + +SecRule REQUEST_FILENAME "@endsWith /doku.php" \ + "id:9004200,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + noauditlog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:do "@streq login" \ + "t:none,\ + chain" + SecRule &ARGS:do "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:p" + + +# +# [ Admin Area ] +# +# Skip this section for performance unless do=admin is in request + +SecRule ARGS:do "!@streq admin" \ + "id:9004300,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-DOKUWIKI-ADMIN" + +SecRule ARGS:do "!@streq admin" \ + "id:9004310,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-DOKUWIKI-ADMIN" + + +# [ Reset password ] +# +# Turn off checks for pass1, pass1-text, pass2 + +SecRule REQUEST_FILENAME "@endsWith /doku.php" \ + "id:9004320,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + noauditlog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:do "@streq login" \ + "t:none,\ + chain" + SecRule &ARGS:do "@eq 1" \ + "t:none,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass2" + + +# [ Save config ] +# +# Allow the config to be saved: +# 942200: If the user adds "..." to tagline: ARGS:config[tagline] +# 942430: if ARGS:config[hidepages] has pages looking like sql statements +# 942430,942440: "--- //[[@MAIL@|@NAME@]] @DATE@//"]" in ARGS:config[signature] + +SecRule REQUEST_FILENAME "@endsWith /doku.php" \ + "id:9004370,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + noauditlog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:page "@streq config" \ + "t:none,\ + chain" + SecRule &ARGS:page "@eq 1" \ + "t:none,\ + chain" + SecRule REQUEST_METHOD "@streq POST" \ + "t:none,\ + chain" + SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \ + "t:none,\ + ctl:ruleRemoveTargetById=920230;ARGS:config[dformat],\ + ctl:ruleRemoveTargetById=942200;ARGS:config[tagline],\ + ctl:ruleRemoveTargetById=942430;ARGS:config[hidepages],\ + ctl:ruleRemoveTargetById=942430-942440;ARGS:config[signature]" + + +# When the config loads after a save, it gets blocked because +# it has 'readdir' and lines that look like sql +# 942430,942440: "--- //[[@MAIL@|@NAME@]] @DATE@//"]" in ARGS:config[signature] +# 951240,953110: When the page reloads, it triggers +# postgres and php code disclosure rules. + +SecRule REQUEST_FILENAME "@endsWith /doku.php" \ + "id:9004380,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + noauditlog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule ARGS:page "@streq config" \ + "t:none,\ + chain" + SecRule &ARGS:page "@eq 1" \ + "t:none,\ + chain" + SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \ + "t:none,\ + ctl:ruleRemoveById=951240,\ + ctl:ruleRemoveById=953110" + + +# End [ Admin Area ] + +SecMarker "END-DOKUWIKI-ADMIN" + +SecMarker "END-DOKUWIKI" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf new file mode 100644 index 000000000..fc1e19caf --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9005-CPANEL-EXCLUSION-RULES.conf @@ -0,0 +1,64 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# These exclusions remedy false positives in a default cPanel environment. +# The exclusions are only active if crs_exclusions_cpanel=1 is set. +# See rule 900130 in crs-setup.conf.example for instructions. + + +SecRule &TX:crs_exclusions_cpanel|TX:crs_exclusions_cpanel "@eq 0" \ + "id:9005000,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-CPANEL" + +SecRule &TX:crs_exclusions_cpanel|TX:crs_exclusions_cpanel "@eq 0" \ + "id:9005001,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-CPANEL" + + +# +# [ cPanel whm-server-status ] +# +# Cpanel's WHM auto generates requests to /whm-server-status from +# 127.0.0.1 (triggers rule 920280, non-blocking, log only) Once every 5 minutes. +# These false positives have a low impact (logged, non-blocking) to a large number of users (all cPanel admins). +# + +# +# Rule to allow cPanel whm-server-status requests from localhost without log entry. +# +SecRule REQUEST_LINE "@rx ^GET /whm-server-status(?:/|/\?auto)? HTTP/[12]\.[01]$" \ + "id:9005100,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-apache',\ + tag:'attack-generic',\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule REMOTE_ADDR "@ipMatch 127.0.0.1,::1" \ + "t:none,\ + ctl:ruleRemoveById=920280,\ + ctl:ruleRemoveById=920350" + + +SecMarker "END-CPANEL" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf new file mode 100644 index 000000000..23d7ff0db --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-903.9006-XENFORO-EXCLUSION-RULES.conf @@ -0,0 +1,587 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# These exclusions remedy false positives in a default XenForo install. +# The exclusions are only active if crs_exclusions_xenforo=1 is set. +# See rule 900130 in crs-setup.conf.example for instructions. + +SecRule &TX:crs_exclusions_xenforo|TX:crs_exclusions_xenforo "@eq 0" \ + "id:9006000,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-XENFORO" + +SecRule &TX:crs_exclusions_xenforo|TX:crs_exclusions_xenforo "@eq 0" \ + "id:9006001,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-XENFORO" + + +# +# -=[ XenForo Front-End ]=- +# + +# Proxy for images and remote content embedded in forum posts +# GET /xf/proxy.php?image=https://example.com/some.jpg&hash=foo +# GET /xf/proxy.php?link=https://example.com&hash=foo +# POST /xf/proxy.php, body: referrer=... +SecRule REQUEST_FILENAME "@endsWith /proxy.php" \ + "id:9006100,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:image,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:link,\ + ctl:ruleRemoveTargetById=931130;ARGS:referrer,\ + ctl:ruleRemoveTargetById=942230;ARGS:referrer,\ + ver:'OWASP_CRS/3.3.7'" + +# Store drafts for private message, forum post, thread reply +# POST /xf/conversations/draft +# POST /xf/conversations/convo-title.12345/draft +# POST /xf/forums/forum-title.12345/draft +# POST /xf/threads/thread-title-%E2%98%85.12345/draft +# +# attachment_hash_combined example: +# {"type":"post","context":{"post_id":12345},"hash":"0123456789abcdef..."} +SecRule REQUEST_FILENAME "@rx /(?:conversations|(?:conversations|forums|threads)/.*)/draft$" \ + "id:9006110,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=931130;ARGS:href,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:title,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message_html,\ + ctl:ruleRemoveTargetById=942200;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942260;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942340;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942370;ARGS:attachment_hash_combined,\ + ver:'OWASP_CRS/3.3.7'" + +# Send PM, edit post, create thread, reply to thread +# POST /xf/conversations/add +# POST /xf/conversations/add-preview +# POST /xf/conversations/messages/1463947/edit +# POST /xf/posts/12345/edit +# POST /xf/posts/12345/preview +# POST /xf/conversations/convo-title.12345/add-reply +# POST /xf/threads/thread-title.12345/add-reply +# POST /xf/threads/thread-title.12345/reply-preview +# POST /xf/forums/forum-title.12345/post-thread +# POST /xf/forums/blogs/post-thread +# POST /xf/forums/forum-title.12345/thread-preview +SecRule REQUEST_FILENAME "@rx /(?:conversations/add(?:-preview)?|conversations/messages/\d+/edit|posts/\d+/(?:edit|preview)|(?:conversations|threads)/.*\.\d+/(?:add-reply|reply-preview)|forums/.*/(?:post-thread|thread-preview))$" \ + "id:9006120,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:title,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message_html,\ + ctl:ruleRemoveTargetById=942200;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942260;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942340;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942370;ARGS:attachment_hash_combined,\ + ver:'OWASP_CRS/3.3.7'" + +# Quote +# POST /xf/posts/12345/quote +SecRule REQUEST_FILENAME "@rx /posts/\d+/quote$" \ + "id:9006130,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:quoteHtml,\ + ver:'OWASP_CRS/3.3.7'" + +# Multi quote +# POST /xf/conversations/convo-title.12345/multi-quote +# POST /xf/threads/thread-title.12345/multi-quote +# quotes={"12345":["quote-html"]} +SecRule REQUEST_FILENAME "@rx /(?:conversations|threads)/.*\.\d+/multi-quote$" \ + "id:9006140,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:quotes,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[0][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[1][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[2][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[3][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[4][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[5][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[6][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[7][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[8][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:insert[9][value],\ + ver:'OWASP_CRS/3.3.7'" + +# Delete thread +# POST /xf/threads/thread-title.12345/delete +SecRule REQUEST_FILENAME "@rx /threads/.*\.\d+/delete$" \ + "id:9006150,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=942130;ARGS:starter_alert_reason,\ + ver:'OWASP_CRS/3.3.7'" + +# Feature thread +# POST /xf/threads/thread-title.12345/feature-edit +SecRule REQUEST_FILENAME "@rx /threads/.*\.\d+/feature-edit$" \ + "id:9006155,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:feature[feature_excerpt]" + +# Inline moderate thread +# POST /xf/inline-mod/ +SecRule REQUEST_FILENAME "@endsWith /inline-mod/" \ + "id:9006160,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:author_alert_reason,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message,\ + ver:'OWASP_CRS/3.3.7'" + +# Warn member +# POST /xf/members/name.12345/warn +# POST /xf/posts/12345/warn +SecRule REQUEST_FILENAME "@rx /(?:members/.*\.\d+|posts/\d+)/warn$" \ + "id:9006170,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:conversation_message,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:notes,\ + ver:'OWASP_CRS/3.3.7'" + +# Editor +SecRule REQUEST_URI "@endsWith /index.php?editor/to-html" \ + "id:9006200,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:bb_code,\ + ctl:ruleRemoveTargetById=942200;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942260;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942340;ARGS:attachment_hash_combined,\ + ctl:ruleRemoveTargetById=942370;ARGS:attachment_hash_combined,\ + ver:'OWASP_CRS/3.3.7'" + +# Editor +SecRule REQUEST_URI "@endsWith /index.php?editor/to-bb-code" \ + "id:9006210,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:html,\ + ver:'OWASP_CRS/3.3.7'" + +# Post attachment +# POST /xf/account/avatar +# POST /xf/attachments/upload?type=post&context[thread_id]=12345&hash=foo +SecRule REQUEST_FILENAME "@rx /(?:account/avatar|attachments/upload)$" \ + "id:9006220,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=200003,\ + ctl:ruleRemoveTargetById=942220;ARGS:flowChunkSize,\ + ctl:ruleRemoveTargetById=942440;ARGS:flowIdentifier,\ + ctl:ruleRemoveTargetById=942440;ARGS:flowFilename,\ + ctl:ruleRemoveTargetById=942440;ARGS:flowRelativePath,\ + ver:'OWASP_CRS/3.3.7'" + +# Media +# POST /xf/index.php?editor/media +SecRule REQUEST_URI "@endsWith /index.php?editor/media" \ + "id:9006230,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=931130;ARGS:url,\ + ctl:ruleRemoveTargetById=942130;ARGS:url,\ + ver:'OWASP_CRS/3.3.7'" + +# Emoji +# GET /xf/index.php?misc/find-emoji&q=(%0A%0A +SecRule REQUEST_URI "@rx /index\.php\?misc/find-emoji&q=" \ + "id:9006240,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=921151;ARGS:q,\ + ver:'OWASP_CRS/3.3.7'" + +# Login +# POST /xf/login/login +SecRule REQUEST_FILENAME "@endsWith /login/login" \ + "id:9006300,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:password,\ + ver:'OWASP_CRS/3.3.7'" + +# Register account +# POST /xf/register/register +# The password is passed in a variable-name form parameter. We don't +# want to exclude all parameters completely as this would cause an +# unacceptable bypass. So, we exclude only commonly hit rules. +SecRule REQUEST_FILENAME "@endsWith /register/register" \ + "id:9006310,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=942130;ARGS,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:reg_key,\ + ver:'OWASP_CRS/3.3.7'" + +# Confirm account +# GET /xf/account-confirmation/name.12345/email?c=foo +SecRule REQUEST_FILENAME "@rx /account-confirmation/.*\.\d+/email$" \ + "id:9006315,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:c" + +# Edit account +# POST /xf/account/account-details +SecRule REQUEST_FILENAME "@endsWith /account/account-details" \ + "id:9006320,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=931130;ARGS:custom_fields[picture],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:about_html,\ + ver:'OWASP_CRS/3.3.7'" + +# Lost password +# POST /xf/lost-password/user-name.12345/confirm?c=foo +SecRule REQUEST_FILENAME "@rx /lost-password/.*\.\d+/confirm$" \ + "id:9006330,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:c,\ + ver:'OWASP_CRS/3.3.7'" + +# Set forum signature +# POST /xf/account/signature +SecRule REQUEST_FILENAME "@endsWith /account/signature" \ + "id:9006340,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:signature_html,\ + ver:'OWASP_CRS/3.3.7'" + +# Search +# POST /xf/search/search +SecRule REQUEST_FILENAME "@endsWith /search/search" \ + "id:9006400,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:keywords,\ + ctl:ruleRemoveTargetById=942200;ARGS:constraints,\ + ctl:ruleRemoveTargetById=942260;ARGS:constraints,\ + ctl:ruleRemoveTargetById=942340;ARGS:constraints,\ + ctl:ruleRemoveTargetById=942370;ARGS:constraints,\ + ver:'OWASP_CRS/3.3.7'" + +# Search within thread +# GET /xf/threads/foo.12345/page12?highlight=foo +SecRule REQUEST_FILENAME "@rx /threads/.*\.\d+/(?:page\d+)?$" \ + "id:9006410,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:highlight,\ + ver:'OWASP_CRS/3.3.7'" + +# Search within search result +# GET /xf/search/12345/?q=foo +SecRule REQUEST_FILENAME "@rx /search/\d+/$" \ + "id:9006420,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:q,\ + ver:'OWASP_CRS/3.3.7'" + +# Contact form +# POST /xf/misc/contact +SecRule REQUEST_FILENAME "@endsWith /misc/contact" \ + "id:9006500,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:subject,\ + ver:'OWASP_CRS/3.3.7'" + +# Report post +# POST /xf/posts/12345/report +SecRule REQUEST_FILENAME "@rx /posts/\d+/report$" \ + "id:9006510,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message,\ + ver:'OWASP_CRS/3.3.7'" + +# Alternate thread view route +# /xf/index.php?threads/title-having-some-sql.12345/ +# +# Especially threads with the HAVING sql keyword are FP prone. +# This rule has some chains to narrow down the exclusion, +# making it harder for an attacker to abuse the ARGS_NAMES +# exclusion on other endpoints. +SecRule REQUEST_FILENAME "@endsWith /index.php" \ + "id:9006600,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule REQUEST_METHOD "@streq GET" \ + "t:none,\ + chain" + SecRule &ARGS "@eq 1" \ + "t:none,\ + chain" + SecRule REQUEST_URI "@rx /index\.php\?threads/.*\.\d+/$" \ + "t:none,\ + ctl:ruleRemoveTargetById=942100;ARGS_NAMES,\ + ctl:ruleRemoveTargetById=942230;ARGS_NAMES" + +# Browser fingerprint (DBTech security extension) +# May Contain various javascript/XSS false positives +SecRule REQUEST_URI "@endsWith /index.php?dbtech-security/fingerprint" \ + "id:9006700,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:components[14][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:components[15][value],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:components[16][value],\ + ver:'OWASP_CRS/3.3.7'" + +# Get location info +SecRule REQUEST_FILENAME "@endsWith /misc/location-info" \ + "id:9006710,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:location,\ + ver:'OWASP_CRS/3.3.7'" + +# +# -=[ XenForo Global Exclusions ]=- +# + +# _xfRedirect, _xfRequestUri can appear on various endpoints. +# Cookies can appear on all endpoints. + +SecAction \ + "id:9006800,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=931120;ARGS:_xfRedirect,\ + ctl:ruleRemoveTargetById=941150;ARGS:_xfRedirect,\ + ctl:ruleRemoveTargetById=942230;ARGS:_xfRedirect,\ + ctl:ruleRemoveTargetById=942260;ARGS:_xfRedirect,\ + ctl:ruleRemoveTargetById=931120;ARGS:_xfRequestUri,\ + ctl:ruleRemoveTargetById=941150;ARGS:_xfRequestUri,\ + ctl:ruleRemoveTargetById=942130;ARGS:_xfRequestUri,\ + ctl:ruleRemoveTargetById=942230;ARGS:_xfRequestUri,\ + ctl:ruleRemoveTargetById=942260;ARGS:_xfRequestUri,\ + ctl:ruleRemoveTargetById=942100;REQUEST_COOKIES:xf_csrf,\ + ctl:ruleRemoveTargetById=942210;REQUEST_COOKIES:xf_csrf,\ + ctl:ruleRemoveTargetById=942440;REQUEST_COOKIES:xf_csrf,\ + ctl:ruleRemoveTargetById=942100;REQUEST_COOKIES:xf_emoji_usage,\ + ctl:ruleRemoveTargetById=942150;REQUEST_COOKIES:xf_emoji_usage,\ + ctl:ruleRemoveTargetById=942410;REQUEST_COOKIES:xf_emoji_usage,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;REQUEST_COOKIES:xf_ls,\ + ctl:ruleRemoveTargetById=942100;REQUEST_COOKIES:xf_session,\ + ctl:ruleRemoveTargetById=942100;REQUEST_COOKIES:xf_user,\ + ver:'OWASP_CRS/3.3.7'" + +# +# -=[ XenForo Administration Back-End ]=- +# + +# Skip this section for performance unless requested file is admin.php + +SecRule REQUEST_FILENAME "!@endsWith /admin.php" \ + "id:9006900,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-XENFORO-ADMIN" + +SecRule REQUEST_FILENAME "!@endsWith /admin.php" \ + "id:9006901,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-XENFORO-ADMIN" + +# Admin edit user +# POST /xf/admin.php?users/the-user-name.12345/edit +SecRule REQUEST_URI "@rx /admin\.php\?users/.*\.\d+/edit$" \ + "id:9006910,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:profile[about],\ + ctl:ruleRemoveTargetById=931130;ARGS:profile[website],\ + ver:'OWASP_CRS/3.3.7'" + +# Admin save user +# POST /xf/admin.php?users/the-user-name.12345/save +# Runs in phase 1 to be able to remove rule 200003. +SecRule REQUEST_URI "@rx /admin\.php\?users/.*\.\d+/save$" \ + "id:9006920,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveById=200003,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:custom_fields[occupation],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:custom_fields[personal_quote],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:profile[about],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:profile[signature],\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:custom_fields[sexuality],\ + ctl:ruleRemoveTargetById=931130;ARGS:custom_fields[picture],\ + ctl:ruleRemoveTargetById=931130;ARGS:profile[website],\ + ver:'OWASP_CRS/3.3.7'" + + +# Admin edit forum notice +# POST /xf/admin.php?notices/0/save +# POST /xf/admin.php?notices/forum-name.12345/save +SecRule REQUEST_URI "@rx /admin\.php\?notices/(?:.*\.)?\d+/save$" \ + "id:9006930,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:message,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:title,\ + ver:'OWASP_CRS/3.3.7'" + +# Admin batch thread update +# POST /xf/admin.php?threads/batch-update/action +SecRule REQUEST_URI "@rx /admin\.php\?(?:threads|users)/batch-update/action$" \ + "id:9006940,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=942200;ARGS:criteria,\ + ctl:ruleRemoveTargetById=942260;ARGS:criteria,\ + ctl:ruleRemoveTargetById=942330;ARGS:criteria,\ + ctl:ruleRemoveTargetById=942340;ARGS:criteria,\ + ctl:ruleRemoveTargetById=942370;ARGS:criteria,\ + ver:'OWASP_CRS/3.3.7'" + +# Edit forum theme +# POST /xf/admin.php?styles/title.1234/style-properties/group&group=basic +SecRule REQUEST_URI "@rx /admin\.php\?styles/" \ + "id:9006950,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetById=942200;ARGS:json,\ + ctl:ruleRemoveTargetById=942260;ARGS:json,\ + ctl:ruleRemoveTargetById=942300;ARGS:json,\ + ctl:ruleRemoveTargetById=942330;ARGS:json,\ + ctl:ruleRemoveTargetById=942340;ARGS:json,\ + ctl:ruleRemoveTargetById=942370;ARGS:json,\ + ctl:ruleRemoveTargetById=942440;ARGS:json,\ + ver:'OWASP_CRS/3.3.7'" + +# Set forum options +# POST /xf/admin.php?options/update +SecRule REQUEST_URI "@rx /admin\.php\?options/update" \ + "id:9006960,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:options[boardInactiveMessage],\ + ver:'OWASP_CRS/3.3.7'" + +# Edit pages/templates +# POST /xf/admin.php?pages/0/save +# POST /xf/admin.php?pages/foo.12345/save +# POST /xf/admin.php?templates/foo.1234/save +SecRule REQUEST_URI "@rx /admin\.php\?(?:pages|templates)/.*/save" \ + "id:9006970,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:template,\ + ver:'OWASP_CRS/3.3.7'" + +SecMarker "END-XENFORO-ADMIN" + +SecMarker "END-XENFORO" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-905-COMMON-EXCEPTIONS.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-905-COMMON-EXCEPTIONS.conf index 7e12926f6..8e06693ae 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-905-COMMON-EXCEPTIONS.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-905-COMMON-EXCEPTIONS.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -24,12 +24,11 @@ SecRule REQUEST_LINE "@streq GET /" \ tag:'language-multi',\ tag:'platform-apache',\ tag:'attack-generic',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ chain" SecRule REMOTE_ADDR "@ipMatch 127.0.0.1,::1" \ "t:none,\ - ctl:ruleRemoveByTag=OWASP_CRS,\ + ctl:ruleEngine=Off,\ ctl:auditEngine=Off" # @@ -45,13 +44,12 @@ SecRule REMOTE_ADDR "@ipMatch 127.0.0.1,::1" \ tag:'language-multi',\ tag:'platform-apache',\ tag:'attack-generic',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ chain" SecRule REQUEST_HEADERS:User-Agent "@endsWith (internal dummy connection)" \ "t:none,\ chain" SecRule REQUEST_LINE "@rx ^(?:GET /|OPTIONS \*) HTTP/[12]\.[01]$" \ "t:none,\ - ctl:ruleRemoveByTag=OWASP_CRS,\ + ctl:ruleEngine=Off,\ ctl:auditEngine=Off" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-910-IP-REPUTATION.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-910-IP-REPUTATION.conf new file mode 100644 index 000000000..e469826e8 --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-910-IP-REPUTATION.conf @@ -0,0 +1,323 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# +# -= Paranoia Level 0 (empty) =- (apply unconditionally) +# + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:910011,phase:1,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:910012,phase:2,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +# +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) +# + +# +# -=[ IP Reputation Block Flag Check ]=- +# +# The first check we do is to see if the client IP address has already +# been blacklisted by rules from previous requests. +# +# If the rule matches, it will do a skipAfter and pick up processing +# at the end of the request phase for actual blocking. +# +SecRule TX:DO_REPUT_BLOCK "@eq 1" \ + "id:910000,\ + phase:2,\ + block,\ + t:none,\ + msg:'Request from Known Malicious Client (Based on previous traffic violations)',\ + logdata:'Previous Block Reason: %{ip.reput_block_reason}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + chain,\ + skipAfter:BEGIN-REQUEST-BLOCKING-EVAL" + SecRule IP:REPUT_BLOCK_FLAG "@eq 1" \ + "setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# +# -=[ GeoIP Checks ]=- +# +# This rule requires activating the SecGeoLookupDB directive +# in the crs-setup.conf file and specifying +# the list of blocked countries (tx.high_risk_country_codes). +# +# This rule does a GeoIP resolution on the client IP address. +# +SecRule TX:HIGH_RISK_COUNTRY_CODES "!@rx ^$" \ + "id:910100,\ + phase:2,\ + block,\ + t:none,\ + msg:'Client IP is from a HIGH Risk Country Location',\ + logdata:'%{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + chain" + SecRule TX:REAL_IP "@geoLookup" \ + "chain" + SecRule GEO:COUNTRY_CODE "@within %{tx.high_risk_country_codes}" \ + "setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}'" + + +# +# -=[ IP Reputation Checks ]=- +# +# ModSecurity Rules from Trustwave SpiderLabs: IP Blacklist Alert +# Ref: http://www.modsecurity.org/projects/commercial/rules/ +# +# This rule checks the client IP address against a list of recent IPs captured +# from the SpiderLabs web honeypot systems (last 48 hours). +# +#SecRule TX:REAL_IP "@ipMatchFromFile ip_blacklist.data" \ +# "id:910110,\ +# phase:2,\ +# block,\ +# t:none,\ +# msg:'Client IP in Trustwave SpiderLabs IP Reputation Blacklist',\ +# tag:'application-multi',\ +# tag:'language-multi',\ +# tag:'platform-multi',\ +# tag:'attack-reputation-ip',\ +# tag:'paranoia-level/1',\ +# severity:'CRITICAL',\ +# setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ +# setvar:'ip.reput_block_flag=1',\ +# setvar:'ip.reput_block_reason=%{rule.msg}',\ +# expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}'" + + +# +# First check if we have already run an @rbl check for this IP by checking in IP collection. +# If we have, then skip doing another check. +# +SecRule IP:PREVIOUS_RBL_CHECK "@eq 1" \ + "id:910120,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-RBL-LOOKUP" + +# +# Check Client IP against ProjectHoneypot's HTTP Blacklist +# Ref: http://www.projecthoneypot.org/httpbl_api.php +# +# To use the blacklist, you must register for an HttpBL API Key +# and choose the traffic types to block. See section +# "Project Honey Pot HTTP Blacklist" in crs-setup.conf. +# +# Ref: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#wiki-SecHttpBlKey +# + +# Skip HttpBL checks if user has not defined one of the TX:block_* variables. +# This prevents error "Operator error: RBL httpBl called but no key defined: set SecHttpBlKey" +SecRule &TX:block_suspicious_ip "@eq 0" \ + "id:910130,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + chain,\ + skipAfter:END-RBL-CHECK" + SecRule &TX:block_harvester_ip "@eq 0" \ + "chain" + SecRule &TX:block_spammer_ip "@eq 0" \ + "chain" + SecRule &TX:block_search_ip "@eq 0" + +SecRule TX:REAL_IP "@rbl dnsbl.httpbl.org" \ + "id:910140,\ + phase:2,\ + pass,\ + capture,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.httpbl_msg=%{tx.0}',\ + chain" + SecRule TX:httpbl_msg "@rx RBL lookup of .*?.dnsbl.httpbl.org succeeded at TX:checkip. (.*?): .*" \ + "capture,\ + t:none,\ + setvar:'tx.httpbl_msg=%{tx.1}'" + +# The following regexs are generated based off re_operators.c +SecRule TX:block_search_ip "@eq 1" \ + "id:910150,\ + phase:2,\ + block,\ + t:none,\ + msg:'HTTP Blacklist match for search engine IP',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + chain,\ + skipAfter:END-RBL-CHECK" + SecRule TX:httpbl_msg "@rx Search Engine" \ + "setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + setvar:'ip.previous_rbl_check=1',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}',\ + expirevar:'ip.previous_rbl_check=86400'" + +SecRule TX:block_spammer_ip "@eq 1" \ + "id:910160,\ + phase:2,\ + block,\ + t:none,\ + msg:'HTTP Blacklist match for spammer IP',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + chain,\ + skipAfter:END-RBL-CHECK" + SecRule TX:httpbl_msg "@rx (?i)^.*? spammer .*?$" \ + "setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + setvar:'ip.previous_rbl_check=1',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}',\ + expirevar:'ip.previous_rbl_check=86400'" + +SecRule TX:block_suspicious_ip "@eq 1" \ + "id:910170,\ + phase:2,\ + block,\ + t:none,\ + msg:'HTTP Blacklist match for suspicious IP',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + chain,\ + skipAfter:END-RBL-CHECK" + SecRule TX:httpbl_msg "@rx (?i)^.*? suspicious .*?$" \ + "setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + setvar:'ip.previous_rbl_check=1',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}',\ + expirevar:'ip.previous_rbl_check=86400'" + +SecRule TX:block_harvester_ip "@eq 1" \ + "id:910180,\ + phase:2,\ + block,\ + t:none,\ + msg:'HTTP Blacklist match for harvester IP',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + chain,\ + skipAfter:END-RBL-CHECK" + SecRule TX:httpbl_msg "@rx (?i)^.*? harvester .*?$" \ + "setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + setvar:'ip.previous_rbl_check=1',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}',\ + expirevar:'ip.previous_rbl_check=86400'" + +SecAction \ + "id:910190,\ + phase:2,\ + pass,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'ip.previous_rbl_check=1',\ + expirevar:'ip.previous_rbl_check=86400'" + +SecMarker "END-RBL-LOOKUP" + +SecMarker "END-RBL-CHECK" + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:910013,phase:1,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:910014,phase:2,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +# +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) +# + + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:910015,phase:1,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:910016,phase:2,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +# +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) +# + + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:910017,phase:1,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:910018,phase:2,pass,nolog,skipAfter:END-REQUEST-910-IP-REPUTATION" +# +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) +# + + + +# +# -= Paranoia Levels Finished =- +# +SecMarker "END-REQUEST-910-IP-REPUTATION" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-911-METHOD-ENFORCEMENT.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-911-METHOD-ENFORCEMENT.conf index be9f0f7bb..b8602bc01 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-911-METHOD-ENFORCEMENT.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-911-METHOD-ENFORCEMENT.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,10 +14,10 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:911011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:911012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:911011,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:911012,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # @@ -27,7 +27,7 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:911012,phase:2,pass,nolog,tag:'O # SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}" \ "id:911100,\ - phase:1,\ + phase:2,\ block,\ msg:'Method is not allowed by policy',\ logdata:'%{MATCHED_VAR}',\ @@ -39,33 +39,33 @@ SecRule REQUEST_METHOD "!@within %{tx.allowed_methods}" \ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/274',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:911013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:911014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:911013,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:911014,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:911015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:911016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:911015,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:911016,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:911017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:911018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:911017,phase:1,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:911018,phase:2,pass,nolog,skipAfter:END-REQUEST-911-METHOD-ENFORCEMENT" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-912-DOS-PROTECTION.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-912-DOS-PROTECTION.conf new file mode 100644 index 000000000..4bbf97b98 --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-912-DOS-PROTECTION.conf @@ -0,0 +1,324 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# +# Anti-Automation rules to detect Denial of Service attacks. +# +# Description of mechanics: +# When a request hits a non-static resource (TX:STATIC_EXTENSIONS), then a counter for the IP +# address is being raised (IP:DOS_COUNTER). If the counter (IP:DOS_COUNTER) hits a limit +# (TX:DOS_COUNTER_THRESHOLD), then a burst is identified (IP:DOS_BURST_COUNTER) and the +# counter (IP:DOS_COUNTER) is reset. The burst counter expires within a timeout period +# (TX:DOS_BURST_TIME_SLICE). +# If the burst counter (IP:DOS_BURST_COUNTER) is greater equal 2, then the blocking flag +# is being set (IP:DOS_BLOCK). The blocking flag (IP:DOS_BLOCK) expires within a timeout +# period (TX:DOS_BLOCK_TIMEOUT). All this counting happens in phase 5. +# There is a stricter sibling to this rule (912170) in paranoia level 2, where the +# burst counter check (IP:DOS_BURST_COUNTER) hits at greater equal 1. +# +# The blocking is done in phase 1: When the blocking flag is encountered (IP:DOS_BLOCK), +# then the request is dropped without sending a response. If this happens, then a +# counter is # raised (IP:DOS_BLOCK_COUNTER). +# When an IP address is blocked for the first time, then the blocking is reported in a +# message and a flag (IP:DOS_BLOCK_FLAG) is set. This flag expires in 60 seconds. +# When an IP address is blocked and the flag (IP:DOS_BLOCK_FLAG) is set, then the +# blocking is not being reported (to prevent a flood of alerts). When the flag +# (IP:DOS_BLOCK_FLAG) has expired and a new request is being blocked, then the +# counter (IP:DOS_BLOCK_COUNTER) is being reset to 0 and the block is being treated +# as the first block (-> alert). +# In order to be able to display the counter (IP:DOS_BLOCK_COUNTER) and resetting +# it at the same time, we copy the counter (IP:DOS_BLOCK_COUNTER) into a different +# variable (TX:DOS_BLOCK_COUNTER), which is then displayed in turn. +# +# Variables: +# IP:DOS_BLOCK Flag if an IP address should be blocked +# IP:DOS_BLOCK_COUNTER Counter of blocked requests +# IP:DOS_BLOCK_FLAG Flag keeping track of alert. Flag expires after 60 seconds. +# IP:DOS_BURST_COUNTER Burst counter +# IP:DOS_COUNTER Request counter (static resources are ignored) +# TX:DOS_BLOCK_COUNTER Copy of IP:DOS_BLOCK_COUNTER (needed for display reasons) +# TX:DOS_BLOCK_TIMEOUT Period in seconds a blocked IP will be blocked +# TX:DOS_COUNTER_THRESHOLD Limit of requests, where a burst is identified +# TX:DOS_BURST_TIME_SLICE Period in seconds when we will forget a burst +# TX:STATIC_EXTENSIONS Paths which can be ignored with regards to DoS +# +# As a precondition for these rules, please set the following three variables: +# - TX:DOS_BLOCK_TIMEOUT +# - TX:DOS_COUNTER_THRESHOLD +# - TX:DOS_BURST_TIME_SLICE +# +# And make sure that TX:STATIC_EXTENSIONS is also set. +# + +# +# -= Paranoia Level 0 (empty) =- (apply unconditionally) +# + +# +# Skip if variables defining DoS protection are not set +# +SecRule &TX:dos_burst_time_slice "@eq 0" \ + "id:912100,\ + phase:1,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain,\ + skipAfter:END-DOS-PROTECTION-CHECKS" + SecRule &TX:dos_counter_threshold "@eq 0" \ + "chain" + SecRule &TX:dos_block_timeout "@eq 0" + +SecRule &TX:dos_burst_time_slice "@eq 0" \ + "id:912110,\ + phase:5,\ + pass,\ + t:none,\ + nolog,\ + ver:'OWASP_CRS/3.3.7',\ + chain,\ + skipAfter:END-DOS-PROTECTION-CHECKS" + SecRule &TX:dos_counter_threshold "@eq 0" \ + "chain" + SecRule &TX:dos_block_timeout "@eq 0" + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:912011,phase:1,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:912012,phase:2,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +# +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) +# + +# +# -=[ Anti-Automation / DoS Protection : Block ]=- +# + +# +# Block and track # of requests and log +# +SecRule IP:DOS_BLOCK "@eq 1" \ + "id:912120,\ + phase:1,\ + drop,\ + msg:'Denial of Service (DoS) attack identified from %{tx.real_ip} (%{tx.dos_block_counter} hits since last alert)',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'paranoia-level/1',\ + tag:'attack-dos',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/227/469',\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule &IP:DOS_BLOCK_FLAG "@eq 0" \ + "setvar:'ip.dos_block_counter=+1',\ + setvar:'ip.dos_block_flag=1',\ + setvar:'tx.dos_block_counter=%{ip.dos_block_counter}',\ + setvar:'ip.dos_block_counter=0',\ + expirevar:'ip.dos_block_flag=60'" + + +# +# Block and track # of requests but don't log +# +SecRule IP:DOS_BLOCK "@eq 1" \ + "id:912130,\ + phase:1,\ + drop,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-dos',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/227/469',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'ip.dos_block_counter=+1'" + + +# +# -=[ Anti-Automation / DoS Protection: Count requests ]=- +# + +# +# Skip if we have blocked the request +# +SecRule IP:DOS_BLOCK "@eq 1" \ + "id:912140,\ + phase:5,\ + pass,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-dos',\ + ver:'OWASP_CRS/3.3.7',\ + skipAfter:END-DOS-PROTECTION-CHECKS" + + +# +# DOS Counter: Count the number of requests to non-static resources +# +SecRule REQUEST_BASENAME "@rx .*?(\.[a-z0-9]{1,10})?$" \ + "id:912150,\ + phase:5,\ + pass,\ + capture,\ + t:none,t:lowercase,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-dos',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/227/469',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.extension=/%{TX.1}/',\ + chain" + SecRule TX:EXTENSION "!@within %{tx.static_extensions}" \ + "setvar:'ip.dos_counter=+1'" + + +# +# Check DOS Counter +# If the request count is greater than or equal to user settings, +# we raise the burst counter. This happens via two separate rules: +# - 912160: raise from 0 to 1 +# - 912161: raise from 1 to 2 +# +# This approach with two rules avoids raising the burst counter +# from 0 to 2 via two concurrent requests. We do not raise the +# burst counter beyond 2. +# +# +SecRule IP:DOS_COUNTER "@ge %{tx.dos_counter_threshold}" \ + "id:912160,\ + phase:5,\ + pass,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-dos',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/227/469',\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule &IP:DOS_BURST_COUNTER "@eq 0" \ + "setvar:'ip.dos_burst_counter=1',\ + setvar:'!ip.dos_counter',\ + expirevar:'ip.dos_burst_counter=%{tx.dos_burst_time_slice}'" + + +SecRule IP:DOS_COUNTER "@ge %{tx.dos_counter_threshold}" \ + "id:912161,\ + phase:5,\ + pass,\ + t:none,\ + nolog,\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-dos',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/227/469',\ + ver:'OWASP_CRS/3.3.7',\ + chain" + SecRule &IP:DOS_BURST_COUNTER "@ge 1" \ + "setvar:'ip.dos_burst_counter=2',\ + setvar:'!ip.dos_counter',\ + expirevar:'ip.dos_burst_counter=%{tx.dos_burst_time_slice}'" + + +# +# Check DOS Burst Counter and set Block +# Check the burst counter - if greater than or equal to 2, then we set the IP +# block variable for a given expiry and issue an alert. +# +SecRule IP:DOS_BURST_COUNTER "@ge 2" \ + "id:912170,\ + phase:5,\ + pass,\ + t:none,\ + log,\ + msg:'Potential Denial of Service (DoS) Attack from %{tx.real_ip} - # of Request Bursts: %{ip.dos_burst_counter}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'paranoia-level/1',\ + tag:'attack-dos',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/227/469',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'ip.dos_block=1',\ + expirevar:'ip.dos_block=%{tx.dos_block_timeout}'" + + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:912013,phase:1,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:912014,phase:2,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:912019,phase:5,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +# +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) +# + +# +# Check DOS Burst Counter and set Block +# Check the burst counter - if greater than or equal to 1, then we set the IP +# block variable for a given expiry and issue an alert. +# +# This is a stricter sibling of rule 912170. +# +SecRule IP:DOS_BURST_COUNTER "@ge 1" \ + "id:912171,\ + phase:5,\ + pass,\ + t:none,\ + log,\ + msg:'Potential Denial of Service (DoS) Attack from %{tx.real_ip} - # of Request Bursts: %{ip.dos_burst_counter}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-dos',\ + tag:'paranoia-level/2',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/227/469',\ + ver:'OWASP_CRS/3.3.7',\ + setvar:'ip.dos_block=1',\ + expirevar:'ip.dos_block=%{tx.dos_block_timeout}'" + + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:912015,phase:1,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:912016,phase:2,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +# +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) +# + + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:912017,phase:1,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:912018,phase:2,pass,nolog,skipAfter:END-REQUEST-912-DOS-PROTECTION" +# +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) +# + + + +# +# -= Paranoia Levels Finished =- +# +SecMarker "END-REQUEST-912-DOS-PROTECTION" + +SecMarker "END-DOS-PROTECTION-CHECKS" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-913-SCANNER-DETECTION.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-913-SCANNER-DETECTION.conf index e9e0db7d7..42f9d565d 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-913-SCANNER-DETECTION.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-913-SCANNER-DETECTION.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,33 +14,29 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:913011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:913012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:913011,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:913012,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # -# -=[ Security Scanner Checks ]=- +# -=[ Vulnerability Scanner Checks ]=- # -# This rule inspects the default User-Agent and Header values sent by -# various commercial and open source scanners, mostly -# security / vulnerability scanners. +# These rules inspect the default User-Agent and Header values sent by +# various commercial and open source vuln scanners. # -# It is based on a curated list of known malicious scanners in widespread use. -# This list is maintained in scanners-user-agents.data. +# The following rules contain User-Agent lists: +# 913100 - security scanners (data file scanners-user-agents.data) +# 913101 - scripting/generic HTTP clients (data file scripting-user-agents.data) +# 913102 - web crawlers/bots (data file crawlers-user-agents.data) # -# With CRSv4, the project has given up on keeping track of different categories -# of scanners and scripting agents, mostly because it's very hard to draw -# a line between benign, mostly benign and malicious. And because dedicated -# attackers will change the user agent anyways. - SecRule REQUEST_HEADERS:User-Agent "@pmFromFile scanners-user-agents.data" \ "id:913100,\ - phase:1,\ + phase:2,\ block,\ capture,\ - t:none,\ + t:none,t:lowercase,\ msg:'Found User-Agent associated with security scanner',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -51,31 +47,148 @@ SecRule REQUEST_HEADERS:User-Agent "@pmFromFile scanners-user-agents.data" \ tag:'OWASP_CRS',\ tag:'capec/1000/118/224/541/310',\ tag:'PCI/6.5.10',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}'" + +SecRule REQUEST_HEADERS_NAMES|REQUEST_HEADERS "@pmFromFile scanners-headers.data" \ + "id:913110,\ + phase:2,\ + block,\ + capture,\ + t:none,t:lowercase,\ + msg:'Found request header associated with security scanner',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-scanner',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/118/224/541/310',\ + tag:'PCI/6.5.10',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:913013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:913014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" + +SecRule REQUEST_FILENAME|ARGS "@pmFromFile scanners-urls.data" \ + "id:913120,\ + phase:2,\ + block,\ + capture,\ + t:none,t:lowercase,\ + msg:'Found request filename/argument associated with security scanner',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-scanner',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/118/224/541/310',\ + tag:'PCI/6.5.10',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}'" + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:913013,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:913014,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) +# + + +# +# -=[ Scripting/Generic User-Agents ]=- +# +# This rule detects user-agents associated with various HTTP client libraries +# and scripting languages. Detection suggests attempted access by some +# automated tool. +# +# This rule is a sibling of rule 913100. +# +SecRule REQUEST_HEADERS:User-Agent "@pmFromFile scripting-user-agents.data" \ + "id:913101,\ + phase:2,\ + block,\ + capture,\ + t:none,t:lowercase,\ + msg:'Found User-Agent associated with scripting/generic HTTP client',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-scripting',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/118/224/541/310',\ + tag:'PCI/6.5.10',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}'" + + + +# +# -=[ Crawler User-Agents ]=- +# +# This rule detects user-agents associated with various crawlers, SEO tools, +# and bots, which have been reported to potentially misbehave. +# These crawlers can have legitimate uses when used with authorization. +# +# This rule is a sibling of rule 913100. +# +SecRule REQUEST_HEADERS:User-Agent "@pmFromFile crawlers-user-agents.data" \ + "id:913102,\ + phase:2,\ + block,\ + capture,\ + t:none,t:lowercase,\ + msg:'Found User-Agent associated with web crawler/bot',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-crawler',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/118/224/541/310',\ + tag:'PCI/6.5.10',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}',\ + setvar:'ip.reput_block_flag=1',\ + setvar:'ip.reput_block_reason=%{rule.msg}',\ + expirevar:'ip.reput_block_flag=%{tx.reput_block_duration}'" + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:913015,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:913016,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" +# +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:913015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:913016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:913017,phase:1,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:913018,phase:2,pass,nolog,skipAfter:END-REQUEST-913-SCANNER-DETECTION" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) -# - - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:913017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:913018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-913-SCANNER-DETECTION" -# -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf index 2b4e3f285..50bd35ec3 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,7 +14,7 @@ # # The purpose of this rules file is to enforce HTTP RFC requirements that state how # the client is supposed to interact with the server. -# https://www.rfc-editor.org/rfc/rfc9110.html +# https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html @@ -23,10 +23,10 @@ # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:920011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:920012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:920011,phase:1,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:920012,phase:2,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # @@ -37,22 +37,17 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:920012,phase:2,pass,nolog,tag:'O # Uses rule negation against the regex for positive security. The regex specifies the proper # construction of URI request lines such as: # -# "http" "://" authority path-abempty [ "?" query ] +# "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]] # # It also outlines proper construction for CONNECT, OPTIONS and GET requests. # -# Regular expression generated from regex-assembly/920100.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 920100 -# # -=[ References ]=- -# https://www.rfc-editor.org/rfc/rfc9110.html#section-4.2.1 +# https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2.1 # http://capec.mitre.org/data/definitions/272.html # -SecRule REQUEST_LINE "!@rx (?i)^(?:get /[^#\?]*(?:\?[^\s\x0b#]*)?(?:#[^\s\x0b]*)?|(?:connect (?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}\.?(?::[0-9]+)?|[\--9A-Z_a-z]+:[0-9]+)|options \*|[a-z]{3,10}[\s\x0b]+(?:[0-9A-Z_a-z]{3,7}?://[\--9A-Z_a-z]*(?::[0-9]+)?)?/[^#\?]*(?:\?[^\s\x0b#]*)?(?:#[^\s\x0b]*)?)[\s\x0b]+[\.-9A-Z_a-z]+)$" \ +SecRule REQUEST_LINE "!@rx ^(?i:(?:[a-z]{3,10}\s+(?:\w{3,7}?://[\w\-\./]*(?::\d+)?)?/[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?|connect (?:\d{1,3}\.){3}\d{1,3}\.?(?::\d+)?|options \*)\s+[\w\./]+|get /[^?#]*(?:\?[^#\s]*)?(?:#[\S]*)?)$" \ "id:920100,\ - phase:1,\ + phase:2,\ block,\ t:none,\ msg:'Invalid HTTP Request Line',\ @@ -64,9 +59,9 @@ SecRule REQUEST_LINE "!@rx (?i)^(?:get /[^#\?]*(?:\?[^\s\x0b#]*)?(?:#[^\s\x0b]*) tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.warning_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.warning_anomaly_score}'" # @@ -81,31 +76,26 @@ SecRule REQUEST_LINE "!@rx (?i)^(?:get /[^#\?]*(?:\?[^\s\x0b#]*)?(?:#[^\s\x0b]*) # # -=[ Rule Logic ]=- # These rules check for the existence of the ' " ; = meta-characters in -# either the "name" (FILES) and "filename" (FILES_NAMES) variables. -# HTML entities may lead to false positives, which is why -# frequently used ones, such as "ä", are allowed at PL1. +# either the file or file name variables. +# HTML entities may lead to false positives, why they are allowed on PL1. +# Negative look behind assertions allow frequently used entities &_; # # -=[ Targets, characters and html entities ]=- # # 920120: PL1 : FILES_NAMES, FILES -# Disallow ['\";=\\], except for frequently used HTML entities (see 920120.ra). +# ['\";=\x5c] but allowed: +# &[aAoOuUyY]uml); &[aAeEiIoOuU]circ; &[eEiIoOuUyY]acute; +# &[aAeEiIoOuU]grave; &[cC]cedil; &[aAnNoO]tilde; & ' # # 920121: PL2 : FILES_NAMES, FILES -# Disallow ['\";=\\] +# ['\";=\x5c] : ' " ; = meta-characters +# +# Not supported by re2 (?@#*-]+)*$" \ +# +SecRule REQUEST_HEADERS:Content-Type "!@rx ^[\w/.+-]+(?:\s?;\s?(?:action|boundary|charset|type|start(?:-info)?)\s?=\s?['\"\w.()+,/:=?<>@-]+)*$" \ "id:920470,\ phase:1,\ block,\ @@ -983,16 +927,16 @@ SecRule REQUEST_HEADERS:Content-Type "!@rx ^[\w/.+*-]+(?:\s?;\s?(?:action|bounda tag:'OWASP_CRS',\ tag:'capec/1000/255/153',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # In case Content-Type header can be parsed, check the mime-type against # the policy defined in the 'allowed_request_content_type' variable. # To change your policy, edit crs-setup.conf and activate rule 900220. SecRule REQUEST_HEADERS:Content-Type "@rx ^[^;\s]+" \ "id:920420,\ - phase:1,\ + phase:2,\ block,\ capture,\ t:none,\ @@ -1006,13 +950,13 @@ SecRule REQUEST_HEADERS:Content-Type "@rx ^[^;\s]+" \ tag:'OWASP_CRS',\ tag:'capec/1000/255/153',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.content_type=|%{tx.0}|',\ chain" SecRule TX:content_type "!@within %{tx.allowed_request_content_type}" \ "t:lowercase,\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -1023,7 +967,7 @@ SecRule REQUEST_HEADERS:Content-Type "@rx charset\s*=\s*[\"']?([^;\"'\s]+)" \ phase:1,\ block,\ capture,\ - t:none,\ + t:none,t:lowercase,\ msg:'Request content type charset is not allowed by policy',\ logdata:'%{MATCHED_VAR}',\ tag:'application-multi',\ @@ -1034,14 +978,13 @@ SecRule REQUEST_HEADERS:Content-Type "@rx charset\s*=\s*[\"']?([^;\"'\s]+)" \ tag:'OWASP_CRS',\ tag:'capec/1000/255/153',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.content_type_charset=|%{tx.1}|',\ chain" - SecRule TX:content_type_charset "!@within %{tx.allowed_request_content_type_charset}" \ - "t:lowercase,\ + SecRule TX:1 "!@rx ^%{tx.allowed_request_content_type_charset}$" \ + "t:none,\ ctl:forceRequestBodyVariable=On,\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Restrict charset parameter inside content type header to occur max once. @@ -1061,9 +1004,9 @@ SecRule REQUEST_HEADERS:Content-Type "@rx charset.*?charset" \ tag:'OWASP_CRS',\ tag:'capec/1000/255/153',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Restrict protocol versions. @@ -1083,19 +1026,19 @@ SecRule REQUEST_PROTOCOL "!@within %{tx.allowed_http_versions}" \ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ tag:'PCI/6.5.10',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Restrict file extension # SecRule REQUEST_BASENAME "@rx \.([^.]+)$" \ "id:920440,\ - phase:1,\ + phase:2,\ block,\ capture,\ - t:none,t:urlDecodeUni,\ + t:none,\ msg:'URL file extension is restricted by policy',\ logdata:'%{TX.0}',\ tag:'application-multi',\ @@ -1106,13 +1049,13 @@ SecRule REQUEST_BASENAME "@rx \.([^.]+)$" \ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ tag:'PCI/6.5.10',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.extension=.%{tx.1}/',\ chain" SecRule TX:EXTENSION "@within %{tx.restricted_extensions}" \ - "t:none,t:lowercase,\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + "t:none,t:urlDecodeUni,t:lowercase,\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Backup or "working" file extension @@ -1120,7 +1063,7 @@ SecRule REQUEST_BASENAME "@rx \.([^.]+)$" \ # SecRule REQUEST_FILENAME "@rx \.[^.~]+~(?:/.*|)$" \ "id:920500,\ - phase:1,\ + phase:2,\ block,\ t:none,t:urlDecodeUni,\ msg:'Attempt to access a backup or working file',\ @@ -1133,47 +1076,38 @@ SecRule REQUEST_FILENAME "@rx \.[^.~]+~(?:/.*|)$" \ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ tag:'PCI/6.5.10',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Restricted HTTP headers # # -=[ Rule Logic ]=- -# The use of certain headers is restricted. They are listed in two variables: -# - TX.restricted_headers_basic: Known security risks, always forbidden (rule -# 920450) -# - TX.restricted_headers_extended: Possible false positives, possible security -# risks, may be forbidden (rule 920451) +# The use of certain headers is restricted. They are listed in the variable +# TX.restricted_headers. # -# The headers are transformed into lowercase before the match. In order to make -# sure that only complete header names match, the names in the -# TX.restricted_headers_* variables are wrapped in slashes. This guarantees that -# the Range header (which becomes /range/) will not match the restricted -# /content-range/ header, for example. +# The headers are transformed into lowercase before the match. In order to +# make sure that only complete header names are matching, the names in +# TX.restricted_headers are wrapped in slashes. This guarantees that the +# header Range (-> /range/) is not matching the restricted header +# /content-range/ for example. # # This is a chained rule, where the first rule fills a set of variables of the -# form TX.header_name__. The second rule is then executed -# for all variables of the form TX.header_name__. +# form TX.header_name_. The second rule is then executed for all +# variables of the form TX.header_name_. # # As a consequence of the construction of the rule, the alert message and the # alert data will not display the original header name Content-Range, but # /content-range/ instead. # -# This rule has a stricter sibling, 920451, which matches against the variable -# TX.restricted_headers_extended. It handles deprecated headers that are still -# in use (so false positives are possible, hence unsuitable for blocking in a -# default paranoia level 1 installation) and headers with possible security -# risks. # # -=[ References ]=- # https://access.redhat.com/security/vulnerabilities/httpoxy (Header Proxy) -# https://www.sidechannel.blog/en/http-method-override-what-it-is-and-how-a-pentester-can-use-it # SecRule REQUEST_HEADERS_NAMES "@rx ^.*$" \ "id:920450,\ - phase:1,\ + phase:2,\ block,\ capture,\ t:none,t:lowercase,\ @@ -1187,43 +1121,12 @@ SecRule REQUEST_HEADERS_NAMES "@rx ^.*$" \ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.header_name_920450_%{tx.0}=/%{tx.0}/',\ + setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',\ chain" - SecRule TX:/^header_name_920450_/ "@within %{tx.restricted_headers_basic}" \ - "setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# -# Rule against CVE-2022-21907 -# This rule blocks Accept-Encoding headers longer than 100 characters. -# The length of 100 is a heuristic based on the length of values from -# the RFC (https://datatracker.ietf.org/doc/rfc9110/) -# and the respective values assigned by IANA -# (https://www.iana.org/assignments/http-parameters/http-parameters.xml#content-coding). -# Concatenating all valid values for Accept-Encoding (without q=0.5) resulted in a value of 93: -# aes128gcm, br, compress, deflate, exi, gzip, identity, pack200-gzip, x-compress, x-gzip, zstd -# -# This rule has a stricter sibling: 920521 -# -SecRule REQUEST_HEADERS:Accept-Encoding "@gt 100" \ - "id:920520,\ - phase:1,\ - block,\ - t:none,t:lowercase,t:length,\ - msg:'Accept-Encoding header exceeded sensible length',\ - logdata:'%{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/255/153',\ - tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + SecRule TX:/^header_name_/ "@within %{tx.restricted_headers}" \ + "setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Restrict response charsets that we allow. @@ -1235,12 +1138,12 @@ SecRule REQUEST_HEADERS:Accept-Encoding "@gt 100" \ # Some servers rely on the request Accept header to determine what charset to respond with. # This rule restricts these to familiar charsets. # -# Regular expression generated from regex-assembly/920600.ra. +# Regular expression generated from util/regexp-assemble/data/920600.data. # To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 920600 +# (consult util/regexp-assemble/README.md for details): +# util/regexp-assemble/regexp-assemble.py update 920600 # -SecRule REQUEST_HEADERS:Accept "!@rx ^(?:(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)/(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\x0b]*;[\s\x0b]*(?:charset[\s\x0b]*=[\s\x0b]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\x0b-\"\(\),/:-\?\[-\]c\{\}]|c(?:[^!\"\(\),/:-\?\[-\]h\{\}]|h(?:[^!\"\(\),/:-\?\[-\]a\{\}]|a(?:[^!\"\(\),/:-\?\[-\]r\{\}]|r(?:[^!\"\(\),/:-\?\[-\]s\{\}]|s(?:[^!\"\(\),/:-\?\[-\]e\{\}]|e[^!\"\(\),/:-\?\[-\]t\{\}]))))))[^!\"\(\),/:-\?\[-\]\{\}]*[\s\x0b]*=[\s\x0b]*[^!\(\),/:-\?\[-\]\{\}]+);?)*(?:[\s\x0b]*,[\s\x0b]*(?:(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)/(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\x0b]*;[\s\x0b]*(?:charset[\s\x0b]*=[\s\x0b]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\x0b-\"\(\),/:-\?\[-\]c\{\}]|c(?:[^!\"\(\),/:-\?\[-\]h\{\}]|h(?:[^!\"\(\),/:-\?\[-\]a\{\}]|a(?:[^!\"\(\),/:-\?\[-\]r\{\}]|r(?:[^!\"\(\),/:-\?\[-\]s\{\}]|s(?:[^!\"\(\),/:-\?\[-\]e\{\}]|e[^!\"\(\),/:-\?\[-\]t\{\}]))))))[^!\"\(\),/:-\?\[-\]\{\}]*[\s\x0b]*=[\s\x0b]*[^!\(\),/:-\?\[-\]\{\}]+);?)*)*$" \ +SecRule REQUEST_HEADERS:Accept "!@rx ^(?:(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+)\/(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+))(?:\s*+;\s*+(?:(?:charset\s*+=\s*+(?:\"?(?:iso-8859-15?|windows-1252|utf-8)\b\"?))|(?:(?:c(?:h(?:a(?:r(?:s(?:e[^t\"(),\/:;<=>?![\x5c\]{}]|[^e\"(),/:;<=>?![\x5c\]{}])|[^s\"(),/:;<=>?![\x5c\]{}])|[^r\"(),/:;<=>?![\x5c\]{}])|[^a\"(),/:;<=>?![\x5c\]{}])|[^h\"(),/:;<=>?![\x5c\]{}])|[^c\"(),/:;<=>?![\x5c\]{}])[^\"(),/:;<=>?![\x5c\]{}]*(?:)\s*+=\s*+[^(),/:;<=>?![\x5c\]{}]+)|;?))*(?:\s*+,\s*+(?:(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+)\/(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+))(?:\s*+;\s*+(?:(?:charset\s*+=\s*+(?:\"?(?:iso-8859-15?|windows-1252|utf-8)\b\"?))|(?:(?:c(?:h(?:a(?:r(?:s(?:e[^t\"(),\/:;<=>?![\x5c\]{}]|[^e\"(),/:;<=>?![\x5c\]{}])|[^s\"(),/:;<=>?![\x5c\]{}])|[^r\"(),/:;<=>?![\x5c\]{}])|[^a\"(),/:;<=>?![\x5c\]{}])|[^h\"(),/:;<=>?![\x5c\]{}])|[^c\"(),/:;<=>?![\x5c\]{}])[^\"(),/:;<=>?![\x5c\]{}]*(?:)\s*+=\s*+[^(),/:;<=>?![\x5c\]{}]+)|;?))*)*$" \ "id:920600,\ phase:1,\ block,\ @@ -1253,69 +1156,22 @@ SecRule REQUEST_HEADERS:Accept "!@rx ^(?:(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)/(?:\* tag:'attack-protocol',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# -# Unicode character bypass check for non JSON requests -# See reported bypass in issue: -# https://github.com/coreruleset/coreruleset/issues/2512 -# -SecRule REQBODY_PROCESSOR "!@streq JSON" \ - "id:920540,\ - phase:2,\ - block,\ - t:none,\ - msg:'Possible Unicode character bypass detected',\ - logdata:'%{MATCHED_VAR_NAME}=%{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/255/153/267/72',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - chain" - SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "@rx (?i)\x5cu[0-9a-f]{4}" \ - "setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# -# Disallow any raw URL fragments. The '#' character should be omitted or URL-encoded. -# CRS rules generally do not check REQUEST_URI_RAW, but some servers accept the fragment as part of the URL path/query. -# This creates false negative evasions. -# -SecRule REQUEST_URI_RAW "@contains #" \ - "id:920610,\ - phase:1,\ - block,\ - t:none,\ - msg:'Raw (unencoded) fragment in request URI',\ - logdata:'%{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # The following rule (920620) checks for the presence of 2 or more request Content-Type headers. -# Content-Type confusion poses a significant security risk to a web application. It occurs when -# the server and client have different interpretations of the Content-Type header, leading to +# Content-Type confusion poses a significant security risk to a web application. It occurs when +# the server and client have different interpretations of the Content-Type header, leading to # miscommunication, potential exploitation and WAF bypass. # -# Using Apache, when multiple Content-Type request headers are received, the server combines them +# Using Apache, when multiple Content-Type request headers are received, the server combines them # into a single header with the values separated by commas. For example, if a client sends multiple # Content-Type headers with values "application/json" and "text/plain", Apache will combine them # into a single header like this: "Content-Type: application/json, text/plain". # -# On the other hand, Nginx handles multiple Content-Type headers differently. It preserves each +# On the other hand, Nginx handles multiple Content-Type headers differently. It preserves each # header as a separate entity without combining them. So, if a client sends multiple Content-Type # headers, Nginx will keep them separate, maintaining the original values. # @@ -1332,15 +1188,14 @@ SecRule &REQUEST_HEADERS:Content-Type "@gt 1" \ tag:'attack-protocol',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:920013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:920014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:920013,phase:1,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:920014,phase:2,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # # @@ -1365,7 +1220,7 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:920014,phase:2,pass,nolog,tag:'O SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "@rx ^bytes=(?:(?:\d+)?-(?:\d+)?\s*,?\s*){6}" \ "id:920200,\ - phase:1,\ + phase:2,\ block,\ t:none,\ msg:'Range: Too many fields (6 or more)',\ @@ -1374,14 +1229,14 @@ SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "@rx ^bytes=(?:(?:\d tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ chain" SecRule REQUEST_BASENAME "!@endsWith .pdf" \ - "setvar:'tx.inbound_anomaly_score_pl2=+%{tx.warning_anomaly_score}'" + "setvar:'tx.anomaly_score_pl2=+%{tx.warning_anomaly_score}'" # # This is a sibling of rule 920200 @@ -1389,23 +1244,23 @@ SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "@rx ^bytes=(?:(?:\d SecRule REQUEST_BASENAME "@endsWith .pdf" \ "id:920201,\ - phase:1,\ + phase:2,\ block,\ - t:none,t:urlDecodeUni,\ + t:none,\ msg:'Range: Too many fields for pdf request (63 or more)',\ logdata:'%{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ chain" SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "@rx ^bytes=(?:(?:\d+)?-(?:\d+)?\s*,?\s*){63}" \ - "setvar:'tx.inbound_anomaly_score_pl2=+%{tx.warning_anomaly_score}'" + "setvar:'tx.anomaly_score_pl2=+%{tx.warning_anomaly_score}'" SecRule ARGS "@rx %[0-9a-fA-F]{2}" \ @@ -1419,14 +1274,49 @@ SecRule ARGS "@rx %[0-9a-fA-F]{2}" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/255/153/267/120',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.warning_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.warning_anomaly_score}'" +# +# Missing Accept Header +# +# -=[ Rule Logic ]=- +# This rule generates a notice if the Accept header is missing. +# +# Notice: The rule tries to avoid known false positives by ignoring +# OPTIONS requests coming from known offending User-Agents via two +# chained rules. +# As ModSecurity only reports the match of the last matching rule, +# the alert is misleading. +# +SecRule &REQUEST_HEADERS:Accept "@eq 0" \ + "id:920300,\ + phase:2,\ + pass,\ + t:none,\ + msg:'Request Missing an Accept Header',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-protocol',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/210/272',\ + tag:'PCI/6.5.10',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'NOTICE',\ + chain" + SecRule REQUEST_METHOD "!@rx ^OPTIONS$" \ + "chain" + SecRule REQUEST_HEADERS:User-Agent "!@pm AppleWebKit Android" \ + "t:none,\ + setvar:'tx.anomaly_score_pl2=+%{tx.notice_anomaly_score}'" + # # PL2: This is a stricter sibling of 920270. # @@ -1441,12 +1331,12 @@ SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "@validateByteRange 9,10,13, tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" @@ -1459,7 +1349,7 @@ SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "@validateByteRange 9,10,13, SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \ "id:920320,\ - phase:1,\ + phase:2,\ pass,\ t:none,\ msg:'Missing User Agent Header',\ @@ -1467,13 +1357,13 @@ SecRule &REQUEST_HEADERS:User-Agent "@eq 0" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ tag:'PCI/6.5.10',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'NOTICE',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.notice_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.notice_anomaly_score}'" # @@ -1490,12 +1380,12 @@ SecRule FILES_NAMES|FILES "@rx ['\";=\x5c]" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # @@ -1507,7 +1397,7 @@ SecRule FILES_NAMES|FILES "@rx ['\";=\x5c]" \ SecRule REQUEST_HEADERS:Content-Length "!@rx ^0$" \ "id:920341,\ - phase:1,\ + phase:2,\ block,\ t:none,\ msg:'Request Containing Content Requires Content-Type header',\ @@ -1518,72 +1408,18 @@ SecRule REQUEST_HEADERS:Content-Length "!@rx ^0$" \ tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ chain" SecRule &REQUEST_HEADERS:Content-Type "@eq 0" \ "t:none,\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:920015,phase:1,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:920016,phase:2,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # -# PL2: This is a stricter sibling of 920450. -# -SecRule REQUEST_HEADERS_NAMES "@rx ^.*$" \ - "id:920451,\ - phase:1,\ - block,\ - capture,\ - t:none,t:lowercase,\ - msg:'HTTP header is restricted by policy (%{MATCHED_VAR})',\ - logdata:'Restricted header detected: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/210/272',\ - tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.header_name_920451_%{tx.0}=/%{tx.0}/',\ - chain" - SecRule TX:/^header_name_920451_/ "@within %{tx.restricted_headers_extended}" \ - "setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# -# Check URL encodings -# -# See comment on rule 920220. -# -SecRule REQUEST_HEADERS:Content-Type "@rx ^(?i)application/x-www-form-urlencoded" \ - "id:920240,\ - phase:2,\ - block,\ - t:none,\ - msg:'URL Encoding Abuse Attack Attempt',\ - logdata:'%{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/255/153/267/72',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'WARNING',\ - chain" - SecRule REQUEST_BODY "@rx \x25" \ - "chain" - SecRule REQUEST_BODY "@validateUrlEncoding" \ - "setvar:'tx.inbound_anomaly_score_pl2=+%{tx.warning_anomaly_score}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:920015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:920016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" -# -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # # @@ -1603,51 +1439,12 @@ SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES|REQUEST_BODY "@validateByteR tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - -# -# Missing Accept Header -# -# This rule has been moved to PL3 -# -# -=[ Rule Logic ]=- -# This rule generates a notice if the Accept header is missing. -# RFC 7231 does not enforce the use of the Accept header. -# It is just typical browser behavior to send and it can indicate a malicious client. -# -# Notice: The rule tries to avoid known false positives by ignoring -# OPTIONS requests, CONNECT requests, and requests coming from known -# offending User-Agents via two chained rules. -# As ModSecurity only reports the match of the last matching rule, -# the alert is misleading. -# -SecRule &REQUEST_HEADERS:Accept "@eq 0" \ - "id:920300,\ - phase:1,\ - pass,\ - t:none,\ - msg:'Request Missing an Accept Header',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/210/272',\ - tag:'PCI/6.5.10',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'NOTICE',\ - chain" - SecRule REQUEST_METHOD "!@rx ^(?:OPTIONS|CONNECT)$" \ - "chain" - SecRule REQUEST_HEADERS:User-Agent "!@pm AppleWebKit Android" \ - "t:none,\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.notice_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # @@ -1658,7 +1455,7 @@ SecRule &REQUEST_HEADERS:Accept "@eq 0" \ # Note that this only works in combination with a User-Agent prefix. # # This rule is based on a blog post by Soroush Dalili at -# https://soroush.me/blog/2019/05/x-up-devcap-post-charset-header-in-aspnet-to-bypass-wafs-again/ +# https://soroush.secproject.com/blog/2019/05/x-up-devcap-post-charset-header-in-aspnet-to-bypass-wafs-again/ # SecRule &REQUEST_HEADERS:x-up-devcap-post-charset "@ge 1" \ "id:920490,\ @@ -1670,22 +1467,22 @@ SecRule &REQUEST_HEADERS:x-up-devcap-post-charset "@ge 1" \ tag:'language-aspnet',\ tag:'platform-windows',\ tag:'attack-protocol',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ chain" SecRule REQUEST_HEADERS:User-Agent "@rx ^(?i)up" \ "t:none,\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # -# Cache-Control Request Header allow list +# Cache-Control Request Header whitelist # # -=[ Rule Logic ]=- -# This rule aims to strictly allow list the Cache-Control request header +# This rule aims to strictly whitelist the Cache-Control request header # values and to blocks all violations. This should be useful to intercept # "bad bot" and tools that impersonate a real browser but with wrong request # header setup. @@ -1722,49 +1519,21 @@ SecRule &REQUEST_HEADERS:Cache-Control "@gt 0" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'header-allowlist',\ + tag:'header-whitelist',\ tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ chain" - SecRule REQUEST_HEADERS:Cache-Control "!@rx ^(?:(?:max-age=[0-9]+|min-fresh=[0-9]+|no-cache|no-store|no-transform|only-if-cached|max-stale(?:=[0-9]+)?)(?:\s*\,\s*|$)){1,7}$" \ - "setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + SecRule REQUEST_HEADERS:Cache-Control "!@rx ^(?:(?:max-age=[0-9]+|min-fresh=[0-9]+|no-cache|no-store|no-transform|only-if-cached|max-stale(?:=[0-9]+)?)(\s*\,\s*|$)){1,7}$" \ + "setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" -# -# This rule checks for valid Accept-Encoding headers -# -# This rule has a less strict sibling: 920520 -# -# Regular expression generated from regex-assembly/920521.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 920521 -# -SecRule REQUEST_HEADERS:Accept-Encoding "!@rx br|compress|deflate|(?:pack200-)?gzip|identity|\*|^$|aes128gcm|exi|zstd|x-(?:compress|gzip)" \ - "id:920521,\ - phase:1,\ - block,\ - t:none,t:lowercase,\ - msg:'Illegal Accept-Encoding header',\ - logdata:'%{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/255/153',\ - tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:920017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:920018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:920017,phase:1,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:920018,phase:2,pass,nolog,skipAfter:END-REQUEST-920-PROTOCOL-ENFORCEMENT" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # # @@ -1773,23 +1542,23 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:920018,phase:2,pass,nolog,tag:'O SecRule REQUEST_BASENAME "@endsWith .pdf" \ "id:920202,\ - phase:1,\ + phase:2,\ block,\ - t:none,t:urlDecodeUni,\ + t:none,\ msg:'Range: Too many fields for pdf request (6 or more)',\ logdata:'%{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/4',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/4',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ chain" SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range "@rx ^bytes=(?:(?:\d+)?-(?:\d+)?\s*,?\s*){6}" \ - "setvar:'tx.inbound_anomaly_score_pl4=+%{tx.warning_anomaly_score}'" + "setvar:'tx.anomaly_score_pl4=+%{tx.warning_anomaly_score}'" # @@ -1809,19 +1578,19 @@ SecRule ARGS|ARGS_NAMES|REQUEST_BODY "@validateByteRange 38,44-46,48-58,61,65-90 tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/4',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/4',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl4=+%{tx.critical_anomaly_score}'" # # This is a stricter sibling of 920270. # -SecRule REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:Cookie|!REQUEST_HEADERS:Sec-Fetch-User|!REQUEST_HEADERS:Sec-CH-UA|!REQUEST_HEADERS:Sec-CH-UA-Mobile "@validateByteRange 32,34,38,42-59,61,65-90,95,97-122" \ +SecRule REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:Cookie|!REQUEST_HEADERS:Sec-Fetch-User "@validateByteRange 32,34,38,42-59,61,65-90,95,97-122" \ "id:920274,\ - phase:1,\ + phase:2,\ block,\ t:none,t:urlDecodeUni,\ msg:'Invalid character in request headers (outside of very strict set)',\ @@ -1830,24 +1599,22 @@ SecRule REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent|!REQUEST_HEADERS:Referer|!RE tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/4',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/4',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl4=+%{tx.critical_anomaly_score}'" # # This is a stricter sibling of 920270. -# The headers of this rule are Structured Header booleans, for which only `?0`, -# and `?1` are inconspicuous. -# Structured Header boolean: https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-header-structure-19#section-3.3.6 -# Sec-Fetch-User: https://www.w3.org/TR/fetch-metadata/#http-headerdef-sec-fetch-user -# Sec-CH-UA-Mobile: https://wicg.github.io/ua-client-hints/#sec-ch-ua-mobile +# The 'Sec-Fetch-User' header may contain the '?' (63) character. +# Therefore we exclude this header from rule 920274 which forbids '?'. +# https://www.w3.org/TR/fetch-metadata/#http-headerdef-sec-fetch-user # -SecRule REQUEST_HEADERS:Sec-Fetch-User|REQUEST_HEADERS:Sec-CH-UA-Mobile "!@rx ^(?:\?[01])?$" \ +SecRule REQUEST_HEADERS:Sec-Fetch-User "@validateByteRange 32,34,38,42-59,61,63,65-90,95,97-122" \ "id:920275,\ - phase:1,\ + phase:2,\ block,\ t:none,t:urlDecodeUni,\ msg:'Invalid character in request headers (outside of very strict set)',\ @@ -1856,12 +1623,12 @@ SecRule REQUEST_HEADERS:Sec-Fetch-User|REQUEST_HEADERS:Sec-CH-UA-Mobile "!@rx ^( tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/4',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/4',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl4=+%{tx.critical_anomaly_score}'" # -=[ Abnormal Character Escapes ]=- # @@ -1888,12 +1655,13 @@ SecRule REQUEST_HEADERS:Sec-Fetch-User|REQUEST_HEADERS:Sec-CH-UA-Mobile "!@rx ^( # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "@rx (?:^|[^\x5c])\x5c[cdeghijklmpqwxyz123456789]" \ +SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "@rx (?:^|[^\\\\])\\\\[cdeghijklmpqwxyz123456789]" \ "id:920460,\ phase:2,\ block,\ capture,\ - t:none,t:htmlEntityDecode,t:lowercase,\ + t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,\ + log,\ msg:'Abnormal character escapes in request',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -1903,10 +1671,11 @@ SecRule REQUEST_URI|REQUEST_HEADERS|ARGS|ARGS_NAMES "@rx (?:^|[^\x5c])\x5c[cdegh tag:'paranoia-level/4',\ tag:'OWASP_CRS',\ tag:'capec/1000/153/267',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl4=+%{tx.critical_anomaly_score}'" # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-921-PROTOCOL-ATTACK.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-921-PROTOCOL-ATTACK.conf index baeaaf906..60c20707a 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-921-PROTOCOL-ATTACK.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-921-PROTOCOL-ATTACK.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,10 +14,10 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:921011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:921012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:921011,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:921012,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # @@ -31,12 +31,12 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:921012,phase:2,pass,nolog,tag:'O # [ References ] # http://projects.webappsec.org/HTTP-Request-Smuggling # -SecRule ARGS_NAMES|ARGS|REQUEST_BODY|XML:/* "@rx (?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\s+[^\s]+\s+http/\d" \ +SecRule ARGS_NAMES|ARGS|REQUEST_BODY|XML:/* "@rx (?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\s+(?:\/|\w)[^\s]*(?:\s+http\/\d|[\r\n])" \ "id:921110,\ phase:2,\ block,\ capture,\ - t:none,t:htmlEntityDecode,t:lowercase,\ + t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,\ msg:'HTTP Request Smuggling Attack',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -46,17 +46,18 @@ SecRule ARGS_NAMES|ARGS|REQUEST_BODY|XML:/* "@rx (?:get|post|head|options|connec tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/33',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # -=[ HTTP Response Splitting ]=- # # [ Rule Logic ] # These rules look for Carriage Return (CR) %0d and Linefeed (LF) %0a characters. -# These characters may cause problems if the data is returned in a response header and +# These characters may cause problems if the data is returned in a respones header and # may be interpreted by an intermediary proxy server and treated as two separate # responses. # @@ -68,7 +69,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME phase:2,\ block,\ capture,\ - t:none,t:lowercase,\ + t:none,t:urlDecodeUni,t:lowercase,\ msg:'HTTP Response Splitting Attack',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -78,10 +79,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/34',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:\bhttp/\d|<(?:html|meta)\b)" \ @@ -89,7 +91,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME phase:2,\ block,\ capture,\ - t:none,t:htmlEntityDecode,t:lowercase,\ + t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,\ msg:'HTTP Response Splitting Attack',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -99,10 +101,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/34',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # -=[ HTTP Header Injection ]=- @@ -120,7 +123,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # SecRule REQUEST_HEADERS_NAMES|REQUEST_HEADERS "@rx [\n\r]" \ "id:921140,\ - phase:1,\ + phase:2,\ block,\ capture,\ t:none,t:htmlEntityDecode,\ @@ -133,10 +136,11 @@ SecRule REQUEST_HEADERS_NAMES|REQUEST_HEADERS "@rx [\n\r]" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/273',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # Detect newlines in argument names. @@ -151,7 +155,7 @@ SecRule ARGS_NAMES "@rx [\n\r]" \ phase:2,\ block,\ capture,\ - t:none,t:htmlEntityDecode,\ + t:none,t:urlDecodeUni,t:htmlEntityDecode,\ msg:'HTTP Header Injection Attack via payload (CR/LF detected)',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -161,10 +165,11 @@ SecRule ARGS_NAMES "@rx [\n\r]" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/33',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule ARGS_GET_NAMES|ARGS_GET "@rx [\n\r]+(?:\s|location|refresh|(?:set-)?cookie|(?:x-)?(?:forwarded-(?:for|host|server)|host|via|remote-ip|remote-addr|originating-IP))\s*:" \ @@ -172,7 +177,7 @@ SecRule ARGS_GET_NAMES|ARGS_GET "@rx [\n\r]+(?:\s|location|refresh|(?:set-)?cook phase:1,\ block,\ capture,\ - t:none,t:htmlEntityDecode,t:lowercase,\ + t:none,t:urlDecodeUni,t:htmlEntityDecode,t:lowercase,\ msg:'HTTP Header Injection Attack via payload (CR/LF and header-name detected)',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -182,17 +187,17 @@ SecRule ARGS_GET_NAMES|ARGS_GET "@rx [\n\r]+(?:\s|location|refresh|(?:set-)?cook tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/33',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # -=[ HTTP Splitting ]=- # # This rule detect \n or \r in the REQUEST FILENAME -# Reference: https://wiki.owasp.org/index.php/Testing_for_HTTP_Splitting/Smuggling_(OTG-INPVAL-016) -# Reference: https://owasp.org/www-project-web-security-testing-guide/assets/archive/OWASP_Testing_Guide_v4.pdf +# Reference: https://www.owasp.org/index.php/Testing_for_HTTP_Splitting/Smuggling_(OTG-INPVAL-016) # SecRule REQUEST_FILENAME "@rx [\n\r]" \ "id:921190,\ @@ -208,10 +213,11 @@ SecRule REQUEST_FILENAME "@rx [\n\r]" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/34',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -224,7 +230,7 @@ SecRule REQUEST_FILENAME "@rx [\n\r]" \ # # [ References ] # * https://www.blackhat.com/presentations/bh-europe-08/Alonso-Parada/Whitepaper/bh-eu-08-alonso-parada-WP.pdf -# * https://www.sonarsource.com/blog/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/ +# * https://blog.ripstech.com/2017/joomla-takeover-in-20-seconds-with-ldap-injection-cve-2017-14596/ # * https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/276#issue-126581660 SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ^[^:\(\)\&\|\!\<\>\~]*\)\s*(?:\((?:[^,\(\)\=\&\|\!\<\>\~]+[><~]?=|\s*[&!|]\s*(?:\)|\()?\s*)|\)\s*\(\s*[\&\|\!]\s*|[&!|]\s*\([^\(\)\=\&\|\!\<\>\~]+[><~]?=[^:\(\)\&\|\!\<\>\~]*)" \ @@ -238,12 +244,12 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'application-multi',\ tag:'language-ldap',\ tag:'platform-multi',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/136',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # -=[ Body Processor Bypass ]=- @@ -253,12 +259,12 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # This rule intends to detect content types in the Content-Type header outside of the actual content type declaration. # This prevents bypasses targeting the Modsecurity recommended rules controlling which body processor is used. # -# Regular expression generated from regex-assembly/921421.ra. +# Regular expression generated from util/regexp-assemble/data/921421.data. # To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 921421 +# (consult util/regexp-assemble/README.md for details): +# util/regexp-assemble/regexp-assemble.py update 921421 # -SecRule REQUEST_HEADERS:Content-Type "@rx ^[^\s\x0b,;]+[\s\x0b,;].*?(?:application/(?:.+\+)?json|(?:application/(?:soap\+)?|text/)xml)" \ +SecRule REQUEST_HEADERS:Content-Type "@rx ^[^;\s,]+[;\s,].*?(?:(?:application(?:\/soap\+|\/)|text\/)xml|application\/(?:.+[+])?json)" \ "id:921421,\ phase:1,\ block,\ @@ -274,41 +280,15 @@ SecRule REQUEST_HEADERS:Content-Type "@rx ^[^\s\x0b,;]+[\s\x0b,;].*?(?:applicati tag:'OWASP_CRS',\ tag:'capec/1000/255/153',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:921013,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:921014,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" # -# Rule against CVE-2021-40438: -# A crafted request uri-path can cause mod_proxy to forward the request to an origin server choosen by the remote user. -# This issue affects Apache HTTP Server 2.4.48 and earlier. -# GET /?unix:AAAAAAAAAAAAA|http://coreruleset.org/ -# -SecRule REQUEST_URI "@rx unix:[^|]*\|" \ - "id:921240,\ - phase:1,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:lowercase,\ - msg:'mod_proxy attack attempt detected',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-apache',\ - tag:'attack-protocol',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/210/272/220/33',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:921013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:921014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" -# -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # @@ -320,7 +300,7 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:921014,phase:2,pass,nolog,tag:'O # SecRule ARGS_GET "@rx [\n\r]" \ "id:921151,\ - phase:1,\ + phase:2,\ block,\ capture,\ t:none,t:urlDecodeUni,t:htmlEntityDecode,\ @@ -333,10 +313,11 @@ SecRule ARGS_GET "@rx [\n\r]" \ tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220/33',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # # -=[ Body Processor Bypass ]=- @@ -348,12 +329,12 @@ SecRule ARGS_GET "@rx [\n\r]" \ # [ References ] # * See rule 921422 # -# Regular expression generated from regex-assembly/921422.ra. +# Regular expression generated from util/regexp-assemble/data/921422.data. # To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 921422 +# (consult util/regexp-assemble/README.md for details): +# util/regexp-assemble/regexp-assemble.py update 921422 # -SecRule REQUEST_HEADERS:Content-Type "@rx ^[^\s\x0b,;]+[\s\x0b,;].*?\b(?:((?:tex|multipar)t|application)|((?:audi|vide)o|image|cs[sv]|(?:vn|relate)d|p(?:df|lain)|json|(?:soa|cs)p|x(?:ml|-www-form-urlencoded)|form-data|x-amf|(?:octe|repor)t|stream)|([\+/]))\b" \ +SecRule REQUEST_HEADERS:Content-Type "@rx ^[^;\s,]+[;\s,].*?\b(?:(audio|image|video|csv|css|vnd|pdf|plain|json|soap|xml|x-www-form-urlencoded|form-data|related|x-amf|octet|stream|csp|report)|(text|multipart|application)|(\/|\+))\b" \ "id:921422,\ phase:1,\ block,\ @@ -369,15 +350,15 @@ SecRule REQUEST_HEADERS:Content-Type "@rx ^[^\s\x0b,;]+[\s\x0b,;].*?\b(?:((?:tex tag:'OWASP_CRS',\ tag:'capec/1000/255/153',\ tag:'PCI/12.1',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:921015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:921016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:921015,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:921016,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # # @@ -405,9 +386,9 @@ SecRule &REQUEST_HEADERS:Range "@gt 0" \ tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/210/272/220',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # -=[ HTTP Parameter Pollution ]=- @@ -439,117 +420,38 @@ SecRule ARGS_NAMES "@rx ." \ tag:'attack-protocol',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/137/15/460',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ setvar:'TX.paramcounter_%{MATCHED_VAR_NAME}=+1'" SecRule TX:/paramcounter_.*/ "@gt 1" \ "id:921180,\ phase:2,\ pass,\ - msg:'HTTP Parameter Pollution (%{MATCHED_VAR_NAME})',\ - logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/137/15/460',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - - -# -=[ HTTP Parameter Pollution ]=- -# -# [ Rule Logic ] -# Parameter pollution rule 921180 PL3 can by bypassed when a weak backend parameter -# parser is ignoring additional characters in a parameter array name after the -# closing of the array. -# Rule 921210 PL3 prevents this by disallowing arbitrary strings after an array has -# been closed or inbetween the square brackets in multidimensional arrays. -# Please note that rule 921210 allows for 2-dimensional, but not for higher dimensional -# arrays. If these are flagged as attacks, a rule exclusion will have to be -# deployed; ideally for the parameter(s) in question. -# -# [ References ] -# Private bug bounty in Spring 2022, findings Z05OZUCH. -# -# [ Payloads ] -# * foo[1]a=bar&foo[1]b= - parameter parsers often cut after the closing of -# the array. 921180 PL3 takes the full name, though. -# This impediance mismatch allows for bypasses. -# * foo[1]x[1]=bar&foo[1]x[2]= - extension of 1; this has the advantage that -# the parameter name does end with "]" just like a valid array notation. -# -SecRule ARGS_NAMES "@rx (][^\]]+$|][^\]]+\[)" \ - "id:921210,\ - phase:2,\ - pass,\ - log,\ - msg:'HTTP Parameter Pollution after detecting bogus char after parameter array',\ + msg:'HTTP Parameter Pollution (%{TX.1})',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/137/15/460',\ tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/137/15/460',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + chain" + SecRule MATCHED_VARS_NAMES "@rx TX:paramcounter_(.*)" \ + "capture,\ + setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:921017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:921018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:921017,phase:1,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:921018,phase:2,pass,nolog,skipAfter:END-REQUEST-921-PROTOCOL-ATTACK" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # -# -=[ HTTP Parameter Pollution ]=- -# -# [ Rule Logic ] -# Parameter pollution rule 921180 PL3 and 921210 PL3 can by bypassed if a -# weak backend parameter parser ignores parameter array alltogether at -# cuts parameter names at the first occurrence of the "[" character. -# The rule 921220 PL4 prevents this by disallowing parameter array names. -# -# If an application needs parameter array names, then this rule should be -# disabled, ideally by issueing a rule exclusion for the parameter names -# that need it. -# -# [ References ] -# Private bug bounty in Spring 2022, finding 5UXE4RK0. -# -# [ Payloads ] -# * foo[1]=bar&foo[2]= -# * foo=bar&foo[1]= -# * foo[1]=bar&foo[1]acb]= - this is an edge case that 921210 PL3 is not -# able to catch since the parameter name ends with "]". -# -SecRule ARGS_NAMES "@rx \[" \ - "id:921220,\ - phase:2,\ - pass,\ - log,\ - msg:'HTTP Parameter Pollution possible via array notation',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-protocol',\ - tag:'paranoia-level/4',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/137/15/460',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.http_violation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'" - # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-922-MULTIPART-ATTACK.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-922-MULTIPART-ATTACK.conf index 1a8f33cbe..75d553f3e 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-922-MULTIPART-ATTACK.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-922-MULTIPART-ATTACK.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -35,26 +35,20 @@ SecRule &MULTIPART_PART_HEADERS:_charset_ "!@eq 0" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-multipart-header',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/255/153',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/1',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.922100_charset=|%{ARGS._charset_}|',\ chain" - SecRule TX:922100_CHARSET "!@within %{tx.allowed_request_content_type_charset}" \ + SecRule ARGS:_charset_ "!@within |%{tx.allowed_request_content_type_charset}|" \ "t:lowercase,\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # Only allow specific charsets same as Rule 920600 # Note: this is in phase:2 because these are headers that come in the body -# -# Regular expression generated from regex-assembly/922110-chain1.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 922110-chain1 -SecRule MULTIPART_PART_HEADERS "@rx ^content-type\s*:\s*(.*)$" \ +SecRule MULTIPART_PART_HEADERS "@rx ^content-type\s*+:\s*+(.*)$" \ "id:922110,\ phase:2,\ block,\ @@ -66,14 +60,15 @@ SecRule MULTIPART_PART_HEADERS "@rx ^content-type\s*:\s*(.*)$" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-protocol',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/272/220',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/1',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ chain" - SecRule TX:1 "!@rx ^(?:(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)/(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\x0b]*;[\s\x0b]*(?:charset[\s\x0b]*=[\s\x0b]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\x0b-\"\(\),/:-\?\[-\]c\{\}]|c(?:[^!\"\(\),/:-\?\[-\]h\{\}]|h(?:[^!\"\(\),/:-\?\[-\]a\{\}]|a(?:[^!\"\(\),/:-\?\[-\]r\{\}]|r(?:[^!\"\(\),/:-\?\[-\]s\{\}]|s(?:[^!\"\(\),/:-\?\[-\]e\{\}]|e[^!\"\(\),/:-\?\[-\]t\{\}]))))))[^!\"\(\),/:-\?\[-\]\{\}]*[\s\x0b]*=[\s\x0b]*[^!\(\),/:-\?\[-\]\{\}]+);?)*(?:[\s\x0b]*,[\s\x0b]*(?:(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)/(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\x0b]*;[\s\x0b]*(?:charset[\s\x0b]*=[\s\x0b]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\x0b-\"\(\),/:-\?\[-\]c\{\}]|c(?:[^!\"\(\),/:-\?\[-\]h\{\}]|h(?:[^!\"\(\),/:-\?\[-\]a\{\}]|a(?:[^!\"\(\),/:-\?\[-\]r\{\}]|r(?:[^!\"\(\),/:-\?\[-\]s\{\}]|s(?:[^!\"\(\),/:-\?\[-\]e\{\}]|e[^!\"\(\),/:-\?\[-\]t\{\}]))))))[^!\"\(\),/:-\?\[-\]\{\}]*[\s\x0b]*=[\s\x0b]*[^!\(\),/:-\?\[-\]\{\}]+);?)*)*$" \ - "setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + SecRule TX:1 "!@rx ^(?:(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+)\/(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+))(?:\s*+;\s*+(?:(?:charset\s*+=\s*+(?:\"?(?:iso-8859-15?|windows-1252|utf-8)\b\"?))|(?:(?:c(?:h(?:a(?:r(?:s(?:e[^t\"(),\/:;<=>?![\x5c\]{}]|[^e\"(),/:;<=>?![\x5c\]{}])|[^s\"(),/:;<=>?![\x5c\]{}])|[^r\"(),/:;<=>?![\x5c\]{}])|[^a\"(),/:;<=>?![\x5c\]{}])|[^h\"(),/:;<=>?![\x5c\]{}])|[^c\"(),/:;<=>?![\x5c\]{}])[^\"(),/:;<=>?![\x5c\]{}]*(?:)\s*+=\s*+[^(),/:;<=>?![\x5c\]{}]+)|;?))*(?:\s*+,\s*+(?:(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+)\/(?:\*|[^\"(),\/:;<=>?![\x5c\]{}]+))(?:\s*+;\s*+(?:(?:charset\s*+=\s*+(?:\"?(?:iso-8859-15?|windows-1252|utf-8)\b\"?))|(?:(?:c(?:h(?:a(?:r(?:s(?:e[^t\"(),\/:;<=>?![\x5c\]{}]|[^e\"(),/:;<=>?![\x5c\]{}])|[^s\"(),/:;<=>?![\x5c\]{}])|[^r\"(),/:;<=>?![\x5c\]{}])|[^a\"(),/:;<=>?![\x5c\]{}])|[^h\"(),/:;<=>?![\x5c\]{}])|[^c\"(),/:;<=>?![\x5c\]{}])[^\"(),/:;<=>?![\x5c\]{}]*(?:)\s*+=\s*+[^(),/:;<=>?![\x5c\]{}]+)|;?))*)*$" \ + "t:lowercase,\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # Content-Transfer-Encoding was deprecated by rfc7578 in 2015 and should not be used (see: https://www.rfc-editor.org/rfc/rfc7578#section-4.7) # Note: this is in phase:2 because these are headers that come in the body @@ -89,12 +84,12 @@ SecRule MULTIPART_PART_HEADERS "@rx content-transfer-encoding:(.*)" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-deprecated-header',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/272/220',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/1',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # Multipart header names can't contain any characters outside of range 33 and 126, # excluding 58 (':') which is the separator. @@ -115,6 +110,6 @@ SecRule MULTIPART_PART_HEADERS "@rx [^\x21-\x7E][\x21-\x39\x3B-\x7E]*:" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/272/220',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf index 4cec13501..647028545 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,10 +14,10 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:930011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:930012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:930011,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:930012,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # @@ -27,18 +27,13 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:930012,phase:2,pass,nolog,tag:'O # # [ Encoded /../ Payloads ] # -# Regular expression generated from regex-assembly/930100.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 930100 -# -SecRule REQUEST_URI_RAW|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|FILES|XML:/* "@rx (?i)(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[56]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1u)|0x(?:2f|5c))(?:\.(?:%0[01]|\?)?|\?\.?|%(?:2(?:(?:5(?:2|c0%25a))?e|%45)|c0(?:\.|%[256aef]e)|u(?:(?:ff0|002)e|2024)|%32(?:%(?:%6|4)5|E)|(?:e|f(?:(?:8|c%80)%8)?0%8)0%80%ae)|0x2e){2,3}(?:[/\x5c]|%(?:2(?:f|5(?:2f|5c|c(?:1%259c|0%25af))|%46)|5c|c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|(?:bg%q|(?:e|f(?:8%8)?0%8)0%80%a)f|u(?:221[56]|EFC8|F025|002f)|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|1u)|0x(?:2f|5c))" \ +SecRule REQUEST_URI_RAW|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|XML:/* "@rx (?i)(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))(?:%(?:(?:f(?:(?:c%80|8)%8)?0%8|e)0%80%ae|2(?:(?:5(?:c0%25a|2))?e|%45)|u(?:(?:002|ff0)e|2024)|%32(?:%(?:%6|4)5|E)|c0(?:%[256aef]e|\.))|\.(?:%0[01]|\?)?|\?\.?|0x2e){2}(?:\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\/))" \ "id:930100,\ phase:2,\ block,\ capture,\ t:none,\ - msg:'Path Traversal Attack (/../) or (/.../)',\ + msg:'Path Traversal Attack (/../)',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ @@ -47,30 +42,21 @@ SecRule REQUEST_URI_RAW|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|FILES|XML: tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/255/153/126',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}'" # -# [ Decoded /../ or /..;/ Payloads ] +# [ Decoded /../ Payloads ] # -# To prevent '..' from triggering, the regexp is split into two parts: -# - ../ -# - /.. -# OR -# - .../ -# - /... -# -# Semicolon added to prevent path traversal via reverse proxy mapping '/..;/' (Tomcat) -# -SecRule REQUEST_URI|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|FILES|XML:/* "@rx (?:(?:^|[\x5c/;])\.{2,3}[\x5c/;]|[\x5c/;]\.{2,3}(?:[\x5c/;]|$))" \ +SecRule REQUEST_URI|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|XML:/* "@rx (?:^|[\\/])\.\.(?:[\\/]|$)" \ "id:930110,\ phase:2,\ block,\ capture,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,t:cmdLine,\ - msg:'Path Traversal Attack (/../) or (/.../)',\ + msg:'Path Traversal Attack (/../)',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ @@ -79,27 +65,23 @@ SecRule REQUEST_URI|ARGS|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|FILES|XML:/* " tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/255/153/126',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ multiMatch,\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}'" # # -=[ OS File Access ]=- # -# We check for OS file access with the help of a local file with OS files data. -# # Ref: https://github.com/lightos/Panoptic/blob/master/cases.xml # -# If you wonder where support for Google OAuth2 has gone, see: -# https://github.com/coreruleset/google-oauth2-plugin SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile lfi-os-files.data" \ "id:930120,\ phase:2,\ block,\ capture,\ - t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,\ + t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\ msg:'OS File Access Attempt',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -110,10 +92,10 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/255/153/126',\ tag:'PCI/6.5.4',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # -=[ Restricted File Access ]=- @@ -123,10 +105,10 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # SecRule REQUEST_FILENAME "@pmFromFile restricted-files.data" \ "id:930130,\ - phase:1,\ + phase:2,\ block,\ capture,\ - t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,\ + t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\ msg:'Restricted File Access Attempt',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -137,62 +119,33 @@ SecRule REQUEST_FILENAME "@pmFromFile restricted-files.data" \ tag:'OWASP_CRS',\ tag:'capec/1000/255/153/126',\ tag:'PCI/6.5.4',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:930013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:930014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:930013,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:930014,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) -# - -# -# -=[ OS File Access ]=- -# -# This is a stricter sibling of rule 930120. -# This stricter sibling checks for OS file data in request headers referer and user-agent. -# We check for OS file access with the help of a local file with OS files data. -# -# Ref: https://github.com/lightos/Panoptic/blob/master/cases.xml -# -SecRule REQUEST_HEADERS:Referer|REQUEST_HEADERS:User-Agent "@pmFromFile lfi-os-files.data" \ - "id:930121,\ - phase:1,\ - block,\ - capture,\ - t:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,\ - msg:'OS File Access Attempt in REQUEST_HEADERS',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-lfi',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/255/153/126',\ - tag:'PCI/6.5.4',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:930015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:930016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" -# -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:930017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:930018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:930015,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:930016,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) +# + + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:930017,phase:1,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:930018,phase:2,pass,nolog,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI" +# +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf index e68fdf469..4e819e784 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -17,10 +17,10 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:931011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:931012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:931011,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:931012,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # -=[ Rule Logic ]=- @@ -34,7 +34,7 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:931012,phase:2,pass,nolog,tag:'O # http://projects.webappsec.org/Remote-File-Inclusion # http://tacticalwebappsec.blogspot.com/2009/06/generic-remote-file-inclusion-attack.html # -SecRule ARGS "@rx ^(?i:file|ftps?|https?)://(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" \ +SecRule ARGS "@rx ^(?i:file|ftps?|https?):\/\/(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})" \ "id:931100,\ phase:2,\ block,\ @@ -49,12 +49,13 @@ SecRule ARGS "@rx ^(?i:file|ftps?|https?)://(?:\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3 tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/175/253',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule QUERY_STRING|REQUEST_BODY "@rx (?i)(?:\binclude\s*\([^)]*|mosConfig_absolute_path|_CONF\[path\]|_SERVER\[DOCUMENT_ROOT\]|GALLERY_BASEDIR|path\[docroot\]|appserv_root|config\[root_dir\])=(?:file|ftps?|https?)://" \ +SecRule QUERY_STRING|REQUEST_BODY "@rx (?i)(?:\binclude\s*\([^)]*|mosConfig_absolute_path|_CONF\[path\]|_SERVER\[DOCUMENT_ROOT\]|GALLERY_BASEDIR|path\[docroot\]|appserv_root|config\[root_dir\])=(?:file|ftps?|https?):\/\/" \ "id:931110,\ phase:2,\ block,\ @@ -69,10 +70,11 @@ SecRule QUERY_STRING|REQUEST_BODY "@rx (?i)(?:\binclude\s*\([^)]*|mosConfig_abso tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/175/253',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule ARGS "@rx ^(?i:file|ftps?|https?).*?\?+$" \ "id:931120,\ @@ -89,31 +91,21 @@ SecRule ARGS "@rx ^(?i:file|ftps?|https?).*?\?+$" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/175/253',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:931013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:931014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:931013,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:931014,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -# url:file:// can be used by Java applications using -# org.apache.commons.io.IOUtils to access internal files, so this has been added -# -# This rule has one (stricter) sibling: 931131. -# That rule applies the same regular expression to the request filename in phase 1. -# -# Regular expression generated from regex-assembly/931130.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 931130 -# -SecRule ARGS "@rx (?i)(?:(?:url|jar):)?(?:a(?:cap|f[ps]|ttachment)|b(?:eshare|itcoin|lob)|c(?:a(?:llto|p)|id|vs|ompress.(?:zlib|bzip2))|d(?:a(?:v|ta)|ict|n(?:s|tp))|e(?:d2k|xpect)|f(?:(?:ee)?d|i(?:le|nger|sh)|tps?)|g(?:it|o(?:pher)?|lob)|h(?:323|ttps?)|i(?:ax|cap|(?:ma|p)ps?|rc[6s]?)|ja(?:bbe)?r|l(?:dap[is]?|ocal_file)|m(?:a(?:ilto|ven)|ms|umble)|n(?:e(?:tdoc|ws)|fs|ntps?)|ogg|p(?:aparazzi|h(?:ar|p)|op(?:2|3s?)|r(?:es|oxy)|syc)|r(?:mi|sync|tm(?:f?p)?|ar)|s(?:3|ftp|ips?|m(?:[bs]|tps?)|n(?:ews|mp)|sh(?:2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?)?|vn(?:\+ssh)?)|t(?:e(?:amspeak|lnet)|ftp|urns?)|u(?:dp|nreal|t2004)|v(?:entrilo|iew-source|nc)|w(?:ebcal|ss?)|x(?:mpp|ri)|zip)://(?:[^@]+@)?([^/]*)" \ +SecRule ARGS "@rx ^(?i:file|ftps?|https?)://([^/]*).*$" \ "id:931130,\ phase:2,\ block,\ @@ -125,60 +117,32 @@ SecRule ARGS "@rx (?i)(?:(?:url|jar):)?(?:a(?:cap|f[ps]|ttachment)|b(?:eshare|it tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-rfi',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/175/253',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rfi_parameter_%{MATCHED_VAR_NAME}=.%{tx.1}',\ chain" SecRule TX:/rfi_parameter_.*/ "!@endsWith .%{request_headers.host}" \ - "setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# This is a (stricter) sibling of 931130. -# -# Regular expression generated from regex-assembly/931131.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 931131 -# -SecRule REQUEST_FILENAME "@rx (?i)(?:(?:url|jar):)?(?:a(?:cap|f[ps]|ttachment)|b(?:eshare|itcoin|lob)|c(?:a(?:llto|p)|id|vs|ompress.(?:zlib|bzip2))|d(?:a(?:v|ta)|ict|n(?:s|tp))|e(?:d2k|xpect)|f(?:(?:ee)?d|i(?:le|nger|sh)|tps?)|g(?:it|o(?:pher)?|lob)|h(?:323|ttps?)|i(?:ax|cap|(?:ma|p)ps?|rc[6s]?)|ja(?:bbe)?r|l(?:dap[is]?|ocal_file)|m(?:a(?:ilto|ven)|ms|umble)|n(?:e(?:tdoc|ws)|fs|ntps?)|ogg|p(?:aparazzi|h(?:ar|p)|op(?:2|3s?)|r(?:es|oxy)|syc)|r(?:mi|sync|tm(?:f?p)?|ar)|s(?:3|ftp|ips?|m(?:[bs]|tps?)|n(?:ews|mp)|sh(?:2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?)?|vn(?:\+ssh)?)|t(?:e(?:amspeak|lnet)|ftp|urns?)|u(?:dp|nreal|t2004)|v(?:entrilo|iew-source|nc)|w(?:ebcal|ss?)|x(?:mpp|ri)|zip)://(?:[^@]+@)?([^/]*)" \ - "id:931131,\ - phase:1,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Possible Remote File Inclusion (RFI) Attack: Off-Domain Reference/Link',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-rfi',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/175/253',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rfi_parameter_%{MATCHED_VAR_NAME}=.%{tx.1}',\ - chain" - SecRule TX:/rfi_parameter_.*/ "!@endsWith .%{request_headers.host}" \ - "setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + "ctl:auditLogParts=+E,\ + setvar:'tx.rfi_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:931015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:931016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:931015,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:931016,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:931017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:931018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:931017,phase:1,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:931018,phase:2,pass,nolog,skipAfter:END-REQUEST-931-APPLICATION-ATTACK-RFI" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf index 8badbba70..002088ad3 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,10 +14,10 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:932011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:932012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:932011,phase:1,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:932012,phase:2,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # @@ -50,8 +50,7 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:932012,phase:2,pass,nolog,tag:'O # \n ;\nifconfig # \r ;\rifconfig # \$\( $(ifconfig) -# \$\(\( $((ifconfig)) -# \$\[ $[2+2] +# $\(\( $((ifconfig)) # ` `ifconfig` # \${ ${ifconfig} # <\( <( ifconfig ) @@ -73,7 +72,9 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:932012,phase:2,pass,nolog,tag:'O # # 4. Paths # -# [\?\*\[\]\(\)\-\|+\w'\"\./\x5c]+/ /sbin/ifconfig, /s?in/./ifconfig, /s[a-b]in/ifconfig etc. +# [\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/ /sbin/ifconfig, /s?in/./ifconfig, /s[a-b]in/ifconfig etc. +# +# This rule is case-sensitive to prevent FP ("Cat" vs. "cat"). # # An effort was made to combat evasions by shell quoting (e.g. 'ls', # 'l'"s", \l\s are all valid). ModSecurity has a t:cmdLine @@ -82,110 +83,30 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:932012,phase:2,pass,nolog,tag:'O # useful for this case. However, emulating the transformation makes # the regexp more complex. # -# This is the base Rule to prevent Unix Command Injection -# for prefix + two and three characters. +# To rebuild the word list regexp: +# cd util/regexp-assemble +# cat regexp-932100.txt | ./regexp-cmdline.py unix | ./regexp-assemble.pl # -# Rule relations: +# Then insert the assembled regexp into this template: # -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932230.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932230 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:7[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[arx])?|(?:(?:b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z|x)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z|h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|[ckz][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?f|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h)|f[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[dg]|g[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[&,<>\|]|(?:[\-\.0-9A-Z_a-z][\"'\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\*\-0-9\?@_a-\{]*)?\x5c?)+[\s\x0b&,<>\|]).*|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?g)|i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b|l[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:s|z[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:4|[\s\x0b&\),<>\|].*))|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|x[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z)|r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*)?|s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|(?:e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|(?:s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?)?h)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n)|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?3[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m)\b" \ - "id:932230,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Unix Command Injection (2-3 chars)',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# [ Unix command injection ] +# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]* +# [regexp assembled from util/regexp-assemble/regexp-932100.txt] +# \b" \ # # This is the base Rule to prevent Unix Command Injection -# for prefix + more than 4 characters. +# Please refer other rules 932105,932106 to know more. # -# Rule relations: +# .932100 +# ├── 932105 +# ├── 932106 # -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932235.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932235 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:(?:HEAD|POST|y(?:arn|elp))[\s\x0b&\)<>\|]|a(?:dd(?:group|user)|getty|(?:l(?:ias|pine)|xel)[\s\x0b&\)<>\|]|nsible|pt(?:-get|itude[\s\x0b&\)<>\|])|r(?:ch[\s\x0b&\)<>\|]|ia2c)|s(?:cii(?:-xfr|85)|pell)|tobm)|b(?:a(?:s(?:e(?:32|64|n(?:ame[\s\x0b&\)<>\|]|c))|h[\s\x0b&\)<>\|])|tch[\s\x0b&\)<>\|])|lkid|pftrace|r(?:eaksw|idge[\s\x0b&\)<>\|])|sd(?:cat|iff|tar)|u(?:iltin|n(?:dler[\s\x0b&\)<>\|]|zip2)|s(?:ctl|ybox))|y(?:ebug|obu)|z(?:c(?:at|mp)|diff|e(?:grep|xe)|f?grep|ip2(?:recover)?|less|more))|c(?:a(?:ncel|psh)[\s\x0b&\)<>\|]|ertbot|h(?:attr|(?:dir|root)[\s\x0b&\)<>\|]|e(?:ck_(?:by_ssh|cups|log|memory|raid|s(?:sl_cert|tatusfile))|f[\s\x0b&\)\-<>\|])|(?:flag|pas)s|g(?:passwd|rp)|mod|o(?:om|wn)|sh)|lang(?:[\s\x0b&\)<>\|]|\+\+)|o(?:(?:b|pro)c|(?:lumn|m(?:m(?:and)?|p(?:oser|ress)))[\s\x0b&\)<>\|]|w(?:say|think))|p(?:an|io|ulimit)|r(?:ash[\s\x0b&\)<>\|]|on(?:[\s\x0b&\)<>\|]|tab))|s(?:cli[\s\x0b&\)<>\|]|plit|vtool)|u(?:psfilter|rl[\s\x0b&\)<>\|]))|d(?:(?:a(?:sh|te)|i(?:alog|ff))[\s\x0b&\)<>\|]|hclient|m(?:esg|idecode|setup)|o(?:as|(?:cker|ne)[\s\x0b&\)<>\|]|sbox)|pkg|vips)|e(?:2fsck|(?:asy_instal|va)l|cho[\s\x0b&\)<>\|]|fax|grep|macs|n(?:d(?:if|sw)|v-update)|sac|x(?:ec[\s\x0b&\)<>\|]|iftool|p(?:(?:and|(?:ec|or)t)[\s\x0b&\)<>\|]|r)))|f(?:acter|(?:etch|lock|unction)[\s\x0b&\)<>\|]|grep|i(?:le(?:[\s\x0b&\)<>\|]|test)|(?:n(?:d|ger)|sh)[\s\x0b&\)<>\|])|o(?:ld[\s\x0b&\)<>\|]|reach)|ping|tp(?:stats|who))|g(?:awk[\s\x0b&\)<>\|]|core|e(?:ni(?:e[\s\x0b&\)<>\|]|soimage)|tfacl[\s\x0b&\)<>\|])|hci|i(?:mp[\s\x0b&\)<>\|]|nsh)|r(?:ep[\s\x0b&\)<>\|]|oup(?:[\s\x0b&\)<>\|]|mod))|tester|unzip|z(?:cat|exe|ip))|h(?:(?:ash|i(?:ghlight|story))[\s\x0b&\)<>\|]|e(?:ad[\s\x0b&\)<>\|]|xdump)|ost(?:id|name)|ping3|t(?:digest|op|passwd))|i(?:conv|f(?:config|top)|nstall[\s\x0b&\)<>\|]|onice|p(?:6?tables|config)|spell)|j(?:ava[\s\x0b&\)<>\|]|exec|o(?:(?:bs|in)[\s\x0b&\)<>\|]|urnalctl)|runscript)|k(?:ill(?:[\s\x0b&\)<>\|]|all)|nife[\s\x0b&\)<>\|]|sshell)|l(?:a(?:st(?:[\s\x0b&\)<>\|]|comm|log(?:in)?)|tex[\s\x0b&\)<>\|])|dconfig|ess(?:[\s\x0b&\)<>\|]|echo|(?:fil|pip)e)|ftp(?:get)?|(?:inks|ynx)[\s\x0b&\)<>\|]|o(?:(?:ca(?:l|te)|ok)[\s\x0b&\)<>\|]|g(?:inctl|(?:nam|sav)e)|setup)|s(?:-F|b_release|cpu|hw|mod|of|pci|usb)|trace|ua(?:la)?tex|wp-(?:d(?:ownload|ump)|mirror|request)|z(?:4c(?:at)?|c(?:at|mp)|diff|[ef]?grep|less|m(?:a(?:dec|info)?|ore)))|m(?:a(?:il(?:[\s\x0b&\)<>q\|]|x[\s\x0b&\)<>\|])|ke[\s\x0b&\)<>\|]|ster\.passwd|wk)|k(?:dir[\s\x0b&\)<>\|]|fifo|nod|temp)|locate|o(?:squitto|unt[\s\x0b&\)<>\|])|sg(?:attrib|c(?:at|onv)|filter|merge|uniq)|utt[\s\x0b&\)<>\|]|ysql(?:admin|dump(?:slow)?|hotcopy|show)?)|n(?:a(?:no[\s\x0b&\)<>\|]|sm|wk)|c(?:\.(?:openbsd|traditional)|at)|e(?:ofetch|t(?:(?:c|st)at|kit-ftp|plan))|(?:ice|ull)[\s\x0b&\)<>\|]|map|o(?:de[\s\x0b&\)<>\|]|hup)|ping|roff|s(?:enter|lookup|tat))|o(?:ctave[\s\x0b&\)<>\|]|nintr|p(?:en(?:ssl|v(?:pn|t))|kg))|p(?:a(?:(?:cman|rted|tch)[\s\x0b&\)<>\|]|s(?:swd|te[\s\x0b&\)<>\|]))|d(?:f(?:la)?tex|ksh)|er(?:(?:f|ms)[\s\x0b&\)<>\|]|l(?:[\s\x0b&\)5<>\|]|sh))|(?:ft|gre)p|hp(?:-cgi|[57])|i(?:(?:co|ng)[\s\x0b&\)<>\|]|dstat|gz)|k(?:exec|g_?info|ill)|opd|rint(?:env|f[\s\x0b&\)<>\|])|s(?:ed|ftp|ql)|tar(?:diff|grep)?|u(?:ppet[\s\x0b&\)<>\|]|shd)|wd\.db|y(?:thon[^\s\x0b]|3?versions))|r(?:ak(?:e[\s\x0b&\)<>\|]|u)|bash|e(?:a(?:delf|lpath)|(?:dcarpet|name|p(?:eat|lace))[\s\x0b&\)<>\|]|stic)|l(?:ogin|wrap)|m(?:dir[\s\x0b&\)<>\|]|user)|nano|oute[\s\x0b&\)<>\|]|pm(?:db|(?:quer|verif)y)|sync|u(?:by[^\s\x0b]|n-(?:mailcap|parts))|vi(?:ew|m))|s(?:(?:ash|c(?:hed|r(?:een|ipt))|nap)[\s\x0b&\)<>\|]|diff|e(?:(?:lf|rvice)[\s\x0b&\)<>\|]|ndmail|t(?:arch|env|facl[\s\x0b&\)<>\|]|sid))|ftp|h(?:\.distrib|(?:adow|ells)[\s\x0b&\)<>\|]|u(?:f|tdown[\s\x0b&\)<>\|]))|l(?:eep[\s\x0b&\)<>\|]|sh)|mbclient|o(?:cat|elim|(?:rt|urce)[\s\x0b&\)<>\|])|p(?:lit[\s\x0b&\)<>\|]|wd\.db)|qlite3|sh(?:-key(?:ge|sca)n|pass)|t(?:art-stop-daemon|d(?:buf|err|in|out)|r(?:ace|ings[\s\x0b&\)<>\|]))|udo|ys(?:ctl|tem(?:ctl|d-resolve)))|t(?:a(?:il[\s\x0b&\)<>f\|]|sk(?:[\s\x0b&\)<>\|]|set))|c(?:l?sh|p(?:dump|ing|traceroute))|elnet|ftp|ime(?:datectl|out[\s\x0b&\)<>\|])|mux|ouch[\s\x0b&\)<>\|]|r(?:aceroute6?|off)|shark)|u(?:limit[\s\x0b&\)<>\|]|n(?:ame|(?:compress|s(?:et|hare))[\s\x0b&\)<>\|]|expand|iq|l(?:ink[\s\x0b&\)<>\|]|z(?:4|ma))|(?:pig|x)z|rar|z(?:ip[\s\x0b&\)<>\|]|std))|p(?:2date[\s\x0b&\)<>\|]|date-alternatives)|ser(?:(?:ad|mo)d|del)|u(?:de|en)code)|v(?:algrind|i(?:ew[\s\x0b&\)<>\|]|gr|mdiff|pw|rsh|sudo)|olatility[\s\x0b&\)<>\|])|w(?:a(?:ll|tch)[\s\x0b&\)<>\|]|get|h(?:iptail[\s\x0b&\)<>\|]|o(?:ami|is))|i(?:reshark|sh[\s\x0b&\)<>\|]))|x(?:args|e(?:la)?tex|mo(?:dmap|re)|pad|term|z(?:c(?:at|mp)|d(?:ec|iff)|[ef]?grep|less|more))|z(?:athura|c(?:at|mp)|diff|e(?:grep|ro[\s\x0b&\)<>\|])|f?grep|ip(?:c(?:loak|mp)|details|grep|info|(?:merg|not)e|split|tool)|less|more|run|s(?:oelim|td(?:(?:ca|m)t|grep|less)?)|ypper))" \ - "id:932235,\ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]*(?:l[\\\\'\"]*(?:w[\\\\'\"]*p[\\\\'\"]*-[\\\\'\"]*(?:d[\\\\'\"]*(?:o[\\\\'\"]*w[\\\\'\"]*n[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*a[\\\\'\"]*d|u[\\\\'\"]*m[\\\\'\"]*p)|r[\\\\'\"]*e[\\\\'\"]*q[\\\\'\"]*u[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|m[\\\\'\"]*i[\\\\'\"]*r[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*r)|s(?:[\\\\'\"]*(?:b[\\\\'\"]*_[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*s[\\\\'\"]*e|c[\\\\'\"]*p[\\\\'\"]*u|m[\\\\'\"]*o[\\\\'\"]*d|p[\\\\'\"]*c[\\\\'\"]*i|u[\\\\'\"]*s[\\\\'\"]*b|-[\\\\'\"]*F|h[\\\\'\"]*w|o[\\\\'\"]*f))?|z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|m[\\\\'\"]*(?:o[\\\\'\"]*r[\\\\'\"]*e|a)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s)|e[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*(?:(?:f[\\\\'\"]*i[\\\\'\"]*l|p[\\\\'\"]*i[\\\\'\"]*p)[\\\\'\"]*e|e[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*o|(?:\s|<|>).*)|a[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*(?:l[\\\\'\"]*o[\\\\'\"]*g(?:[\\\\'\"]*i[\\\\'\"]*n)?|c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*m|(?:\s|<|>).*)|o[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*(?:t[\\\\'\"]*e|l)[\\\\'\"]*(?:\s|<|>).*|g[\\\\'\"]*n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e)|d[\\\\'\"]*(?:c[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*i[\\\\'\"]*g|d[\\\\'\"]*(?:\s|<|>).*)|f[\\\\'\"]*t[\\\\'\"]*p(?:[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*t)?|(?:[np]|y[\\\\'\"]*n[\\\\'\"]*x)[\\\\'\"]*(?:\s|<|>).*)|b[\\\\'\"]*(?:z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*p[\\\\'\"]*2)|s[\\\\'\"]*d[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*f[\\\\'\"]*f|t[\\\\'\"]*a[\\\\'\"]*r)|a[\\\\'\"]*(?:t[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|s[\\\\'\"]*h)|r[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*k[\\\\'\"]*s[\\\\'\"]*w|u[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*n)|c[\\\\'\"]*(?:o[\\\\'\"]*(?:m[\\\\'\"]*(?:p[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*d)[\\\\'\"]*(?:\s|<|>).*|p[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*c)|h[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*r[\\\\'\"]*(?:\s|<|>).*|f[\\\\'\"]*l[\\\\'\"]*a[\\\\'\"]*g[\\\\'\"]*s|a[\\\\'\"]*t[\\\\'\"]*t[\\\\'\"]*r|m[\\\\'\"]*o[\\\\'\"]*d)|r[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*b|(?:[cp]|a[\\\\'\"]*t)[\\\\'\"]*(?:\s|<|>).*|u[\\\\'\"]*r[\\\\'\"]*l|s[\\\\'\"]*h)|f[\\\\'\"]*(?:i(?:[\\\\'\"]*(?:l[\\\\'\"]*e[\\\\'\"]*(?:t[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|(?:\s|<|>).*)|n[\\\\'\"]*d[\\\\'\"]*(?:\s|<|>).*))?|t[\\\\'\"]*p[\\\\'\"]*(?:s[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*s|w[\\\\'\"]*h[\\\\'\"]*o|(?:\s|<|>).*)|u[\\\\'\"]*n[\\\\'\"]*c[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*o[\\\\'\"]*n|(?:e[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*h|c)[\\\\'\"]*(?:\s|<|>).*|o[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*h|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p)|e[\\\\'\"]*(?:n[\\\\'\"]*(?:v(?:[\\\\'\"]*-[\\\\'\"]*u[\\\\'\"]*p[\\\\'\"]*d[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*e)?|d[\\\\'\"]*(?:i[\\\\'\"]*f|s[\\\\'\"]*w))|x[\\\\'\"]*(?:p[\\\\'\"]*(?:a[\\\\'\"]*n[\\\\'\"]*d|o[\\\\'\"]*r[\\\\'\"]*t|r)|e[\\\\'\"]*c[\\\\'\"]*(?:\s|<|>).*)|c[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*(?:\s|<|>).*|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|s[\\\\'\"]*a[\\\\'\"]*c|v[\\\\'\"]*a[\\\\'\"]*l)|h[\\\\'\"]*(?:t[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|p[\\\\'\"]*a[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*w[\\\\'\"]*d)|o[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*(?:n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e|i[\\\\'\"]*d)|(?:e[\\\\'\"]*a[\\\\'\"]*d|u[\\\\'\"]*p)[\\\\'\"]*(?:\s|<|>).*|i[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*y)|i[\\\\'\"]*(?:p[\\\\'\"]*(?:(?:6[\\\\'\"]*)?t[\\\\'\"]*a[\\\\'\"]*b[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*s|c[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*i[\\\\'\"]*g)|r[\\\\'\"]*b(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|f[\\\\'\"]*c[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*i[\\\\'\"]*g|d[\\\\'\"]*(?:\s|<|>).*)|g[\\\\'\"]*(?:(?:e[\\\\'\"]*t[\\\\'\"]*f[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*l|r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*c|i[\\\\'\"]*t)[\\\\'\"]*(?:\s|<|>).*|z[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*p)|u[\\\\'\"]*n[\\\\'\"]*z[\\\\'\"]*i[\\\\'\"]*p|d[\\\\'\"]*b)|a[\\\\'\"]*(?:(?:l[\\\\'\"]*i[\\\\'\"]*a[\\\\'\"]*s|w[\\\\'\"]*k)[\\\\'\"]*(?:\s|<|>).*|d[\\\\'\"]*d[\\\\'\"]*u[\\\\'\"]*s[\\\\'\"]*e[\\\\'\"]*r|p[\\\\'\"]*t[\\\\'\"]*-[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*t|r[\\\\'\"]*(?:c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|p))|d[\\\\'\"]*(?:h[\\\\'\"]*c[\\\\'\"]*l[\\\\'\"]*i[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*t|(?:i[\\\\'\"]*f[\\\\'\"]*f|u)[\\\\'\"]*(?:\s|<|>).*|(?:m[\\\\'\"]*e[\\\\'\"]*s|p[\\\\'\"]*k)[\\\\'\"]*g|o[\\\\'\"]*(?:a[\\\\'\"]*s|n[\\\\'\"]*e)|a[\\\\'\"]*s[\\\\'\"]*h)|m[\\\\'\"]*(?:(?:k[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*r|o[\\\\'\"]*r[\\\\'\"]*e)[\\\\'\"]*(?:\s|<|>).*|a[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*(?:x[\\\\'\"]*(?:\s|<|>).*|q)|l[\\\\'\"]*o[\\\\'\"]*c[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*e)|j[\\\\'\"]*(?:(?:a[\\\\'\"]*v[\\\\'\"]*a|o[\\\\'\"]*b[\\\\'\"]*s)[\\\\'\"]*(?:\s|<|>).*|e[\\\\'\"]*x[\\\\'\"]*e[\\\\'\"]*c)|k[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*l[\\\\'\"]*(?:a[\\\\'\"]*l[\\\\'\"]*l|(?:\s|<|>).*)|(?:G[\\\\'\"]*E[\\\\'\"]*T[\\\\'\"]*(?:\s|<|>)|\.\s).*|7[\\\\'\"]*z(?:[\\\\'\"]*[ar])?)\b" \ + "id:932100,\ phase:2,\ block,\ capture,\ t:none,\ - msg:'Remote Command Execution: Unix Command Injection (command without evasion)',\ + msg:'Remote Command Execution: Unix Command Injection',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-shell',\ @@ -195,108 +116,33 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# [ Windows PowerShell, cmdlets and options ] +# Apache 2.2 requires configuration file lines to be under 8kB. +# Therefore, some remaining commands have been split off to a separate rule. +# For explanation of this rule, see rule 932100. # -# Detect some common PowerShell commands, cmdlets and options. -# These commands should be relatively uncommon in normal text, but -# potentially useful for code injection. +# To rebuild the word list regexp: +# cd util/regexp-assemble +# cat regexp-932105.txt | ./regexp-cmdline.py unix | ./regexp-assemble.pl # -# If you are not running Windows, it is safe to disable this rule. +# Then insert the assembled regexp into this template: # -# https://learn.microsoft.com/en-us/previous-versions/technet-magazine/ff714569(v=msdn.10) +# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]* +# [regexp assembled from util/regexp-assemble/regexp-932105.txt] +# \b" \ # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile windows-powershell-commands.data" \ - "id:932120,\ - phase:2,\ - block,\ - capture,\ - t:none,t:cmdLine,\ - msg:'Remote Command Execution: Windows PowerShell Command Found',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'language-powershell',\ - tag:'platform-windows',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Windows Powershell cmdlet aliases ] -# -# Attempts to detect aliases of the common PowerShell cmdlets in windows-powershell-commands.data -# If you are not running Windows, it is safe to disable this rule. -# -# There are other aliases which are similar to Unix, but they are properly handled by rule 932105 -# -# Regular expression generated from regex-assembly/932125.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932125 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:[\n\r;`\{]|\|\|?|&&?)[\s\x0b]*[\s\x0b\"'\(,@]*(?:[\"'\.-9A-Z_a-z]+/|(?:[\"'\x5c\^]*[0-9A-Z_a-z][\"'\x5c\^]*:.*|[ \"'\.-9A-Z\x5c\^_a-z]*)\x5c)?[\"\^]*(?:(?:a[\"\^]*(?:c|s[\"\^]*n[\"\^]*p)|e[\"\^]*(?:b[\"\^]*p|p[\"\^]*(?:a[\"\^]*l|c[\"\^]*s[\"\^]*v|s[\"\^]*n)|[tx][\"\^]*s[\"\^]*n)|f[\"\^]*(?:[cltw]|o[\"\^]*r[\"\^]*e[\"\^]*a[\"\^]*c[\"\^]*h)|i[\"\^]*(?:[cr][\"\^]*m|e[\"\^]*x|h[\"\^]*y|i|p[\"\^]*(?:a[\"\^]*l|c[\"\^]*s[\"\^]*v|m[\"\^]*o|s[\"\^]*n)|s[\"\^]*e|w[\"\^]*(?:m[\"\^]*i|r))|m[\"\^]*(?:a[\"\^]*n|[dipv]|o[\"\^]*u[\"\^]*n[\"\^]*t)|o[\"\^]*g[\"\^]*v|p[\"\^]*(?:o[\"\^]*p|u[\"\^]*s[\"\^]*h)[\"\^]*d|t[\"\^]*r[\"\^]*c[\"\^]*m|w[\"\^]*j[\"\^]*b)[\"\^]*[\s\x0b,\./;<>].*|c[\"\^]*(?:(?:(?:d|h[\"\^]*d[\"\^]*i[\"\^]*r|v[\"\^]*p[\"\^]*a)[\"\^]*|p[\"\^]*(?:[ip][\"\^]*)?)[\s\x0b,\./;<>].*|l[\"\^]*(?:(?:[cipv]|h[\"\^]*y)[\"\^]*[\s\x0b,\./;<>].*|s)|n[\"\^]*s[\"\^]*n)|d[\"\^]*(?:(?:b[\"\^]*p|e[\"\^]*l|i[\"\^]*(?:f[\"\^]*f|r))[\"\^]*[\s\x0b,\./;<>].*|n[\"\^]*s[\"\^]*n)|g[\"\^]*(?:(?:(?:(?:a[\"\^]*)?l|b[\"\^]*p|d[\"\^]*r|h[\"\^]*y|(?:w[\"\^]*m[\"\^]*)?i|j[\"\^]*b|[uv])[\"\^]*|c[\"\^]*(?:[ims][\"\^]*)?|m[\"\^]*(?:o[\"\^]*)?|s[\"\^]*(?:n[\"\^]*(?:p[\"\^]*)?|v[\"\^]*))[\s\x0b,\./;<>].*|e[\"\^]*r[\"\^]*r|p[\"\^]*(?:(?:s[\"\^]*)?[\s\x0b,\./;<>].*|v))|l[\"\^]*s|n[\"\^]*(?:(?:a[\"\^]*l|d[\"\^]*r|[iv]|m[\"\^]*o|s[\"\^]*n)[\"\^]*[\s\x0b,\./;<>].*|p[\"\^]*s[\"\^]*s[\"\^]*c)|r[\"\^]*(?:(?:(?:(?:b[\"\^]*)?p|e[\"\^]*n|(?:w[\"\^]*m[\"\^]*)?i|j[\"\^]*b|n[\"\^]*[ip])[\"\^]*|d[\"\^]*(?:r[\"\^]*)?|m[\"\^]*(?:(?:d[\"\^]*i[\"\^]*r|o)[\"\^]*)?|s[\"\^]*n[\"\^]*(?:p[\"\^]*)?|v[\"\^]*(?:p[\"\^]*a[\"\^]*)?)[\s\x0b,\./;<>].*|c[\"\^]*(?:j[\"\^]*b[\"\^]*[\s\x0b,\./;<>].*|s[\"\^]*n)|u[\"\^]*j[\"\^]*b)|s[\"\^]*(?:(?:(?:a[\"\^]*(?:j[\"\^]*b|l|p[\"\^]*s|s[\"\^]*v)|b[\"\^]*p|[civ]|w[\"\^]*m[\"\^]*i)[\"\^]*|l[\"\^]*(?:s[\"\^]*)?|p[\"\^]*(?:(?:j[\"\^]*b|p[\"\^]*s|s[\"\^]*v)[\"\^]*)?)[\s\x0b,\./;<>].*|h[\"\^]*c[\"\^]*m|u[\"\^]*j[\"\^]*b))(?:\.[\"\^]*[0-9A-Z_a-z]+)?\b" \ - "id:932125,\ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]*(?:s[\\\\'\"]*(?:e[\\\\'\"]*(?:t[\\\\'\"]*(?:(?:f[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*l[\\\\'\"]*)?(?:\s|<|>).*|e[\\\\'\"]*n[\\\\'\"]*v|s[\\\\'\"]*i[\\\\'\"]*d)|n[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*a[\\\\'\"]*i[\\\\'\"]*l|d[\\\\'\"]*(?:\s|<|>).*)|h[\\\\'\"]*(?:\.[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*b|u[\\\\'\"]*t[\\\\'\"]*d[\\\\'\"]*o[\\\\'\"]*w[\\\\'\"]*n|(?:\s|<|>).*)|o[\\\\'\"]*(?:(?:u[\\\\'\"]*r[\\\\'\"]*c[\\\\'\"]*e|r[\\\\'\"]*t)[\\\\'\"]*(?:\s|<|>).*|c[\\\\'\"]*a[\\\\'\"]*t)|c[\\\\'\"]*(?:h[\\\\'\"]*e[\\\\'\"]*d|p[\\\\'\"]*(?:\s|<|>).*)|t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g[\\\\'\"]*s|(?:l[\\\\'\"]*e[\\\\'\"]*e|f[\\\\'\"]*t)[\\\\'\"]*p|y[\\\\'\"]*s[\\\\'\"]*c[\\\\'\"]*t[\\\\'\"]*l|u[\\\\'\"]*(?:(?:\s|<|>).*|d[\\\\'\"]*o)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|s[\\\\'\"]*h|v[\\\\'\"]*n)|p[\\\\'\"]*(?:k[\\\\'\"]*(?:g(?:(?:[\\\\'\"]*_)?[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*f[\\\\'\"]*o)?|e[\\\\'\"]*x[\\\\'\"]*e[\\\\'\"]*c|i[\\\\'\"]*l[\\\\'\"]*l)|t[\\\\'\"]*a[\\\\'\"]*r(?:[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p))?|a[\\\\'\"]*(?:t[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|s[\\\\'\"]*s[\\\\'\"]*w[\\\\'\"]*d)|r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*(?:e[\\\\'\"]*n[\\\\'\"]*v|f[\\\\'\"]*(?:\s|<|>).*)|y[\\\\'\"]*t[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*n(?:[\\\\'\"]*(?:3(?:[\\\\'\"]*m)?|2))?|e[\\\\'\"]*r[\\\\'\"]*(?:l(?:[\\\\'\"]*(?:s[\\\\'\"]*h|5))?|m[\\\\'\"]*s)|(?:g[\\\\'\"]*r[\\\\'\"]*e|f[\\\\'\"]*t)[\\\\'\"]*p|(?:u[\\\\'\"]*s[\\\\'\"]*h|o[\\\\'\"]*p)[\\\\'\"]*d|h[\\\\'\"]*p(?:[\\\\'\"]*[57])?|i[\\\\'\"]*n[\\\\'\"]*g|s[\\\\'\"]*(?:\s|<|>).*)|n[\\\\'\"]*(?:c[\\\\'\"]*(?:\.[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*a[\\\\'\"]*l|o[\\\\'\"]*p[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*b[\\\\'\"]*s[\\\\'\"]*d)|(?:\s|<|>).*|a[\\\\'\"]*t)|e[\\\\'\"]*t[\\\\'\"]*(?:k[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*-[\\\\'\"]*f[\\\\'\"]*t[\\\\'\"]*p|(?:s[\\\\'\"]*t|c)[\\\\'\"]*a[\\\\'\"]*t|(?:\s|<|>).*)|s[\\\\'\"]*(?:l[\\\\'\"]*o[\\\\'\"]*o[\\\\'\"]*k[\\\\'\"]*u[\\\\'\"]*p|t[\\\\'\"]*a[\\\\'\"]*t)|(?:a[\\\\'\"]*n[\\\\'\"]*o|i[\\\\'\"]*c[\\\\'\"]*e)[\\\\'\"]*(?:\s|<|>).*|(?:o[\\\\'\"]*h[\\\\'\"]*u|m[\\\\'\"]*a)[\\\\'\"]*p|p[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g)|r[\\\\'\"]*(?:e[\\\\'\"]*(?:(?:p[\\\\'\"]*(?:l[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e|e[\\\\'\"]*a[\\\\'\"]*t)|n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e)[\\\\'\"]*(?:\s|<|>).*|a[\\\\'\"]*l[\\\\'\"]*p[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*h)|m[\\\\'\"]*(?:(?:d[\\\\'\"]*i[\\\\'\"]*r[\\\\'\"]*)?(?:\s|<|>).*|u[\\\\'\"]*s[\\\\'\"]*e[\\\\'\"]*r)|u[\\\\'\"]*b[\\\\'\"]*y(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|(?:a[\\\\'\"]*r|c[\\\\'\"]*p|p[\\\\'\"]*m)[\\\\'\"]*(?:\s|<|>).*|n[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*o|o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e|s[\\\\'\"]*y[\\\\'\"]*n[\\\\'\"]*c)|t[\\\\'\"]*(?:c[\\\\'\"]*(?:p[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e|i[\\\\'\"]*n[\\\\'\"]*g)|s[\\\\'\"]*h)|r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e(?:[\\\\'\"]*6)?|e[\\\\'\"]*(?:l[\\\\'\"]*n[\\\\'\"]*e[\\\\'\"]*t|e[\\\\'\"]*(?:\s|<|>).*)|i[\\\\'\"]*m[\\\\'\"]*e[\\\\'\"]*(?:o[\\\\'\"]*u[\\\\'\"]*t|(?:\s|<|>).*)|a[\\\\'\"]*(?:i[\\\\'\"]*l(?:[\\\\'\"]*f)?|r[\\\\'\"]*(?:\s|<|>).*)|o[\\\\'\"]*(?:u[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*(?:\s|<|>).*|p))|u[\\\\'\"]*(?:n[\\\\'\"]*(?:l[\\\\'\"]*(?:i[\\\\'\"]*n[\\\\'\"]*k[\\\\'\"]*(?:\s|<|>).*|z[\\\\'\"]*m[\\\\'\"]*a)|c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*p[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|a[\\\\'\"]*m[\\\\'\"]*e|r[\\\\'\"]*a[\\\\'\"]*r|s[\\\\'\"]*e[\\\\'\"]*t|z[\\\\'\"]*i[\\\\'\"]*p|x[\\\\'\"]*z)|s[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*(?:(?:a[\\\\'\"]*d|m[\\\\'\"]*o)[\\\\'\"]*d|d[\\\\'\"]*e[\\\\'\"]*l)|l[\\\\'\"]*i[\\\\'\"]*m[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*(?:\s|<|>).*)|m[\\\\'\"]*(?:y[\\\\'\"]*s[\\\\'\"]*q[\\\\'\"]*l(?:[\\\\'\"]*(?:d[\\\\'\"]*u[\\\\'\"]*m[\\\\'\"]*p(?:[\\\\'\"]*s[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*w)?|h[\\\\'\"]*o[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*o[\\\\'\"]*p[\\\\'\"]*y|a[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*i[\\\\'\"]*n|s[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*w))?|(?:(?:o[\\\\'\"]*u[\\\\'\"]*n|u[\\\\'\"]*t)[\\\\'\"]*t|v)[\\\\'\"]*(?:\s|<|>).*)|x[\\\\'\"]*(?:z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*(?:i[\\\\'\"]*f[\\\\'\"]*f|e[\\\\'\"]*c)|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|(?:\s|<|>).*)|a[\\\\'\"]*r[\\\\'\"]*g[\\\\'\"]*s|t[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*m|x[\\\\'\"]*d[\\\\'\"]*(?:\s|<|>).*)|z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|i[\\\\'\"]*p[\\\\'\"]*(?:\s|<|>).*|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|r[\\\\'\"]*u[\\\\'\"]*n|s[\\\\'\"]*h)|o[\\\\'\"]*(?:p[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*l|n[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*r)|w[\\\\'\"]*(?:h[\\\\'\"]*o[\\\\'\"]*(?:a[\\\\'\"]*m[\\\\'\"]*i|(?:\s|<|>).*)|g[\\\\'\"]*e[\\\\'\"]*t|3[\\\\'\"]*m)|v[\\\\'\"]*i[\\\\'\"]*(?:m[\\\\'\"]*(?:\s|<|>).*|g[\\\\'\"]*r|p[\\\\'\"]*w)|y[\\\\'\"]*u[\\\\'\"]*m)\b" \ + "id:932105,\ phase:2,\ block,\ capture,\ t:none,\ - msg:'Remote Command Execution: Windows Powershell Alias Command Injection',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-windows',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Unix shell expressions ] -# -# Detects the following patterns which are common in Unix shell scripts -# and one-liners: -# -# $(foo) Command substitution -# ${foo} Parameter expansion -# <(foo) Process substitution -# >(foo) Process substitution -# $((foo)) Arithmetic expansion -# $[2+2] Arithmetic expansion -# /e[t]c Shell glob expression to bypass wordlists -# -# This rule has a stricter sibling: 932131 (PL2) that applies the same regex to User-Agent and Referer -# -# This rule is essential to defend against the Log4J / Log4Shell attacks (see also rule 944150) -# -# Regular expression generated from regex-assembly/932130.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932130 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \$(?:\((?:.*|\(.*\))\)|\{.*\}|\[.*\])|[<>]\(.*\)|/[0-9A-Z_a-z]*\[!?.+\]" \ - "id:932130,\ - phase:2,\ - block,\ - capture,\ - t:none,t:cmdLine,\ - msg:'Remote Command Execution: Unix Shell Expression Found',\ + msg:'Remote Command Execution: Unix Command Injection',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-shell',\ @@ -306,441 +152,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Windows FOR, IF commands ] -# -# This rule detects Windows command shell FOR and IF commands. -# If you are not running Windows, it is safe to disable this rule. -# -# Examples: -# -# FOR %a IN (set) DO -# FOR /D %a IN (dirs) DO -# FOR /F "options" %a IN (text|"text") DO -# FOR /L %a IN (start,step,end) DO -# FOR /R C:\dir %A IN (set) DO -# -# IF [/I] [NOT] EXIST filename | DEFINED define | ERRORLEVEL n | CMDEXTVERSION n -# IF [/I] [NOT] item1 [==|EQU|NEQ|LSS|LEQ|GTR|GEQ] item2 -# IF [/I] [NOT] (item1) [==|EQU|NEQ|LSS|LEQ|GTR|GEQ] (item2) -# -# http://ss64.com/nt/if.html -# http://ss64.com/nt/for.html -# -# Regular expression generated from regex-assembly/932140.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932140 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \b(?:for(?:/[dflr].*)? %+[^ ]+ in\(.*\)[\s\x0b]?do|if(?:/i)?(?: not)?(?: (?:e(?:xist|rrorlevel)|defined|cmdextversion)\b|[ \(].*(?:\b(?:g(?:eq|tr)|equ|neq|l(?:eq|ss))\b|==)))" \ - "id:932140,\ - phase:2,\ - block,\ - capture,\ - t:none,t:cmdLine,\ - msg:'Remote Command Execution: Windows FOR/IF Command Found',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-windows',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Unix shell expressions - Bash Tilde expansion ] -# -# Detects the following patterns which are common in Unix shell scripts -# and one-liners: -# -# ~+ $PWD -# ~- $OLDPWD -# ~4 fourth directory entry on the stack from the top -# ~-2 second directory entry on the stack from the top -# ~+2 second directory entry on the stack from the bottom -# -# Reference - https://linuxsimply.com/bash-scripting-tutorial/expansion/tilde-expansion/ -# -# Regular expression generated from regex-assembly/932270.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932270 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ~(?:[\+\-](?:$|[\s\x0b0-9]+)|[0-9]+)" \ - "id:932270,\ - phase:2,\ - block,\ - capture,\ - t:none,t:cmdLine,\ - msg:'Remote Command Execution: Unix Shell Expression Found',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Unix direct remote command execution ] -# -# Detects Unix commands at the start of a parameter (direct RCE). -# Example: foo=wget%20www.example.com -# -# In this rule we use a different check from command injection (rule 932230), where a -# command string is appended (injected) to a regular parameter, and then -# passed to a shell unescaped. -# -# Additionaly, we require a trailing space (denoting command parameters) or command -# separator character after the command. -# -# This rule is also triggered by an Oracle WebLogic Remote Command Execution exploit: -# [ Oracle WebLogic vulnerability CVE-2017-10271 - Exploit tested: https://www.exploit-db.com/exploits/43458 ] -# -# An effort was made to combat evasions by shell quoting (e.g. 'ls', -# 'l'"s", \l\s are all valid). ModSecurity has a t:cmdLine -# transformation built-in to deal with this, but unfortunately, it -# replaces ';' characters and lowercases the payload, which is less -# useful for this case. However, emulating the transformation makes -# the regexp more complex. -# -# This is the base Rule to prevent Direct Unix Command Injection -# without prefix match. -# -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932250.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932250 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:^|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:7[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[arx])?|(?:b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z|x)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z|[ckz][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?f|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h)|f[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[dg]|g[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?g)|(?:h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b|l[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:s|z(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?4)?)|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|x[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z)|r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p)?|s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|(?:s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?)?h|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n)|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?3[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m)[\s\x0b&\)<>\|]" \ - "id:932250,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Direct Unix Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# [ Unix command injection ] -# -# This rule complements rule 932250 for commands of 4 characters and up. -# -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932260.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932260 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:^|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:a(?:ddgroup|nsible)|b(?:ase(?:32|64|nc)|lkid|sd(?:cat|iff|tar)|u(?:iltin|nzip2|sybox)|yobu|z(?:c(?:at|mp)|diff|e(?:grep|xe)|f?grep|ip2(?:recover)?|less|more))|c(?:h(?:ef[\s\x0b&\)\-<>\|]|g(?:passwd|rp)|pass|sh)|lang\+\+|o(?:mm[\s\x0b&\)<>\|]|proc)|(?:ron|scli)[\s\x0b&\)<>\|])|d(?:iff[\s\x0b&\)<>\|]|mesg|oas)|e(?:2fsck|grep)|f(?:grep|iletest|tp(?:stats|who))|g(?:r(?:ep[\s\x0b&\)<>\|]|oupmod)|unzip|z(?:cat|exe|ip))|htop|l(?:ast(?:comm|log(?:in)?)|ess(?:echo|(?:fil|pip)e)|ftp(?:get)?|osetup|s(?:-F|b_release|cpu|mod|of|pci|usb)|wp-download|z(?:4c(?:at)?|c(?:at|mp)|diff|[ef]?grep|less|m(?:a(?:dec|info)?|ore)))|m(?:a(?:ilq|ster\.passwd)|k(?:fifo|nod|temp)|locate|ysql(?:admin|dump(?:slow)?|hotcopy|show))|n(?:c(?:\.(?:openbsd|traditional)|at)|et(?:(?:c|st)at|kit-ftp|plan)|ohup|ping|stat)|onintr|p(?:dksh|er(?:f[\s\x0b&\)<>\|]|l[\s\x0b&\)5<>\|])|(?:ft|gre)p|hp(?:-cgi|[57])|igz|k(?:exec|ill)|(?:op|se)d|rint(?:env|f[\s\x0b&\)<>\|])|tar(?:diff|grep)?|wd\.db|y(?:thon[23]|3?versions))|r(?:(?:bas|ealpat)h|m(?:dir[\s\x0b&\)<>\|]|user)|nano|sync)|s(?:diff|e(?:ndmail|t(?:env|sid))|ftp|(?:h\.distri|pwd\.d)b|ocat|td(?:err|in|out)|udo|ysctl)|t(?:ailf|c(?:p(?:ing|traceroute)|sh)|elnet|imeout[\s\x0b&\)<>\|]|raceroute6?)|u(?:n(?:ame|lz(?:4|ma)|(?:pig|x)z|rar|zstd)|ser(?:(?:ad|mo)d|del))|vi(?:gr|pw|sudo)|w(?:get|hoami)|x(?:args|z(?:c(?:at|mp)|d(?:ec|iff)|[ef]?grep|less|more))|z(?:c(?:at|mp)|diff|[ef]?grep|ip(?:c(?:loak|mp)|details|grep|info|(?:merg|not)e|split|tool)|less|more|run|std(?:(?:ca|m)t|grep|less)?))" \ - "id:932260,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Direct Unix Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# [ Unix shell history invocation ] -# -# Detects Unix shell history invocations in any context. -# -# Example: -# GET /?rce=example.com -# GET /?rce=curl%20 -# GET /?rce=!-1!-2 -# -# Will execute `curl example.com`. We should be able to detect the '!-' sequence with a very low risk of false-positives since the sequence is very specific -# and does not allow for whitespaces in between. -# -# This rule has stricter siblings: -# * 932331 (PL3) -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx !-\d" \ - "id:932330,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Unix shell history invocation',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Unix shell snippets ] -# -# Detect some common sequences found in shell commands and scripts. -# -# Some commands which were restricted in earlier rules due to FP, -# have been added here with their full path, in order to catch some -# cases where the full path is sent. -# -# Rule relations: -# -# .932160 (base rule, PL1, unix shell commands with full path) -# ..932161 (stricter sibling, PL2, unix shell commands with full path in User-Agent and Referer request headers) -# -# This rule is also triggered by an Apache Struts Remote Code Execution exploit: -# [ Apache Struts vulnerability CVE-2017-9805 - Exploit tested: https://www.exploit-db.com/exploits/42627 ] -# -# This rule is also triggered by an Oracle WebLogic Remote Command Execution exploit: -# [ Oracle WebLogic vulnerability CVE-2017-10271 - Exploit tested: https://www.exploit-db.com/exploits/43458 ] - -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile unix-shell.data" \ - "id:932160,\ - phase:2,\ - block,\ - capture,\ - t:none,t:cmdLine,t:normalizePath,\ - msg:'Remote Command Execution: Unix Shell Code Found',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Shellshock vulnerability (CVE-2014-6271 and CVE-2014-7169) ] -# -# Detect exploitation of "Shellshock" GNU Bash RCE vulnerability. -# -# Based on ModSecurity rules created by Red Hat. -# Permission for use was granted by Martin Prpic -# -# https://access.redhat.com/articles/1212303 -# -SecRule REQUEST_HEADERS|REQUEST_LINE "@rx ^\(\s*\)\s+{" \ - "id:932170,\ - phase:1,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Remote Command Execution: Shellshock (CVE-2014-6271)',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -SecRule ARGS_NAMES|ARGS|FILES_NAMES "@rx ^\(\s*\)\s+{" \ - "id:932171,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Remote Command Execution: Shellshock (CVE-2014-6271)',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# [ Unix shell alias detection ] -# -# Detects Unix shell alias invocations in any context. -# -# Example: -# GET /?rce=alias%20a=b -# -# Shell aliasing can be performed to substitute anything in commands, escaping -# -# References: https://pubs.opengroup.org/onlinepubs/007904975/basedefs/xbd_chap03.html#tag_03_10 : -# "In the shell command language, a word consisting solely of underscores, digits, and alphabetics -# from the portable character set and any of the following characters: '!', '%', ',', '@'." -# -# Implementations may allow other characters within alias names as an extension. -# -# Regular expression generated from regex-assembly/932175.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932175 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \ba[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s\b[\s\x0b]+(?:[\+\-][a-z]+\+?[\s\x0b]+)?[!\"%',-\.0-9@-Z_a-z]+=[^\s\x0b]" \ - "id:932175,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Unix shell alias invocation',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# -# -=[ Restricted File Upload ]=- -# -# Detects attempts to upload a file with a forbidden filename. -# -# Many application contain Unrestricted File Upload vulnerabilities. -# https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload -# -# These might be abused to upload configuration files or other files -# that affect the behavior of the web server, possibly causing remote -# code execution. -# -SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X-File-Name "@pmFromFile restricted-upload.data" \ - "id:932180,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Restricted File Upload Attempt',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # [ Windows command injection ] @@ -748,9 +164,6 @@ SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEAD # This rule detects Windows shell command injections. # If you are not running Windows, it is safe to disable this rule. # -# New in CRSv4: The rules 932110 and 932115 were reorganized and renumbered to 932370 and 932380. -# The new rules target specific Windows binaries to simplify future updates of the command list. -# # A command injection takes a form such as: # # foo.jpg&ver /r @@ -788,8 +201,8 @@ SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEAD # 3. Paths # # [\w'\"\./]+/ /path/cmd -# [\x5c'\"\^]*\w[\x5c'\"\^]*:.*\x5c C:\Program Files\cmd -# [\^\.\w '\"/\x5c]*\x5c)?[\"\^]* \\net\share\dir\cmd +# [\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\ C:\Program Files\cmd +# [\^\.\w '\"/\\\\]*\\\\)?[\"\^]* \\net\share\dir\cmd # # 4. Quoting # @@ -810,13 +223,18 @@ SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEAD # # This rule is case-insensitive. # -# Regular expression generated from regex-assembly/932370.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932370 +# To rebuild the word list regexp: +# cd util/regexp-assemble +# cat regexp-932110.txt | ./regexp-cmdline.py windows | ./regexp-assemble.pl # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:[\n\r;`\{]|\|\|?|&&?)[\s\x0b]*[\s\x0b\"'\(,@]*(?:[\"'\.-9A-Z_a-z]+/|(?:[\"'\x5c\^]*[0-9A-Z_a-z][\"'\x5c\^]*:.*|[ \"'\.-9A-Z\x5c\^_a-z]*)\x5c)?[\"\^]*(?:a[\"\^]*(?:c[\"\^]*c[\"\^]*c[\"\^]*h[\"\^]*e[\"\^]*c[\"\^]*k[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*s[\"\^]*o[\"\^]*l[\"\^]*e|d[\"\^]*(?:p[\"\^]*l[\"\^]*u[\"\^]*s|v[\"\^]*p[\"\^]*a[\"\^]*c[\"\^]*k)|(?:g[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*e[\"\^]*x[\"\^]*e[\"\^]*c[\"\^]*u[\"\^]*t[\"\^]*o|s[\"\^]*p[\"\^]*n[\"\^]*e[\"\^]*t[\"\^]*_[\"\^]*c[\"\^]*o[\"\^]*m[\"\^]*p[\"\^]*i[\"\^]*l[\"\^]*e)[\"\^]*r|p[\"\^]*p[\"\^]*(?:i[\"\^]*n[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*l[\"\^]*l[\"\^]*e[\"\^]*r|v[\"\^]*l[\"\^]*p)|t[\"\^]*(?:[\s\x0b,\./;<>].*|b[\"\^]*r[\"\^]*o[\"\^]*k[\"\^]*e[\"\^]*r))|b[\"\^]*(?:a[\"\^]*s[\"\^]*h|g[\"\^]*i[\"\^]*n[\"\^]*f[\"\^]*o|i[\"\^]*t[\"\^]*s[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n)|c[\"\^]*(?:d[\"\^]*b|e[\"\^]*r[\"\^]*t[\"\^]*(?:o[\"\^]*c|r[\"\^]*e[\"\^]*q|u[\"\^]*t[\"\^]*i[\"\^]*l)|l[\"\^]*_[\"\^]*(?:i[\"\^]*n[\"\^]*v[\"\^]*o[\"\^]*c[\"\^]*a[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n|l[\"\^]*o[\"\^]*a[\"\^]*d[\"\^]*a[\"\^]*s[\"\^]*s[\"\^]*e[\"\^]*m[\"\^]*b[\"\^]*l[\"\^]*y|m[\"\^]*u[\"\^]*t[\"\^]*e[\"\^]*x[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*i[\"\^]*f[\"\^]*i[\"\^]*e[\"\^]*r[\"\^]*s)|m[\"\^]*(?:d(?:[\"\^]*(?:k[\"\^]*e[\"\^]*y|l[\"\^]*3[\"\^]*2))?|s[\"\^]*t[\"\^]*p)|o[\"\^]*(?:m[\"\^]*s[\"\^]*v[\"\^]*c[\"\^]*s|n[\"\^]*(?:f[\"\^]*i[\"\^]*g[\"\^]*s[\"\^]*e[\"\^]*c[\"\^]*u[\"\^]*r[\"\^]*i[\"\^]*t[\"\^]*y[\"\^]*p[\"\^]*o[\"\^]*l[\"\^]*i[\"\^]*c[\"\^]*y|h[\"\^]*o[\"\^]*s[\"\^]*t|t[\"\^]*r[\"\^]*o[\"\^]*l)|r[\"\^]*e[\"\^]*g[\"\^]*e[\"\^]*n)|r[\"\^]*e[\"\^]*a[\"\^]*t[\"\^]*e[\"\^]*d[\"\^]*u[\"\^]*m[\"\^]*p|s[\"\^]*(?:c(?:[\"\^]*r[\"\^]*i[\"\^]*p[\"\^]*t)?|i)|u[\"\^]*s[\"\^]*t[\"\^]*o[\"\^]*m[\"\^]*s[\"\^]*h[\"\^]*e[\"\^]*l[\"\^]*l[\"\^]*h[\"\^]*o[\"\^]*s[\"\^]*t)|d[\"\^]*(?:a[\"\^]*t[\"\^]*a[\"\^]*s[\"\^]*v[\"\^]*c[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|e[\"\^]*(?:f[\"\^]*a[\"\^]*u[\"\^]*l[\"\^]*t[\"\^]*p[\"\^]*a[\"\^]*c[\"\^]*k|s[\"\^]*k(?:[\"\^]*t[\"\^]*o[\"\^]*p[\"\^]*i[\"\^]*m[\"\^]*g[\"\^]*d[\"\^]*o[\"\^]*w[\"\^]*n[\"\^]*l[\"\^]*d[\"\^]*r)?|v[\"\^]*(?:i[\"\^]*c[\"\^]*e[\"\^]*c[\"\^]*r[\"\^]*e[\"\^]*d[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*i[\"\^]*a[\"\^]*l[\"\^]*d[\"\^]*e[\"\^]*p[\"\^]*l[\"\^]*o[\"\^]*y[\"\^]*m[\"\^]*e[\"\^]*n[\"\^]*t|t[\"\^]*o[\"\^]*o[\"\^]*l[\"\^]*s[\"\^]*l[\"\^]*a[\"\^]*u[\"\^]*n[\"\^]*c[\"\^]*h[\"\^]*e[\"\^]*r))|f[\"\^]*s[\"\^]*(?:h[\"\^]*i[\"\^]*m|v[\"\^]*c)|i[\"\^]*(?:a[\"\^]*n[\"\^]*t[\"\^]*z|s[\"\^]*k[\"\^]*s[\"\^]*h[\"\^]*a[\"\^]*d[\"\^]*o[\"\^]*w)|n[\"\^]*(?:s[\"\^]*c[\"\^]*m[\"\^]*d|x)|o[\"\^]*t[\"\^]*n[\"\^]*e[\"\^]*t|u[\"\^]*m[\"\^]*p[\"\^]*6[\"\^]*4|x[\"\^]*c[\"\^]*a[\"\^]*p)|e[\"\^]*(?:s[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*u[\"\^]*t[\"\^]*l|v[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*v[\"\^]*w[\"\^]*r|x[\"\^]*(?:c[\"\^]*e[\"\^]*l|p[\"\^]*(?:a[\"\^]*n[\"\^]*d|l[\"\^]*o[\"\^]*r[\"\^]*e[\"\^]*r)|t[\"\^]*(?:e[\"\^]*x[\"\^]*p[\"\^]*o[\"\^]*r[\"\^]*t|r[\"\^]*a[\"\^]*c[\"\^]*3[\"\^]*2)))|f[\"\^]*(?:i[\"\^]*n[\"\^]*(?:d[\"\^]*s[\"\^]*t|g[\"\^]*e)[\"\^]*r|l[\"\^]*t[\"\^]*m[\"\^]*c|o[\"\^]*r[\"\^]*f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*s|s[\"\^]*(?:i(?:[\"\^]*a[\"\^]*n[\"\^]*y[\"\^]*c[\"\^]*p[\"\^]*u)?|u[\"\^]*t[\"\^]*i[\"\^]*l)|t[\"\^]*p)|g[\"\^]*(?:f[\"\^]*x[\"\^]*d[\"\^]*o[\"\^]*w[\"\^]*n[\"\^]*l[\"\^]*o[\"\^]*a[\"\^]*d[\"\^]*w[\"\^]*r[\"\^]*a[\"\^]*p[\"\^]*p[\"\^]*e[\"\^]*r|p[\"\^]*s[\"\^]*c[\"\^]*r[\"\^]*i[\"\^]*p[\"\^]*t)|h[\"\^]*h|i[\"\^]*(?:e[\"\^]*(?:4[\"\^]*u[\"\^]*i[\"\^]*n[\"\^]*i[\"\^]*t|a[\"\^]*d[\"\^]*v[\"\^]*p[\"\^]*a[\"\^]*c[\"\^]*k|e[\"\^]*x[\"\^]*e[\"\^]*c|f[\"\^]*r[\"\^]*a[\"\^]*m[\"\^]*e)|l[\"\^]*a[\"\^]*s[\"\^]*m|m[\"\^]*e[\"\^]*w[\"\^]*d[\"\^]*b[\"\^]*l[\"\^]*d|n[\"\^]*(?:f[\"\^]*d[\"\^]*e[\"\^]*f[\"\^]*a[\"\^]*u[\"\^]*l[\"\^]*t[\"\^]*i[\"\^]*n[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*l|s[\"\^]*t[\"\^]*a[\"\^]*l[\"\^]*l[\"\^]*u[\"\^]*t[\"\^]*i)[\"\^]*l)|j[\"\^]*s[\"\^]*c|l[\"\^]*(?:a[\"\^]*u[\"\^]*n[\"\^]*c[\"\^]*h[\"\^]*-[\"\^]*v[\"\^]*s[\"\^]*d[\"\^]*e[\"\^]*v[\"\^]*s[\"\^]*h[\"\^]*e[\"\^]*l[\"\^]*l|d[\"\^]*i[\"\^]*f[\"\^]*d[\"\^]*e)|m[\"\^]*(?:a[\"\^]*(?:k[\"\^]*e[\"\^]*c[\"\^]*a[\"\^]*b|n[\"\^]*a[\"\^]*g[\"\^]*e[\"\^]*-[\"\^]*b[\"\^]*d[\"\^]*e|v[\"\^]*i[\"\^]*n[\"\^]*j[\"\^]*e[\"\^]*c[\"\^]*t)|f[\"\^]*t[\"\^]*r[\"\^]*a[\"\^]*c[\"\^]*e|i[\"\^]*c[\"\^]*r[\"\^]*o[\"\^]*s[\"\^]*o[\"\^]*f[\"\^]*t|m[\"\^]*c|p[\"\^]*c[\"\^]*m[\"\^]*d[\"\^]*r[\"\^]*u[\"\^]*n|s[\"\^]*(?:(?:b[\"\^]*u[\"\^]*i[\"\^]*l|o[\"\^]*h[\"\^]*t[\"\^]*m[\"\^]*e)[\"\^]*d|c[\"\^]*o[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*g|d[\"\^]*(?:e[\"\^]*p[\"\^]*l[\"\^]*o[\"\^]*y|t)|h[\"\^]*t[\"\^]*(?:a|m[\"\^]*l)|i[\"\^]*e[\"\^]*x[\"\^]*e[\"\^]*c|p[\"\^]*u[\"\^]*b|x[\"\^]*s[\"\^]*l))|n[\"\^]*(?:e[\"\^]*t[\"\^]*s[\"\^]*h|t[\"\^]*d[\"\^]*s[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l)|o[\"\^]*(?:d[\"\^]*b[\"\^]*c[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*f|f[\"\^]*f[\"\^]*l[\"\^]*i[\"\^]*n[\"\^]*e[\"\^]*s[\"\^]*c[\"\^]*a[\"\^]*n[\"\^]*n[\"\^]*e[\"\^]*r[\"\^]*s[\"\^]*h[\"\^]*e[\"\^]*l[\"\^]*l|n[\"\^]*e[\"\^]*d[\"\^]*r[\"\^]*i[\"\^]*v[\"\^]*e[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*n[\"\^]*d[\"\^]*a[\"\^]*l[\"\^]*o[\"\^]*n[\"\^]*e[\"\^]*u[\"\^]*p[\"\^]*d[\"\^]*a[\"\^]*t[\"\^]*e[\"\^]*r|p[\"\^]*e[\"\^]*n[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*s[\"\^]*o[\"\^]*l[\"\^]*e)|p[\"\^]*(?:c[\"\^]*(?:a[\"\^]*l[\"\^]*u[\"\^]*a|w[\"\^]*(?:r[\"\^]*u[\"\^]*n|u[\"\^]*t[\"\^]*l))|(?:e[\"\^]*s[\"\^]*t[\"\^]*e|s)[\"\^]*r|(?:k[\"\^]*t[\"\^]*m[\"\^]*o|u[\"\^]*b[\"\^]*p[\"\^]*r)[\"\^]*n|n[\"\^]*p[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|o[\"\^]*w[\"\^]*e[\"\^]*r[\"\^]*p[\"\^]*n[\"\^]*t|r[\"\^]*(?:e[\"\^]*s[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*a[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n[\"\^]*h[\"\^]*o[\"\^]*s[\"\^]*t|i[\"\^]*n[\"\^]*t(?:[\"\^]*b[\"\^]*r[\"\^]*m)?|o[\"\^]*(?:c[\"\^]*d[\"\^]*u[\"\^]*m[\"\^]*p|t[\"\^]*o[\"\^]*c[\"\^]*o[\"\^]*l[\"\^]*h[\"\^]*a[\"\^]*n[\"\^]*d[\"\^]*l[\"\^]*e[\"\^]*r)))|r[\"\^]*(?:a[\"\^]*s[\"\^]*a[\"\^]*u[\"\^]*t[\"\^]*o[\"\^]*u|c[\"\^]*s[\"\^]*i|(?:d[\"\^]*r[\"\^]*l[\"\^]*e[\"\^]*a[\"\^]*k[\"\^]*d[\"\^]*i[\"\^]*a|p[\"\^]*c[\"\^]*p[\"\^]*i[\"\^]*n)[\"\^]*g|e[\"\^]*(?:g(?:[\"\^]*(?:a[\"\^]*s[\"\^]*m|e[\"\^]*d[\"\^]*i[\"\^]*t|i[\"\^]*(?:n[\"\^]*i|s[\"\^]*t[\"\^]*e[\"\^]*r[\"\^]*-[\"\^]*c[\"\^]*i[\"\^]*m[\"\^]*p[\"\^]*r[\"\^]*o[\"\^]*v[\"\^]*i[\"\^]*d[\"\^]*e[\"\^]*r)|s[\"\^]*v[\"\^]*(?:c[\"\^]*s|r[\"\^]*3[\"\^]*2)))?|(?:m[\"\^]*o[\"\^]*t|p[\"\^]*l[\"\^]*a[\"\^]*c)[\"\^]*e)|u[\"\^]*n[\"\^]*(?:d[\"\^]*l[\"\^]*l[\"\^]*3[\"\^]*2|(?:e[\"\^]*x[\"\^]*e|s[\"\^]*c[\"\^]*r[\"\^]*i[\"\^]*p[\"\^]*t)[\"\^]*h[\"\^]*e[\"\^]*l[\"\^]*p[\"\^]*e[\"\^]*r|o[\"\^]*n[\"\^]*c[\"\^]*e))|s[\"\^]*(?:c[\"\^]*(?:[\s\x0b,\./;<>].*|h[\"\^]*t[\"\^]*a[\"\^]*s[\"\^]*k[\"\^]*s|r[\"\^]*i[\"\^]*p[\"\^]*t[\"\^]*r[\"\^]*u[\"\^]*n[\"\^]*n[\"\^]*e[\"\^]*r)|e[\"\^]*t[\"\^]*(?:r[\"\^]*e[\"\^]*s|t[\"\^]*i[\"\^]*n[\"\^]*g[\"\^]*s[\"\^]*y[\"\^]*n[\"\^]*c[\"\^]*h[\"\^]*o[\"\^]*s[\"\^]*t|u[\"\^]*p[\"\^]*a[\"\^]*p[\"\^]*i)|h[\"\^]*(?:d[\"\^]*o[\"\^]*c[\"\^]*v[\"\^]*w|e[\"\^]*l[\"\^]*l[\"\^]*3[\"\^]*2)|q[\"\^]*(?:l[\"\^]*(?:d[\"\^]*u[\"\^]*m[\"\^]*p[\"\^]*e[\"\^]*r|(?:t[\"\^]*o[\"\^]*o[\"\^]*l[\"\^]*s[\"\^]*)?p[\"\^]*s)|u[\"\^]*i[\"\^]*r[\"\^]*r[\"\^]*e[\"\^]*l)|s[\"\^]*h|t[\"\^]*o[\"\^]*r[\"\^]*d[\"\^]*i[\"\^]*a[\"\^]*g|y[\"\^]*(?:n[\"\^]*c[\"\^]*a[\"\^]*p[\"\^]*p[\"\^]*v[\"\^]*p[\"\^]*u[\"\^]*b[\"\^]*l[\"\^]*i[\"\^]*s[\"\^]*h[\"\^]*i[\"\^]*n[\"\^]*g[\"\^]*s[\"\^]*e[\"\^]*r[\"\^]*v[\"\^]*e[\"\^]*r|s[\"\^]*s[\"\^]*e[\"\^]*t[\"\^]*u[\"\^]*p))|t[\"\^]*(?:e[\"\^]*[\s\x0b,\./;<>].*|r[\"\^]*a[\"\^]*c[\"\^]*k[\"\^]*e[\"\^]*r|t[\"\^]*(?:d[\"\^]*i[\"\^]*n[\"\^]*j[\"\^]*e[\"\^]*c[\"\^]*t|t[\"\^]*r[\"\^]*a[\"\^]*c[\"\^]*e[\"\^]*r))|u[\"\^]*(?:n[\"\^]*r[\"\^]*e[\"\^]*g[\"\^]*m[\"\^]*p[\"\^]*2|p[\"\^]*d[\"\^]*a[\"\^]*t[\"\^]*e|r[\"\^]*l|t[\"\^]*i[\"\^]*l[\"\^]*i[\"\^]*t[\"\^]*y[\"\^]*f[\"\^]*u[\"\^]*n[\"\^]*c[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n[\"\^]*s)|v[\"\^]*(?:b[\"\^]*c|e[\"\^]*r[\"\^]*c[\"\^]*l[\"\^]*s[\"\^]*i[\"\^]*d|i[\"\^]*s[\"\^]*u[\"\^]*a[\"\^]*l[\"\^]*u[\"\^]*i[\"\^]*a[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*i[\"\^]*f[\"\^]*y[\"\^]*n[\"\^]*a[\"\^]*t[\"\^]*i[\"\^]*v[\"\^]*e|s[\"\^]*(?:i[\"\^]*i[\"\^]*s[\"\^]*e[\"\^]*x[\"\^]*e[\"\^]*l[\"\^]*a[\"\^]*u[\"\^]*n[\"\^]*c[\"\^]*h|j[\"\^]*i[\"\^]*t[\"\^]*d[\"\^]*e[\"\^]*b[\"\^]*u[\"\^]*g[\"\^]*g)[\"\^]*e[\"\^]*r)|w[\"\^]*(?:a[\"\^]*b|(?:f|m[\"\^]*i)[\"\^]*c|i[\"\^]*n[\"\^]*(?:g[\"\^]*e[\"\^]*t|r[\"\^]*m|w[\"\^]*o[\"\^]*r[\"\^]*d)|l[\"\^]*r[\"\^]*m[\"\^]*d[\"\^]*r|o[\"\^]*r[\"\^]*k[\"\^]*f[\"\^]*o[\"\^]*l[\"\^]*d[\"\^]*e[\"\^]*r[\"\^]*s|s[\"\^]*(?:(?:c[\"\^]*r[\"\^]*i[\"\^]*p|r[\"\^]*e[\"\^]*s[\"\^]*e)[\"\^]*t|l)|t[\"\^]*[\s\x0b,\./;<>].*|u[\"\^]*a[\"\^]*u[\"\^]*c[\"\^]*l[\"\^]*t)|x[\"\^]*w[\"\^]*i[\"\^]*z[\"\^]*a[\"\^]*r[\"\^]*d|z[\"\^]*i[\"\^]*p[\"\^]*f[\"\^]*l[\"\^]*d[\"\^]*r)(?:\.[\"\^]*[0-9A-Z_a-z]+)?\b" \ - "id:932370,\ +# Then insert the assembled regexp into this template: +# +# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]* +# [regexp assembled from util/regexp-assemble/regexp-932110.txt] +# (?:\.[\"\^]*\w+)?\b" \ +# +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]*(?:m[\"\^]*(?:y[\"\^]*s[\"\^]*q[\"\^]*l(?:[\"\^]*(?:d[\"\^]*u[\"\^]*m[\"\^]*p(?:[\"\^]*s[\"\^]*l[\"\^]*o[\"\^]*w)?|h[\"\^]*o[\"\^]*t[\"\^]*c[\"\^]*o[\"\^]*p[\"\^]*y|a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n|s[\"\^]*h[\"\^]*o[\"\^]*w))?|s[\"\^]*(?:i[\"\^]*(?:n[\"\^]*f[\"\^]*o[\"\^]*3[\"\^]*2|e[\"\^]*x[\"\^]*e[\"\^]*c)|c[\"\^]*o[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*g|g[\"\^]*(?:[\s,;]|\.|/|<|>).*|t[\"\^]*s[\"\^]*c)|o[\"\^]*(?:u[\"\^]*n[\"\^]*t[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|v[\"\^]*o[\"\^]*l)|v[\"\^]*e[\"\^]*u[\"\^]*s[\"\^]*e[\"\^]*r|[dr][\"\^]*e[\"\^]*(?:[\s,;]|\.|/|<|>).*)|k[\"\^]*(?:d[\"\^]*i[\"\^]*r[\"\^]*(?:[\s,;]|\.|/|<|>).*|l[\"\^]*i[\"\^]*n[\"\^]*k)|d[\"\^]*(?:s[\"\^]*c[\"\^]*h[\"\^]*e[\"\^]*d|(?:[\s,;]|\.|/|<|>).*)|a[\"\^]*p[\"\^]*i[\"\^]*s[\"\^]*e[\"\^]*n[\"\^]*d|b[\"\^]*s[\"\^]*a[\"\^]*c[\"\^]*l[\"\^]*i|e[\"\^]*a[\"\^]*s[\"\^]*u[\"\^]*r[\"\^]*e|m[\"\^]*s[\"\^]*y[\"\^]*s)|d[\"\^]*(?:i[\"\^]*(?:s[\"\^]*k[\"\^]*(?:(?:m[\"\^]*g[\"\^]*m|p[\"\^]*a[\"\^]*r)[\"\^]*t|s[\"\^]*h[\"\^]*a[\"\^]*d[\"\^]*o[\"\^]*w)|r[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|u[\"\^]*s[\"\^]*e)|f[\"\^]*f[\"\^]*(?:[\s,;]|\.|/|<|>).*)|e[\"\^]*(?:l[\"\^]*(?:p[\"\^]*r[\"\^]*o[\"\^]*f|t[\"\^]*r[\"\^]*e[\"\^]*e|(?:[\s,;]|\.|/|<|>).*)|v[\"\^]*(?:m[\"\^]*g[\"\^]*m[\"\^]*t|c[\"\^]*o[\"\^]*n)|(?:f[\"\^]*r[\"\^]*a|b[\"\^]*u)[\"\^]*g)|s[\"\^]*(?:a[\"\^]*(?:c[\"\^]*l[\"\^]*s|d[\"\^]*d)|q[\"\^]*u[\"\^]*e[\"\^]*r[\"\^]*y|m[\"\^]*o[\"\^]*(?:v[\"\^]*e|d)|g[\"\^]*e[\"\^]*t|r[\"\^]*m)|(?:r[\"\^]*i[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*q[\"\^]*u[\"\^]*e[\"\^]*r|o[\"\^]*s[\"\^]*k[\"\^]*e)[\"\^]*y|(?:c[\"\^]*o[\"\^]*m[\"\^]*c[\"\^]*n[\"\^]*f|x[\"\^]*d[\"\^]*i[\"\^]*a)[\"\^]*g|a[\"\^]*t[\"\^]*e[\"\^]*(?:[\s,;]|\.|/|<|>).*|n[\"\^]*s[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*t)|c[\"\^]*(?:o[\"\^]*(?:m[\"\^]*(?:p[\"\^]*(?:(?:a[\"\^]*c[\"\^]*t[\"\^]*)?(?:[\s,;]|\.|/|<|>).*|m[\"\^]*g[\"\^]*m[\"\^]*t)|e[\"\^]*x[\"\^]*p)|n[\"\^]*(?:2[\"\^]*p|v[\"\^]*e)[\"\^]*r[\"\^]*t|p[\"\^]*y)|l[\"\^]*(?:e[\"\^]*a[\"\^]*(?:n[\"\^]*m[\"\^]*g[\"\^]*r|r[\"\^]*m[\"\^]*e[\"\^]*m)|u[\"\^]*s[\"\^]*t[\"\^]*e[\"\^]*r)|h[\"\^]*(?:k[\"\^]*(?:n[\"\^]*t[\"\^]*f[\"\^]*s|d[\"\^]*s[\"\^]*k)|d[\"\^]*i[\"\^]*r[\"\^]*(?:[\s,;]|\.|/|<|>).*)|s[\"\^]*(?:c[\"\^]*(?:r[\"\^]*i[\"\^]*p[\"\^]*t|c[\"\^]*m[\"\^]*d)|v[\"\^]*d[\"\^]*e)|e[\"\^]*r[\"\^]*t[\"\^]*(?:u[\"\^]*t[\"\^]*i[\"\^]*l|r[\"\^]*e[\"\^]*q)|a[\"\^]*(?:l[\"\^]*l[\"\^]*(?:[\s,;]|\.|/|<|>).*|c[\"\^]*l[\"\^]*s)|m[\"\^]*d(?:[\"\^]*k[\"\^]*e[\"\^]*y)?|i[\"\^]*p[\"\^]*h[\"\^]*e[\"\^]*r|u[\"\^]*r[\"\^]*l)|f[\"\^]*(?:o[\"\^]*r[\"\^]*(?:m[\"\^]*a[\"\^]*t[\"\^]*(?:[\s,;]|\.|/|<|>).*|f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*s|e[\"\^]*a[\"\^]*c[\"\^]*h)|i[\"\^]*n[\"\^]*d[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|s[\"\^]*t[\"\^]*r)|s[\"\^]*(?:m[\"\^]*g[\"\^]*m[\"\^]*t|u[\"\^]*t[\"\^]*i[\"\^]*l)|t[\"\^]*(?:p[\"\^]*(?:[\s,;]|\.|/|<|>).*|y[\"\^]*p[\"\^]*e)|r[\"\^]*e[\"\^]*e[\"\^]*d[\"\^]*i[\"\^]*s[\"\^]*k|c[\"\^]*(?:[\s,;]|\.|/|<|>).*|g[\"\^]*r[\"\^]*e[\"\^]*p)|n[\"\^]*(?:e[\"\^]*t[\"\^]*(?:s[\"\^]*(?:t[\"\^]*a[\"\^]*t|v[\"\^]*c|h)|(?:[\s,;]|\.|/|<|>).*|c[\"\^]*a[\"\^]*t|d[\"\^]*o[\"\^]*m)|t[\"\^]*(?:b[\"\^]*a[\"\^]*c[\"\^]*k[\"\^]*u[\"\^]*p|r[\"\^]*i[\"\^]*g[\"\^]*h[\"\^]*t[\"\^]*s)|(?:s[\"\^]*l[\"\^]*o[\"\^]*o[\"\^]*k[\"\^]*u|m[\"\^]*a)[\"\^]*p|c[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|a[\"\^]*t)|b[\"\^]*t[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*t)|e[\"\^]*(?:x[\"\^]*p[\"\^]*(?:a[\"\^]*n[\"\^]*d[\"\^]*(?:[\s,;]|\.|/|<|>).*|l[\"\^]*o[\"\^]*r[\"\^]*e[\"\^]*r)|v[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*(?:c[\"\^]*r[\"\^]*e[\"\^]*a[\"\^]*t[\"\^]*e|v[\"\^]*w[\"\^]*r)|n[\"\^]*d[\"\^]*l[\"\^]*o[\"\^]*c[\"\^]*a[\"\^]*l|g[\"\^]*r[\"\^]*e[\"\^]*p|r[\"\^]*a[\"\^]*s[\"\^]*e|c[\"\^]*h[\"\^]*o)|g[\"\^]*(?:a[\"\^]*t[\"\^]*h[\"\^]*e[\"\^]*r[\"\^]*n[\"\^]*e[\"\^]*t[\"\^]*w[\"\^]*o[\"\^]*r[\"\^]*k[\"\^]*i[\"\^]*n[\"\^]*f[\"\^]*o|p[\"\^]*(?:(?:r[\"\^]*e[\"\^]*s[\"\^]*u[\"\^]*l|e[\"\^]*d[\"\^]*i)[\"\^]*t|u[\"\^]*p[\"\^]*d[\"\^]*a[\"\^]*t[\"\^]*e)|i[\"\^]*t[\"\^]*(?:[\s,;]|\.|/|<|>).*|e[\"\^]*t[\"\^]*m[\"\^]*a[\"\^]*c)|i[\"\^]*(?:r[\"\^]*b(?:[\"\^]*(?:1(?:[\"\^]*[89])?|2[\"\^]*[012]))?|f[\"\^]*m[\"\^]*e[\"\^]*m[\"\^]*b[\"\^]*e[\"\^]*r|p[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*g|n[\"\^]*e[\"\^]*t[\"\^]*c[\"\^]*p[\"\^]*l|c[\"\^]*a[\"\^]*c[\"\^]*l[\"\^]*s)|a[\"\^]*(?:d[\"\^]*(?:d[\"\^]*u[\"\^]*s[\"\^]*e[\"\^]*r[\"\^]*s|m[\"\^]*o[\"\^]*d[\"\^]*c[\"\^]*m[\"\^]*d)|r[\"\^]*p[\"\^]*(?:[\s,;]|\.|/|<|>).*|t[\"\^]*t[\"\^]*r[\"\^]*i[\"\^]*b|s[\"\^]*s[\"\^]*o[\"\^]*c|z[\"\^]*m[\"\^]*a[\"\^]*n)|l[\"\^]*(?:o[\"\^]*g[\"\^]*(?:e[\"\^]*v[\"\^]*e[\"\^]*n[\"\^]*t|t[\"\^]*i[\"\^]*m[\"\^]*e|m[\"\^]*a[\"\^]*n|o[\"\^]*f[\"\^]*f)|a[\"\^]*b[\"\^]*e[\"\^]*l[\"\^]*(?:[\s,;]|\.|/|<|>).*|u[\"\^]*s[\"\^]*r[\"\^]*m[\"\^]*g[\"\^]*r)|b[\"\^]*(?:(?:c[\"\^]*d[\"\^]*(?:b[\"\^]*o[\"\^]*o|e[\"\^]*d[\"\^]*i)|r[\"\^]*o[\"\^]*w[\"\^]*s[\"\^]*t[\"\^]*a)[\"\^]*t|i[\"\^]*t[\"\^]*s[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n|o[\"\^]*o[\"\^]*t[\"\^]*c[\"\^]*f[\"\^]*g)|h[\"\^]*(?:o[\"\^]*s[\"\^]*t[\"\^]*n[\"\^]*a[\"\^]*m[\"\^]*e|d[\"\^]*w[\"\^]*w[\"\^]*i[\"\^]*z)|j[\"\^]*a[\"\^]*v[\"\^]*a[\"\^]*(?:[\s,;]|\.|/|<|>).*|7[\"\^]*z(?:[\"\^]*[ar])?)(?:\.[\"\^]*\w+)?\b" \ + "id:932110,\ phase:2,\ block,\ capture,\ @@ -831,146 +249,353 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" +# Apache 2.2 requires configuration file lines to be under 8kB. +# Therefore, some remaining commands have been split off to a separate rule. +# For explanation of this rule, see rule 932110. +# +# This rule is also triggered by an Oracle WebLogic Remote Command Execution exploit: +# [ Oracle WebLogic vulnerability CVE-2017-10271 - Exploit tested: https://www.exploit-db.com/exploits/43458 ] +# +# To rebuild the word list regexp: +# cd util/regexp-assemble +# cat regexp-932115.txt | ./regexp-cmdline.py windows | ./regexp-assemble.pl +# +# Then insert the assembled regexp into this template: +# +# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]* +# [regexp assembled from util/regexp-assemble/regexp-932110.txt] +# (?:\.[\"\^]*\w+)?\b" \ +# +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:;|\{|\||\|\||&|&&|\n|\r|`)\s*[\(,@\'\"\s]*(?:[\w'\"\./]+/|[\\\\'\"\^]*\w[\\\\'\"\^]*:.*\\\\|[\^\.\w '\"/\\\\]*\\\\)?[\"\^]*(?:s[\"\^]*(?:y[\"\^]*s[\"\^]*(?:t[\"\^]*e[\"\^]*m[\"\^]*(?:p[\"\^]*r[\"\^]*o[\"\^]*p[\"\^]*e[\"\^]*r[\"\^]*t[\"\^]*i[\"\^]*e[\"\^]*s[\"\^]*(?:d[\"\^]*a[\"\^]*t[\"\^]*a[\"\^]*e[\"\^]*x[\"\^]*e[\"\^]*c[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n[\"\^]*p[\"\^]*r[\"\^]*e[\"\^]*v[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n|(?:p[\"\^]*e[\"\^]*r[\"\^]*f[\"\^]*o[\"\^]*r[\"\^]*m[\"\^]*a[\"\^]*n[\"\^]*c|h[\"\^]*a[\"\^]*r[\"\^]*d[\"\^]*w[\"\^]*a[\"\^]*r)[\"\^]*e|a[\"\^]*d[\"\^]*v[\"\^]*a[\"\^]*n[\"\^]*c[\"\^]*e[\"\^]*d)|i[\"\^]*n[\"\^]*f[\"\^]*o)|k[\"\^]*e[\"\^]*y|d[\"\^]*m)|h[\"\^]*(?:o[\"\^]*(?:w[\"\^]*(?:g[\"\^]*r[\"\^]*p|m[\"\^]*b[\"\^]*r)[\"\^]*s|r[\"\^]*t[\"\^]*c[\"\^]*u[\"\^]*t)|e[\"\^]*l[\"\^]*l[\"\^]*r[\"\^]*u[\"\^]*n[\"\^]*a[\"\^]*s|u[\"\^]*t[\"\^]*d[\"\^]*o[\"\^]*w[\"\^]*n|r[\"\^]*p[\"\^]*u[\"\^]*b[\"\^]*w|a[\"\^]*r[\"\^]*e|i[\"\^]*f[\"\^]*t)|e[\"\^]*(?:t[\"\^]*(?:(?:x[\"\^]*)?(?:[\s,;]|\.|/|<|>).*|l[\"\^]*o[\"\^]*c[\"\^]*a[\"\^]*l)|c[\"\^]*p[\"\^]*o[\"\^]*l|l[\"\^]*e[\"\^]*c[\"\^]*t)|c[\"\^]*(?:h[\"\^]*t[\"\^]*a[\"\^]*s[\"\^]*k[\"\^]*s|l[\"\^]*i[\"\^]*s[\"\^]*t)|u[\"\^]*b[\"\^]*(?:i[\"\^]*n[\"\^]*a[\"\^]*c[\"\^]*l|s[\"\^]*t)|t[\"\^]*a[\"\^]*r[\"\^]*t[\"\^]*(?:[\s,;]|\.|/|<|>).*|i[\"\^]*g[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*i[\"\^]*f|l[\"\^]*(?:e[\"\^]*e[\"\^]*p|m[\"\^]*g[\"\^]*r)|o[\"\^]*r[\"\^]*t|f[\"\^]*c|v[\"\^]*n)|p[\"\^]*(?:s[\"\^]*(?:s[\"\^]*(?:h[\"\^]*u[\"\^]*t[\"\^]*d[\"\^]*o[\"\^]*w[\"\^]*n|e[\"\^]*r[\"\^]*v[\"\^]*i[\"\^]*c[\"\^]*e|u[\"\^]*s[\"\^]*p[\"\^]*e[\"\^]*n[\"\^]*d)|l[\"\^]*(?:o[\"\^]*g[\"\^]*(?:g[\"\^]*e[\"\^]*d[\"\^]*o[\"\^]*n|l[\"\^]*i[\"\^]*s[\"\^]*t)|i[\"\^]*s[\"\^]*t)|p[\"\^]*(?:a[\"\^]*s[\"\^]*s[\"\^]*w[\"\^]*d|i[\"\^]*n[\"\^]*g)|g[\"\^]*e[\"\^]*t[\"\^]*s[\"\^]*i[\"\^]*d|e[\"\^]*x[\"\^]*e[\"\^]*c|f[\"\^]*i[\"\^]*l[\"\^]*e|i[\"\^]*n[\"\^]*f[\"\^]*o|k[\"\^]*i[\"\^]*l[\"\^]*l)|o[\"\^]*(?:w[\"\^]*e[\"\^]*r[\"\^]*(?:s[\"\^]*h[\"\^]*e[\"\^]*l[\"\^]*l(?:[\"\^]*_[\"\^]*i[\"\^]*s[\"\^]*e)?|c[\"\^]*f[\"\^]*g)|r[\"\^]*t[\"\^]*q[\"\^]*r[\"\^]*y|p[\"\^]*d)|r[\"\^]*(?:i[\"\^]*n[\"\^]*t[\"\^]*(?:(?:[\s,;]|\.|/|<|>).*|b[\"\^]*r[\"\^]*m)|n[\"\^]*(?:c[\"\^]*n[\"\^]*f[\"\^]*g|m[\"\^]*n[\"\^]*g[\"\^]*r)|o[\"\^]*m[\"\^]*p[\"\^]*t)|a[\"\^]*t[\"\^]*h[\"\^]*(?:p[\"\^]*i[\"\^]*n[\"\^]*g|(?:[\s,;]|\.|/|<|>).*)|e[\"\^]*r[\"\^]*(?:l(?:[\"\^]*(?:s[\"\^]*h|5))?|f[\"\^]*m[\"\^]*o[\"\^]*n)|y[\"\^]*t[\"\^]*h[\"\^]*o[\"\^]*n(?:[\"\^]*(?:3(?:[\"\^]*m)?|2))?|k[\"\^]*g[\"\^]*m[\"\^]*g[\"\^]*r|h[\"\^]*p(?:[\"\^]*[57])?|u[\"\^]*s[\"\^]*h[\"\^]*d|i[\"\^]*n[\"\^]*g)|r[\"\^]*(?:e[\"\^]*(?:(?:p[\"\^]*l[\"\^]*a[\"\^]*c[\"\^]*e|n(?:[\"\^]*a[\"\^]*m[\"\^]*e)?|s[\"\^]*e[\"\^]*t)[\"\^]*(?:[\s,;]|\.|/|<|>).*|g[\"\^]*(?:s[\"\^]*v[\"\^]*r[\"\^]*3[\"\^]*2|e[\"\^]*d[\"\^]*i[\"\^]*t|(?:[\s,;]|\.|/|<|>).*|i[\"\^]*n[\"\^]*i)|c[\"\^]*(?:d[\"\^]*i[\"\^]*s[\"\^]*c|o[\"\^]*v[\"\^]*e[\"\^]*r)|k[\"\^]*e[\"\^]*y[\"\^]*w[\"\^]*i[\"\^]*z)|u[\"\^]*(?:n[\"\^]*(?:d[\"\^]*l[\"\^]*l[\"\^]*3[\"\^]*2|a[\"\^]*s)|b[\"\^]*y[\"\^]*(?:1(?:[\"\^]*[89])?|2[\"\^]*[012]))|a[\"\^]*(?:s[\"\^]*(?:p[\"\^]*h[\"\^]*o[\"\^]*n[\"\^]*e|d[\"\^]*i[\"\^]*a[\"\^]*l)|r[\"\^]*(?:[\s,;]|\.|/|<|>).*)|m[\"\^]*(?:(?:d[\"\^]*i[\"\^]*r[\"\^]*)?(?:[\s,;]|\.|/|<|>).*|t[\"\^]*s[\"\^]*h[\"\^]*a[\"\^]*r[\"\^]*e)|o[\"\^]*(?:u[\"\^]*t[\"\^]*e[\"\^]*(?:[\s,;]|\.|/|<|>).*|b[\"\^]*o[\"\^]*c[\"\^]*o[\"\^]*p[\"\^]*y)|s[\"\^]*(?:t[\"\^]*r[\"\^]*u[\"\^]*i|y[\"\^]*n[\"\^]*c)|d[\"\^]*(?:[\s,;]|\.|/|<|>).*)|t[\"\^]*(?:a[\"\^]*(?:s[\"\^]*k[\"\^]*(?:k[\"\^]*i[\"\^]*l[\"\^]*l|l[\"\^]*i[\"\^]*s[\"\^]*t|s[\"\^]*c[\"\^]*h[\"\^]*d|m[\"\^]*g[\"\^]*r)|k[\"\^]*e[\"\^]*o[\"\^]*w[\"\^]*n)|(?:i[\"\^]*m[\"\^]*e[\"\^]*o[\"\^]*u|p[\"\^]*m[\"\^]*i[\"\^]*n[\"\^]*i|e[\"\^]*l[\"\^]*n[\"\^]*e|l[\"\^]*i[\"\^]*s)[\"\^]*t|s[\"\^]*(?:d[\"\^]*i[\"\^]*s[\"\^]*c[\"\^]*o|s[\"\^]*h[\"\^]*u[\"\^]*t[\"\^]*d)[\"\^]*n|y[\"\^]*p[\"\^]*e[\"\^]*(?:p[\"\^]*e[\"\^]*r[\"\^]*f|(?:[\s,;]|\.|/|<|>).*)|r[\"\^]*(?:a[\"\^]*c[\"\^]*e[\"\^]*r[\"\^]*t|e[\"\^]*e))|w[\"\^]*(?:i[\"\^]*n[\"\^]*(?:d[\"\^]*i[\"\^]*f[\"\^]*f|m[\"\^]*s[\"\^]*d[\"\^]*p|v[\"\^]*a[\"\^]*r|r[\"\^]*[ms])|u[\"\^]*(?:a[\"\^]*(?:u[\"\^]*c[\"\^]*l[\"\^]*t|p[\"\^]*p)|s[\"\^]*a)|s[\"\^]*c[\"\^]*(?:r[\"\^]*i[\"\^]*p[\"\^]*t|u[\"\^]*i)|e[\"\^]*v[\"\^]*t[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|m[\"\^]*i[\"\^]*(?:m[\"\^]*g[\"\^]*m[\"\^]*t|c)|a[\"\^]*i[\"\^]*t[\"\^]*f[\"\^]*o[\"\^]*r|h[\"\^]*o[\"\^]*a[\"\^]*m[\"\^]*i|g[\"\^]*e[\"\^]*t)|u[\"\^]*(?:s[\"\^]*(?:e[\"\^]*r[\"\^]*a[\"\^]*c[\"\^]*c[\"\^]*o[\"\^]*u[\"\^]*n[\"\^]*t[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*t[\"\^]*r[\"\^]*o[\"\^]*l[\"\^]*s[\"\^]*e[\"\^]*t[\"\^]*t[\"\^]*i[\"\^]*n[\"\^]*g[\"\^]*s|r[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*t)|n[\"\^]*(?:r[\"\^]*a[\"\^]*r|z[\"\^]*i[\"\^]*p))|q[\"\^]*(?:u[\"\^]*e[\"\^]*r[\"\^]*y[\"\^]*(?:[\s,;]|\.|/|<|>).*|p[\"\^]*r[\"\^]*o[\"\^]*c[\"\^]*e[\"\^]*s[\"\^]*s|w[\"\^]*i[\"\^]*n[\"\^]*s[\"\^]*t[\"\^]*a|g[\"\^]*r[\"\^]*e[\"\^]*p)|o[\"\^]*(?:d[\"\^]*b[\"\^]*c[\"\^]*(?:a[\"\^]*d[\"\^]*3[\"\^]*2|c[\"\^]*o[\"\^]*n[\"\^]*f)|p[\"\^]*e[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*s)|v[\"\^]*(?:o[\"\^]*l[\"\^]*(?:[\s,;]|\.|/|<|>).*|e[\"\^]*r[\"\^]*i[\"\^]*f[\"\^]*y)|x[\"\^]*c[\"\^]*(?:a[\"\^]*c[\"\^]*l[\"\^]*s|o[\"\^]*p[\"\^]*y)|z[\"\^]*i[\"\^]*p[\"\^]*(?:[\s,;]|\.|/|<|>).*)(?:\.[\"\^]*\w+)?\b" \ + "id:932115,\ + phase:2,\ + block,\ + capture,\ + t:none,\ + msg:'Remote Command Execution: Windows Command Injection',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-shell',\ + tag:'platform-windows',\ + tag:'attack-rce',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/88',\ + tag:'PCI/6.5.2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# [ Windows PowerShell, cmdlets and options ] +# +# Detect some common PowerShell commands, cmdlets and options. +# These commands should be relatively uncommon in normal text, but +# potentially useful for code injection. # -# This rule detects Windows shell command injections. # If you are not running Windows, it is safe to disable this rule. # -# New in CRSv4: The rules 932110 and 932115 were reorganized and renumbered to 932370 and 932380. -# The new rules target specific Windows binaries to simplify future updates of the command list. +# https://technet.microsoft.com/en-us/magazine/ff714569.aspx +# https://msdn.microsoft.com/en-us/powershell/scripting/core-powershell/console/powershell.exe-command-line-help # -# See rule 932370 above for further explanation. -# -# This rule is case-insensitive. -# -# Regular expression generated from regex-assembly/932380.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932380 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:[\n\r;`\{]|\|\|?|&&?)[\s\x0b]*[\s\x0b\"'\(,@]*(?:[\"'\.-9A-Z_a-z]+/|(?:[\"'\x5c\^]*[0-9A-Z_a-z][\"'\x5c\^]*:.*|[ \"'\.-9A-Z\x5c\^_a-z]*)\x5c)?[\"\^]*(?:a[\"\^]*(?:s[\"\^]*s[\"\^]*o[\"\^]*c|t[\"\^]*(?:m[\"\^]*a[\"\^]*d[\"\^]*m|t[\"\^]*r[\"\^]*i[\"\^]*b)|u[\"\^]*(?:d[\"\^]*i[\"\^]*t[\"\^]*p[\"\^]*o[\"\^]*l|t[\"\^]*o[\"\^]*(?:c[\"\^]*(?:h[\"\^]*k|o[\"\^]*n[\"\^]*v)|(?:f[\"\^]*m|m[\"\^]*o[\"\^]*u[\"\^]*n)[\"\^]*t)))|b[\"\^]*(?:c[\"\^]*d[\"\^]*(?:b[\"\^]*o[\"\^]*o|e[\"\^]*d[\"\^]*i)[\"\^]*t|(?:d[\"\^]*e[\"\^]*h[\"\^]*d|o[\"\^]*o[\"\^]*t)[\"\^]*c[\"\^]*f[\"\^]*g|i[\"\^]*t[\"\^]*s[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n)|c[\"\^]*(?:a[\"\^]*c[\"\^]*l[\"\^]*s|e[\"\^]*r[\"\^]*t[\"\^]*(?:r[\"\^]*e[\"\^]*q|u[\"\^]*t[\"\^]*i[\"\^]*l)|h[\"\^]*(?:c[\"\^]*p|d[\"\^]*i[\"\^]*r|g[\"\^]*(?:l[\"\^]*o[\"\^]*g[\"\^]*o[\"\^]*n|p[\"\^]*o[\"\^]*r[\"\^]*t|u[\"\^]*s[\"\^]*r)|k[\"\^]*(?:d[\"\^]*s[\"\^]*k|n[\"\^]*t[\"\^]*f[\"\^]*s))|l[\"\^]*e[\"\^]*a[\"\^]*n[\"\^]*m[\"\^]*g[\"\^]*r|m[\"\^]*(?:d(?:[\"\^]*k[\"\^]*e[\"\^]*y)?|s[\"\^]*t[\"\^]*p)|s[\"\^]*c[\"\^]*r[\"\^]*i[\"\^]*p[\"\^]*t)|d[\"\^]*(?:c[\"\^]*(?:d[\"\^]*i[\"\^]*a[\"\^]*g|g[\"\^]*p[\"\^]*o[\"\^]*f[\"\^]*i[\"\^]*x)|e[\"\^]*(?:f[\"\^]*r[\"\^]*a[\"\^]*g|l)|f[\"\^]*s[\"\^]*(?:d[\"\^]*i[\"\^]*a|r[\"\^]*m[\"\^]*i)[\"\^]*g|i[\"\^]*(?:a[\"\^]*n[\"\^]*t[\"\^]*z|r|s[\"\^]*(?:k[\"\^]*(?:c[\"\^]*o[\"\^]*(?:m[\"\^]*p|p[\"\^]*y)|p[\"\^]*(?:a[\"\^]*r[\"\^]*t|e[\"\^]*r[\"\^]*f)|r[\"\^]*a[\"\^]*i[\"\^]*d|s[\"\^]*h[\"\^]*a[\"\^]*d[\"\^]*o[\"\^]*w)|p[\"\^]*d[\"\^]*i[\"\^]*a[\"\^]*g))|n[\"\^]*s[\"\^]*c[\"\^]*m[\"\^]*d|(?:o[\"\^]*s[\"\^]*k[\"\^]*e|r[\"\^]*i[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*q[\"\^]*u[\"\^]*e[\"\^]*r)[\"\^]*y)|e[\"\^]*(?:n[\"\^]*d[\"\^]*l[\"\^]*o[\"\^]*c[\"\^]*a[\"\^]*l|v[\"\^]*e[\"\^]*n[\"\^]*t[\"\^]*c[\"\^]*r[\"\^]*e[\"\^]*a[\"\^]*t[\"\^]*e)|E[\"\^]*v[\"\^]*n[\"\^]*t[\"\^]*c[\"\^]*m[\"\^]*d|f[\"\^]*(?:c|i[\"\^]*(?:l[\"\^]*e[\"\^]*s[\"\^]*y[\"\^]*s[\"\^]*t[\"\^]*e[\"\^]*m[\"\^]*s|n[\"\^]*d[\"\^]*s[\"\^]*t[\"\^]*r)|l[\"\^]*a[\"\^]*t[\"\^]*t[\"\^]*e[\"\^]*m[\"\^]*p|o[\"\^]*r(?:[\"\^]*f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*s)?|r[\"\^]*e[\"\^]*e[\"\^]*d[\"\^]*i[\"\^]*s[\"\^]*k|s[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|(?:t[\"\^]*y[\"\^]*p|v[\"\^]*e[\"\^]*u[\"\^]*p[\"\^]*d[\"\^]*a[\"\^]*t)[\"\^]*e)|g[\"\^]*(?:e[\"\^]*t[\"\^]*(?:m[\"\^]*a[\"\^]*c|t[\"\^]*y[\"\^]*p[\"\^]*e)|o[\"\^]*t[\"\^]*o|p[\"\^]*(?:f[\"\^]*i[\"\^]*x[\"\^]*u[\"\^]*p|(?:r[\"\^]*e[\"\^]*s[\"\^]*u[\"\^]*l[\"\^]*)?t|u[\"\^]*p[\"\^]*d[\"\^]*a[\"\^]*t[\"\^]*e)|r[\"\^]*a[\"\^]*f[\"\^]*t[\"\^]*a[\"\^]*b[\"\^]*l)|h[\"\^]*(?:e[\"\^]*l[\"\^]*p[\"\^]*c[\"\^]*t[\"\^]*r|o[\"\^]*s[\"\^]*t[\"\^]*n[\"\^]*a[\"\^]*m[\"\^]*e)|i[\"\^]*(?:c[\"\^]*a[\"\^]*c[\"\^]*l[\"\^]*s|f|p[\"\^]*(?:c[\"\^]*o[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*g|x[\"\^]*r[\"\^]*o[\"\^]*u[\"\^]*t[\"\^]*e)|r[\"\^]*f[\"\^]*t[\"\^]*p)|j[\"\^]*e[\"\^]*t[\"\^]*p[\"\^]*a[\"\^]*c[\"\^]*k|k[\"\^]*(?:l[\"\^]*i[\"\^]*s[\"\^]*t|s[\"\^]*e[\"\^]*t[\"\^]*u[\"\^]*p|t[\"\^]*(?:m[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|p[\"\^]*a[\"\^]*s[\"\^]*s))|l[\"\^]*(?:o[\"\^]*(?:d[\"\^]*c[\"\^]*t[\"\^]*r|g[\"\^]*(?:m[\"\^]*a[\"\^]*n|o[\"\^]*f[\"\^]*f))|p[\"\^]*[qr])|m[\"\^]*(?:a[\"\^]*(?:c[\"\^]*f[\"\^]*i[\"\^]*l[\"\^]*e|k[\"\^]*e[\"\^]*c[\"\^]*a[\"\^]*b|p[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n)|k[\"\^]*(?:d[\"\^]*i[\"\^]*r|l[\"\^]*i[\"\^]*n[\"\^]*k)|m[\"\^]*c|o[\"\^]*u[\"\^]*n[\"\^]*t[\"\^]*v[\"\^]*o[\"\^]*l|q[\"\^]*(?:b[\"\^]*k[\"\^]*u[\"\^]*p|(?:t[\"\^]*g[\"\^]*)?s[\"\^]*v[\"\^]*c)|s[\"\^]*(?:d[\"\^]*t|i[\"\^]*(?:e[\"\^]*x[\"\^]*e[\"\^]*c|n[\"\^]*f[\"\^]*o[\"\^]*3[\"\^]*2)|t[\"\^]*s[\"\^]*c))|n[\"\^]*(?:b[\"\^]*t[\"\^]*s[\"\^]*t[\"\^]*a[\"\^]*t|e[\"\^]*t[\"\^]*(?:c[\"\^]*f[\"\^]*g|d[\"\^]*o[\"\^]*m|s[\"\^]*(?:h|t[\"\^]*a[\"\^]*t))|f[\"\^]*s[\"\^]*(?:a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n|s[\"\^]*(?:h[\"\^]*a[\"\^]*r[\"\^]*e|t[\"\^]*a[\"\^]*t))|l[\"\^]*(?:b[\"\^]*m[\"\^]*g[\"\^]*r|t[\"\^]*e[\"\^]*s[\"\^]*t)|s[\"\^]*l[\"\^]*o[\"\^]*o[\"\^]*k[\"\^]*u[\"\^]*p|t[\"\^]*(?:b[\"\^]*a[\"\^]*c[\"\^]*k[\"\^]*u[\"\^]*p|c[\"\^]*m[\"\^]*d[\"\^]*p[\"\^]*r[\"\^]*o[\"\^]*m[\"\^]*p[\"\^]*t|f[\"\^]*r[\"\^]*s[\"\^]*u[\"\^]*t[\"\^]*l))|o[\"\^]*(?:f[\"\^]*f[\"\^]*l[\"\^]*i[\"\^]*n[\"\^]*e|p[\"\^]*e[\"\^]*n[\"\^]*f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*s)|p[\"\^]*(?:a[\"\^]*(?:g[\"\^]*e[\"\^]*f[\"\^]*i[\"\^]*l[\"\^]*e[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*f[\"\^]*i|t[\"\^]*h[\"\^]*p[\"\^]*i[\"\^]*n)[\"\^]*g|(?:b[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i|k[\"\^]*t[\"\^]*m[\"\^]*o)[\"\^]*n|e[\"\^]*(?:n[\"\^]*t[\"\^]*n[\"\^]*t|r[\"\^]*f[\"\^]*m[\"\^]*o[\"\^]*n)|n[\"\^]*p[\"\^]*u[\"\^]*(?:n[\"\^]*a[\"\^]*t[\"\^]*t[\"\^]*e[\"\^]*n[\"\^]*d|t[\"\^]*i[\"\^]*l)|o[\"\^]*(?:p[\"\^]*d|w[\"\^]*e[\"\^]*r[\"\^]*s[\"\^]*h[\"\^]*e[\"\^]*l[\"\^]*l)|r[\"\^]*n[\"\^]*(?:c[\"\^]*n[\"\^]*f[\"\^]*g|(?:d[\"\^]*r[\"\^]*v|m[\"\^]*n[\"\^]*g)[\"\^]*r|j[\"\^]*o[\"\^]*b[\"\^]*s|p[\"\^]*o[\"\^]*r[\"\^]*t|q[\"\^]*c[\"\^]*t[\"\^]*l)|u[\"\^]*(?:b[\"\^]*p[\"\^]*r[\"\^]*n|s[\"\^]*h[\"\^]*(?:d|p[\"\^]*r[\"\^]*i[\"\^]*n[\"\^]*t[\"\^]*e[\"\^]*r[\"\^]*c[\"\^]*o[\"\^]*n[\"\^]*n[\"\^]*e[\"\^]*c[\"\^]*t[\"\^]*i[\"\^]*o[\"\^]*n[\"\^]*s))|w[\"\^]*(?:l[\"\^]*a[\"\^]*u[\"\^]*n[\"\^]*c[\"\^]*h[\"\^]*e[\"\^]*r|s[\"\^]*h))|q[\"\^]*(?:a[\"\^]*p[\"\^]*p[\"\^]*s[\"\^]*r[\"\^]*v|p[\"\^]*r[\"\^]*o[\"\^]*c[\"\^]*e[\"\^]*s[\"\^]*s|u[\"\^]*s[\"\^]*e[\"\^]*r|w[\"\^]*i[\"\^]*n[\"\^]*s[\"\^]*t[\"\^]*a)|r[\"\^]*(?:d(?:[\"\^]*p[\"\^]*s[\"\^]*i[\"\^]*g[\"\^]*n)?|e[\"\^]*(?:f[\"\^]*s[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|g(?:[\"\^]*(?:i[\"\^]*n[\"\^]*i|s[\"\^]*v[\"\^]*r[\"\^]*3[\"\^]*2))?|l[\"\^]*o[\"\^]*g|(?:(?:p[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i|s[\"\^]*c[\"\^]*a)[\"\^]*)?n|x[\"\^]*e[\"\^]*c)|i[\"\^]*s[\"\^]*e[\"\^]*t[\"\^]*u[\"\^]*p|m[\"\^]*d[\"\^]*i[\"\^]*r|o[\"\^]*b[\"\^]*o[\"\^]*c[\"\^]*o[\"\^]*p[\"\^]*y|p[\"\^]*c[\"\^]*(?:i[\"\^]*n[\"\^]*f[\"\^]*o|p[\"\^]*i[\"\^]*n[\"\^]*g)|s[\"\^]*h|u[\"\^]*n[\"\^]*d[\"\^]*l[\"\^]*l[\"\^]*3[\"\^]*2|w[\"\^]*i[\"\^]*n[\"\^]*s[\"\^]*t[\"\^]*a)|s[\"\^]*(?:a[\"\^]*n|c[\"\^]*(?:h[\"\^]*t[\"\^]*a[\"\^]*s[\"\^]*k[\"\^]*s|w[\"\^]*c[\"\^]*m[\"\^]*d)|e[\"\^]*(?:c[\"\^]*e[\"\^]*d[\"\^]*i[\"\^]*t|r[\"\^]*v[\"\^]*e[\"\^]*r[\"\^]*(?:(?:c[\"\^]*e[\"\^]*i[\"\^]*p|w[\"\^]*e[\"\^]*r)[\"\^]*o[\"\^]*p[\"\^]*t[\"\^]*i[\"\^]*n|m[\"\^]*a[\"\^]*n[\"\^]*a[\"\^]*g[\"\^]*e[\"\^]*r[\"\^]*c[\"\^]*m[\"\^]*d)|t[\"\^]*x)|f[\"\^]*c|(?:h[\"\^]*o[\"\^]*w[\"\^]*m[\"\^]*o[\"\^]*u[\"\^]*n|u[\"\^]*b[\"\^]*s)[\"\^]*t|x[\"\^]*s[\"\^]*t[\"\^]*r[\"\^]*a[\"\^]*c[\"\^]*e|y[\"\^]*s[\"\^]*(?:o[\"\^]*c[\"\^]*m[\"\^]*g[\"\^]*r|t[\"\^]*e[\"\^]*m[\"\^]*i[\"\^]*n[\"\^]*f[\"\^]*o))|t[\"\^]*(?:a[\"\^]*(?:k[\"\^]*e[\"\^]*o[\"\^]*w[\"\^]*n|p[\"\^]*i[\"\^]*c[\"\^]*f[\"\^]*g|s[\"\^]*k[\"\^]*(?:k[\"\^]*i[\"\^]*l[\"\^]*l|l[\"\^]*i[\"\^]*s[\"\^]*t))|(?:c[\"\^]*m[\"\^]*s[\"\^]*e[\"\^]*t[\"\^]*u|f[\"\^]*t)[\"\^]*p|(?:(?:e[\"\^]*l[\"\^]*n[\"\^]*e|i[\"\^]*m[\"\^]*e[\"\^]*o[\"\^]*u)[\"\^]*|r[\"\^]*a[\"\^]*c[\"\^]*e[\"\^]*r[\"\^]*(?:p[\"\^]*)?)t|l[\"\^]*n[\"\^]*t[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*n|p[\"\^]*m[\"\^]*(?:t[\"\^]*o[\"\^]*o[\"\^]*l|v[\"\^]*s[\"\^]*c[\"\^]*m[\"\^]*g[\"\^]*r)|s[\"\^]*(?:(?:d[\"\^]*i[\"\^]*s[\"\^]*)?c[\"\^]*o[\"\^]*n|e[\"\^]*c[\"\^]*i[\"\^]*m[\"\^]*p|k[\"\^]*i[\"\^]*l[\"\^]*l|p[\"\^]*r[\"\^]*o[\"\^]*f)|y[\"\^]*p[\"\^]*e[\"\^]*p[\"\^]*e[\"\^]*r[\"\^]*f|z[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l)|u[\"\^]*n[\"\^]*(?:e[\"\^]*x[\"\^]*p[\"\^]*o[\"\^]*s[\"\^]*e|i[\"\^]*q[\"\^]*u[\"\^]*e[\"\^]*i[\"\^]*d|l[\"\^]*o[\"\^]*d[\"\^]*c[\"\^]*t[\"\^]*r)|v[\"\^]*(?:o[\"\^]*l|s[\"\^]*s[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n)|w[\"\^]*(?:a[\"\^]*i[\"\^]*t[\"\^]*f[\"\^]*o[\"\^]*r|b[\"\^]*a[\"\^]*d[\"\^]*m[\"\^]*i[\"\^]*n|(?:d[\"\^]*s|e[\"\^]*(?:c|v[\"\^]*t))[\"\^]*u[\"\^]*t[\"\^]*i[\"\^]*l|h[\"\^]*(?:e[\"\^]*r[\"\^]*e|o[\"\^]*a[\"\^]*m[\"\^]*i)|i[\"\^]*n[\"\^]*(?:n[\"\^]*t(?:[\"\^]*3[\"\^]*2)?|r[\"\^]*s)|m[\"\^]*i[\"\^]*c|s[\"\^]*c[\"\^]*r[\"\^]*i[\"\^]*p[\"\^]*t)|x[\"\^]*c[\"\^]*o[\"\^]*p[\"\^]*y)(?:\.[\"\^]*[0-9A-Z_a-z]+)?\b" \ - "id:932380,\ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile windows-powershell-commands.data" \ + "id:932120,\ phase:2,\ block,\ capture,\ - t:none,\ - msg:'Remote Command Execution: Windows Command Injection',\ + t:none,t:urlDecodeUni,t:cmdLine,t:lowercase,\ + msg:'Remote Command Execution: Windows PowerShell Command Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-shell',\ + tag:'language-powershell',\ tag:'platform-windows',\ tag:'attack-rce',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:932013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:932014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" +# [ Unix shell expressions ] # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# Detects the following patterns which are common in Unix shell scripts +# and one-liners: # - -# [ Unix command injection ] +# $(foo) Command substitution +# ${foo} Parameter expansion +# <(foo) Process substitution +# >(foo) Process substitution +# $((foo)) Arithmetic expansion # -# This rule targets pefix + the source command (dot character) at PL2. +# Regexp generated from util/regexp-assemble/regexp-932130.data using Regexp::Assemble. +# See https://coreruleset.org/20190826/optimizing-regular-expressions/ for usage. # -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932231.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932231 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*\.[\s\x0b].*\b" \ - "id:932231,\ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:\$(?:\((?:\(.*\)|.*)\)|\{.*\})|[<>]\(.*\))" \ + "id:932130,\ phase:2,\ block,\ capture,\ - t:none,\ - msg:'Remote Command Execution: Unix Command Injection',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# This is a stricter sibling of rule 932130. -# -# It applies the same regular expression to the -# User-Agent and Referer HTTP headers. -# -# Unlike the sibling rule, this rule runs in phase 1. -# -# Regular expression generated from regex-assembly/932131.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932131 -# -SecRule REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer "@rx \$(?:\((?:.*|\(.*\))\)|\{.*\}|\[.*\])|[<>]\(.*\)|/[0-9A-Z_a-z]*\[!?.+\]" \ - "id:932131,\ - phase:1,\ - block,\ - capture,\ - t:none,t:cmdLine,\ + t:none,t:urlDecodeUni,t:cmdLine,\ msg:'Remote Command Execution: Unix Shell Expression Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ - tag:'paranoia-level/2',\ + tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# [ Windows FOR, IF commands ] +# +# This rule detects Windows command shell FOR and IF commands. +# If you are not running Windows, it is safe to disable this rule. +# +# Examples: +# +# FOR %a IN (set) DO +# FOR /D %a IN (dirs) DO +# FOR /F "options" %a IN (text|"text") DO +# FOR /L %a IN (start,step,end) DO +# FOR /R C:\dir %A IN (set) DO +# +# IF [/I] [NOT] EXIST filename | DEFINED define | ERRORLEVEL n | CMDEXTVERSION n +# IF [/I] [NOT] item1 [==|EQU|NEQ|LSS|LEQ|GTR|GEQ] item2 +# IF [/I] [NOT] (item1) [==|EQU|NEQ|LSS|LEQ|GTR|GEQ] (item2) +# +# http://ss64.com/nt/if.html +# http://ss64.com/nt/for.html +# +# Regexp generated from util/regexp-assemble/regexp-932140.data using Regexp::Assemble. +# See https://coreruleset.org/20190826/optimizing-regular-expressions/ for usage. +# +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \b(?:if(?:/i)?(?: not)?(?: exist\b| defined\b| errorlevel\b| cmdextversion\b|(?: |\().*(?:\bgeq\b|\bequ\b|\bneq\b|\bleq\b|\bgtr\b|\blss\b|==))|for(?:/[dflr].*)? %+[^ ]+ in\(.*\)\s?do)" \ + "id:932140,\ + phase:2,\ + block,\ + capture,\ + t:none,t:urlDecodeUni,t:cmdLine,\ + msg:'Remote Command Execution: Windows FOR/IF Command Found',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-shell',\ + tag:'platform-windows',\ + tag:'attack-rce',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/88',\ + tag:'PCI/6.5.2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# [ Unix direct remote command execution ] +# +# Detects Unix commands at the start of a parameter (direct RCE). +# Example: foo=wget%20www.example.com +# +# This case is different from command injection (rule 932100), where a +# command string is appended (injected) to a regular parameter, and then +# passed to a shell unescaped. +# +# This rule is also triggered by an Oracle WebLogic Remote Command Execution exploit: +# [ Oracle WebLogic vulnerability CVE-2017-10271 - Exploit tested: https://www.exploit-db.com/exploits/43458 ] +# +# Due to a higher risk of false positives, the following changes have been +# made relative to rule 932100: +# 1) the set of commands is smaller +# 2) we require a trailing space (denoting command parameters) or command +# separator character after the command +# +# To rebuild the word list regexp: +# cd util/regexp-assemble +# cat regexp-932150.txt | ./regexp-cmdline.py unix | ./regexp-assemble.pl +# +# Then insert the assembled regexp into this template: +# +# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:^|=)\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]* +# [regexp assembled from util/regexp-assemble/regexp-932150.txt] +# [\\\\'\"]*(?:\s|;|\||&|<|>)" \ +# +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:^|=)\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]*(?:l[\\\\'\"]*(?:s(?:[\\\\'\"]*(?:b[\\\\'\"]*_[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*a[\\\\'\"]*s[\\\\'\"]*e|c[\\\\'\"]*p[\\\\'\"]*u|m[\\\\'\"]*o[\\\\'\"]*d|p[\\\\'\"]*c[\\\\'\"]*i|u[\\\\'\"]*s[\\\\'\"]*b|-[\\\\'\"]*F|o[\\\\'\"]*f))?|z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|m[\\\\'\"]*(?:o[\\\\'\"]*r[\\\\'\"]*e|a)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s)|e[\\\\'\"]*s[\\\\'\"]*s[\\\\'\"]*(?:(?:f[\\\\'\"]*i[\\\\'\"]*l|p[\\\\'\"]*i[\\\\'\"]*p)[\\\\'\"]*e|e[\\\\'\"]*c[\\\\'\"]*h[\\\\'\"]*o)|a[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*(?:l[\\\\'\"]*o[\\\\'\"]*g(?:[\\\\'\"]*i[\\\\'\"]*n)?|c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*m)|w[\\\\'\"]*p(?:[\\\\'\"]*-[\\\\'\"]*d[\\\\'\"]*o[\\\\'\"]*w[\\\\'\"]*n[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*a[\\\\'\"]*d)?|f[\\\\'\"]*t[\\\\'\"]*p(?:[\\\\'\"]*g[\\\\'\"]*e[\\\\'\"]*t)?|y[\\\\'\"]*n[\\\\'\"]*x)|s[\\\\'\"]*(?:e[\\\\'\"]*(?:t[\\\\'\"]*(?:e[\\\\'\"]*n[\\\\'\"]*v|s[\\\\'\"]*i[\\\\'\"]*d)|n[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*a[\\\\'\"]*i[\\\\'\"]*l|d)|h(?:[\\\\'\"]*\.[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*s[\\\\'\"]*t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*b)?|o[\\\\'\"]*(?:u[\\\\'\"]*r[\\\\'\"]*c[\\\\'\"]*e|c[\\\\'\"]*a[\\\\'\"]*t)|t[\\\\'\"]*r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g[\\\\'\"]*s|y[\\\\'\"]*s[\\\\'\"]*c[\\\\'\"]*t[\\\\'\"]*l|c[\\\\'\"]*(?:h[\\\\'\"]*e[\\\\'\"]*d|p)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|f[\\\\'\"]*t[\\\\'\"]*p|u[\\\\'\"]*d[\\\\'\"]*o|s[\\\\'\"]*h|v[\\\\'\"]*n)|p[\\\\'\"]*(?:t[\\\\'\"]*a[\\\\'\"]*r(?:[\\\\'\"]*(?:d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p))?|y[\\\\'\"]*t[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*n(?:[\\\\'\"]*(?:3(?:[\\\\'\"]*m)?|2))?|k[\\\\'\"]*(?:e[\\\\'\"]*x[\\\\'\"]*e[\\\\'\"]*c|i[\\\\'\"]*l[\\\\'\"]*l)|r[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*v|(?:g[\\\\'\"]*r[\\\\'\"]*e|f[\\\\'\"]*t)[\\\\'\"]*p|e[\\\\'\"]*r[\\\\'\"]*l(?:[\\\\'\"]*5)?|h[\\\\'\"]*p(?:[\\\\'\"]*[57])?|i[\\\\'\"]*n[\\\\'\"]*g|o[\\\\'\"]*p[\\\\'\"]*d)|n[\\\\'\"]*(?:c(?:[\\\\'\"]*(?:\.[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*d[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*o[\\\\'\"]*n[\\\\'\"]*a[\\\\'\"]*l|o[\\\\'\"]*p[\\\\'\"]*e[\\\\'\"]*n[\\\\'\"]*b[\\\\'\"]*s[\\\\'\"]*d)|a[\\\\'\"]*t))?|e[\\\\'\"]*t[\\\\'\"]*(?:k[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*-[\\\\'\"]*f[\\\\'\"]*t[\\\\'\"]*p|(?:s[\\\\'\"]*t|c)[\\\\'\"]*a[\\\\'\"]*t)|o[\\\\'\"]*h[\\\\'\"]*u[\\\\'\"]*p|p[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*g|s[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*t)|t[\\\\'\"]*(?:c[\\\\'\"]*(?:p[\\\\'\"]*(?:t[\\\\'\"]*r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e|i[\\\\'\"]*n[\\\\'\"]*g)|s[\\\\'\"]*h)|r[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t[\\\\'\"]*e(?:[\\\\'\"]*6)?|i[\\\\'\"]*m[\\\\'\"]*e(?:[\\\\'\"]*o[\\\\'\"]*u[\\\\'\"]*t)?|a[\\\\'\"]*(?:i[\\\\'\"]*l(?:[\\\\'\"]*f)?|r)|e[\\\\'\"]*l[\\\\'\"]*n[\\\\'\"]*e[\\\\'\"]*t)|r[\\\\'\"]*(?:e[\\\\'\"]*(?:p[\\\\'\"]*(?:l[\\\\'\"]*a[\\\\'\"]*c[\\\\'\"]*e|e[\\\\'\"]*a[\\\\'\"]*t)|a[\\\\'\"]*l[\\\\'\"]*p[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*h|n[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*e)|u[\\\\'\"]*b[\\\\'\"]*y(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|m[\\\\'\"]*(?:u[\\\\'\"]*s[\\\\'\"]*e|d[\\\\'\"]*i)[\\\\'\"]*r|n[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*o|s[\\\\'\"]*y[\\\\'\"]*n[\\\\'\"]*c|c[\\\\'\"]*p)|b[\\\\'\"]*(?:z[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|c[\\\\'\"]*a[\\\\'\"]*t)|s[\\\\'\"]*d[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*f[\\\\'\"]*f|t[\\\\'\"]*a[\\\\'\"]*r)|u[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*n|a[\\\\'\"]*s[\\\\'\"]*h)|m[\\\\'\"]*(?:y[\\\\'\"]*s[\\\\'\"]*q[\\\\'\"]*l[\\\\'\"]*(?:d[\\\\'\"]*u[\\\\'\"]*m[\\\\'\"]*p(?:[\\\\'\"]*s[\\\\'\"]*l[\\\\'\"]*o[\\\\'\"]*w)?|h[\\\\'\"]*o[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*o[\\\\'\"]*p[\\\\'\"]*y|a[\\\\'\"]*d[\\\\'\"]*m[\\\\'\"]*i[\\\\'\"]*n|s[\\\\'\"]*h[\\\\'\"]*o[\\\\'\"]*w)|l[\\\\'\"]*o[\\\\'\"]*c[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*e|a[\\\\'\"]*i[\\\\'\"]*l[\\\\'\"]*q)|u[\\\\'\"]*(?:n[\\\\'\"]*(?:c[\\\\'\"]*o[\\\\'\"]*m[\\\\'\"]*p[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|l[\\\\'\"]*z[\\\\'\"]*m[\\\\'\"]*a|a[\\\\'\"]*m[\\\\'\"]*e|r[\\\\'\"]*a[\\\\'\"]*r|s[\\\\'\"]*e[\\\\'\"]*t|z[\\\\'\"]*i[\\\\'\"]*p|x[\\\\'\"]*z)|s[\\\\'\"]*e[\\\\'\"]*r[\\\\'\"]*(?:(?:a[\\\\'\"]*d|m[\\\\'\"]*o)[\\\\'\"]*d|d[\\\\'\"]*e[\\\\'\"]*l))|x[\\\\'\"]*(?:z(?:[\\\\'\"]*(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|d[\\\\'\"]*(?:i[\\\\'\"]*f[\\\\'\"]*f|e[\\\\'\"]*c)|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e))?|a[\\\\'\"]*r[\\\\'\"]*g[\\\\'\"]*s)|z[\\\\'\"]*(?:(?:(?:[ef][\\\\'\"]*)?g[\\\\'\"]*r[\\\\'\"]*e|i)[\\\\'\"]*p|c[\\\\'\"]*(?:a[\\\\'\"]*t|m[\\\\'\"]*p)|d[\\\\'\"]*i[\\\\'\"]*f[\\\\'\"]*f|l[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*s|m[\\\\'\"]*o[\\\\'\"]*r[\\\\'\"]*e|r[\\\\'\"]*u[\\\\'\"]*n|s[\\\\'\"]*h)|f[\\\\'\"]*(?:t[\\\\'\"]*p[\\\\'\"]*(?:s[\\\\'\"]*t[\\\\'\"]*a[\\\\'\"]*t[\\\\'\"]*s|w[\\\\'\"]*h[\\\\'\"]*o)|i[\\\\'\"]*l[\\\\'\"]*e[\\\\'\"]*t[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*t|e[\\\\'\"]*t[\\\\'\"]*c[\\\\'\"]*h|g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p)|c[\\\\'\"]*(?:o[\\\\'\"]*(?:m[\\\\'\"]*m[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*d|p[\\\\'\"]*r[\\\\'\"]*o[\\\\'\"]*c)|u[\\\\'\"]*r[\\\\'\"]*l|s[\\\\'\"]*h|c)|e[\\\\'\"]*(?:g[\\\\'\"]*r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*h[\\\\'\"]*o|v[\\\\'\"]*a[\\\\'\"]*l|x[\\\\'\"]*e[\\\\'\"]*c|n[\\\\'\"]*v)|d[\\\\'\"]*(?:m[\\\\'\"]*e[\\\\'\"]*s[\\\\'\"]*g|a[\\\\'\"]*s[\\\\'\"]*h|i[\\\\'\"]*f[\\\\'\"]*f|o[\\\\'\"]*a[\\\\'\"]*s)|g[\\\\'\"]*(?:z[\\\\'\"]*(?:c[\\\\'\"]*a[\\\\'\"]*t|i[\\\\'\"]*p)|r[\\\\'\"]*e[\\\\'\"]*p|c[\\\\'\"]*c)|j[\\\\'\"]*(?:o[\\\\'\"]*b[\\\\'\"]*s[\\\\'\"]*\s+[\\\\'\"]*-[\\\\'\"]*x|a[\\\\'\"]*v[\\\\'\"]*a)|w[\\\\'\"]*(?:h[\\\\'\"]*o[\\\\'\"]*a[\\\\'\"]*m[\\\\'\"]*i|g[\\\\'\"]*e[\\\\'\"]*t|3[\\\\'\"]*m)|i[\\\\'\"]*r[\\\\'\"]*b(?:[\\\\'\"]*(?:1(?:[\\\\'\"]*[89])?|2[\\\\'\"]*[012]))?|o[\\\\'\"]*n[\\\\'\"]*i[\\\\'\"]*n[\\\\'\"]*t[\\\\'\"]*r|h[\\\\'\"]*(?:e[\\\\'\"]*a[\\\\'\"]*d|u[\\\\'\"]*p)|v[\\\\'\"]*i[\\\\'\"]*(?:g[\\\\'\"]*r|p[\\\\'\"]*w)|G[\\\\'\"]*E[\\\\'\"]*T)[\\\\'\"]*(?:\s|;|\||&|<|>)" \ + "id:932150,\ + phase:2,\ + block,\ + capture,\ + t:none,\ + msg:'Remote Command Execution: Direct Unix Command Execution',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-shell',\ + tag:'platform-unix',\ + tag:'attack-rce',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/88',\ + tag:'PCI/6.5.2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# [ Unix shell snippets ] +# +# Detect some common sequences found in shell commands and scripts. +# +# Some commands which were restricted in earlier rules due to FP, +# have been added here with their full path, in order to catch some +# cases where the full path is sent. +# +# This rule is also triggered by an Apache Struts Remote Code Execution exploit: +# [ Apache Struts vulnerability CVE-2017-9805 - Exploit tested: https://www.exploit-db.com/exploits/42627 ] +# +# This rule is also triggered by an Oracle WebLogic Remote Command Execution exploit: +# [ Oracle WebLogic vulnerability CVE-2017-10271 - Exploit tested: https://www.exploit-db.com/exploits/43458 ] + +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@pmFromFile unix-shell.data" \ + "id:932160,\ + phase:2,\ + block,\ + capture,\ + t:none,t:urlDecodeUni,t:cmdLine,t:normalizePath,t:lowercase,\ + msg:'Remote Command Execution: Unix Shell Code Found',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-shell',\ + tag:'platform-unix',\ + tag:'attack-rce',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/88',\ + tag:'PCI/6.5.2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# [ Shellshock vulnerability (CVE-2014-6271 and CVE-2014-7169) ] +# +# Detect exploitation of "Shellshock" GNU Bash RCE vulnerability. +# +# Based on ModSecurity rules created by Red Hat. +# Permission for use was granted by Martin Prpic +# +# https://access.redhat.com/articles/1212303 +# +SecRule REQUEST_HEADERS|REQUEST_LINE "@rx ^\(\s*\)\s+{" \ + "id:932170,\ + phase:2,\ + block,\ + capture,\ + t:none,t:urlDecode,\ + msg:'Remote Command Execution: Shellshock (CVE-2014-6271)',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-shell',\ + tag:'platform-unix',\ + tag:'attack-rce',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/88',\ + tag:'PCI/6.5.2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + +SecRule ARGS_NAMES|ARGS|FILES_NAMES "@rx ^\(\s*\)\s+{" \ + "id:932171,\ + phase:2,\ + block,\ + capture,\ + t:none,t:urlDecode,t:urlDecodeUni,\ + msg:'Remote Command Execution: Shellshock (CVE-2014-6271)',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-shell',\ + tag:'platform-unix',\ + tag:'attack-rce',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/88',\ + tag:'PCI/6.5.2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# +# -=[ Restricted File Upload ]=- +# +# Detects attempts to upload a file with a forbidden filename. +# +# Many application contain Unrestricted File Upload vulnerabilities. +# https://www.owasp.org/index.php/Unrestricted_File_Upload +# +# These might be abused to upload configuration files or other files +# that affect the behavior of the web server, possibly causing remote +# code execution. +# +SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X-File-Name \ + "@pmFromFile restricted-upload.data" \ + "id:932180,\ + phase:2,\ + block,\ + capture,\ + t:none,t:lowercase,\ + msg:'Restricted File Upload Attempt',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-rce',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/88',\ + tag:'PCI/6.5.2',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:932013,phase:1,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:932014,phase:2,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" +# +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) +# + # # -=[ Rule 932200 ]=- @@ -985,29 +610,17 @@ SecRule REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer "@rx \$(?:\((?:.*|\(. # - bar;cd+/etc;/bin$u/ca*+passwd # - foo;ca\t+/et\c/pa\s\swd # - foo;c'at'+/etc/pa's'swd -# - foo;c$@at+/et$@c/pas$@swd -# - foo;c$!at+/et$!c/pas$!swd -# - foo;c$*at+/et$*c/pas$*swd -# - foo;c$?at+/et$?c/pas$?swd -# - foo;c$-at+/et$-c/pas$-swd -# - foo;c$_at+/et$_c/pas$_swd -# - foo;c$$at+/et$$c/pas$$swd # -# Regex notes: https://regex101.com/r/V6wrCO/1 +# Regex notes: https://regex101.com/r/JgZFRi/7 # -# Regular expression generated from regex-assembly/932200.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932200 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ['\*\?\x5c`][^\n/]+/|/[^/]+?['\*\?\x5c`]|\$[!#\$\(\*\-0-9\?-\[_a-\{]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ([*?`\\'][^/\n]+/|\$[({\[#a-zA-Z0-9]|/[^/]+?[*?`\\'])" \ "id:932200,\ phase:2,\ block,\ capture,\ t:none,t:lowercase,t:urlDecodeUni,\ msg:'RCE Bypass Technique',\ - logdata:'Matched Data: %{TX.0} found within %{TX.932200_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ @@ -1016,548 +629,41 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.932200_matched_var_name=%{matched_var_name}',\ chain" - SecRule MATCHED_VAR "@rx /" \ - "t:none,\ - chain" - SecRule MATCHED_VAR "@rx \s" \ - "t:none,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -# -=[ Rule 932205 ]=- -# -# Sibling of 932200 targeting the Referer header. URLs cause false positives in rule 932200 -# and must be handled with additional checks. -# -# The last chain prevents FPs against the "Scroll to text fragment" browser feature -# (https://wicg.github.io/scroll-to-text-fragment/). -# -# Regular expression generated from regex-assembly/932205.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932205 -# -SecRule REQUEST_HEADERS:Referer "@rx ^[^#]+" \ - "id:932205,\ - phase:1,\ - block,\ - capture,\ - t:none,t:lowercase,t:urlDecodeUni,\ - msg:'RCE Bypass Technique',\ - logdata:'Matched Data: %{TX.2} found within %{TX.932205_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.932205_matched_var_name=%{matched_var_name}',\ - chain" - SecRule TX:0 "@rx ^[^\.]+\.[^;\?]+[;\?](.*(['\*\?\x5c`][^\n/]+/|/[^/]+?['\*\?\x5c`]|\$[!#\$\(\*\-0-9\?-\[_a-\{]))" \ - "capture,\ - t:none,\ - chain" - SecRule TX:1 "@rx /" \ - "t:none,\ - chain" - SecRule TX:1 "@rx \s" \ - "t:none,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -# -=[ Rule 932206 ]=- -# -# Sibling of 932200 targeting the Referer header. URLs cause false positives in rule 932200 -# and must be handled with additional checks. -# -# Regular expression generated from regex-assembly/932206.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932206 -# -SecRule REQUEST_HEADERS:Referer "@rx ^[^\.]*?(?:['\*\?\x5c`][^\n/]+/|/[^/]+?['\*\?\x5c`]|\$[!#\$\(\*\-0-9\?-\[_a-\{])" \ - "id:932206,\ - phase:1,\ - block,\ - capture,\ - t:none,t:lowercase,t:urlDecodeUni,\ - msg:'RCE Bypass Technique',\ - logdata:'Matched Data: %{TX.0} found within %{TX.932206_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.932206_matched_var_name=%{matched_var_name}',\ - chain" - SecRule MATCHED_VAR "@rx /" \ - "t:none,\ - chain" - SecRule MATCHED_VAR "@rx \s" \ - "t:none,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# Regular expression generated from regex-assembly/932220.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932220 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i).\|(?:[\s\x0b]*|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:7[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[arx])?|G[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?E[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?T|a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:b|(?:p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?)?t|r(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[jp])?|s(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[ks])|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[89][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?9|[au][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t|c|(?:m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?)?p|s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h)|d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[dfu]|i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[gr])|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[bdx]|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|q[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n|s(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h)?)|f[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[cdgi]|m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p)|g[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[chr][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c|d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m|i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t|o|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?g)|h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:d|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p)|i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[dp]|r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b)|j[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:j[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s|q)|k[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|l[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:d(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d)?|[nps]|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a|z(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?4)?)|m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r|v)|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[cl]|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t|(?:p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?)?m)|o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:[at][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b|f|(?:k[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?)?g|h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[cp]|r(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|x[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?z)|r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r|c(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p)?|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[dv]|(?:p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?)?m)|s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[dt]|[ghu]|s(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h)?|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n)|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[cr]|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l|[co][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[ex]|i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c)|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|l)|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:3[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m|c)|x[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:x[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|z)|y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m)|z[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h))" \ - "id:932220,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Unix Command Injection with pipe',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -=[ Rule 932240 ]=- -# -# Generic RCE Bypass blocking using different techniques: see https://github.com/coreruleset/coreruleset/issues/2632 -# -# This rule complements rule 932230 with generic evasion detection. -# Anything that uses a well-known evasion technique should be blocked at this level. -# The chained rule will exclude false positives due to german thousands separators (e.g., 10'000). -# -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932240.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932240 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS|XML:/* "@rx (?i)[\-0-9_a-z]+(?:[\s\x0b]*[\"'][^\s\x0b\"']+[\"']|(?:[\"'][\"']+|[\[-\]]+|\$+[!#\*\-0-9\?@\x5c_a-\{]+|``|[\$<>]\(\))[\s\x0b]*)[\-0-9_a-z]+" \ - "id:932240,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Unix Command Injection evasion attempt detected',\ - logdata:'Matched Data: %{TX.0} found within %{TX.932240_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.932240_matched_var_name=%{matched_var_name}',\ - chain" - SecRule MATCHED_VAR "!@rx [0-9]\s*\'\s*[0-9]" \ - "t:none,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + SecRule MATCHED_VAR "@rx /" "t:none,t:urlDecodeUni,chain" + SecRule MATCHED_VAR "@rx \s" "t:none,t:urlDecodeUni,\ + setvar:'tx.lfi_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# [ Sqlite System Command Execution ] +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:932015,phase:1,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:932016,phase:2,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" # -# This rule prevents execution of SQLite CLI commands like .system and .shell -# -# You can find a vulnerable script and a sample payload here: -# https://github.com/qxxxb/ctf/tree/master/2021/zer0pts_ctf/baby_sqli -# -# List of sqlite3 CLI commands: -# https://sqlite.org/cli.html -# -# Regular expression generated from regex-assembly/932210.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932210 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ;[\s\x0b]*\.[\s\x0b]*[\"']?(?:a(?:rchive|uth)|b(?:a(?:ckup|il)|inary)|c(?:d|h(?:anges|eck)|lone|onnection)|d(?:atabases|b(?:config|info)|ump)|e(?:cho|qp|x(?:cel|it|p(?:ert|lain)))|f(?:ilectrl|ullschema)|he(?:aders|lp)|i(?:mpo(?:rt|ster)|ndexes|otrace)|l(?:i(?:mi|n)t|o(?:ad|g))|(?:mod|n(?:onc|ullvalu)|unmodul)e|o(?:nce|pen|utput)|p(?:arameter|r(?:int|o(?:gress|mpt)))|quit|re(?:ad|cover|store)|s(?:ave|c(?:anstats|hema)|e(?:lftest|parator|ssion)|h(?:a3sum|ell|ow)?|tats|ystem)|t(?:ables|estc(?:ase|trl)|ime(?:out|r)|race)|vfs(?:info|list|name)|width)" \ - "id:932210,\ - phase:2,\ - block,\ - t:none,t:escapeSeqDecode,t:compressWhitespace,\ - msg:'Remote Command Execution: SQLite System Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -=[ SMTP/IMAP/POP3 Command Execution ]=- -# -# Rationale -# ========= -# -# The rules for email command execution are based on the RFCs for each protocol. -# Some of the commands have optional and/or additional parameters, so we tried to be -# precise to avoid as many FP in PL2 rules. -# For those commands that resemble common English words, and may pose a higher risk of false positives, -# they have been split off to a sibling rule in PL3. - -# =[ SMTP Command Execution ]= -# -# This rule prevents execution of SMTP related system commands. -# -# List of SMTP commands: from rfc 5321 (https://www.rfc-editor.org/rfc/rfc5321) -# -# Regular expression generated from regex-assembly/932300.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932300 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \r\n.*?\b(?:E(?:HLO [\-\.A-Za-z\x17f\x212a]{1,255}|XPN .{1,64})|HELO [\-\.A-Za-z\x17f\x212a]{1,255}|MAIL FROM:<.{1,64}@.{1,255}>|R(?:CPT TO:(?:<.{1,64}@.{1,255}>| )?<.{1,64}>|SET\b)|VRFY .{1,64}(?: <.{1,64}@.{1,255}>|@.{1,255})|AUTH [\-0-9A-Z_a-z\x17f\x212a]{1,20} (?:(?:[\+/-9A-Z_a-z\x17f\x212a]{4})*(?:[\+/-9A-Z_a-z\x17f\x212a]{2}=|[\+/-9A-Z_a-z\x17f\x212a]{3}))?=|STARTTLS\b|NOOP\b(?: .{1,255})?)" \ - "id:932300,\ - phase:2,\ - block,\ - capture,\ - t:none,t:escapeSeqDecode,\ - msg:'Remote Command Execution: SMTP Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/137/134',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# =[ IMAP Command Execution ]= -# -# This rule prevents execution of IMAP4 related system commands. -# -# List of IMAP4 commands: from rfc 3501 (https://datatracker.ietf.org/doc/html/rfc3501#section-9) -# -# Note: Mailbox International Naming Convention uses UTF-7, so it was left out explicitly. -# -# Regular expression generated from regex-assembly/932310.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932310 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?is)\r\n[0-9A-Z_a-z]{1,50}\b (?:A(?:PPEND (?:[\"#%&\*\--9A-Z\x5c_a-z]+)?(?: \([ \x5ca-z]+\))?(?: \"?[0-9]{1,2}-[0-9A-Z_a-z]{3}-[0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2} [\+\-][0-9]{4}\"?)? \{[0-9]{1,20}\+?\}|UTHENTICATE [\-0-9_a-z]{1,20}\r\n)|L(?:SUB (?:[\"#\*\.-9A-Z_a-z~]+)? (?:[\"%&\*\.-9A-Z\x5c_a-z]+)?|ISTRIGHTS (?:[\"%&\*\--9A-Z\x5c_a-z]+)?)|S(?:TATUS (?:[\"%&\*\--9A-Z\x5c_a-z]+)? \((?:U(?:NSEEN|IDNEXT)|MESSAGES|UIDVALIDITY|RECENT| )+\)|ETACL (?:[\"%&\*\--9A-Z\x5c_a-z]+)? [\+\-][ac-eiklpr-twx]+?)|UID (?:COPY|FETCH|STORE) (?:[\*,0-:]+)?|(?:(?:DELETE|GET)ACL|MYRIGHTS) (?:[\"%&\*\--9A-Z\x5c_a-z]+)?)" \ - "id:932310,\ - phase:2,\ - block,\ - t:none,t:escapeSeqDecode,\ - msg:'Remote Command Execution: IMAP Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/137/134',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# =[ POP3 Command Execution ]= -# -# This rule prevents execution of POP3 related system commands. -# -# List of POP3 commands: -# - from rfc 1939 (https://www.rfc-editor.org/rfc/rfc1939#appendix-B) -# - extensions from rfc 2449 (https://www.rfc-editor.org/rfc/rfc2449) -# -# These commands all have some kind of parameter that makes them a good PL2 target. -# -# Regular expression generated from regex-assembly/932320.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932320 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?is)\r\n.*?\b(?:(?:LIST|TOP [0-9]+)(?: [0-9]+)?|U(?:SER .+?|IDL(?: [0-9]+)?)|PASS .+?|(?:RETR|DELE) [0-9]+?|A(?:POP [0-9A-Z_a-z]+ [0-9a-f]{32}|UTH [\-0-9_a-z]{1,20} (?:(?:[\+/-9A-Z_a-z]{4})*(?:[\+/-9A-Z_a-z]{2}=|[\+/-9A-Z_a-z]{3}))?=))" \ - "id:932320,\ - phase:2,\ - block,\ - t:none,t:escapeSeqDecode,\ - msg:'Remote Command Execution: POP3 Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/137/134',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# [ Unix command injection ] -# -# This is a stricter sibling of rules 932230, 932235, 932250, 932260. -# This stricter sibling detects Unix RCE with and without prefix and words of any length. -# It uses the same regex. -# -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932236.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932236 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:^|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:7z[arx]?|(?:(?:GE|POS)T|HEAD)[\s\x0b&\)<>\|]|a(?:(?:b|w[ks]|l(?:ias|pine)|xel)[\s\x0b&\)<>\|]|pt(?:[\s\x0b&\)<>\|]|-get)|r(?:[\s\x0b&\)<>j\|]|(?:p|ch)[\s\x0b&\)<>\|]|ia2c)|s(?:h[\s\x0b&\)<>\|]|cii(?:-xfr|85)|pell)|dd(?:group|user)|getty|nsible|tobm)|b(?:z(?:z[\s\x0b&\)<>\|]|c(?:at|mp)|diff|e(?:grep|xe)|f?grep|ip2(?:recover)?|less|more)|a(?:s(?:e(?:32|64|n(?:ame[\s\x0b&\)<>\|]|c))|h[\s\x0b&\)<>\|])|tch[\s\x0b&\)<>\|])|lkid|pftrace|r(?:eaksw|idge[\s\x0b&\)<>\|])|sd(?:cat|iff|tar)|u(?:iltin|n(?:dler[\s\x0b&\)<>\|]|zip2)|s(?:ctl|ybox))|y(?:ebug|obu))|c(?:[89]9|(?:a(?:t|ncel|psh)|c)[\s\x0b&\)<>\|]|mp|p(?:[\s\x0b&\)<>\|]|an|io|ulimit)|s(?:h|cli[\s\x0b&\)<>\|]|plit|vtool)|u(?:(?:t|rl)[\s\x0b&\)<>\|]|psfilter)|ertbot|h(?:attr|(?:dir|root)[\s\x0b&\)<>\|]|e(?:ck_(?:by_ssh|cups|log|memory|raid|s(?:sl_cert|tatusfile))|f[\s\x0b&\)\-<>\|])|(?:flag|pas)s|g(?:passwd|rp)|mod|o(?:om|wn)|sh)|lang(?:[\s\x0b&\)<>\|]|\+\+)|o(?:(?:b|pro)c|(?:lumn|m(?:m(?:and)?|p(?:oser|ress)))[\s\x0b&\)<>\|]|w(?:say|think))|r(?:ash[\s\x0b&\)<>\|]|on(?:[\s\x0b&\)<>\|]|tab)))|d(?:(?:[du]|i(?:(?:alo)?g|r|ff)|a(?:sh|te))[\s\x0b&\)<>\|]|f|hclient|m(?:esg|idecode|setup)|o(?:as|(?:cker|ne)[\s\x0b&\)<>\|]|sbox)|pkg|vips)|e(?:(?:[bd]|cho)[\s\x0b&\)<>\|]|n(?:v(?:[\s\x0b&\)<>\|]|-update)|d(?:if|sw))|qn|s(?:[\s\x0b&\)<>h\|]|ac)|x(?:(?:ec)?[\s\x0b&\)<>\|]|iftool|p(?:(?:and|(?:ec|or)t)[\s\x0b&\)<>\|]|r))|2fsck|(?:asy_instal|va)l|fax|grep|macs)|f(?:(?:c|etch|lock|unction)[\s\x0b&\)<>\|]|d|g(?:rep)?|i(?:(?:n(?:d|ger)|sh)?[\s\x0b&\)<>\|]|le(?:[\s\x0b&\)<>\|]|test))|mt|tp(?:[\s\x0b&\)<>\|]|stats|who)|acter|o(?:ld[\s\x0b&\)<>\|]|reach)|ping)|g(?:c(?:c[^\s\x0b]|ore)|db|e(?:(?:m|tfacl)[\s\x0b&\)<>\|]|ni(?:e[\s\x0b&\)<>\|]|soimage))|hci?|i(?:(?:t|mp)[\s\x0b&\)<>\|]|nsh)|(?:o|awk)[\s\x0b&\)<>\|]|pg|r(?:c|ep[\s\x0b&\)<>\|]|oup(?:[\s\x0b&\)<>\|]|mod))|tester|unzip|z(?:cat|exe|ip))|h(?:(?:d|up|ash|i(?:ghlight|story))[\s\x0b&\)<>\|]|e(?:ad[\s\x0b&\)<>\|]|xdump)|ost(?:id|name)|ping3|t(?:digest|op|passwd))|i(?:d|p(?:6?tables|config)?|rb|conv|f(?:config|top)|nstall[\s\x0b&\)<>\|]|onice|spell)|j(?:js|q|ava[\s\x0b&\)<>\|]|exec|o(?:(?:bs|in)[\s\x0b&\)<>\|]|urnalctl)|runscript)|k(?:s(?:h|shell)|ill(?:[\s\x0b&\)<>\|]|all)|nife[\s\x0b&\)<>\|])|l(?:d(?:d?[\s\x0b&\)<>\|]|config)|(?:[np]|inks|ynx)[\s\x0b&\)<>\|]|s(?:-F|b_release|cpu|hw|mod|of|pci|usb)?|ua(?:[\s\x0b&\)<>\|]|(?:la)?tex)|z(?:[\s\x0b&\)4<>\|]|4c(?:at)?|c(?:at|mp)|diff|[ef]?grep|less|m(?:a(?:dec|info)?|ore))|a(?:st(?:[\s\x0b&\)<>\|]|comm|log(?:in)?)|tex[\s\x0b&\)<>\|])|ess(?:[\s\x0b&\)<>\|]|echo|(?:fil|pip)e)|ftp(?:get)?|o(?:(?:ca(?:l|te)|ok)[\s\x0b&\)<>\|]|g(?:inctl|(?:nam|sav)e)|setup)|trace|wp-(?:d(?:ownload|ump)|mirror|request))|m(?:a(?:(?:n|ke)[\s\x0b&\)<>\|]|il(?:[\s\x0b&\)<>q\|]|x[\s\x0b&\)<>\|])|ster\.passwd|wk)|tr|(?:v|utt)[\s\x0b&\)<>\|]|k(?:dir[\s\x0b&\)<>\|]|fifo|nod|temp)|locate|o(?:squitto|unt[\s\x0b&\)<>\|])|sg(?:attrib|c(?:at|onv)|filter|merge|uniq)|ysql(?:admin|dump(?:slow)?|hotcopy|show)?)|n(?:c(?:[\s\x0b&\)<>\|]|\.(?:openbsd|traditional)|at)|e(?:t(?:[\s\x0b&\)<>\|]|(?:c|st)at|kit-ftp|plan)|ofetch)|(?:(?:ul)?l|ice)[\s\x0b&\)<>\|]|m(?:[\s\x0b&\)<>\|]|ap)|p(?:m[\s\x0b&\)<>\|]|ing)|a(?:no[\s\x0b&\)<>\|]|sm|wk)|o(?:de[\s\x0b&\)<>\|]|hup)|roff|s(?:enter|lookup|tat))|o(?:(?:d|ctave)[\s\x0b&\)<>\|]|nintr|p(?:en(?:ssl|v(?:pn|t))|kg))|p(?:a(?:(?:x|rted|tch)[\s\x0b&\)<>\|]|s(?:swd|te[\s\x0b&\)<>\|]))|d(?:b|f(?:la)?tex|ksh)|f(?:[\s\x0b&\)<>\|]|tp)|g(?:rep)?|hp(?:[\s\x0b&\)57<>\|]|-cgi)|i(?:(?:co?|ng)[\s\x0b&\)<>\|]|p[^\s\x0b]|dstat|gz)|k(?:g(?:_?info)?|exec|ill)|r(?:y?[\s\x0b&\)<>\|]|int(?:env|f[\s\x0b&\)<>\|]))|t(?:x|ar(?:diff|grep)?)|wd(?:\.db)?|xz|er(?:(?:f|ms)[\s\x0b&\)<>\|]|l(?:[\s\x0b&\)5<>\|]|sh))|opd|s(?:ed|ftp|ql)|u(?:ppet[\s\x0b&\)<>\|]|shd)|y(?:thon[^\s\x0b]|3?versions))|r(?:a(?:r[\s\x0b&\)<>\|]|k(?:e[\s\x0b&\)<>\|]|u))|c(?:p[\s\x0b&\)<>\|])?|e(?:(?:d(?:carpet)?|v|name|p(?:eat|lace))[\s\x0b&\)<>\|]|a(?:delf|lpath)|stic)|m(?:(?:dir)?[\s\x0b&\)<>\|]|user)|pm(?:[\s\x0b&\)<>\|]|db|(?:quer|verif)y)|bash|l(?:ogin|wrap)|nano|oute[\s\x0b&\)<>\|]|sync|u(?:by[^\s\x0b]|n-(?:mailcap|parts))|vi(?:ew|m))|s(?:c(?:p|(?:hed|r(?:een|ipt))[\s\x0b&\)<>\|])|e(?:(?:d|lf|rvice)[\s\x0b&\)<>\|]|t(?:(?:facl)?[\s\x0b&\)<>\|]|arch|env|sid)|ndmail)|(?:g|ash|nap)[\s\x0b&\)<>\|]|h(?:(?:adow|ells)?[\s\x0b&\)<>\|]|\.distrib|u(?:f|tdown[\s\x0b&\)<>\|]))|s(?:[\s\x0b&\)<>\|]|h(?:[\s\x0b&\)<>\|]|-key(?:ge|sca)n|pass))|u(?:[\s\x0b&\)<>\|]|do)|vn|diff|ftp|l(?:eep[\s\x0b&\)<>\|]|sh)|mbclient|o(?:cat|elim|(?:rt|urce)[\s\x0b&\)<>\|])|p(?:lit[\s\x0b&\)<>\|]|wd\.db)|qlite3|t(?:art-stop-daemon|d(?:buf|err|in|out)|r(?:ace|ings[\s\x0b&\)<>\|]))|ys(?:ctl|tem(?:ctl|d-resolve)))|t(?:a(?:c|r[\s\x0b&\)<>\|]|il[\s\x0b&\)<>f\|]|sk(?:[\s\x0b&\)<>\|]|set))|bl|c(?:p(?:[\s\x0b&\)<>\|]|dump|ing|traceroute)|l?sh)|e(?:[ex][\s\x0b&\)<>\|]|lnet)|i(?:c[\s\x0b&\)<>\|]|me(?:datectl|out[\s\x0b&\)<>\|]))|o(?:p|uch[\s\x0b&\)<>\|])|ftp|mux|r(?:aceroute6?|off)|shark)|u(?:dp|l(?:imit)?[\s\x0b&\)<>\|]|n(?:ame|(?:compress|s(?:et|hare))[\s\x0b&\)<>\|]|expand|iq|l(?:ink[\s\x0b&\)<>\|]|z(?:4|ma))|(?:pig|x)z|rar|z(?:ip[\s\x0b&\)<>\|]|std))|pdate-alternatives|ser(?:(?:ad|mo)d|del)|u(?:de|en)code)|v(?:i(?:m(?:[\s\x0b&\)<>\|]|diff)|ew[\s\x0b&\)<>\|]|gr|pw|rsh|sudo)|algrind|olatility[\s\x0b&\)<>\|])|w(?:3m|c|a(?:ll|tch)[\s\x0b&\)<>\|]|get|h(?:iptail[\s\x0b&\)<>\|]|o(?:ami|is))|i(?:reshark|sh[\s\x0b&\)<>\|]))|x(?:(?:x|pa)d|z(?:[\s\x0b&\)<>\|]|c(?:at|mp)|d(?:ec|iff)|[ef]?grep|less|more)|args|e(?:la)?tex|mo(?:dmap|re)|term)|y(?:(?:e(?:s|lp)|arn)[\s\x0b&\)<>\|]|um)|z(?:ip(?:[\s\x0b&\)<>\|]|c(?:loak|mp)|details|grep|info|(?:merg|not)e|split|tool)|s(?:h|oelim|td(?:(?:ca|m)t|grep|less)?)|athura|c(?:at|mp)|diff|e(?:grep|ro[\s\x0b&\)<>\|])|f?grep|less|more|run|ypper))" \ - "id:932236,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Unix Command Injection (command without evasion)',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# [ Unix command injection ] -# -# This is a sibling of rule 932236. -# This sibling detects Unix RCE in request headers Referer and User-Agent. -# It uses the same regex but excludes known user-agents to avoid false positives. -# -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# -# Regular expression generated from regex-assembly/932239.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932239 -# -SecRule REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer "@rx (?i)(?:^|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:7z[arx]?|(?:(?:GE|POS)T|HEAD)[\s\x0b&\)<>\|]|a(?:(?:b|w[ks]|l(?:ias|pine)|xel)[\s\x0b&\)<>\|]|pt(?:[\s\x0b&\)<>\|]|-get)|r(?:[\s\x0b&\)<>j\|]|(?:p|ch)[\s\x0b&\)<>\|]|ia2c)|s(?:h[\s\x0b&\)<>\|]|cii(?:-xfr|85)|pell)|dd(?:group|user)|getty|nsible|tobm)|b(?:z(?:z[\s\x0b&\)<>\|]|c(?:at|mp)|diff|e(?:grep|xe)|f?grep|ip2(?:recover)?|less|more)|a(?:s(?:e(?:32|64|n(?:ame[\s\x0b&\)<>\|]|c))|h[\s\x0b&\)<>\|])|tch[\s\x0b&\)<>\|])|lkid|pftrace|r(?:eaksw|idge[\s\x0b&\)<>\|])|sd(?:cat|iff|tar)|u(?:iltin|n(?:dler[\s\x0b&\)<>\|]|zip2)|s(?:ctl|ybox))|y(?:ebug|obu))|c(?:[89]9|(?:a(?:t|ncel|psh)|c)[\s\x0b&\)<>\|]|mp|p(?:[\s\x0b&\)<>\|]|io|ulimit)|s(?:h|cli[\s\x0b&\)<>\|]|plit|vtool)|u(?:t[\s\x0b&\)<>\|]|psfilter)|ertbot|h(?:attr|(?:dir|root)[\s\x0b&\)<>\|]|e(?:ck_(?:by_ssh|cups|log|memory|raid|s(?:sl_cert|tatusfile))|f[\s\x0b&\)\-<>\|])|(?:flag|pas)s|g(?:passwd|rp)|mod|o(?:om|wn)|sh)|lang(?:[\s\x0b&\)<>\|]|\+\+)|o(?:(?:b|pro)c|(?:lumn|m(?:m(?:and)?|p(?:oser|ress)))[\s\x0b&\)<>\|]|w(?:say|think))|r(?:ash[\s\x0b&\)<>\|]|on(?:[\s\x0b&\)<>\|]|tab)))|d(?:(?:[du]|i(?:(?:alo)?g|r|ff)|a(?:sh|te))[\s\x0b&\)<>\|]|f|hclient|m(?:esg|idecode|setup)|o(?:as|(?:cker|ne)[\s\x0b&\)<>\|]|sbox)|pkg|vips)|e(?:(?:[bd]|cho)[\s\x0b&\)<>\|]|n(?:v(?:[\s\x0b&\)<>\|]|-update)|d(?:if|sw))|qn|s(?:[\s\x0b&\)<>h\|]|ac)|x(?:(?:ec)?[\s\x0b&\)<>\|]|iftool|p(?:(?:and|(?:ec|or)t)[\s\x0b&\)<>\|]|r))|2fsck|(?:asy_instal|va)l|fax|grep|macs)|f(?:(?:c|etch|lock|unction)[\s\x0b&\)<>\|]|d|g(?:rep)?|i(?:(?:n(?:d|ger)|sh)?[\s\x0b&\)<>\|]|le(?:[\s\x0b&\)<>\|]|test))|mt|tp(?:[\s\x0b&\)<>\|]|stats|who)|acter|o(?:ld[\s\x0b&\)<>\|]|reach)|ping)|g(?:c(?:c[^\s\x0b]|ore)|db|e(?:(?:m|tfacl)[\s\x0b&\)<>\|]|ni(?:e[\s\x0b&\)<>\|]|soimage))|hci?|i(?:(?:t|mp)[\s\x0b&\)<>\|]|nsh)|(?:o|awk)[\s\x0b&\)<>\|]|pg|r(?:c|ep[\s\x0b&\)<>\|]|oup(?:[\s\x0b&\)<>\|]|mod))|tester|unzip|z(?:cat|exe|ip))|h(?:(?:d|up|ash|i(?:ghlight|story))[\s\x0b&\)<>\|]|e(?:ad[\s\x0b&\)<>\|]|xdump)|ost(?:id|name)|ping3|t(?:digest|op|passwd))|i(?:d|p(?:6?tables|config)?|rb|conv|f(?:config|top)|nstall[\s\x0b&\)<>\|]|onice|spell)|j(?:js|q|ava[\s\x0b&\)<>\|]|exec|o(?:(?:bs|in)[\s\x0b&\)<>\|]|urnalctl)|runscript)|k(?:s(?:h|shell)|ill(?:[\s\x0b&\)<>\|]|all)|nife[\s\x0b&\)<>\|])|l(?:d(?:d?[\s\x0b&\)<>\|]|config)|(?:[np]|ynx)[\s\x0b&\)<>\|]|s(?:-F|b_release|cpu|hw|mod|of|pci|usb)?|ua(?:[\s\x0b&\)<>\|]|(?:la)?tex)|z(?:[\s\x0b&\)4<>\|]|4c(?:at)?|c(?:at|mp)|diff|[ef]?grep|less|m(?:a(?:dec|info)?|ore))|a(?:st(?:[\s\x0b&\)<>\|]|comm|log(?:in)?)|tex[\s\x0b&\)<>\|])|ess(?:[\s\x0b&\)<>\|]|echo|(?:fil|pip)e)|ftp(?:get)?|o(?:(?:ca(?:l|te)|ok)[\s\x0b&\)<>\|]|g(?:inctl|(?:nam|sav)e)|setup)|trace|wp-(?:d(?:ownload|ump)|mirror|request))|m(?:a(?:(?:n|ke)[\s\x0b&\)<>\|]|il(?:[\s\x0b&\)<>q\|]|x[\s\x0b&\)<>\|])|ster\.passwd|wk)|tr|(?:v|utt)[\s\x0b&\)<>\|]|k(?:dir[\s\x0b&\)<>\|]|fifo|nod|temp)|locate|o(?:squitto|unt[\s\x0b&\)<>\|])|sg(?:attrib|c(?:at|onv)|filter|merge|uniq)|ysql(?:admin|dump(?:slow)?|hotcopy|show)?)|n(?:c(?:[\s\x0b&\)<>\|]|\.(?:openbsd|traditional)|at)|e(?:t(?:[\s\x0b&\)<>\|]|(?:c|st)at|kit-ftp|plan)|ofetch)|(?:(?:ul)?l|ice)[\s\x0b&\)<>\|]|m(?:[\s\x0b&\)<>\|]|ap)|p(?:m[\s\x0b&\)<>\|]|ing)|a(?:no[\s\x0b&\)<>\|]|sm|wk)|o(?:de[\s\x0b&\)<>\|]|hup)|roff|s(?:enter|lookup|tat))|o(?:(?:d|ctave)[\s\x0b&\)<>\|]|nintr|p(?:en(?:ssl|v(?:pn|t))|kg))|p(?:a(?:(?:x|rted|tch)[\s\x0b&\)<>\|]|s(?:swd|te[\s\x0b&\)<>\|]))|d(?:b|f(?:la)?tex|ksh)|f(?:[\s\x0b&\)<>\|]|tp)|g(?:rep)?|hp(?:[\s\x0b&\)57<>\|]|-cgi)|i(?:(?:co?|ng)[\s\x0b&\)<>\|]|p[^\s\x0b]|dstat|gz)|k(?:g(?:_?info)?|exec|ill)|r(?:y?[\s\x0b&\)<>\|]|int(?:env|f[\s\x0b&\)<>\|]))|t(?:x|ar(?:diff|grep)?)|wd(?:\.db)?|xz|er(?:(?:f|ms)[\s\x0b&\)<>\|]|l(?:[\s\x0b&\)5<>\|]|sh))|opd|s(?:ed|ftp|ql)|u(?:ppet[\s\x0b&\)<>\|]|shd)|y(?:thon[23]|3?versions))|r(?:a(?:r[\s\x0b&\)<>\|]|k(?:e[\s\x0b&\)<>\|]|u))|c(?:p[\s\x0b&\)<>\|])?|e(?:(?:d(?:carpet)?|v|name|p(?:eat|lace))[\s\x0b&\)<>\|]|a(?:delf|lpath)|stic)|m(?:(?:dir)?[\s\x0b&\)<>\|]|user)|pm(?:[\s\x0b&\)<>\|]|db|(?:quer|verif)y)|bash|l(?:ogin|wrap)|nano|oute[\s\x0b&\)<>\|]|sync|u(?:by[^\s\x0b]|n-(?:mailcap|parts))|vi(?:ew|m))|s(?:c(?:p|(?:hed|r(?:een|ipt))[\s\x0b&\)<>\|])|e(?:(?:d|lf|rvice)[\s\x0b&\)<>\|]|t(?:(?:facl)?[\s\x0b&\)<>\|]|arch|env|sid)|ndmail)|(?:g|ash)[\s\x0b&\)<>\|]|h(?:(?:adow|ells)?[\s\x0b&\)<>\|]|\.distrib|u(?:f|tdown[\s\x0b&\)<>\|]))|s(?:[\s\x0b&\)<>\|]|h(?:[\s\x0b&\)<>\|]|-key(?:ge|sca)n|pass))|u(?:[\s\x0b&\)<>\|]|do)|vn|diff|ftp|l(?:eep[\s\x0b&\)<>\|]|sh)|mbclient|o(?:cat|elim|(?:rt|urce)[\s\x0b&\)<>\|])|p(?:lit[\s\x0b&\)<>\|]|wd\.db)|qlite3|t(?:art-stop-daemon|d(?:buf|err|in|out)|r(?:ace|ings[\s\x0b&\)<>\|]))|ys(?:ctl|tem(?:ctl|d-resolve)))|t(?:a(?:c|r[\s\x0b&\)<>\|]|il[\s\x0b&\)<>f\|]|sk(?:[\s\x0b&\)<>\|]|set))|bl|c(?:p(?:[\s\x0b&\)<>\|]|dump|ing|traceroute)|l?sh)|e(?:[ex][\s\x0b&\)<>\|]|lnet)|i(?:c[\s\x0b&\)<>\|]|me(?:datectl|out[\s\x0b&\)<>\|]))|o(?:p|uch[\s\x0b&\)<>\|])|ftp|mux|r(?:aceroute6?|off)|shark)|u(?:dp|l(?:imit)?[\s\x0b&\)<>\|]|n(?:ame|(?:compress|s(?:et|hare))[\s\x0b&\)<>\|]|expand|iq|l(?:ink[\s\x0b&\)<>\|]|z(?:4|ma))|(?:pig|x)z|rar|z(?:ip[\s\x0b&\)<>\|]|std))|pdate-alternatives|ser(?:(?:ad|mo)d|del)|u(?:de|en)code)|v(?:i(?:m(?:[\s\x0b&\)<>\|]|diff)|ew[\s\x0b&\)<>\|]|gr|pw|rsh|sudo)|algrind|olatility[\s\x0b&\)<>\|])|w(?:c|a(?:ll|tch)[\s\x0b&\)<>\|]|h(?:iptail[\s\x0b&\)<>\|]|o(?:ami|is))|i(?:reshark|sh[\s\x0b&\)<>\|]))|x(?:(?:x|pa)d|z(?:[\s\x0b&\)<>\|]|c(?:at|mp)|d(?:ec|iff)|[ef]?grep|less|more)|args|e(?:la)?tex|mo(?:dmap|re)|term)|y(?:(?:e(?:s|lp)|arn)[\s\x0b&\)<>\|]|um)|z(?:ip(?:[\s\x0b&\)<>\|]|c(?:loak|mp)|details|grep|info|(?:merg|not)e|split|tool)|s(?:h|oelim|td(?:(?:ca|m)t|grep|less)?)|athura|c(?:at|mp)|diff|e(?:grep|ro[\s\x0b&\)<>\|])|f?grep|less|more|run|ypper))" \ - "id:932239,\ - phase:1,\ - block,\ - capture,\ - t:none,\ - msg:'Remote Command Execution: Unix Command Injection found in user-agent or referer header',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# [ Unix shell snippets ] -# -# Detect some common sequences found in shell commands and scripts. -# -# Some commands which were restricted in earlier rules due to FP, -# have been added here with their full path, in order to catch some -# cases where the full path is sent. -# -# Rule relations: -# -# .932160 (base rule, PL1, unix shell commands with full path) -# ..932161 (stricter sibling, PL2, unix shell commands with full path in User-Agent and Referer request headers) -# -SecRule REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer "@pmFromFile unix-shell.data" \ - "id:932161,\ - phase:1,\ - block,\ - capture,\ - t:none,t:cmdLine,t:normalizePath,\ - msg:'Remote Command Execution: Unix Shell Code Found in REQUEST_HEADERS',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:932015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:932016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" -# -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -# [ Unix command injection ] +# Missing Unix commands have been added to a new word list i.e. +# util/regexp-assemble/regexp-932106.txt +# These commands may have a higher risk of false positives. +# Therefore, they have been split off to a separate rule in PL3. +# For explanation of this rule, see rule 932100. # -# This rule targets pefix + commans that are prone to false positive detection at PL3. +# To rebuild the word list regexp: +# cd util/regexp-assemble +# cat regexp-932106.txt | ./regexp-cmdline.py unix | ./regexp-assemble.pl # -# Rule relations: +# Then insert the assembled regexp into this template: # -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) +# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]* +# [regexp assembled from util/regexp-assemble/regexp-932106.txt] +# \b" \ # -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932232.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932232 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:(?:(?:a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?2[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?f|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|s)|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o|[\s\x0b&\),<>\|].*))\b" \ - "id:932232,\ +# This rule is a stricter sibling of rule 932100. + +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:;|\{|\||\|\||&|&&|\n|\r|\$\(|\$\(\(|`|\${|<\(|>\(|\(\s*\))\s*(?:{|\s*\(\s*|\w+=(?:[^\s]*|\$.*|\$.*|<.*|>.*|\'.*\'|\".*\")\s+|!\s*|\$)*\s*(?:'|\")*(?:[\?\*\[\]\(\)\-\|+\w'\"\./\\\\]+/)?[\\\\'\"]*(?:(?:(?:a[\\\\'\"]*p[\\\\'\"]*t[\\\\'\"]*i[\\\\'\"]*t[\\\\'\"]*u[\\\\'\"]*d|u[\\\\'\"]*p[\\\\'\"]*2[\\\\'\"]*d[\\\\'\"]*a[\\\\'\"]*t)[\\\\'\"]*e|d[\\\\'\"]*n[\\\\'\"]*f|v[\\\\'\"]*i)[\\\\'\"]*(?:\s|<|>).*|p[\\\\'\"]*(?:a[\\\\'\"]*c[\\\\'\"]*m[\\\\'\"]*a[\\\\'\"]*n[\\\\'\"]*(?:\s|<|>).*|w[\\\\'\"]*d|s)|w[\\\\'\"]*(?:(?:\s|<|>).*|h[\\\\'\"]*o))\b" \ + "id:932106,\ phase:2,\ block,\ capture,\ @@ -1568,129 +674,15 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - -# [ Unix command injection ] -# -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932237.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932237 -# -SecRule REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer "@rx (?i)\b(?:7z[arx]?|(?:(?:GE|POS)T|HEAD)[\s\x0b&\)<>\|]|a(?:(?:b|w[ks]|l(?:ias|pine)|xel)[\s\x0b&\)<>\|]|pt(?:(?:itude)?[\s\x0b&\)<>\|]|-get)|r(?:[\s\x0b&\)<>j\|]|(?:p|ch)[\s\x0b&\)<>\|]|ia2c)|s(?:h?[\s\x0b&\)<>\|]|cii(?:-xfr|85)|pell)|t(?:[\s\x0b&\)<>\|]|obm)|dd(?:group|user)|getty|nsible)|b(?:z(?:z[\s\x0b&\)<>\|]|c(?:at|mp)|diff|e(?:grep|xe)|f?grep|ip2(?:recover)?|less|more)|a(?:s(?:e(?:32|64|n(?:ame[\s\x0b&\)<>\|]|c))|h[\s\x0b&\)<>\|])|tch[\s\x0b&\)<>\|])|lkid|pftrace|r(?:eaksw|idge[\s\x0b&\)<>\|])|sd(?:cat|iff|tar)|u(?:iltin|n(?:dler[\s\x0b&\)<>\|]|zip2)|s(?:ctl|ybox))|y(?:ebug|obu))|c(?:[89]9|(?:a(?:t|ncel|psh)|c)[\s\x0b&\)<>\|]|mp|p(?:[\s\x0b&\)<>\|]|io|ulimit)|s(?:h|cli[\s\x0b&\)<>\|]|plit|vtool)|u(?:t[\s\x0b&\)<>\|]|psfilter)|ertbot|h(?:attr|(?:dir|root)[\s\x0b&\)<>\|]|e(?:ck_(?:by_ssh|cups|log|memory|raid|s(?:sl_cert|tatusfile))|f[\s\x0b&\)\-<>\|])|(?:flag|pas)s|g(?:passwd|rp)|mod|o(?:om|wn)|sh)|lang(?:[\s\x0b&\)<>\|]|\+\+)|o(?:(?:b|pro)c|(?:lumn|m(?:m(?:and)?|p(?:oser|ress)))[\s\x0b&\)<>\|]|w(?:say|think))|r(?:ash[\s\x0b&\)<>\|]|on(?:[\s\x0b&\)<>\|]|tab)))|d(?:(?:[du]|i(?:(?:alo)?g|r|ff)|a(?:sh|te))[\s\x0b&\)<>\|]|n?f|hclient|m(?:esg|idecode|setup)|o(?:as|(?:cker|ne)[\s\x0b&\)<>\|]|sbox)|pkg|vips)|e(?:(?:[bd]|cho)[\s\x0b&\)<>\|]|n(?:v(?:[\s\x0b&\)<>\|]|-update)|d(?:if|sw))|qn|s(?:[\s\x0b&\)<>h\|]|ac)|x(?:(?:ec)?[\s\x0b&\)<>\|]|iftool|p(?:(?:and|(?:ec|or)t)[\s\x0b&\)<>\|]|r))|2fsck|(?:asy_instal|va)l|fax|grep|macs)|f(?:(?:c|etch|lock|unction)[\s\x0b&\)<>\|]|d|g(?:rep)?|i(?:(?:n(?:d|ger)|sh)?[\s\x0b&\)<>\|]|le(?:[\s\x0b&\)<>\|]|test))|mt|tp(?:[\s\x0b&\)<>\|]|stats|who)|acter|o(?:ld[\s\x0b&\)<>\|]|reach)|ping)|g(?:c(?:c[^\s\x0b]|ore)|db|e(?:(?:m|tfacl)[\s\x0b&\)<>\|]|ni(?:e[\s\x0b&\)<>\|]|soimage))|hci?|i(?:(?:t|mp)[\s\x0b&\)<>\|]|nsh)|(?:o|awk)[\s\x0b&\)<>\|]|pg|r(?:c|ep[\s\x0b&\)<>\|]|oup(?:[\s\x0b&\)<>\|]|mod))|tester|unzip|z(?:cat|exe|ip))|h(?:(?:d|up|ash|i(?:ghlight|story))[\s\x0b&\)<>\|]|e(?:ad[\s\x0b&\)<>\|]|xdump)|ost(?:id|name)|ping3|t(?:digest|op|passwd))|i(?:d|p(?:6?tables|config)?|rb|conv|f(?:config|top)|nstall[\s\x0b&\)<>\|]|onice|spell)|j(?:js|q|ava[\s\x0b&\)<>\|]|exec|o(?:(?:bs|in)[\s\x0b&\)<>\|]|urnalctl)|runscript)|k(?:s(?:h|shell)|ill(?:[\s\x0b&\)<>\|]|all)|nife[\s\x0b&\)<>\|])|l(?:d(?:d?[\s\x0b&\)<>\|]|config)|(?:[np]|ynx)[\s\x0b&\)<>\|]|s(?:-F|b_release|cpu|hw|mod|of|pci|usb)?|ua(?:[\s\x0b&\)<>\|]|(?:la)?tex)|z(?:[\s\x0b&\)4<>\|]|4c(?:at)?|c(?:at|mp)|diff|[ef]?grep|less|m(?:a(?:dec|info)?|ore))|a(?:st(?:[\s\x0b&\)<>\|]|comm|log(?:in)?)|tex[\s\x0b&\)<>\|])|ess(?:[\s\x0b&\)<>\|]|echo|(?:fil|pip)e)|ftp(?:get)?|o(?:(?:ca(?:l|te)|ok)[\s\x0b&\)<>\|]|g(?:inctl|(?:nam|sav)e)|setup)|trace|wp-(?:d(?:ownload|ump)|mirror|request))|m(?:a(?:(?:n|ke)[\s\x0b&\)<>\|]|il(?:[\s\x0b&\)<>q\|]|x[\s\x0b&\)<>\|])|ster\.passwd|wk)|tr|(?:v|utt)[\s\x0b&\)<>\|]|k(?:dir[\s\x0b&\)<>\|]|fifo|nod|temp)|locate|o(?:(?:re|unt)[\s\x0b&\)<>\|]|squitto)|sg(?:attrib|c(?:at|onv)|filter|merge|uniq)|ysql(?:admin|dump(?:slow)?|hotcopy|show)?)|n(?:c(?:[\s\x0b&\)<>\|]|\.(?:openbsd|traditional)|at)|e(?:t(?:[\s\x0b&\)<>\|]|(?:c|st)at|kit-ftp|plan)|ofetch)|(?:(?:ul)?l|ice)[\s\x0b&\)<>\|]|m(?:[\s\x0b&\)<>\|]|ap)|p(?:m[\s\x0b&\)<>\|]|ing)|a(?:no[\s\x0b&\)<>\|]|sm|wk)|o(?:de[\s\x0b&\)<>\|]|hup)|roff|s(?:enter|lookup|tat))|o(?:(?:d|ctave)[\s\x0b&\)<>\|]|nintr|p(?:en(?:ssl|v(?:pn|t))|kg))|p(?:a(?:(?:x|cman|rted|tch)[\s\x0b&\)<>\|]|s(?:swd|te[\s\x0b&\)<>\|]))|d(?:b|f(?:la)?tex|ksh)|f(?:[\s\x0b&\)<>\|]|tp)|g(?:rep)?|hp(?:[\s\x0b&\)57<>\|]|-cgi)|i(?:(?:co?|ng)[\s\x0b&\)<>\|]|p[^\s\x0b]|dstat|gz)|k(?:g(?:_?info)?|exec|ill)|r(?:y?[\s\x0b&\)<>\|]|int(?:env|f[\s\x0b&\)<>\|]))|s(?:[\s\x0b&\)<>\|]|ed|ftp|ql)?|t(?:x|ar(?:diff|grep)?)|wd(?:\.db)?|xz|er(?:(?:f|ms)[\s\x0b&\)<>\|]|l(?:[\s\x0b&\)5<>\|]|sh))|opd|u(?:ppet[\s\x0b&\)<>\|]|shd)|y(?:thon[23]|3?versions))|r(?:a(?:r[\s\x0b&\)<>\|]|k(?:e[\s\x0b&\)<>\|]|u))|c(?:p[\s\x0b&\)<>\|])?|e(?:(?:d(?:carpet)?|v|name|p(?:eat|lace))[\s\x0b&\)<>\|]|a(?:delf|lpath)|stic)|m(?:(?:dir)?[\s\x0b&\)<>\|]|user)|pm(?:[\s\x0b&\)<>\|]|db|(?:quer|verif)y)|bash|l(?:ogin|wrap)|nano|oute[\s\x0b&\)<>\|]|sync|u(?:by[^\s\x0b]|n-(?:mailcap|parts))|vi(?:ew|m))|s(?:c(?:p|(?:hed|r(?:een|ipt))[\s\x0b&\)<>\|])|e(?:(?:d|lf|rvice)[\s\x0b&\)<>\|]|t(?:(?:facl)?[\s\x0b&\)<>\|]|arch|env|sid)|ndmail)|(?:g|ash)[\s\x0b&\)<>\|]|h(?:(?:adow|ells)?[\s\x0b&\)<>\|]|\.distrib|u(?:f|tdown[\s\x0b&\)<>\|]))|s(?:[\s\x0b&\)<>\|]|h(?:[\s\x0b&\)<>\|]|-key(?:ge|sca)n|pass))|u(?:[\s\x0b&\)<>\|]|do)|vn|diff|ftp|l(?:eep[\s\x0b&\)<>\|]|sh)|mbclient|o(?:cat|elim|(?:rt|urce)[\s\x0b&\)<>\|])|p(?:lit[\s\x0b&\)<>\|]|wd\.db)|qlite3|t(?:art-stop-daemon|d(?:buf|err|in|out)|r(?:ace|ings[\s\x0b&\)<>\|]))|ys(?:ctl|tem(?:ctl|d-resolve)))|t(?:a(?:c|r[\s\x0b&\)<>\|]|il[\s\x0b&\)<>f\|]|sk(?:[\s\x0b&\)<>\|]|set))|bl|c(?:p(?:[\s\x0b&\)<>\|]|dump|ing|traceroute)|l?sh)|e(?:[ex][\s\x0b&\)<>\|]|lnet)|i(?:c[\s\x0b&\)<>\|]|me(?:(?:out)?[\s\x0b&\)<>\|]|datectl))|o(?:p|uch[\s\x0b&\)<>\|])|ftp|mux|r(?:aceroute6?|off)|shark)|u(?:dp|l(?:imit)?[\s\x0b&\)<>\|]|n(?:ame|(?:compress|s(?:et|hare))[\s\x0b&\)<>\|]|expand|iq|l(?:ink[\s\x0b&\)<>\|]|z(?:4|ma))|(?:pig|x)z|rar|z(?:ip[\s\x0b&\)<>\|]|std))|p(?:2date[\s\x0b&\)<>\|]|date-alternatives)|ser(?:(?:ad|mo)d|del)|u(?:de|en)code)|v(?:i(?:(?:ew)?[\s\x0b&\)<>\|]|m(?:[\s\x0b&\)<>\|]|diff)|gr|pw|rsh|sudo)|algrind|olatility[\s\x0b&\)<>\|])|w(?:[\s\x0b&\)<>c\|]|h(?:o(?:[\s\x0b&\)<>\|]|ami|is)?|iptail[\s\x0b&\)<>\|])|a(?:ll|tch)[\s\x0b&\)<>\|]|i(?:reshark|sh[\s\x0b&\)<>\|]))|x(?:(?:x|pa)d|z(?:[\s\x0b&\)<>\|]|c(?:at|mp)|d(?:ec|iff)|[ef]?grep|less|more)|args|e(?:la)?tex|mo(?:dmap|re)|term)|y(?:(?:e(?:s|lp)|arn)[\s\x0b&\)<>\|]|um)|z(?:ip(?:[\s\x0b&\)<>\|]|c(?:loak|mp)|details|grep|info|(?:merg|not)e|split|tool)|s(?:h|oelim|td(?:(?:ca|m)t|grep|less)?)|athura|c(?:at|mp)|diff|e(?:grep|ro[\s\x0b&\)<>\|])|f?grep|less|more|run|ypper))(?:\b|[^0-9A-Z_a-z])" \ - "id:932237,\ - phase:1,\ - block,\ - capture,\ - t:none,t:cmdLine,t:normalizePath,\ - msg:'Remote Command Execution: Unix Shell Code Found in REQUEST_HEADERS',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - -# [ Unix command injection ] -# -# Rule relations: -# -# .932230 (base rule, PL1, targets prefix + two and three character commands) -# ..932231 (stricter sibling, PL2, targets prefix + the source shortcut command) -# ..932232 (stricter sibling, PL3, targets prefix + additional command words) -# .932235 (base rule, PL1, targets prefix + known command word of length > 3 without evasion) -# -# .932250 (base rule, PL1, targets two and three character commands) -# .932260 (base rule, PL1, targets known command word of length > 3 without evasion) -# -# .932240 (generic detection, PL2, targets generic evasion attempts) -# .932236 (stricter sibling of 932230, 932235, 932250, 932260, PL2, -# - with and without prefix -# - words of any length) -# ..932239 (sibling of 932236, PL2, -# - with and without prefix -# - words of any length -# - targets request headers user-agent and referer only -# - excluded words: known user-agents) -# ..932238 (stricter sibling of 932236, PL3, -# - no excluded words) -# .932237 (stricter sibling of 932230, 932235, 932250, 932260, PL3, -# - targets request headers user-agent and referer only -# - without prefix -# - with word boundaries -# - words of any length -# - excluded words: known user-agents) -# -# -# Regular expression generated from regex-assembly/932238.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932238 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/*|REQUEST_HEADERS:Referer|REQUEST_HEADERS:User-Agent "@rx (?i)(?:^|b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?s[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?y[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?b[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?x|c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|e[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?v|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?l)|[ls][\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?r[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p|t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e(?:[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)?|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?h|[\n\r;=`\{]|\|\|?|&&?|\$(?:\(\(?|[\[\{])|<(?:\(|<<)|>\(|\([\s\x0b]*\))[\s\x0b]*(?:[\$\{]|(?:[\s\x0b]*\(|!)[\s\x0b]*|[0-9A-Z_a-z]+=(?:[^\s\x0b]*|\$(?:.*|.*)|[<>].*|'.*'|\".*\")[\s\x0b]+)*[\s\x0b]*[\"']*(?:[\"'-\+\--9\?A-\]_a-z\|]+/)?[\"'\x5c]*(?:(?:(?:a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d|u[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?2[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?t)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?e|v[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?i)[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|d[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?f|p[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?c[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?m[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?a[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?n[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?[\s\x0b&\),<>\|].*|s)|w[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?(?:h[\"'\)\[\x5c]*(?:(?:(?:\|\||&&)[\s\x0b]*)?\$[!#\(\*\-0-9\?@_a-\{]*)?\x5c?o|[\s\x0b&\),<>\|].*))" \ - "id:932238,\ - phase:2,\ - block,\ - capture,\ - t:none,t:cmdLine,t:normalizePath,\ - msg:'Remote Command Execution: Unix Shell Code Found in REQUEST_HEADERS',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # # -=[ Bypass Rule 930120 (wildcard) ]=- @@ -1702,169 +694,32 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # In some other cases, it could be bypassed even if the Paranoia Level is set to 3. # Please, keep in mind that this rule could lead to many false positives. # -# The following two blog posts explain the evasions this rule is designed to detect: -# - https://medium.com/secjuice/waf-evasion-techniques-718026d693d8 -# - https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0 - -SecRule ARGS "@rx /(?:[?*]+[a-z/]+|[a-z/]+[?*]+)" \ +SecRule ARGS "@rx (?:/|\\\\)(?:[\?\*]+[a-z/\\\\]+|[a-z/\\\\]+[\?\*]+)" \ "id:932190,\ phase:2,\ block,\ capture,\ - t:none,t:urlDecodeUni,t:normalizePath,t:cmdLine,\ + t:none,t:urlDecode,t:urlDecodeUni,t:normalizePath,t:cmdLine,\ msg:'Remote Command Execution: Wildcard bypass technique attempt',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-shell',\ tag:'platform-unix',\ tag:'attack-rce',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/88',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - - -# -=[ SMTP commands ]=- -# -# This rule prevents execution of SMTP related system commands. -# -# These commands may have a higher risk of false positives. -# For explanation of this rule, see above rule 932300. -# -# Rule 932301 is a stricter sibling of rule 932300. -# -# Regular expression generated from regex-assembly/932301.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932301 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \r\n.*?\b(?:DATA|QUIT|HELP(?: .{1,255})?)" \ - "id:932301,\ - phase:2,\ - block,\ - t:none,t:escapeSeqDecode,\ - msg:'Remote Command Execution: SMTP Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/137/134',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" -# =[ IMAP4 Command Execution ]= +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:932017,phase:1,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:932018,phase:2,pass,nolog,skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" # -# This rule prevents execution of IMAP4 related system commands. -# -# These commands may have a higher risk of false positives. -# For explanation of this rule, see above rule 932310. -# -# Rule 932311 is a stricter sibling of rule 932310. -# -# Regular expression generated from regex-assembly/932311.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932311 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?is)\r\n[0-9A-Z_a-z]{1,50}\b (?:C(?:(?:REATE|OPY [\*,0-:]+) [\"#%&\*\--9A-Z\x5c_a-z]+|APABILITY|HECK|LOSE)|DELETE [\"#%&\*\-\.0-9A-Z\x5c_a-z]+|EX(?:AMINE [\"#%&\*\-\.0-9A-Z\x5c_a-z]+|PUNGE)|FETCH [\*,0-:]+|L(?:IST [\"#\*\--9A-Z\x5c_a-z~]+? [\"#%&\*\--9A-Z\x5c_a-z]+|OG(?:IN [\-\.0-9@_a-z]{1,40} .*?|OUT))|RENAME [\"#%&\*\--9A-Z\x5c_a-z]+? [\"#%&\*\--9A-Z\x5c_a-z]+|S(?:E(?:LECT [\"#%&\*\--9A-Z\x5c_a-z]+|ARCH(?: CHARSET [\-\.0-9A-Z_a-z]{1,40})? (?:(KEYWORD \x5c)?(?:A(?:LL|NSWERED)|BCC|D(?:ELETED|RAFT)|(?:FLAGGE|OL)D|RECENT|SEEN|UN(?:(?:ANSWER|FLAGG)ED|D(?:ELETED|RAFT)|SEEN)|NEW)|(?:BODY|CC|FROM|HEADER .{1,100}|NOT|OR .{1,255}|T(?:EXT|O)) .{1,255}|LARGER [0-9]{1,20}|[\*,0-:]+|(?:BEFORE|ON|S(?:ENT(?:(?:BEFOR|SINC)E|ON)|INCE)) \"?[0-9]{1,2}-[0-9A-Z_a-z]{3}-[0-9]{4}\"?|S(?:MALLER [0-9]{1,20}|UBJECT .{1,255})|U(?:ID [\*,0-:]+?|NKEYWORD \x5c(Seen|(?:Answer|Flagg)ed|D(?:eleted|raft)|Recent))))|T(?:ORE [\*,0-:]+? [\+\-]?FLAGS(?:\.SILENT)? (?:\(\x5c[a-z]{1,20}\))?|ARTTLS)|UBSCRIBE [\"#%&\*\--9A-Z\x5c_a-z]+)|UN(?:SUBSCRIBE [\"#%&\*\--9A-Z\x5c_a-z]+|AUTHENTICATE)|NOOP)" \ - "id:932311,\ - phase:2,\ - block,\ - t:none,t:escapeSeqDecode,\ - msg:'Remote Command Execution: IMAP Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/137/134',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - -# =[ POP3 Command Execution ]= -# -# This rule prevents execution of POP3 related system commands. -# -# These commands may have a higher risk of false positives. -# For explanation of this rule, see above rule 932320. -# -# Rule 932321 is a stricter sibling of rule 932320. -# -# Regular expression generated from regex-assembly/932321.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 932321 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \r\n.*?\b(?:(?:QUI|STA|RSE)T|NOOP|CAPA)" \ - "id:932321,\ - phase:2,\ - block,\ - t:none,t:escapeSeqDecode,\ - msg:'Remote Command Execution: POP3 Command Execution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/137/134',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - - -# =[ Unix shell history invocation ]= -# -# This rule is a stricter sibling of 932330. -# Shell history can also be invoked by providing an absolute position: '!1' or by repeating the last command '!!'. -# The latter might seem harmless as you would expect that it already requires a successful exploitation, but it is a threat in disguise. -# -# Imagine the following requests: -# GET /?rce=c -# GET /?rce=!!!! -# The last request will invoke /usr/bin/cc, which is otherwise blocked by 932250. -# -# Neither !1 nor !! is necessarily valid speech, but blocking either of them is much more likely to cause false-positives than 932330. -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx !(?:\d|!)" \ - "id:932331,\ - phase:2,\ - block,\ - t:none,\ - msg:'Remote Command Execution: Unix shell history invocation',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-shell',\ - tag:'platform-unix',\ - tag:'attack-rce',\ - tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/88',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:932017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:932018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-932-APPLICATION-ATTACK-RCE" -# -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf index 2af7d0a4a..707ed45b1 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,18 +14,18 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:933011,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:933012,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # # -=[ PHP Injection Attacks ]=- # # [ References ] -# https://rips-scanner.sourceforge.net/ -# https://wiki.owasp.org/index.php/PHP_Top_5#P1:_Remote_Code_Executionh +# http://rips-scanner.sourceforge.net/ +# https://www.owasp.org/index.php/PHP_Top_5#P1:_Remote_Code_Executionh # # @@ -44,12 +44,12 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:933012,phase:2,pass,nolog,tag:'O # Therefore, that pattern is now checked by rule 933190 in paranoia levels # 3 or higher. # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)<\?(?:[^x]|x(?:[^m]|m(?:[^l]|l(?:[^\s\x0b]|[\s\x0b]+[^a-z]|$)))|$|php)|\[[/\x5c]?php\]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:<\?(?:[^x]|x[^m]|xm[^l]|xml[^\s]|xml$|$)|<\?php|\[(?:\/|\\\\)?php\])" \ "id:933100,\ phase:2,\ block,\ capture,\ - t:none,\ + t:none,t:urlDecodeUni,t:lowercase,\ msg:'PHP Injection Attack: PHP Open Tag Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -59,10 +59,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [ PHP Script Uploads ] @@ -71,7 +72,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # (.php, .phps, .phtml, .php5 etc). # # Many application contain Unrestricted File Upload vulnerabilities. -# https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload +# https://www.owasp.org/index.php/Unrestricted_File_Upload # # Attackers may use such a vulnerability to achieve remote code execution # by uploading a .php file. If the upload storage location is predictable @@ -79,13 +80,13 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # .php file and have the code within it executed on the server. # # Also block files with just dot (.) characters after the extension: -# https://www.rapid7.com/blog/post/2013/08/15/time-to-patch-joomla/ +# https://community.rapid7.com/community/metasploit/blog/2013/08/15/time-to-patch-joomla # # Some AJAX uploaders use the nonstandard request headers X-Filename, # X_Filename, or X-File-Name to transmit the file name to the server; # scan these request headers as well as multipart/form-data file names. # -SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.ph(?:p\d*|tml|ar|ps|t|pt)\.*$" \ +SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.(?:php\d*|phtml)\.*$" \ "id:933110,\ phase:2,\ block,\ @@ -100,10 +101,11 @@ SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEAD tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -114,9 +116,9 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME phase:2,\ block,\ capture,\ - t:none,t:normalisePath,\ + t:none,t:urlDecodeUni,t:normalisePath,t:lowercase,\ msg:'PHP Injection Attack: Configuration Directive Found',\ - logdata:'Matched Data: %{TX.1} found within %{TX.933120_MATCHED_VAR_NAME}: %{TX.933120_MATCHED_VAR}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ @@ -124,17 +126,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.933120_matched_var=%{MATCHED_VAR}',\ - setvar:'tx.933120_matched_var_name=%{MATCHED_VAR_NAME}',\ chain" - SecRule MATCHED_VARS "@rx \b([^\s]+)\s*=" \ + SecRule MATCHED_VARS "@pm =" \ "capture,\ - chain" - SecRule TX:1 "@pmFromFile php-config-directives.data" \ - "setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + ctl:auditLogParts=+E,\ + setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -145,7 +144,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME phase:2,\ block,\ capture,\ - t:none,t:normalisePath,t:urlDecodeUni,\ + t:none,t:normalisePath,t:urlDecodeUni,t:lowercase,\ msg:'PHP Injection Attack: Variables Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -155,10 +154,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -191,10 +191,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -205,15 +206,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # could lead to RCE as describled by Sam Thomas at BlackHat USA 2018 (https://bit.ly/2yaKV5X), even # wrappers like zlib://, glob://, rar://, zip://, etc... could lead to LFI and expect:// to RCE. # -# Valid PHP wrappers can be found in the PHP documentation here: -# https://www.php.net/manual/en/wrappers.php -# -# Regular expression generated from regex-assembly/933200.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 933200 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:bzip2|expect|glob|ogg|(?:ph|r)ar|ssh2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?|z(?:ip|lib))://" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:zlib|glob|phar|ssh2|rar|ogg|expect|zip)://" \ "id:933200,\ phase:2,\ block,\ @@ -227,10 +220,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -253,7 +247,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # false positives in natural language or other contexts. # Examples: 'chr', 'eval'. # To mitigate false positives, a regexp looks for PHP function syntax, e.g. 'eval()'. -# Regexp is generated from function names in /regexp-assemble/data/933160.ra +# Regexp is generated from function names in util/regexp-assemble/regexp-933160.data # # - Rule 933151: ~1300 words of lesser importance. This includes most PHP functions and keywords. # Examples: 'addslashes', 'array_diff'. @@ -267,7 +261,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # Examples: 'abs', 'cos'. # To mitigate false positives, a regexp matches on function syntax, e.g. 'abs()'. # This rule only runs in paranoia level 3 or higher. -# Regexp is generated from function names in /regexp-assemble/data/933161.ra +# Regexp is generated from function names in util/regexp-assemble/regexp-933161.data # @@ -284,7 +278,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F phase:2,\ block,\ capture,\ - t:none,\ + t:none,t:lowercase,\ msg:'PHP Injection Attack: High-Risk PHP Function Name Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -294,10 +288,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -321,17 +316,18 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F # system //comment \n (...) # system #comment \n (...) # -# This rule is triggered by the following exploits as well, as they include the string 'exec(...)': +# This rule is also triggered by the following exploit(s): # [ Apache Struts vulnerability CVE-2017-9791 - Exploit tested: https://www.exploit-db.com/exploits/42324 ] # [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45260 ] # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/933160.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 933160 +# Regexp generated from util/regexp-assemble/regexp-933160.data using Regexp::Assemble. +# See https://coreruleset.org/20190826/optimizing-regular-expressions/ for usage. # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b\(?[\"']*(?:assert(?:_options)?|c(?:hr|reate_function)|e(?:val|x(?:ec|p))|file(?:group)?|glob|i(?:mage(?:gif|(?:jpe|pn)g|wbmp|xbm)|s_a)|md5|o(?:pendir|rd)|p(?:assthru|open|rev)|(?:read|tmp)file|un(?:pac|lin)k|s(?:tat|ubstr|ystem))(?:/(?:\*.*\*/|/.*)|#.*|[\s\x0b\"])*[\"']*\)?[\s\x0b]*\(.*\)" \ +# Note that after assemble, PHP function syntax pre/postfix is added to the Regexp::Assemble +# output. Example: "@rx (?i)\bASSEMBLE_OUTPUT_HERE(?:\s|/\*.*\*/|//.*|#.*)*\(.*\)" +# +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:s(?:e(?:t(?:_(?:e(?:xception|rror)_handler|magic_quotes_runtime|include_path)|defaultstub)|ssion_s(?:et_save_handler|tart))|qlite_(?:(?:(?:unbuffered|single|array)_)?query|create_(?:aggregate|function)|p?open|exec)|tr(?:eam_(?:context_create|socket_client)|ipc?slashes|rev)|implexml_load_(?:string|file)|ocket_c(?:onnect|reate)|h(?:ow_sourc|a1_fil)e|pl_autoload_register|ystem)|p(?:r(?:eg_(?:replace(?:_callback(?:_array)?)?|match(?:_all)?|split)|oc_(?:(?:terminat|clos|nic)e|get_status|open)|int_r)|o(?:six_(?:get(?:(?:e[gu]|g)id|login|pwnam)|mk(?:fifo|nod)|ttyname|kill)|pen)|hp(?:_(?:strip_whitespac|unam)e|version|info)|g_(?:(?:execut|prepar)e|connect|query)|a(?:rse_(?:ini_file|str)|ssthru)|utenv)|r(?:unkit_(?:function_(?:re(?:defin|nam)e|copy|add)|method_(?:re(?:defin|nam)e|copy|add)|constant_(?:redefine|add))|e(?:(?:gister_(?:shutdown|tick)|name)_function|ad(?:(?:gz)?file|_exif_data|dir))|awurl(?:de|en)code)|i(?:mage(?:createfrom(?:(?:jpe|pn)g|x[bp]m|wbmp|gif)|(?:jpe|pn)g|g(?:d2?|if)|2?wbmp|xbm)|s_(?:(?:(?:execut|write?|read)ab|fi)le|dir)|ni_(?:get(?:_all)?|set)|terator_apply|ptcembed)|g(?:et(?:_(?:c(?:urrent_use|fg_va)r|meta_tags)|my(?:[gpu]id|inode)|(?:lastmo|cw)d|imagesize|env)|z(?:(?:(?:defla|wri)t|encod|fil)e|compress|open|read)|lob)|a(?:rray_(?:u(?:intersect(?:_u?assoc)?|diff(?:_u?assoc)?)|intersect_u(?:assoc|key)|diff_u(?:assoc|key)|filter|reduce|map)|ssert(?:_options)?)|h(?:tml(?:specialchars(?:_decode)?|_entity_decode|entities)|(?:ash(?:_(?:update|hmac))?|ighlight)_file|e(?:ader_register_callback|x2bin))|f(?:i(?:le(?:(?:[acm]tim|inod)e|(?:_exist|perm)s|group)?|nfo_open)|tp_(?:nb_(?:ge|pu)|connec|ge|pu)t|(?:unction_exis|pu)ts|write|open)|o(?:b_(?:get_(?:c(?:ontents|lean)|flush)|end_(?:clean|flush)|clean|flush|start)|dbc_(?:result(?:_all)?|exec(?:ute)?|connect)|pendir)|m(?:b_(?:ereg(?:_(?:replace(?:_callback)?|match)|i(?:_replace)?)?|parse_str)|(?:ove_uploaded|d5)_file|ethod_exists|ysql_query|kdir)|e(?:x(?:if_(?:t(?:humbnail|agname)|imagetype|read_data)|ec)|scapeshell(?:arg|cmd)|rror_reporting|val)|c(?:url_(?:file_create|exec|init)|onvert_uuencode|reate_function|hr)|u(?:n(?:serialize|pack)|rl(?:de|en)code|[ak]?sort)|(?:json_(?:de|en)cod|debug_backtrac|tmpfil)e|b(?:(?:son_(?:de|en)|ase64_en)code|zopen)|var_dump)(?:\s|/\*.*\*/|//.*|#.*)*\(.*\)" \ "id:933160,\ phase:2,\ block,\ @@ -346,10 +342,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -366,7 +363,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F # unserialize() call, resulting in an arbitrary PHP object(s) injection into the # application scope. # -# https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection +# https://www.owasp.org/index.php/PHP_Object_Injection # # In serialized form, PHP objects have the following format: # @@ -374,7 +371,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F # O:3:"Foo":0:{} # # Also detected are PHP objects with a custom unserializer: -# https://www.phpinternalsbook.com/php5/classes_objects/serialization.html +# http://www.phpinternalsbook.com/classes_objects/serialization.html # These have the following format: # # C:11:"ArrayObject":37:{x:i:0;a:1:{s:1:"a";s:1:"b";};m:a:0:{}} @@ -401,10 +398,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" @@ -456,24 +454,24 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # [ PHP Functions: Variable Function Prevent Bypass ] # # Referring to https://www.secjuice.com/php-rce-bypass-filters-sanitization-waf/ -# Regex test on https://regex101.com/r/x1tfXG/1 # the rule 933180 could be bypassed by using the following payloads: # -# - (system)('uname'); -# - (sy.(st).em)('uname'); -# - (string)"system"('uname'); -# - define('x', 'sys' . 'tem');(x)/* comment */('uname'); -# - $y = 'sys'.'tem';($y)('uname'); +# - (system)('uname') +# - (sy.(st).em)('uname') +# - (string)"system"('uname') +# - define('x', 'sys' . 'tem');(x)/* comment */('uname') +# - $y = 'sys'.'tem';($y)('uname') # - define('z', [['sys' .'tem']]);(z)[0][0]('uname'); -# - (system)(ls); +# - (system)(ls) # - (/**/system)(ls/**/); # - (['system'])[0]('uname'); # - (++[++system++][++0++])++{/*dsasd*/0}++(++ls++); @@ -483,17 +481,12 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F # - [ACME] this is a test (just a test) # - Test (with two) rounded (brackets) # -# Regular expression generated from regex-assembly/933210.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 933210 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\x0b\"'\-\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(\),\./;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\);" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:(?:\(|\[)[a-zA-Z0-9_.$\"'\[\](){}/*\s]+(?:\)|\])[0-9_.$\"'\[\](){}/*\s]*\([a-zA-Z0-9_.$\"'\[\](){}/*\s].*\)|\([\s]*string[\s]*\)[\s]*(?:\"|'))" \ "id:933210,\ phase:2,\ block,\ capture,\ - t:none,t:urlDecodeUni,t:replaceComments,t:removeWhitespace,\ + t:none,t:urlDecode,t:replaceComments,t:compressWhitespace,\ msg:'PHP Injection Attack: Variable Function Call Found',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ @@ -503,15 +496,16 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:933014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:933013,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:933014,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # # @@ -536,35 +530,32 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F phase:2,\ block,\ capture,\ - t:none,\ + t:none,t:lowercase,\ msg:'PHP Injection Attack: Medium-Risk PHP Function Name Found',\ - logdata:'Matched Data: %{TX.1} found within %{TX.933151_MATCHED_VAR_NAME}: %{TX.933151_MATCHED_VAR}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.933151_matched_var=%{MATCHED_VAR}',\ - setvar:'tx.933151_matched_var_name=%{MATCHED_VAR_NAME}',\ chain" - SecRule MATCHED_VARS "@rx \b([^\s]+)\s*[(]" \ + SecRule MATCHED_VARS "@pm (" \ "capture,\ - chain" - SecRule TX:1 "@pmFromFile php-function-names-933151.data" \ - "setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + ctl:auditLogParts=+E,\ + setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:933015,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:933016,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # # @@ -583,13 +574,12 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:933016,phase:2,pass,nolog,tag:'O # regex in this case to look for these values whereas in its sibling rule we use # @pmFromFile for flexibility and performance. # -# Regular expression generated from regex-assembly/933131.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 933131 +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl < regexp-933131.data # # This rule is a stricter sibling of rule 933130. -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx AUTH_TYPE|HTTP_(?:ACCEPT(?:_(?:CHARSET|ENCODING|LANGUAGE))?|CONNECTION|(?:HOS|USER_AGEN)T|KEEP_ALIVE|(?:REFERE|X_FORWARDED_FO)R)|ORIG_PATH_INFO|PATH_(?:INFO|TRANSLATED)|QUERY_STRING|REQUEST_URI" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:HTTP_(?:ACCEPT(?:_(?:ENCODING|LANGUAGE|CHARSET))?|(?:X_FORWARDED_FO|REFERE)R|(?:USER_AGEN|HOS)T|CONNECTION|KEEP_ALIVE)|PATH_(?:TRANSLATED|INFO)|ORIG_PATH_INFO|QUERY_STRING|REQUEST_URI|AUTH_TYPE)" \ "id:933131,\ phase:2,\ block,\ @@ -601,13 +591,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # @@ -628,12 +619,13 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # [ Apache Struts vulnerability CVE-2018-11776 - Exploit tested: https://www.exploit-db.com/exploits/45262 ] # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/933161.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 933161 +# Regexp generated from util/regexp-assemble/regexp-933161.data using Regexp::Assemble. +# See https://coreruleset.org/20190826/optimizing-regular-expressions/ for usage. # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:a(?:bs|s(?:in|sert(?:_options)?))|basename|c(?:h(?:eckdate|r(?:oot)?)|o(?:(?:mpac|(?:nsta|u)n)t|py|sh?)|r(?:eate_function|ypt)|urrent)|d(?:ate|e(?:coct|fined?)|ir)|e(?:nd|val|x(?:ec|p(?:lode)?|tract))|f(?:ile(?:(?:[acm]tim|inod|siz|typ)e|group|owner|perms)?|l(?:o(?:ck|or)|ush))|glob|h(?:ash|eader)|i(?:date|m(?:age(?:gif|(?:jpe|pn)g|wbmp|xbm)|plode)|s_a)|key|l(?:ink|og)|m(?:a(?:il|x)|d5|in)|n(?:ame|ext)|o(?:pendir|rd)|p(?:a(?:ck|ss(?:thru)?)|i|o(?:pen|w)|rev)|r(?:an(?:d|ge)|e(?:(?:adfil|nam)e|set)|ound)|s(?:(?:erializ|huffl)e|in|leep|(?:or|ta)t|ubstr|y(?:mlink|s(?:log|tem)))|t(?:an|(?:im|mpfil)e|ouch|rim)|u(?:cfirst|n(?:lin|pac)k)|virtual)(?:[\s\x0b]|/\*.*\*/|(?:#|//).*)*\(.*\)" \ +# Note that after assemble, PHP function syntax pre/postfix is added to the Regexp::Assemble +# output. Example: "@rx (?i)\bASSEMBLE_OUTPUT_HERE(?:\s|/\*.*\*/|//.*|#.*)*\(.*\)" +# +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:i(?:s(?:_(?:in(?:t(?:eger)?|finite)|n(?:u(?:meric|ll)|an)|(?:calla|dou)ble|s(?:calar|tring)|f(?:inite|loat)|re(?:source|al)|l(?:ink|ong)|a(?:rray)?|object|bool)|set)|n(?:(?:clud|vok)e|t(?:div|val))|(?:mplod|dat)e|conv)|s(?:t(?:r(?:(?:le|sp)n|coll)|at)|(?:e(?:rializ|ttyp)|huffl)e|i(?:milar_text|zeof|nh?)|p(?:liti?|rintf)|(?:candi|ubst)r|y(?:mlink|slog)|o(?:undex|rt)|leep|rand|qrt)|f(?:ile(?:(?:siz|typ)e|owner|pro)|l(?:o(?:atval|ck|or)|ush)|(?:rea|mo)d|t(?:ell|ok)|unction|close|gets|stat|eof)|c(?:h(?:o(?:wn|p)|eckdate|root|dir|mod)|o(?:(?:(?:nsta|u)n|mpac)t|sh?|py)|lose(?:dir|log)|(?:urren|ryp)t|eil)|e(?:x(?:(?:trac|i)t|p(?:lode)?)|a(?:ster_da(?:te|ys)|ch)|r(?:ror_log|egi?)|mpty|cho|nd)|l(?:o(?:g(?:1[0p])?|caltime)|i(?:nk(?:info)?|st)|(?:cfirs|sta)t|evenshtein|trim)|d(?:i(?:(?:skfreespac)?e|r(?:name)?)|e(?:fined?|coct)|(?:oubleva)?l|ate)|r(?:e(?:(?:quir|cod|nam)e|adlin[ek]|wind|set)|an(?:ge|d)|ound|sort|trim)|m(?:b(?:split|ereg)|i(?:crotime|n)|a(?:i[ln]|x)|etaphone|y?sql|hash)|u(?:n(?:(?:tain|se)t|iqid|link)|s(?:leep|ort)|cfirst|mask)|a(?:s(?:(?:se|o)rt|inh?)|r(?:sort|ray)|tan[2h]?|cosh?|bs)|t(?:e(?:xtdomain|mpnam)|a(?:int|nh?)|ouch|ime|rim)|h(?:e(?:ader(?:s_(?:lis|sen)t)?|brev)|ypot|ash)|p(?:a(?:thinfo|ck)|r(?:intf?|ev)|close|o[sw]|i)|g(?:et(?:t(?:ext|ype)|date)|mdate)|o(?:penlog|ctdec|rd)|b(?:asename|indec)|n(?:atsor|ex)t|k(?:sort|ey)|quotemeta|wordwrap|virtual|join)(?:\s|/\*.*\*/|//.*|#.*)*\(.*\)" \ "id:933161,\ phase:2,\ block,\ @@ -645,13 +637,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # @@ -687,13 +680,14 @@ SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEAD tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # [ PHP Closing Tag Found ] @@ -716,54 +710,20 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-php',\ tag:'platform-multi',\ tag:'attack-injection-php',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - - -# [ PHP Functions: Variable Function Prevent Bypass ] -# -# This rule is a stricter sibling of 933210. -# Unlike 933210, this rule will also match "this is a 'dog' (not a cat)", because the semi-colon at the end of the string is optional. -# This is useful for PHP evals where the semi-colon is already hardcoded: -# -# -# Any potential function calls not at the end of a string will require a semi-colon to form valid PHP, which is automatically covered by 933210. -# -# Regular expression generated from regex-assembly/933211.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 933211 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?:\((?:.+\)(?:[\"'][\-0-9A-Z_a-z]+[\"'])?\(.+|[^\)]*string[^\)]*\)[\s\x0b\"'\-\.0-9A-\[\]_a-\{\}]+\([^\)]*)|(?:\[[0-9]+\]|\{[0-9]+\}|\$[^\(\),\./;\x5c]+|[\"'][\-0-9A-Z\x5c_a-z]+[\"'])\(.+)\)(?:;|$)?" \ - "id:933211,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:replaceComments,t:removeWhitespace,\ - msg:'PHP Injection Attack: Variable Function Call Found',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-injection-php',\ tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.php_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:933018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:933017,phase:1,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:933018,phase:2,pass,nolog,skipAfter:END-REQUEST-933-APPLICATION-ATTACK-PHP" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf deleted file mode 100644 index 51625e23a..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf +++ /dev/null @@ -1,366 +0,0 @@ -# ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 -# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. -# -# The OWASP CRS is distributed under -# Apache Software License (ASL) version 2 -# Please see the enclosed LICENSE file for full details. -# ------------------------------------------------------------------------ - -# -# -= Paranoia Level 0 (empty) =- (apply unconditionally) -# - - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:934011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:934012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -# -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) -# - - -# [ NodeJS Insecure unserialization / generic RCE signatures ] -# -# Libraries performing insecure unserialization: -# - node-serialize: _$$ND_FUNC$$_ (CVE-2017-5941) -# - funcster: __js_function -# -# See: -# https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/ -# https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/ -# -# Some generic snippets used: -# - function() { -# - new Function( -# - eval( -# - String.fromCharCode( -# -# Last two are used by nodejsshell.py, -# https://github.com/ajinabraham/Node.Js-Security-Course/blob/master/nodejsshell.py -# -# As base64 is sometimes (but not always) used to encode serialized values, -# use multiMatch and t:base64decode. -# -# Regular expression generated from regex-assembly/934100.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 934100 -# -# Stricter sibling: 934101 -SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx _(?:\$\$ND_FUNC\$\$_|_js_function)|(?:\beval|new[\s\x0b]+Function[\s\x0b]*)\(|String\.fromCharCode|function\(\)\{|this\.constructor|module\.exports=|\([\s\x0b]*[^0-9A-Z_a-z]child_process[^0-9A-Z_a-z][\s\x0b]*\)|process(?:\.(?:(?:a(?:ccess|ppendfile|rgv|vailability)|c(?:aveats|h(?:mod|own)|(?:los|opyfil)e|p|reate(?:read|write)stream)|ex(?:ec(?:file)?|ists)|f(?:ch(?:mod|own)|data(?:sync)?|s(?:tat|ync)|utimes)|inodes|l(?:chmod|ink|stat|utimes)|mkd(?:ir|temp)|open(?:dir)?|r(?:e(?:ad(?:dir|file|link|v)?|name)|m)|s(?:pawn(?:file)?|tat|ymlink)|truncate|u(?:n(?:link|watchfile)|times)|w(?:atchfile|rite(?:file|v)?))(?:sync)?(?:\.call)?\(|binding|constructor|env|global|main(?:Module)?|process|require)|\[[\"'`](?:(?:a(?:ccess|ppendfile|rgv|vailability)|c(?:aveats|h(?:mod|own)|(?:los|opyfil)e|p|reate(?:read|write)stream)|ex(?:ec(?:file)?|ists)|f(?:ch(?:mod|own)|data(?:sync)?|s(?:tat|ync)|utimes)|inodes|l(?:chmod|ink|stat|utimes)|mkd(?:ir|temp)|open(?:dir)?|r(?:e(?:ad(?:dir|file|link|v)?|name)|m)|s(?:pawn(?:file)?|tat|ymlink)|truncate|u(?:n(?:link|watchfile)|times)|w(?:atchfile|rite(?:file|v)?))(?:sync)?|binding|constructor|env|global|main(?:Module)?|process|require)[\"'`]\])|(?:binding|constructor|env|global|main(?:Module)?|process|require)\[|console(?:\.(?:debug|error|info|trace|warn)(?:\.call)?\(|\[[\"'`](?:debug|error|info|trace|warn)[\"'`]\])|require(?:\.(?:resolve(?:\.call)?\(|main|extensions|cache)|\[[\"'`](?:(?:resolv|cach)e|main|extensions)[\"'`]\])" \ - "id:934100,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:jsDecode,t:removeWhitespace,t:base64Decode,t:urlDecodeUni,t:jsDecode,t:removeWhitespace,\ - msg:'Node.js Injection Attack 1/2',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-javascript',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'attack-injection-generic',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - multiMatch,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# -=[ SSRF Attacks ]=- -# -# We provide only partial protection to SSRF. DNS Rebinding attacks needs -# to be handled at application level, and even those might be difficult to catch. -# -# PL1 rules are based on common attacks on cloud providers, based on well-known URLs. -# -# -=[ References ]=- -# https://highon.coffee/blog/ssrf-cheat-sheet/ -# https://cwe.mitre.org/data/definitions/918.html -# https://capec.mitre.org/data/definitions/664.html) -# -# Preventing: https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html - -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@pmFromFile ssrf.data" \ - "id:934110,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Possible Server Side Request Forgery (SSRF) Attack: Cloud provider metadata URL in Parameter',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-ssrf',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/664',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# JavaScript prototype pollution injection attempts -# -# Example from https://hackerone.com/reports/869574 critical -# vulnerability in the TypeORM library: -# {"text":"a","title":{"__proto__":{"where":{"name":"sqlinjection","where":null}}}} -# -# Test cases are based on this list of payloads: -# https://github.com/BlackFan/client-side-prototype-pollution/blob/master/README.md -# -# See also: https://cwe.mitre.org/data/definitions/1321.html -# -# Note: only server-based (not DOM-based) attacks are covered here. -# Stricter sibling: 934131 - -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:__proto__|constructor\s*(?:\.|\[)\s*prototype)" \ - "id:934130,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:jsDecode,\ - msg:'JavaScript Prototype Pollution',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-javascript',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'attack-injection-generic',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1/180/77',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - multiMatch,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# [ Ruby generic RCE signatures ] -# -# Detects Ruby-based injection attacks. -# Example: Process.spawn("id") -# -# Regular expression generated from regex-assembly/934150.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 934150 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx Process[\s\x0b]*\.[\s\x0b]*spawn[\s\x0b]*\(" \ - "id:934150,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Ruby Injection Attack',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-ruby',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'attack-injection-generic',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# [ NodeJS DoS signatures ] -# -# NodeJS runs in a single thread, so any evaluated payloads that block execution can cause an easy DoS. -# This rule attempts to block e.g. while(true). -# -# Regular expression generated from regex-assembly/934160.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 934160 -# -SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx while[\s\x0b]*\([\s\x0b\(]*(?:!+(?:false|null|undefined|NaN|[\+\-]?0|\"{2}|'{2}|`{2})|(?:!!)*(?:(?:t(?:rue|his)|[\+\-]?(?:Infinity|[1-9][0-9]*)|new [A-Za-z][0-9A-Z_a-z]*|window|String|(?:Boolea|Functio)n|Object|Array)\b|\{.*\}|\[.*\]|\"[^\"]+\"|'[^']+'|`[^`]+`)).*\)" \ - "id:934160,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:jsDecode,t:base64Decode,t:urlDecodeUni,t:jsDecode,t:replaceComments,\ - msg:'Node.js DoS attack',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-javascript',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'attack-injection-generic',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - multiMatch,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# [ PHP data: scheme ] -# -# PHP supports the `data:` scheme without using `//` before the content-type. -# -# Regular expression generated from regex-assembly/934170.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 934170 -# -SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ^data:(?:(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)/(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\x0b]*;[\s\x0b]*(?:charset[\s\x0b]*=[\s\x0b]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\x0b-\"\(\),/:-\?\[-\]c\{\}]|c(?:[^!\"\(\),/:-\?\[-\]h\{\}]|h(?:[^!\"\(\),/:-\?\[-\]a\{\}]|a(?:[^!\"\(\),/:-\?\[-\]r\{\}]|r(?:[^!\"\(\),/:-\?\[-\]s\{\}]|s(?:[^!\"\(\),/:-\?\[-\]e\{\}]|e[^!\"\(\),/:-\?\[-\]t\{\}]))))))[^!\"\(\),/:-\?\[-\]\{\}]*[\s\x0b]*=[\s\x0b]*[^!\(\),/:-\?\[-\]\{\}]+);?)*(?:[\s\x0b]*,[\s\x0b]*(?:(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)/(?:\*|[^!\"\(\),/:-\?\[-\]\{\}]+)|\*)(?:[\s\x0b]*;[\s\x0b]*(?:charset[\s\x0b]*=[\s\x0b]*\"?(?:iso-8859-15?|utf-8|windows-1252)\b\"?|(?:[^\s\x0b-\"\(\),/:-\?\[-\]c\{\}]|c(?:[^!\"\(\),/:-\?\[-\]h\{\}]|h(?:[^!\"\(\),/:-\?\[-\]a\{\}]|a(?:[^!\"\(\),/:-\?\[-\]r\{\}]|r(?:[^!\"\(\),/:-\?\[-\]s\{\}]|s(?:[^!\"\(\),/:-\?\[-\]e\{\}]|e[^!\"\(\),/:-\?\[-\]t\{\}]))))))[^!\"\(\),/:-\?\[-\]\{\}]*[\s\x0b]*=[\s\x0b]*[^!\(\),/:-\?\[-\]\{\}]+);?)*)*" \ - "id:934170,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'PHP data scheme attack',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-ssrf',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:934013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:934014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -# -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) -# - -# This rule is a stricter sibling of 934100. -SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:close|exists|fork|(?:ope|spaw)n|re(?:ad|quire)|w(?:atch|rite))[\s\x0b]*\(" \ - "id:934101,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:jsDecode,t:base64Decode,t:urlDecodeUni,t:jsDecode,\ - msg:'Node.js Injection Attack 2/2',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-javascript',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'attack-injection-generic',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - multiMatch,\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -=[ SSRF Attacks ]=- -# -# PL2 rules adds SSRF capture for common evasion techniques. -# -# We add captures for these evasion techniques: (see source in util/regexp-assemble/data/regexp-934120.data) -# http://425.510.425.510/ Dotted decimal with overflow (already covered by RFI rule 931100) -# http://2852039166/ Dotless decimal - \d{10} -# http://7147006462/ Dotless decimal with overflow - \d{10} -# http://0xA9.0xFE.0xA9.0xFE/ Dotted hexadecimal - (?:0x[a-f0-9]{2}\.){3}0x[a-f0-9]{2} -# http://0xA9FEA9FE/ Dotless hexadecimal - 0x[a-f0-9]{8} -# http://0x41414141A9FEA9FE/ Dotless hexadecimal with overflow - 0x[a-f0-9]{16} -# http://0251.0376.0251.0376/ Dotted octal - Covered by the same below -# http://0251.00376.000251.0000376/ Dotted octal with padding - (?:0{1,4}\d{3}\.){3}0{1,4}\d{3}) -# http://169.254.43518/ - (?:\d{1,3}\.){2}\.\d{5} -# http://169.16689662/ - \d{1,3}\.\d{8} -# http://[::ffff:a9fe:a9fe] IPV6 Compressed - IPv6 regex from https://ihateregex.io/expr/ipv6/, with [0-9] converted to \d and with non-capturing groups (below) -# http://[0:0:0:0:0:ffff:a9fe:a9fe] IPV6 Expanded - (?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(?::0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(2[0-4]|1{0,1}\d){0,1}\d)\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)) -# http://[0:0:0:0:0:ffff:169.254.169.254] IPV6/IPV4 - ((?:[0-9a-fA-F]{1,4}:){6}(?:(25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}\d){0,1}\d)) -# http://[::] -# http://127.88.23.245:22/+&@google.com:80#+@google.com:80/ (already covered by RFI rule 931100) -# http://127.88.23.245:22/?@google.com:80/ (already covered by RFI rule 931100) -# http://127.88.23.245:22/#@www.google.com:80/ (already covered by RFI rule 931100) -# http://google.com:80\\@127.88.23.245:22/ (already covered by RFI rule 931100) -# http://google.com:80+&@127.88.23.245:22/#+@google.com:80/ -# http://google.com:80+&@google.com:80#+@127.88.23.245:22/ -# -# Regular expression generated from regex-assembly/934120.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 934120 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* "@rx (?i)((?:a(?:cap|f[ps]|ttachment)|b(?:eshare|itcoin|lob)|c(?:a(?:llto|p)|id|vs|ompress.(?:zlib|bzip2))|d(?:a(?:v|ta)|ict|n(?:s|tp))|e(?:d2k|xpect)|f(?:(?:ee)?d|i(?:le|nger|sh)|tps?)|g(?:it|o(?:pher)?|lob)|h(?:323|ttps?)|i(?:ax|cap|(?:ma|p)ps?|rc[6s]?)|ja(?:bbe)?r|l(?:dap[is]?|ocal_file)|m(?:a(?:ilto|ven)|ms|umble)|n(?:e(?:tdoc|ws)|fs|ntps?)|ogg|p(?:aparazzi|h(?:ar|p)|op(?:2|3s?)|r(?:es|oxy)|syc)|r(?:mi|sync|tm(?:f?p)?|ar)|s(?:3|ftp|ips?|m(?:[bs]|tps?)|n(?:ews|mp)|sh(?:2(?:.(?:s(?:hell|(?:ft|c)p)|exec|tunnel))?)?|vn(?:\+ssh)?)|t(?:e(?:amspeak|lnet)|ftp|urns?)|u(?:dp|nreal|t2004)|v(?:entrilo|iew-source|nc)|w(?:ebcal|ss?)|x(?:mpp|ri)|zip)://(?:[0-9]{10}|(?:0x[0-9a-f]{2}\.){3}0x[0-9a-f]{2}|0x(?:[0-9a-f]{8}|[0-9a-f]{16})|(?:0{1,4}[0-9]{1,3}\.){3}0{1,4}[0-9]{1,3}|[0-9]{1,3}\.(?:[0-9]{1,3}\.[0-9]{5}|[0-9]{8})|(?:\x5c\x5c[\-0-9a-z]\.?_?)+|\[[0-:a-f]+(?:[\.0-9]+|%[0-9A-Z_a-z]+)?\]|[a-z][\-\.0-9A-Z_a-z]{1,255}:[0-9]{1,5}(?:#?[\s\x0b]*&?@(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3}|[a-z][\-\.0-9A-Z_a-z]{1,255}):[0-9]{1,5}/?)+|[\.0-9]{0,11}(?:\xe2(?:\x91[\xa0-\xbf]|\x92[\x80-\xbf]|\x93[\x80-\xa9\xab-\xbf])|\xe3\x80\x82)+))" \ - "id:934120,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Possible Server Side Request Forgery (SSRF) Attack: URL Parameter using IP Address',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-ssrf',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/664',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# [ Perl generic RCE signatures ] -# -# Detects Perl-based injection attacks. -# Example: @{[system whoami]} -# -# Regular expression generated from regex-assembly/934140.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 934140 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ^(?:[^@]|@[^\{])*@+\{.*\}" \ - "id:934140,\ - phase:2,\ - block,\ - capture,\ - t:none,\ - msg:'Perl Injection Attack',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-perl',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'attack-injection-generic',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:934015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:934016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -# -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) -# - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:934017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:934018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-934-APPLICATION-ATTACK-GENERIC" -# -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) -# - - - -# -# -= Paranoia Levels Finished =- -# -SecMarker "END-REQUEST-934-APPLICATION-ATTACK-GENERIC" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf new file mode 100644 index 000000000..acd05520e --- /dev/null +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-934-APPLICATION-ATTACK-NODEJS.conf @@ -0,0 +1,96 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set ver.3.3.7 +# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set is distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# +# -= Paranoia Level 0 (empty) =- (apply unconditionally) +# + + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:934011,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:934012,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +# +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) +# + + +# [ Insecure unserialization / generic RCE signatures ] +# +# Libraries performing insecure unserialization: +# - node-serialize: _$$ND_FUNC$$_ (CVE-2017-5941) +# - funcster: __js_function +# +# See: +# https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/ +# https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/ +# +# Some generic snippets used: +# - function() { +# - new Function( +# - eval( +# - String.fromCharCode( +# +# Last two are used by nodejsshell.py, +# https://github.com/ajinabraham/Node.Js-Security-Course/blob/master/nodejsshell.py +# +# As base64 is sometimes (but not always) used to encode serialized values, +# use multiMatch and t:base64decode. +# +# Regexp generated from util/regexp-assemble/regexp-934100.data using Regexp::Assemble. +# See https://coreruleset.org/20190826/optimizing-regular-expressions/ for usage. + +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:(?:_(?:\$\$ND_FUNC\$\$_|_js_function)|(?:new\s+Function|\beval)\s*\(|String\s*\.\s*fromCharCode|function\s*\(\s*\)\s*{|this\.constructor)|module\.exports\s*=)" \ + "id:934100,\ + phase:2,\ + block,\ + capture,\ + t:none,t:urlDecodeUni,t:base64Decode,\ + msg:'Node.js Injection Attack',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-javascript',\ + tag:'platform-multi',\ + tag:'attack-rce',\ + tag:'attack-injection-nodejs',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/242',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + multiMatch,\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:934013,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:934014,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +# +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) +# + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:934015,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:934016,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +# +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) +# + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:934017,phase:1,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:934018,phase:2,pass,nolog,skipAfter:END-REQUEST-934-APPLICATION-ATTACK-NODEJS" +# +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) +# + + + +# +# -= Paranoia Levels Finished =- +# +SecMarker "END-REQUEST-934-APPLICATION-ATTACK-NODEJS" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf index d6a1abaf2..0a272c752 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,57 +14,13 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:941011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:941012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:941011,phase:1,pass,nolog,skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:941012,phase:2,pass,nolog,skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # -# In CRS v4.0, we have added REQUEST_FILENAME to the list of variables to -# be checked for XSS to catch path-based XSS exploits such as: -# /index.php/%3Csvg/onload=alert() -# -# However, the REQUEST_FILENAME is always populated (while ARGS etc. are -# only set on some requests) and we found that always checking the -# REQUEST_FILENAME has a significant performance impact. -# Therefore, we are disabling the REQUEST_FILENAME XSS checks when the -# REQUEST_FILENAME is clearly not containing special characters necessary -# for a successful XSS. -# -# Some bona-fide REQUEST_FILENAMEs will still contain special characters -# and will be checked by the rules, but it will be a much lower amount, -# and that is a trade-off we are willing to make. -# -# So, we check for XSS in REQUEST_FILENAME only if it contains -# other characters than alphanumeric characters, hyphens, underscores etc. -# typically found in filenames and paths: -# -# - ascii 20 (whitespace) -# - ascii 45-47 (- . /) -# - ascii 48-57 (0-9) -# - ascii 65-90 (A-Z) -# - ascii 95 (underscore) -# - ascii 97-122 (a-z) -# -# If just these characters are present, we make use of a special tag to remove -# REQUEST_FILENAME from the target list of all the 941xxx rules starting 941100. -# -# Please note that it would be preferable to start without REQUEST_FILENAME in the -# target list and to add it on a case to case base, but the rule language does not -# support this feature at runtime. -# -SecRule REQUEST_FILENAME "!@validateByteRange 20, 45-47, 48-57, 65-90, 95, 97-122" \ - "id:941010,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ctl:ruleRemoveTargetByTag=xss-perf-disable;REQUEST_FILENAME,\ - ver:'OWASP_CRS/4.6.0'" - - # # -=[ Libinjection - XSS Detection ]=- # @@ -77,7 +33,7 @@ SecRule REQUEST_FILENAME "!@validateByteRange 20, 45-47, 48-57, 65-90, 95, 97-12 # REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent| # ARGS_NAMES|ARGS|XML:/* # -# 941101: PL2 : REQUEST_FILENAME|REQUEST_HEADERS:Referer +# 941101: PL2 : REQUEST_HEADERS:Referer # SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "@detectXSS" \ "id:941100,\ @@ -90,14 +46,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -117,25 +73,51 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_F tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + + +# +# -=[ XSS Filters - Category 2 ]=- +# XSS vectors making use of event handlers like onerror, onload etc, e.g., +# +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s\"'`;\/0-9=\x0B\x09\x0C\x3B\x2C\x28\x3B]on[a-zA-Z]+[\s\x0B\x09\x0C\x3B\x2C\x28\x3B]*?=" \ + "id:941120,\ + phase:2,\ + block,\ + capture,\ + t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ + msg:'XSS Filter - Category 2: Event Handler Vector',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-xss',\ + tag:'paranoia-level/1',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/242',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # -=[ XSS Filters - Category 3 ]=- # -# Regular expression generated from regex-assembly/941130.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 941130 +# Regexp generated from util/regexp-assemble/regexp-941130.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-941130.data # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i).(?:\b(?:x(?:link:href|html|mlns)|data:text/html|formaction|pattern\b.*?=)|!ENTITY[\s\x0b]+(?:%[\s\x0b]+)?[^\s\x0b]+[\s\x0b]+(?:SYSTEM|PUBLIC)|@import|;base64)\b" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s\S](?:!ENTITY\s+(?:\S+|%\s+\S+)\s+(?:PUBLIC|SYSTEM)|x(?:link:href|html|mlns)|data:text\/html|pattern\b.*?=|formaction|\@import|;base64)\b" \ "id:941130,\ phase:2,\ block,\ @@ -147,43 +129,40 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # -=[ XSS Filters - Category 4 ]=- # XSS vectors making use of javascript uri and tags, e.g.,

-# https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#css-expressions-ie7 -# https://portswigger.net/web-security/cross-site-scripting/cheat-sheet#behaviors-for-older-modes-of-ie -# examples: https://regex101.com/r/FFEpsh/1 # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)[a-z]+=(?:[^:=]+:.+;)*?[^:=]+:url\(javascript" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:<(?:(?:apple|objec)t|isindex|embed|style|form|meta)\b[^>]*?>[\s\S]*?|(?:=|U\s*?R\s*?L\s*?\()\s*?[^>]*?\s*?S\s*?C\s*?R\s*?I\s*?P\s*?T\s*?:)" \ "id:941140,\ phase:2,\ block,\ capture,\ - t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,t:removeWhitespace,\ + t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ msg:'XSS Filter - Category 4: Javascript URI Vector',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # @@ -192,12 +171,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H # # [NoScript InjectionChecker] HTML injection # -# Regular expression generated from regex-assembly/941160.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 941160 +# Regexp generated from util/regexp-assemble/regexp-941160.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-941160.data +# Note that after assemble an ignore case flag (i) is added to the to the Regexp::Assemble output: +# Add ignore case flag between '?' and ':': "(?i:...)" # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)<[^0-9<>A-Z_a-z]*(?:[^\s\x0b\"'<>]*:)?[^0-9<>A-Z_a-z]*[^0-9A-Z_a-z]*?(?:s[^0-9A-Z_a-z]*?(?:c[^0-9A-Z_a-z]*?r[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?p[^0-9A-Z_a-z]*?t|t[^0-9A-Z_a-z]*?y[^0-9A-Z_a-z]*?l[^0-9A-Z_a-z]*?e|v[^0-9A-Z_a-z]*?g|e[^0-9A-Z_a-z]*?t[^0-9>A-Z_a-z])|f[^0-9A-Z_a-z]*?o[^0-9A-Z_a-z]*?r[^0-9A-Z_a-z]*?m|d[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?a[^0-9A-Z_a-z]*?l[^0-9A-Z_a-z]*?o[^0-9A-Z_a-z]*?g|m[^0-9A-Z_a-z]*?(?:a[^0-9A-Z_a-z]*?r[^0-9A-Z_a-z]*?q[^0-9A-Z_a-z]*?u[^0-9A-Z_a-z]*?e[^0-9A-Z_a-z]*?e|e[^0-9A-Z_a-z]*?t[^0-9A-Z_a-z]*?a[^0-9>A-Z_a-z])|(?:l[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?n[^0-9A-Z_a-z]*?k|o[^0-9A-Z_a-z]*?b[^0-9A-Z_a-z]*?j[^0-9A-Z_a-z]*?e[^0-9A-Z_a-z]*?c[^0-9A-Z_a-z]*?t|e[^0-9A-Z_a-z]*?m[^0-9A-Z_a-z]*?b[^0-9A-Z_a-z]*?e[^0-9A-Z_a-z]*?d|a[^0-9A-Z_a-z]*?(?:p[^0-9A-Z_a-z]*?p[^0-9A-Z_a-z]*?l[^0-9A-Z_a-z]*?e[^0-9A-Z_a-z]*?t|u[^0-9A-Z_a-z]*?d[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?o|n[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?m[^0-9A-Z_a-z]*?a[^0-9A-Z_a-z]*?t[^0-9A-Z_a-z]*?e)|p[^0-9A-Z_a-z]*?a[^0-9A-Z_a-z]*?r[^0-9A-Z_a-z]*?a[^0-9A-Z_a-z]*?m|i?[^0-9A-Z_a-z]*?f[^0-9A-Z_a-z]*?r[^0-9A-Z_a-z]*?a[^0-9A-Z_a-z]*?m[^0-9A-Z_a-z]*?e|b[^0-9A-Z_a-z]*?(?:a[^0-9A-Z_a-z]*?s[^0-9A-Z_a-z]*?e|o[^0-9A-Z_a-z]*?d[^0-9A-Z_a-z]*?y|i[^0-9A-Z_a-z]*?n[^0-9A-Z_a-z]*?d[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?n[^0-9A-Z_a-z]*?g[^0-9A-Z_a-z]*?s)|i[^0-9A-Z_a-z]*?m[^0-9A-Z_a-z]*?a?[^0-9A-Z_a-z]*?g[^0-9A-Z_a-z]*?e?|v[^0-9A-Z_a-z]*?i[^0-9A-Z_a-z]*?d[^0-9A-Z_a-z]*?e[^0-9A-Z_a-z]*?o)[^0-9>A-Z_a-z])|(?:<[0-9A-Z_a-z].*[\s\x0b/]|[\"'](?:.*[\s\x0b/])?)(?:background|formaction|lowsrc|on(?:a(?:bort|ctivate|d(?:apteradded|dtrack)|fter(?:print|(?:scriptexecu|upda)te)|lerting|n(?:imation(?:cancel|end|iteration|start)|tennastatechange)|ppcommand|u(?:dio(?:end|process|start)|xclick))|b(?:e(?:fore(?:(?:(?:(?:de)?activa|scriptexecu)t|toggl)e|c(?:opy|ut)|editfocus|input|p(?:aste|rint)|u(?:nload|pdate))|gin(?:Event)?)|l(?:ocked|ur)|oun(?:ce|dary)|roadcast|usy)|c(?:a(?:(?:ch|llschang)ed|nplay(?:through)?|rdstatechange)|(?:ell|fstate)change|h(?:a(?:rging(?:time)?cha)?nge|ecking)|l(?:ick|ose)|o(?:m(?:mand(?:update)?|p(?:lete|osition(?:end|start|update)))|n(?:nect(?:ed|ing)|t(?:extmenu|rolselect))|py)|u(?:echange|t))|d(?:ata(?:(?:availabl|chang)e|error|setc(?:hanged|omplete))|blclick|e(?:activate|livery(?:error|success)|vice(?:found|light|(?:mo|orienta)tion|proximity))|i(?:aling|s(?:abled|c(?:hargingtimechange|onnect(?:ed|ing))))|o(?:m(?:a(?:ctivate|ttrmodified)|(?:characterdata|subtree)modified|focus(?:in|out)|mousescroll|node(?:inserted(?:intodocument)?|removed(?:fromdocument)?))|wnloading)|r(?:ag(?:drop|e(?:n(?:d|ter)|xit)|(?:gestur|leav)e|over|start)|op)|urationchange)|e(?:mptied|n(?:abled|d(?:ed|Event)?|ter)|rror(?:update)?|xit)|f(?:ailed|i(?:lterchange|nish)|o(?:cus(?:in|out)?|rm(?:change|input))|ullscreenchange)|g(?:amepad(?:axismove|button(?:down|up)|(?:dis)?connected)|et)|h(?:ashchange|e(?:adphoneschange|l[dp])|olding)|i(?:cc(?:cardlockerror|infochange)|n(?:coming|put|valid))|key(?:down|press|up)|l(?:evelchange|o(?:ad(?:e(?:d(?:meta)?data|nd)|start)?|secapture)|y)|m(?:ark|essage|o(?:use(?:down|enter|(?:lea|mo)ve|o(?:ut|ver)|up|wheel)|ve(?:end|start)?|z(?:a(?:fterpaint|udioavailable)|(?:beforeresiz|orientationchang|t(?:apgestur|imechang))e|(?:edgeui(?:c(?:ancel|omplet)|start)e|network(?:down|up)loa)d|fullscreen(?:change|error)|m(?:agnifygesture(?:start|update)?|ouse(?:hittest|pixelscroll))|p(?:ointerlock(?:change|error)|resstapgesture)|rotategesture(?:start|update)?|s(?:crolledareachanged|wipegesture(?:end|start|update)?))))|no(?:match|update)|o(?:(?:bsolet|(?:ff|n)lin)e|pen|verflow(?:changed)?)|p(?:a(?:ge(?:hide|show)|int|(?:st|us)e)|lay(?:ing)?|o(?:inter(?:down|enter|(?:(?:lea|mo)v|rawupdat)e|o(?:ut|ver)|up)|p(?:state|up(?:hid(?:den|ing)|show(?:ing|n))))|ro(?:gress|pertychange))|r(?:atechange|e(?:adystatechange|ceived|movetrack|peat(?:Event)?|quest|s(?:et|ize|u(?:lt|m(?:e|ing)))|trieving)|ow(?:e(?:nter|xit)|s(?:delete|inserted)))|s(?:croll(?:end)?|e(?:arch|ek(?:complete|ed|ing)|lect(?:ionchange|start)?|n(?:ding|t)|t)|how|(?:ound|peech)(?:end|start)|t(?:a(?:lled|rt|t(?:echange|uschanged))|k(?:comma|sessione)nd|op)|u(?:bmit|ccess|spend)|vg(?:abort|error|(?:un)?load|resize|scroll|zoom))|t(?:ext|ime(?:out|update)|o(?:ggle|uch(?:cancel|en(?:d|ter)|(?:lea|mo)ve|start))|ransition(?:cancel|end|run|start))|u(?:n(?:derflow|handledrejection|load)|p(?:dateready|gradeneeded)|s(?:erproximity|sdreceived))|v(?:ersion|o(?:ic|lum)e)change|w(?:a(?:it|rn)ing|ebkit(?:animation(?:end|iteration|start)|transitionend)|heel)|zoom)|ping|s(?:rc|tyle))[\x08-\n\f\r ]*?=" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:<\w[\s\S]*[\s\/]|['\"](?:[\s\S]*[\s\/])?)(?:on(?:d(?:e(?:vice(?:(?:orienta|mo)tion|proximity|found|light)|livery(?:success|error)|activate)|r(?:ag(?:e(?:n(?:ter|d)|xit)|(?:gestur|leav)e|start|drop|over)|op)|i(?:s(?:c(?:hargingtimechange|onnect(?:ing|ed))|abled)|aling)|ata(?:setc(?:omplete|hanged)|(?:availabl|chang)e|error)|urationchange|ownloading|blclick)|Moz(?:M(?:agnifyGesture(?:Update|Start)?|ouse(?:PixelScroll|Hittest))|S(?:wipeGesture(?:Update|Start|End)?|crolledAreaChanged)|(?:(?:Press)?TapGestur|BeforeResiz)e|EdgeUI(?:C(?:omplet|ancel)|Start)ed|RotateGesture(?:Update|Start)?|A(?:udioAvailable|fterPaint))|c(?:o(?:m(?:p(?:osition(?:update|start|end)|lete)|mand(?:update)?)|n(?:t(?:rolselect|extmenu)|nect(?:ing|ed))|py)|a(?:(?:llschang|ch)ed|nplay(?:through)?|rdstatechange)|h(?:(?:arging(?:time)?ch)?ange|ecking)|(?:fstate|ell)change|u(?:echange|t)|l(?:ick|ose))|s(?:t(?:a(?:t(?:uschanged|echange)|lled|rt)|k(?:sessione|comma)nd|op)|e(?:ek(?:complete|ing|ed)|(?:lec(?:tstar)?)?t|n(?:ding|t))|(?:peech|ound)(?:start|end)|u(?:ccess|spend|bmit)|croll|how)|m(?:o(?:z(?:(?:pointerlock|fullscreen)(?:change|error)|(?:orientation|time)change|network(?:down|up)load)|use(?:(?:lea|mo)ve|o(?:ver|ut)|enter|wheel|down|up)|ve(?:start|end)?)|essage|ark)|a(?:n(?:imation(?:iteration|start|end)|tennastatechange)|fter(?:(?:scriptexecu|upda)te|print)|udio(?:process|start|end)|d(?:apteradded|dtrack)|ctivate|lerting|bort)|b(?:e(?:fore(?:(?:(?:de)?activa|scriptexecu)te|u(?:nload|pdate)|p(?:aste|rint)|c(?:opy|ut)|editfocus)|gin(?:Event)?)|oun(?:dary|ce)|l(?:ocked|ur)|roadcast|usy)|DOM(?:Node(?:Inserted(?:IntoDocument)?|Removed(?:FromDocument)?)|(?:CharacterData|Subtree)Modified|A(?:ttrModified|ctivate)|Focus(?:Out|In)|MouseScroll)|r(?:e(?:s(?:u(?:m(?:ing|e)|lt)|ize|et)|adystatechange|pea(?:tEven)?t|movetrack|trieving|ceived)|ow(?:s(?:inserted|delete)|e(?:nter|xit))|atechange)|p(?:op(?:up(?:hid(?:den|ing)|show(?:ing|n))|state)|a(?:ge(?:hide|show)|(?:st|us)e|int)|ro(?:pertychange|gress)|lay(?:ing)?)|t(?:ouch(?:(?:lea|mo)ve|en(?:ter|d)|cancel|start)|ransition(?:cancel|end|run)|ime(?:update|out)|ext)|u(?:s(?:erproximity|sdreceived)|p(?:gradeneeded|dateready)|n(?:derflow|load))|f(?:o(?:rm(?:change|input)|cus(?:out|in)?)|i(?:lterchange|nish)|ailed)|l(?:o(?:ad(?:e(?:d(?:meta)?data|nd)|start)|secapture)|evelchange|y)|g(?:amepad(?:(?:dis)?connected|button(?:down|up)|axismove)|et)|e(?:n(?:d(?:Event|ed)?|abled|ter)|rror(?:update)?|mptied|xit)|i(?:cc(?:cardlockerror|infochange)|n(?:coming|valid|put))|o(?:(?:(?:ff|n)lin|bsolet)e|verflow(?:changed)?|pen)|SVG(?:(?:Unl|L)oad|Resize|Scroll|Abort|Error|Zoom)|h(?:e(?:adphoneschange|l[dp])|ashchange|olding)|v(?:o(?:lum|ic)e|ersion)change|w(?:a(?:it|rn)ing|heel)|key(?:press|down|up)|(?:AppComman|Loa)d|no(?:update|match)|Request|zoom)|s(?:tyle|rc)|background|formaction|lowsrc|ping)[\s\x08]*?=|<[^\w<>]*(?:[^<>\"'\s]*:)?[^\w<>]*\W*?(?:(?:a\W*?(?:n\W*?i\W*?m\W*?a\W*?t\W*?e|p\W*?p\W*?l\W*?e\W*?t|u\W*?d\W*?i\W*?o)|b\W*?(?:i\W*?n\W*?d\W*?i\W*?n\W*?g\W*?s|a\W*?s\W*?e|o\W*?d\W*?y)|i?\W*?f\W*?r\W*?a\W*?m\W*?e|o\W*?b\W*?j\W*?e\W*?c\W*?t|i\W*?m\W*?a?\W*?g\W*?e?|e\W*?m\W*?b\W*?e\W*?d|p\W*?a\W*?r\W*?a\W*?m|v\W*?i\W*?d\W*?e\W*?o|l\W*?i\W*?n\W*?k)[^>\w]|s\W*?(?:c\W*?r\W*?i\W*?p\W*?t|t\W*?y\W*?l\W*?e|e\W*?t[^>\w]|v\W*?g)|m\W*?(?:a\W*?r\W*?q\W*?u\W*?e\W*?e|e\W*?t\W*?a[^>\w])|f\W*?o\W*?r\W*?m))" \ "id:941160,\ phase:2,\ block,\ @@ -209,20 +190,20 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # [NoScript InjectionChecker] Attributes injection # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)(?:\W|^)(?:javascript:(?:[\s\S]+[=\x5c\(\[\.<]|[\s\S]*?(?:\bname\b|\x5c[ux]\d))|data:(?:(?:[a-z]\w+/\w[\w+-]+\w)?[;,]|[\s\S]*?;[\s\S]*?\b(?:base64|charset=)|[\s\S]*?,[\s\S]*?<[\s\S]*?\w[\s\S]*?>))|@\W*?i\W*?m\W*?p\W*?o\W*?r\W*?t\W*?(?:/\*[\s\S]*?)?(?:[\"']|\W*?u\W*?r\W*?l[\s\S]*?\()|[^-]*?-\W*?m\W*?o\W*?z\W*?-\W*?b\W*?i\W*?n\W*?d\W*?i\W*?n\W*?g[^:]*?:\W*?u\W*?r\W*?l[\s\S]*?\(" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:\W|^)(?:javascript:(?:[\s\S]+[=\\\(\[\.<]|[\s\S]*?(?:\bname\b|\\[ux]\d))|data:(?:(?:[a-z]\w+\/\w[\w+-]+\w)?[;,]|[\s\S]*?;[\s\S]*?\b(?:base64|charset=)|[\s\S]*?,[\s\S]*?<[\s\S]*?\w[\s\S]*?>))|@\W*?i\W*?m\W*?p\W*?o\W*?r\W*?t\W*?(?:\/\*[\s\S]*?)?(?:[\"']|\W*?u\W*?r\W*?l[\s\S]*?\()|\W*?-\W*?m\W*?o\W*?z\W*?-\W*?b\W*?i\W*?n\W*?d\W*?i\W*?n\W*?g[\s\S]*?:[\s\S]*?\W*?u\W*?r\W*?l[\s\S]*?\(" \ "id:941170,\ phase:2,\ block,\ @@ -234,41 +215,40 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # -# [Deny List Keywords from Node-Validator] -# https://github.com/validatorjs/validator.js/ -# This rule has a stricter sibling 941181 (PL2) that covers the additional payload "-->" +# [Blacklist Keywords from Node-Validator] +# https://raw.github.com/chriso/node-validator/master/validator.js # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@pm document.cookie document.domain document.write .parentnode .innerhtml window.location -moz-binding .*?(?:@[i\x5c]|(?:[:=]|&#x?0*(?:58|3A|61|3D);?).*?(?:[(\x5c]|&#x?0*(?:40|28|92|5C);?)))" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:.*?(?:@[i\\\\]|(?:[:=]|&#x?0*(?:58|3A|61|3D);?).*?(?:[(\\\\]|&#x?0*(?:40|28|92|5C);?)))" \ "id:941190,\ phase:2,\ block,\ @@ -288,17 +268,17 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i:<.*[:]?vmlframe.*?[\s/+]*?src[\s/+]*=)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:<.*[:]?vmlframe.*?[\s/+]*?src[\s/+]*=)" \ "id:941200,\ phase:2,\ block,\ @@ -310,17 +290,17 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)(?:j|&#(?:0*(?:74|106)|x0*[46]A);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:a|&#(?:0*(?:65|97)|x0*[46]1);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:v|&#(?:0*(?:86|118)|x0*[57]6);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:a|&#(?:0*(?:65|97)|x0*[46]1);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:s|&#(?:0*(?:115|83)|x0*[57]3);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:c|&#(?:x0*[46]3|0*(?:99|67));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:r|&#(?:x0*[57]2|0*(?:114|82));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:i|&#(?:x0*[46]9|0*(?:105|73));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:p|&#(?:x0*[57]0|0*(?:112|80));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:t|&#(?:x0*[57]4|0*(?:116|84));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?::|&(?:#(?:0*58|x0*3A);?|colon;))." \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:j|&#x?0*(?:74|4A|106|6A);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:a|&#x?0*(?:65|41|97|61);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:v|&#x?0*(?:86|56|118|76);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:a|&#x?0*(?:65|41|97|61);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:s|&#x?0*(?:83|53|115|73);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:c|&#x?0*(?:67|43|99|63);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:r|&#x?0*(?:82|52|114|72);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:i|&#x?0*(?:73|49|105|69);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:p|&#x?0*(?:80|50|112|70);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:t|&#x?0*(?:84|54|116|74);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?::|&(?:#x?0*(?:58|3A);?|colon;)).)" \ "id:941210,\ phase:2,\ block,\ @@ -332,17 +312,17 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)(?:v|&#(?:0*(?:118|86)|x0*[57]6);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:b|&#(?:0*(?:98|66)|x0*[46]2);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:s|&#(?:0*(?:115|83)|x0*[57]3);)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:c|&#(?:x0*[46]3|0*(?:99|67));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:r|&#(?:x0*[57]2|0*(?:114|82));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:i|&#(?:x0*[46]9|0*(?:105|73));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:p|&#(?:x0*[57]0|0*(?:112|80));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?:t|&#(?:x0*[57]4|0*(?:116|84));)(?:[\t\n\r]|&(?:#(?:0*(?:9|1[03])|x0*[AD]);?|(?:tab|newline);))*(?::|&(?:#(?:0*58|x0*3A);?|colon;))." \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:v|&#x?0*(?:86|56|118|76);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:b|&#x?0*(?:66|42|98|62);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:s|&#x?0*(?:83|53|115|73);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:c|&#x?0*(?:67|43|99|63);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:r|&#x?0*(?:82|52|114|72);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:i|&#x?0*(?:73|49|105|69);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:p|&#x?0*(?:80|50|112|70);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?:t|&#x?0*(?:84|54|116|74);?)(?:\t|&(?:#x?0*(?:9|13|10|A|D);?|tab;|newline;))*(?::|&(?:#x?0*(?:58|3A);?|colon;)).)" \ "id:941220,\ phase:2,\ block,\ @@ -354,17 +334,17 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)]" \ "id:941290,\ phase:2,\ block,\ @@ -508,17 +488,17 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)). However, -# the characters where the brackets would be are ISO 8859-1 characters: -# - ¼: 0x00BC -# - ¾: 0x00BE -# - ¢: 0x00A2 -# -# And this is how the sequence looks in in US-ASCII: -# -# -# -# This enables an attacker to craft a string that will be delivered in a form that a browser will execute as script -# while being ignored by input filters. -# -# This rule looks for a start tag sequence that looks like "<...>" (checks for hex and plain to be sure). -# Because the bytes matched occur in many different languages encoded as multibyte characters (e.g. UTF-8) -# (e.g. German umlauts, Russian characters) this isn't very helpful and can cause many false positives. We, therefore, -# use a chained rule to also look for an end tag sequence that looks like "". Only if the chained rule matches will -# the request be blocked. -# -# This is of course still not perfect but should at least make it harder to hide most tags using this technique while -# requiring very specific patterns in a language to match, which should get rid of most false positives. -# These rules would, for example, not guard against an element without an end tag, e.g. "". -# -# US-ASCII on Wikipedia: https://en.wikipedia.org/wiki/ASCII -# ISO 8859-1 on Wikipedia: https://en.wikipedia.org/wiki/ISO/IEC_8859-1 -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx \xbc[^\xbe>]*[\xbe>]|<[^\xbe]*\xbe" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \xbc[^\xbe>]*[\xbe>]|<[^\xbe]*\xbe" \ "id:941310,\ phase:2,\ block,\ capture,\ - t:none,t:lowercase,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,\ + t:none,t:urlDecodeUni,t:lowercase,t:urlDecode,t:htmlEntityDecode,t:jsDecode,\ msg:'US-ASCII Malformed Encoding XSS Filter - Attack Detected',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-tomcat',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - chain" - SecRule MATCHED_VARS "@rx (?:\xbc\s*/\s*[^\xbe>]*[\xbe>])|(?:<\s*/\s*[^\xbe]*\xbe)" \ - "setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # https://nedbatchelder.com/blog/200704/xss_with_utf7.html @@ -607,26 +552,26 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # Reported by Vladimir Ivanov # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx \+ADw-.*(?:\+AD4-|>)|<.*\+AD4-" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx \+ADw-.*(?:\+AD4-|>)|<.*\+AD4-" \ "id:941350,\ phase:2,\ block,\ capture,\ - t:none,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,\ + t:none,t:urlDecodeUni,t:urlDecode,t:htmlEntityDecode,t:jsDecode,\ msg:'UTF-7 Encoding IE XSS - Attack Detected',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-internet-explorer',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Defend against JSFuck and Hieroglyphy obfuscation of Javascript code @@ -650,7 +595,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # !+[] # ! [] -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx ![!+ ]\[\]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ![!+ ]\[\]" \ "id:941360,\ phase:2,\ block,\ @@ -661,14 +606,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'application-multi',\ tag:'language-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242/63',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # Prevent 941180 bypass by using JavaScript global variables @@ -678,7 +623,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # - /?search=/?a=";+alert(self["document"]["cookie"]);// # - /?search=/?a=";+document+/*foo*/+.+/*bar*/+cookie;// # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?:self|document|this|top|window)\s*(?:/\*|[\[)]).+?(?:\]|\*/)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS|XML:/* "@rx (?:self|document|this|top|window)\s*(?:/\*|[\[)]).+?(?:\]|\*/)" \ "id:941370,\ phase:2,\ block,\ @@ -689,90 +634,28 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS|REQU tag:'application-multi',\ tag:'language-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242/63',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# -# JavaScript methods which take code as a string types are considered unsafe. -# Unsafe JS functions like eval(), setInterval(), setTimeout() -# Unsafe JS constructor new Function() -# https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#dangerous-contexts -# https://snyk.io/blog/5-ways-to-prevent-code-injection-in-javascript-and-node-js/ -# -# Regular expression generated from regex-assembly/941390.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 941390 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)\b(?:eval|set(?:timeout|interval)|new[\s\x0b]+Function|a(?:lert|tob)|btoa|prompt|confirm)[\s\x0b]*\(" \ - "id:941390,\ - phase:2,\ - block,\ - capture,\ - t:none,t:htmlEntityDecode,t:jsDecode,\ - msg:'Javascript method detected',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'attack-xss',\ - tag:'xss-perf-disable',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:941013,phase:1,pass,nolog,skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:941014,phase:2,pass,nolog,skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" # -# JavaScript function without parentheses -# Reference: https://portswigger.net/research/the-seventh-way-to-call-a-javascript-function-without-parentheses -# -# Example Payloads: -# [].sort.call`${alert}1337` -# [].map.call`${eval}\\u{61}lert\x281337\x29` -# Reflect.apply.call`${navigation.navigate}${navigation}${[name]}` -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx ((?:\[[^\]]*\][^.]*\.)|Reflect[^.]*\.).*(?:map|sort|apply)[^.]*\..*call[^`]*`.*`" \ - "id:941400,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:compressWhitespace,\ - msg:'XSS JavaScript function without parentheses',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'attack-xss',\ - tag:'xss-perf-disable',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:941013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:941014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-941-APPLICATION-ATTACK-XSS" -# -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # # # This is a stricter sibling of rule 941100. # -SecRule REQUEST_FILENAME|REQUEST_HEADERS:Referer "@detectXSS" \ +SecRule REQUEST_HEADERS:Referer "@detectXSS" \ "id:941101,\ - phase:1,\ + phase:2,\ block,\ capture,\ t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ @@ -782,55 +665,21 @@ SecRule REQUEST_FILENAME|REQUEST_HEADERS:Referer "@detectXSS" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# -# -=[ XSS Filters - Category 2 ]=- -# XSS vectors making use of event handlers like onerror, onload etc, e.g., -# -# We are not listing all the known event handlers like rule 941160, but we -# limit the alerts to keywords of 3-25 characters after the prefix ("on"). -# -# The shortest known event is "onget". The longest known event is "onmozorientationchange" -# with 23 chars after the prefix. 25 chars adds a little bit of safety. -# -# This rule has been moved to PL2 since it has a tendency to trigger on random input. -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)[\s\"'`;/0-9=\x0B\x09\x0C\x3B\x2C\x28\x3B]on[a-zA-Z]{3,25}[\s\x0B\x09\x0C\x3B\x2C\x28\x3B]*?=[^=]" \ - "id:941120,\ - phase:2,\ - block,\ - capture,\ - t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:removeNulls,\ - msg:'XSS Filter - Category 2: Event Handler Vector',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # # -=[ XSS Filters - Category 5 ]=- # HTML attributes - src, style and href # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)\b(?:s(?:tyle|rc)|href)\b[\s\S]*?=" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:s(?:tyle|rc)|href)\b[\s\S]*?=" \ "id:941150,\ phase:2,\ block,\ @@ -842,48 +691,16 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-xss',\ - tag:'xss-perf-disable',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - - -# -# [Deny List Keywords from Node-Validator] -# https://github.com/validatorjs/validator.js/ -# This rule is a stricter sibling of 941180 (PL1) -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@contains -->" \ - "id:941181,\ - phase:2,\ - block,\ - capture,\ - t:none,t:utf8toUnicode,t:urlDecodeUni,t:htmlEntityDecode,t:jsDecode,t:cssDecode,t:lowercase,t:removeNulls,\ - msg:'Node-Validator Deny List Keywords',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-xss',\ - tag:'xss-perf-disable',\ tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.xss_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -# -=[ XSS Filters from IE ]=- - # Detect tags that are the most common direct HTML injection points. # # ~]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:[\s()]case\s*?\(|\)\s*?like\s*?\(|having\s*?[^\s]+\s*?[^\w\s]|if\s?\([\d\w]\s*?[=<>~])" \ "id:942230,\ phase:2,\ block,\ @@ -269,17 +220,20 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942240.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942240 +# Regexp generated from util/regexp-assemble/regexp-942240.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942240.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)alter[\s\x0b]*?[0-9A-Z_a-z]+.*?char(?:acter)?[\s\x0b]+set[\s\x0b]+[0-9A-Z_a-z]+|[\"'`](?:;*?[\s\x0b]*?waitfor[\s\x0b]+(?:time|delay)[\s\x0b]+[\"'`]|;.*?:[\s\x0b]*?goto)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:[\"'`](?:;*?\s*?waitfor\s+(?:delay|time)\s+[\"'`]|;.*?:\s*?goto)|alter\s*?\w+.*?cha(?:racte)?r\s+set\s+\w+))" \ "id:942240,\ phase:2,\ block,\ @@ -295,10 +249,10 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:merge.*?using\s*?\(|execute\s*?immediate\s*?[\"'`]|match\s*?[\w(),+-]+\s*?against\s*?\()" \ "id:942250,\ @@ -316,10 +270,10 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)union.*?select.*?from" \ "id:942270,\ @@ -337,17 +291,20 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942280.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942280 +# Regexp generated from util/regexp-assemble/regexp-942280.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942280.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)select[\s\x0b]*?pg_sleep|waitfor[\s\x0b]*?delay[\s\x0b]?[\"'`]+[\s\x0b]?[0-9]|;[\s\x0b]*?shutdown[\s\x0b]*?(?:[#;\{]|/\*|--)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:;\s*?shutdown\s*?(?:[#;]|\/\*|--|\{)|waitfor\s*?delay\s?[\"'`]+\s?\d|select\s*?pg_sleep))" \ "id:942280,\ phase:2,\ block,\ @@ -363,17 +320,12 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942290.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942290 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\[?\$(?:n(?:e|in?|o[rt])|e(?:q|xists|lemMatch)|l(?:te?|ike)|mod|a(?:ll|nd)|(?:s(?:iz|lic)|wher)e|t(?:ype|ext)|x?or|div|between|regex|jsonSchema)\]?" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:\[\$(?:ne|eq|lte?|gte?|n?in|mod|all|size|exists|type|slice|x?or|div|like|between|and)\]))" \ "id:942290,\ phase:2,\ block,\ @@ -389,20 +341,20 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# This rule has a stricter sibling (942321) that checks for MySQL and PostgreSQL procedures / functions in -# request headers referer and user-agent. +# Regexp generated from util/regexp-assemble/regexp-942320.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942320.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -# Regular expression generated from regex-assembly/942320.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942320 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)create[\s\x0b]+(?:function|procedure)[\s\x0b]*?[0-9A-Z_a-z]+[\s\x0b]*?\([\s\x0b]*?\)[\s\x0b]*?-|d(?:eclare[^0-9A-Z_a-z]+[#@][\s\x0b]*?[0-9A-Z_a-z]+|iv[\s\x0b]*?\([\+\-]*[\s\x0b\.0-9]+,[\+\-]*[\s\x0b\.0-9]+\))|exec[\s\x0b]*?\([\s\x0b]*?@|(?:lo_(?:impor|ge)t|procedure[\s\x0b]+analyse)[\s\x0b]*?\(|;[\s\x0b]*?(?:declare|open)[\s\x0b]+[\-0-9A-Z_a-z]+|::(?:b(?:igint|ool)|double[\s\x0b]+precision|int(?:eger)?|numeric|oid|real|(?:tex|smallin)t)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:create\s+(?:procedure|function)\s*?\w+\s*?\(\s*?\)\s*?-|;\s*?(?:declare|open)\s+[\w-]+|procedure\s+analyse\s*?\(|declare[^\w]+[@#]\s*?\w+|exec\s*?\(\s*?\@))" \ "id:942320,\ phase:2,\ block,\ @@ -418,17 +370,20 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942350.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942350 +# Regexp generated from util/regexp-assemble/regexp-942350.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942350.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)create[\s\x0b]+function[\s\x0b].+[\s\x0b]returns|;[\s\x0b]*?(?:alter|(?:(?:cre|trunc|upd)at|renam)e|d(?:e(?:lete|sc)|rop)|(?:inser|selec)t|load)\b[\s\x0b]*?[\(\[]?[0-9A-Z_a-z]{2,}" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:;\s*?(?:(?:(?:trunc|cre|upd)at|renam)e|(?:inser|selec)t|de(?:lete|sc)|alter|load)\b\s*?[\[(]?\w{2,}|create\s+function\s+.+\s+returns))" \ "id:942350,\ phase:2,\ block,\ @@ -444,30 +399,31 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# This rule has two stricter sibling: 942361 and 942362. +# This rule has a stricter sibling: 942361. # The keywords 'alter' and 'union' led to false positives. # Therefore they have been moved to PL2 and the keywords have been extended on PL1. -# The original version also had loose word boundaries and context checksum cause further false positives. -# Because fixing those introduced bypass, the original variant was moved to PL2 as 942362. # # Sources for SQL ALTER statements: # MySQL: https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-data-definition.html -# Oracle/PLSQL: https://docs.oracle.com/search/?q=alter&size=60&category=database +# Oracle/PLSQL: https://docs.oracle.com/apps/search/search.jsp?q=alter&size=60&category=database # PostgreQSL: https://www.postgresql.org/search/?u=%2Fdocs&q=alter -# MSSQL: https://learn.microsoft.com/en-us/sql/t-sql/statements/statements?view=sql-server-ver16 -# DB2: https://www.ibm.com/docs/en/search/alter?scope=SSEPGG_9.5.0 +# MSSQL: https://docs.microsoft.com/en-us/sql/t-sql/statements/statements +# DB2: https://www.ibm.com/support/knowledgecenter/en/search/alter?scope=SSEPGG_9.5.0 # -# Regular expression generated from regex-assembly/942360.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942360 +# Regexp generated from util/regexp-assemble/regexp-942360.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942360.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:(?:alter|(?:(?:cre|trunc|upd)at|renam)e|de(?:lete|sc)|(?:inser|selec)t|load)[\s\x0b]+(?:char|group_concat|load_file)\b[\s\x0b]*\(?|end[\s\x0b]*?\);)|[\s\x0b\(]load_file[\s\x0b]*?\(|[\"'`][\s\x0b]+regexp[^0-9A-Z_a-z]|[\"'0-9A-Z_-z][\s\x0b]+as\b[\s\x0b]*[\"'0-9A-Z_-z]+[\s\x0b]*\bfrom|^[^A-Z_a-z]+[\s\x0b]*?(?:(?:(?:(?:cre|trunc)at|renam)e|d(?:e(?:lete|sc)|rop)|(?:inser|selec)t|load)[\s\x0b]+[0-9A-Z_a-z]+|u(?:pdate[\s\x0b]+[0-9A-Z_a-z]+|nion[\s\x0b]*(?:all|(?:sele|distin)ct)\b)|alter[\s\x0b]*(?:a(?:(?:ggregat|pplication[\s\x0b]*rol)e|s(?:sembl|ymmetric[\s\x0b]*ke)y|u(?:dit|thorization)|vailability[\s\x0b]*group)|b(?:roker[\s\x0b]*priority|ufferpool)|c(?:ertificate|luster|o(?:l(?:latio|um)|nversio)n|r(?:edential|yptographic[\s\x0b]*provider))|d(?:atabase|efault|i(?:mension|skgroup)|omain)|e(?:(?:ndpoi|ve)nt|xte(?:nsion|rnal))|f(?:lashback|oreign|u(?:lltext|nction))|hi(?:erarchy|stogram)|group|in(?:dex(?:type)?|memory|stance)|java|l(?:a(?:ngua|r)ge|ibrary|o(?:ckdown|g(?:file[\s\x0b]*group|in)))|m(?:a(?:s(?:k|ter[\s\x0b]*key)|terialized)|e(?:ssage[\s\x0b]*type|thod)|odule)|(?:nicknam|queu)e|o(?:perator|utline)|p(?:a(?:ckage|rtition)|ermission|ro(?:cedur|fil)e)|r(?:e(?:mot|sourc)e|o(?:l(?:e|lback)|ute))|s(?:chema|e(?:arch|curity|rv(?:er|ice)|quence|ssion)|y(?:mmetric[\s\x0b]*key|nonym)|togroup)|t(?:able(?:space)?|ext|hreshold|r(?:igger|usted)|ype)|us(?:age|er)|view|w(?:ork(?:load)?|rapper)|x(?:ml[\s\x0b]*schema|srobject))\b)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:^[\W\d]+\s*?(?:(?:alter\s*(?:a(?:(?:pplication\s*rol|ggregat)e|s(?:ymmetric\s*ke|sembl)y|u(?:thorization|dit)|vailability\s*group)|c(?:r(?:yptographic\s*provider|edential)|o(?:l(?:latio|um)|nversio)n|ertificate|luster)|s(?:e(?:rv(?:ice|er)|curity|quence|ssion|arch)|y(?:mmetric\s*key|nonym)|togroup|chema)|m(?:a(?:s(?:ter\s*key|k)|terialized)|e(?:ssage\s*type|thod)|odule)|l(?:o(?:g(?:file\s*group|in)|ckdown)|a(?:ngua|r)ge|ibrary)|t(?:(?:abl(?:espac)?|yp)e|r(?:igger|usted)|hreshold|ext)|p(?:a(?:rtition|ckage)|ro(?:cedur|fil)e|ermission)|d(?:i(?:mension|skgroup)|atabase|efault|omain)|r(?:o(?:l(?:lback|e)|ute)|e(?:sourc|mot)e)|f(?:u(?:lltext|nction)|lashback|oreign)|e(?:xte(?:nsion|rnal)|(?:ndpoi|ve)nt)|in(?:dex(?:type)?|memory|stance)|b(?:roker\s*priority|ufferpool)|x(?:ml\s*schema|srobject)|w(?:ork(?:load)?|rapper)|hi(?:erarchy|stogram)|o(?:perator|utline)|(?:nicknam|queu)e|us(?:age|er)|group|java|view)|u(?:nion\s*(?:(?:distin|sele)ct|all)|pdate)|(?:truncat|renam)e|(?:inser|selec)t|de(?:lete|sc)|load)\b|create\s+\w+)|(?:(?:(?:trunc|cre|upd)at|renam)e|(?:inser|selec)t|de(?:lete|sc)|alter|load)\s+(?:group_concat|load_file|char)\s?\(?|[\d\W]\s+as\b\s*[\"'`\w]+\s*\bfrom|[\s(]load_file\s*?\(|[\"'`]\s+regexp\W|end\s*?\);))" \ "id:942360,\ phase:2,\ block,\ @@ -483,10 +439,10 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # # -=[ Detect MySQL in-line comments ]=- @@ -503,12 +459,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # The minimal string that triggers this regexp is: /*!*/ or /*+*/. # The rule 942500 is related to 942440 which catches both /*! and */ independently. # -# Regular expression generated from regex-assembly/942500.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942500 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)/\*[\s\x0b]*?[!\+](?:[\s\x0b\(\)\-0-9=A-Z_a-z]+)?\*/" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:/\*[!+](?:[\w\s=_\-()]+)?\*/)" \ "id:942500,\ phase:2,\ block,\ @@ -524,112 +475,48 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - multiMatch,\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# This rule catches an authentication bypass via SQL injection that abuses semi-colons to end the SQL query early. -# Any characters after the semi-colon are ignored by some DBMSes (e.g. SQLite). +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:942013,phase:1,pass,nolog,skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:942014,phase:2,pass,nolog,skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" # -# An example of this would be: -# email=admin%40juice-sh.op';&password=foo +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -# The server then turns this into: -# SELECT * FROM users WHERE email='admin@juice-sh.op';' AND password='foo' + + # -# Regular expression generated from regex-assembly/942540.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942540 +# -=[ String Termination/Statement Ending Injection Testing ]=- # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ^(?:[^']*'|[^\"]*\"|[^`]*`)[\s\x0b]*;" \ - "id:942540,\ +# Identifies common initial SQLi probing requests where attackers insert/append +# quote characters to the existing normal payload to see how the app/db responds. +# +# This rule is also triggered by the following exploit(s): +# [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] +# +SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?:^\s*[\"'`;]+|[\"'`]+\s*$)" \ + "id:942110,\ phase:2,\ block,\ capture,\ - t:none,t:urlDecodeUni,t:replaceComments,\ - msg:'SQL Authentication bypass (split query)',\ + t:none,t:utf8toUnicode,t:urlDecodeUni,\ + msg:'SQL Injection Attack: Common Injection Testing Detected',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ tag:'OWASP_CRS',\ - tag:'paranoia-level/1',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# This rule catches on Scientific Notation bypass payloads in MySQL -# Reference: https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/MySQL%20Injection.md#scientific-notation -# -# Regular expression generated from regex-assembly/942560.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942560 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)1\.e[\(\),]" \ - "id:942560,\ - phase:2,\ - block,\ - t:none,t:urlDecodeUni,t:replaceComments,\ - msg:'MySQL Scientific Notation payload detected',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# This rule tries to match JSON SQL syntax that could be used as a bypass technique. -# Referring to this research: https://claroty.com/team82/research/js-on-security-off-abusing-json-based-sql-to-bypass-waf -# -# Regular expression generated from regex-assembly/942550.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942550 -# -SecRule REQUEST_FILENAME|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx [\"'`][\[\{].*[\]\}][\"'`].*(::.*jsonb?)?.*(?:(?:@|->?)>|<@|\?[&\|]?|#>>?|[<>]|<-)|(?:(?:@|->?)>|<@|\?[&\|]?|#>>?|[<>]|<-)[\"'`][\[\{].*[\]\}][\"'`]|json_extract.*\(.*\)" \ - "id:942550,\ - phase:2,\ - block,\ - t:none,t:urlDecodeUni,t:lowercase,t:removeWhitespace,\ - msg:'JSON-Based SQL Injection',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:942013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:942014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" -# -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) -# + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'WARNING',\ + setvar:'tx.sql_injection_score=+%{tx.warning_anomaly_score}',\ + setvar:'tx.anomaly_score_pl2=+%{tx.warning_anomaly_score}'" # @@ -638,12 +525,15 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:942014,phase:2,pass,nolog,tag:'O # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/942120.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942120 +# Regexp generated from util/regexp-assemble/regexp-942120.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942120.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)!=|&&|\|\||>[=>]|<(?:<|=>?|>(?:[\s\x0b]+binary)?)|\b(?:(?:xor|r(?:egexp|like)|i(?:snull|like)|notnull)\b|collate(?:[^0-9A-Z_a-z]*?(?:U&)?[\"'`]|[^0-9A-Z_a-z]+(?:(?:binary|nocase|rtrim)\b|[0-9A-Z_a-z]*?_))|(?:likel(?:ihood|y)|unlikely)[\s\x0b]*\()|r(?:egexp|like)[\s\x0b]+binary|not[\s\x0b]+between[\s\x0b]+(?:0[\s\x0b]+and|(?:'[^']*'|\"[^\"]*\")[\s\x0b]+and[\s\x0b]+(?:'[^']*'|\"[^\"]*\"))|is[\s\x0b]+null|like[\s\x0b]+(?:null|[0-9A-Z_a-z]+[\s\x0b]+escape\b)|(?:^|[^0-9A-Z_a-z])in[\s\x0b\+]*\([\s\x0b\"0-9]+[^\(\)]*\)|[!<->]{1,2}[\s\x0b]*all\b" \ +SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:(?:^|\W)in[+\s]*\([\s\d\"]+[^()]*\)|\b(?:r(?:egexp|like)|isnull|xor)\b|<(?:>(?:\s+binary)?|=>?|<)|r(?:egexp|like)\s+binary|not\s+between\s+0\s+and|(?:like|is)\s+null|>[=>]|\|\||!=|&&))" \ "id:942120,\ phase:2,\ block,\ @@ -655,96 +545,51 @@ SecRule ARGS_NAMES|ARGS|REQUEST_FILENAME|XML:/* "@rx (?i)!=|&&|\|\||>[=>]|<(?:<| tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # # -=[ SQL Tautologies ]=- # -# Boolean-based SQL injection or tautology attack. Boolean values (True or False) are used to carry out -# this type of SQL injection. The malicious SQL query forces the web application to return a different result de- -# pending on whether the query returns a TRUE or FALSE result. +# Regexp generated from util/regexp-assemble/regexp-942130.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942130.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -# The original 942130 was split in two rules: -# - 942130 targets tautologies using equalities (e.g. 1 = 1) -# - 942131 targets tautologies using inequalities (e.g. 1 != 2) +# Not supported by re2 (backreferences, lookaheads). # -# We use captures to check for (in)equality in the regexp. So TX.1 will capture the left hand side (LHS) of the inequality, -# and TX.2 will capture the right hand side (RHS) of the logical query. -# -# Regular expression generated from regex-assembly/942130.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942130 -# -SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s\x0b\"'-\)`]*?\b([0-9A-Z_a-z]+)\b[\s\x0b\"'-\)`]*?(?:=|<=>|(?:sounds[\s\x0b]+)?like|glob|r(?:like|egexp))[\s\x0b\"'-\)`]*?\b([0-9A-Z_a-z]+)\b" \ +SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i:[\s'\"`()]*?\b([\d\w]+)\b[\s'\"`()]*?(?:<(?:=(?:[\s'\"`()]*?(?!\b\1\b)[\d\w]+|>[\s'\"`()]*?(?:\b\1\b))|>?[\s'\"`()]*?(?!\b\1\b)[\d\w]+)|(?:not\s+(?:regexp|like)|is\s+not|>=?|!=|\^)[\s'\"`()]*?(?!\b\1\b)[\d\w]+|(?:(?:sounds\s+)?like|r(?:egexp|like)|=)[\s'\"`()]*?(?:\b\1\b)))" \ "id:942130,\ phase:2,\ block,\ capture,\ t:none,t:urlDecodeUni,t:replaceComments,\ - msg:'SQL Injection Attack: SQL Boolean-based attack detected',\ - logdata:'Matched Data: %{TX.0} found within %{TX.942130_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + msg:'SQL Injection Attack: SQL Tautology Detected',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.942130_matched_var_name=%{matched_var_name}',\ - chain" - SecRule TX:1 "@streq %{TX.2}" \ - "t:none,\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# Rule Targeting logical inequalities that return TRUE (e.g. 1 != 2) -# -# -# We use captures to check for (in)equality in the regexp. So TX.1 will capture the left hand side (LHS) of the inequality, -# and TX.2 will capture the right hand side (RHS) of the logical query. -# -# Regular expression generated from regex-assembly/942131.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942131 -# -SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s\x0b\"'-\)`]*?\b([0-9A-Z_a-z]+)\b[\s\x0b\"'-\)`]*?(?:![<->]|<[=>]?|>=?|\^|is[\s\x0b]+not|not[\s\x0b]+(?:like|r(?:like|egexp)))[\s\x0b\"'-\)`]*?\b([0-9A-Z_a-z]+)\b" \ - "id:942131,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,t:replaceComments,\ - msg:'SQL Injection Attack: SQL Boolean-based attack detected',\ - logdata:'Matched Data: %{TX.0} found within %{TX.942131_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ multiMatch,\ - setvar:'tx.942131_matched_var_name=%{matched_var_name}',\ - chain" - SecRule TX:1 "!@streq %{TX.2}" \ - "t:none,\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + # # -=[ SQL Function Names ]=- @@ -752,55 +597,46 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\s\x0b\"'-\)`]*?\b([0-9A-Z_a-z]+)\b[\s\ # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/942150.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942150 +# Regexp generated from util/regexp-assemble/regexp-942150.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942150.data +# Note that after assemble an ignore case flag and a word boundary is added +# in front of the Regexp::Assemble output. +# And a non-word character and an opening bracket is added behind the Regexp::Assemble output: +# (?i)\bASSEMBLE_OUTPUT\W*\( # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:json(?:_[0-9A-Z_a-z]+)?|a(?:bs|(?:cos|sin)h?|tan[2h]?|vg)|c(?:eil(?:ing)?|h(?:a(?:nges|r(?:set)?)|r)|o(?:alesce|sh?|unt)|ast)|d(?:e(?:grees|fault)|a(?:te|y))|exp|f(?:loor(?:avg)?|ormat|ield)|g(?:lob|roup_concat)|h(?:ex|our)|i(?:f(?:null)?|if|n(?:str)?)|l(?:ast(?:_insert_rowid)?|ength|ike(?:l(?:ihood|y))?|n|o(?:ad_extension|g(?:10|2)?|wer(?:pi)?|cal)|trim)|m(?:ax|in(?:ute)?|o(?:d|nth))|n(?:ullif|ow)|p(?:i|ow(?:er)?|rintf|assword)|quote|r(?:a(?:dians|ndom(?:blob)?)|e(?:p(?:lace|eat)|verse)|ound|trim|ight)|s(?:i(?:gn|nh?)|oundex|q(?:lite_(?:compileoption_(?:get|used)|offset|source_id|version)|rt)|u(?:bstr(?:ing)?|m)|econd|leep)|t(?:anh?|otal(?:_changes)?|r(?:im|unc)|ypeof|ime)|u(?:n(?:icode|likely)|(?:pp|s)er)|zeroblob|bin|v(?:alues|ersion)|week|year)[^0-9A-Z_a-z]*\(" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:c(?:o(?:n(?:v(?:ert(?:_tz)?)?|cat(?:_ws)?|nection_id)|(?:mpres)?s|ercibility|(?:un)?t|llation|alesce)|ur(?:rent_(?:time(?:stamp)?|date|user)|(?:dat|tim)e)|h(?:ar(?:(?:acter)?_length|set)?|r)|iel(?:ing)?|ast|r32)|s(?:u(?:b(?:str(?:ing(?:_index)?)?|(?:dat|tim)e)|m)|t(?:d(?:dev_(?:sam|po)p)?|r(?:_to_date|cmp))|e(?:c(?:_to_time|ond)|ssion_user)|ys(?:tem_user|date)|ha[12]?|oundex|chema|ig?n|leep|pace|qrt)|i(?:s(?:_(?:ipv(?:4(?:_(?:compat|mapped))?|6)|n(?:ot(?:_null)?|ull)|(?:free|used)_lock)|null)|n(?:et(?:6_(?:aton|ntoa)|_(?:aton|ntoa))|s(?:ert|tr)|terval)?|f(?:null)?)|d(?:a(?:t(?:e(?:_(?:format|add|sub)|diff)?|abase)|y(?:of(?:month|week|year)|name)?)|e(?:(?:s_(?:de|en)cryp|faul)t|grees|code)|count|ump)|l(?:o(?:ca(?:l(?:timestamp)?|te)|g(?:10|2)?|ad_file|wer)|ast(?:_(?:inser_id|day))?|e(?:(?:as|f)t|ngth)|case|trim|pad|n)|u(?:n(?:compress(?:ed_length)?|ix_timestamp|hex)|tc_(?:time(?:stamp)?|date)|p(?:datexml|per)|uid(?:_short)?|case|ser)|t(?:ime(?:_(?:format|to_sec)|stamp(?:diff|add)?|diff)?|o(?:(?:second|day)s|_base64|n?char)|r(?:uncate|im)|an)|m(?:a(?:ke(?:_set|date)|ster_pos_wait|x)|i(?:(?:crosecon)?d|n(?:ute)?)|o(?:nth(?:name)?|d)|d5)|r(?:e(?:p(?:lace|eat)|lease_lock|verse)|a(?:wtohex|dians|nd)|o(?:w_count|und)|ight|trim|pad)|f(?:i(?:eld(?:_in_set)?|nd_in_set)|rom_(?:unixtime|base64|days)|o(?:und_rows|rmat)|loor)|p(?:o(?:w(?:er)?|sition)|eriod_(?:diff|add)|rocedure_analyse|assword|g_sleep|i)|a(?:s(?:cii(?:str)?|in)|es_(?:de|en)crypt|dd(?:dat|tim)e|(?:co|b)s|tan2?|vg)|b(?:i(?:t_(?:length|count|x?or|and)|n(?:_to_num)?)|enchmark)|e(?:x(?:tract(?:value)?|p(?:ort_set)?)|nc(?:rypt|ode)|lt)|g(?:r(?:oup_conca|eates)t|et_(?:format|lock))|v(?:a(?:r(?:_(?:sam|po)p|iance)|lues)|ersion)|o(?:(?:ld_passwo)?rd|ct(?:et_length)?)|we(?:ek(?:ofyear|day)?|ight_string)|n(?:o(?:t_in|w)|ame_const|ullif)|h(?:ex(?:toraw)?|our)|qu(?:arter|ote)|year(?:week)?|xmltype)\W*\(" \ "id:942150,\ phase:2,\ block,\ capture,\ - t:none,t:urlDecodeUni,\ - msg:'SQL Injection Attack: SQL function name detected',\ + t:none,t:urlDecodeUni,t:lowercase,\ + msg:'SQL Injection Attack',\ logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" +# Regexp generated from util/regexp-assemble/regexp-942180.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942180.data +# Note that after assemble an ignore case flag is inserted in the +# first non-capturing group from the Regexp::Assemble output: +# ASSEMBLE_OUTPUT | s/^(?:/(?i:/ # -# -=[ SQL Authentication Bypasses ]=- -# -# Authentication bypass occurs when the attacker can log in as another user -# without knowing the user's password. The example bypass could look like this: -# -# x' OR 'x -# -# Because of the quantity of different rules they are split into: -# - 942540 PL1 -# - 942180 PL2 -# - 942260 PL2 -# - 942340 PL2 -# - 942520 PL2 -# - 942521 PL2 -# - 942522 PL2 - -# Regular expression generated from regex-assembly/942180.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942180 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:/\*)+[\"'`]+[\s\x0b]?(?:--|[#\{]|/\*)?|[\"'`](?:[\s\x0b]*(?:(?:x?or|and|div|like|between)[\s\x0b\-0-9A-Z_a-z]+[\(\)\+-\-<->][\s\x0b]*[\"'0-9`]|[!=\|](?:[\s\x0b!\+\-0-9=]+.*?[\"'\(`].*?|[\s\x0b!0-9=]+.*?[0-9]+)$|(?:like|print)[^0-9A-Z_a-z]+[\"'\(0-9A-Z_-z]|;)|(?:[<>~]+|[\s\x0b]*[^\s\x0b0-9A-Z_a-z]?=[\s\x0b]*|[^0-9A-Z_a-z]*?[\+=]+[^0-9A-Z_a-z]*?)[\"'`])|[0-9][\"'`][\s\x0b]+[\"'`][\s\x0b]+[0-9]|^admin[\s\x0b]*?[\"'`]|[\s\x0b\"'\(`][\s\x0b]*?glob[^0-9A-Z_a-z]+[\"'\(0-9A-Z_-z]|[\s\x0b]is[\s\x0b]*?0[^0-9A-Z_a-z]|where[\s\x0b][\s\x0b,-\.0-9A-Z_a-z]+[\s\x0b]=" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:[\"'`](?:\s*?(?:(?:between|x?or|and|div)[\w\s-]+\s*?[+<>=(),-]\s*?[\d\"'`]|like(?:[\w\s-]+\s*?[+<>=(),-]\s*?[\d\"'`]|\W+[\w\"'`(])|[!=|](?:[\d\s!=+-]+.*?[\"'`(].*?|[\d\s!=]+.*?\d+)$|[^\w\s]?=\s*?[\"'`])|(?:\W*?[+=]+\W*?|[<>~]+)[\"'`])|(?:/\*)+[\"'`]+\s?(?:\/\*|--|\{|#)?|\d[\"'`]\s+[\"'`]\s+\d|where\s[\s\w\.,-]+\s=|^admin\s*?[\"'`]|\sis\s*?0\W)" \ "id:942180,\ phase:2,\ block,\ @@ -812,24 +648,27 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/942200.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942200 +# Regexp generated from util/regexp-assemble/regexp-942200.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942200.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "@rx (?i),.*?[\"'\)0-9`-f][\"'`](?:[\"'`].*?[\"'`]|(?:\r?\n)?\z|[^\"'`]+)|[^0-9A-Z_a-z]select.+[^0-9A-Z_a-z]*?from|(?:alter|(?:(?:cre|trunc|upd)at|renam)e|d(?:e(?:lete|sc)|rop)|(?:inser|selec)t|load)[\s\x0b]*?\([\s\x0b]*?space[\s\x0b]*?\(" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:(?:(?:(?:trunc|cre|upd)at|renam)e|(?:inser|selec)t|de(?:lete|sc)|alter|load)\s*?\(\s*?space\s*?\(|,.*?[)\da-f\"'`][\"'`](?:[\"'`].*?[\"'`]|(?:\r?\n)?\z|[^\"'`]+)|\Wselect.+\W*?from))" \ "id:942200,\ phase:2,\ block,\ @@ -841,24 +680,27 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/942210.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942210 +# Regexp generated from util/regexp-assemble/regexp-942210.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942210.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:&&|\|\||and|between|div|like|n(?:and|ot)|(?:xx?)?or)[\s\x0b\(]+[0-9A-Z_a-z]+[\s\x0b\)]*?[!\+=]+[\s\x0b0-9]*?[\"'-\)=`]|[0-9](?:[\s\x0b]*?(?:and|between|div|like|x?or)[\s\x0b]*?[0-9]+[\s\x0b]*?[\+\-]|[\s\x0b]+group[\s\x0b]+by.+\()|/[0-9A-Z_a-z]+;?[\s\x0b]+(?:and|between|div|having|like|x?or|select)[^0-9A-Z_a-z]|(?:[#;]|--)[\s\x0b]*?(?:alter|drop|(?:insert|update)[\s\x0b]*?[0-9A-Z_a-z]{2,})|@.+=[\s\x0b]*?\([\s\x0b]*?select|[^0-9A-Z_a-z]SET[\s\x0b]*?@[0-9A-Z_a-z]+" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:(?:n(?:and|ot)|(?:x?x)?or|between|\|\||like|and|div|&&)[\s(]+\w+[\s)]*?[!=+]+[\s\d]*?[\"'`=()]|\d(?:\s*?(?:between|like|x?or|and|div)\s*?\d+\s*?[\-+]|\s+group\s+by.+\()|\/\w+;?\s+(?:between|having|select|like|x?or|and|div)\W|--\s*?(?:(?:insert|update)\s*?\w{2,}|alter|drop)|#\s*?(?:(?:insert|update)\s*?\w{2,}|alter|drop)|;\s*?(?:(?:insert|update)\s*?\w{2,}|alter|drop)|\@.+=\s*?\(\s*?select|[^\w]SET\s*?\@\w+))" \ "id:942210,\ phase:2,\ block,\ @@ -870,21 +712,24 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942260.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942260 +# Regexp generated from util/regexp-assemble/regexp-942260.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble-v2.pl regexp-942260.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# ASSEMBLE_OUTPUT | s/^(?:/(?i:/ # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\"'`][\s\x0b]*?(?:(?:and|n(?:and|ot)|(?:xx?)?or|div|like|between|\|\||&&)[\s\x0b]+[\s\x0b0-9A-Z_a-z]+=[\s\x0b]*?[0-9A-Z_a-z]+[\s\x0b]*?having[\s\x0b]+|like[^0-9A-Z_a-z]*?[\"'0-9`])|[0-9A-Z_a-z][\s\x0b]+like[\s\x0b]+[\"'`]|like[\s\x0b]*?[\"'`]%|select[\s\x0b]+?[\s\x0b\"'-\),-\.0-9A-\[\]_-z]+from[\s\x0b]+" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:[\"'`]\s*?(?:(?:n(?:and|ot)|(?:x?x)?or|between|\|\||and|div|&&)\s+[\s\w]+=\s*?\w+\s*?having\s+|like(?:\s+[\s\w]+=\s*?\w+\s*?having\s+|\W*?[\"'`\d])|[^?\w\s=.,;)(]++\s*?[(@\"'`]*?\s*?\w+\W+\w|\*\s*?\w+\W+[\"'`])|(?:union\s*?(?:distinct|[(!@]*?|all)?\s*?[([]*?\s*?select|select\s+?[\[\]()\s\w\.,\"'`-]+from)\s+|\w\s+like\s+[\"'`]|find_in_set\s*?\(|like\s*?[\"'`]%)" \ "id:942260,\ phase:2,\ block,\ @@ -896,21 +741,24 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942300.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942300 +# Regexp generated from util/regexp-assemble/regexp-942300.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942300.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\)[\s\x0b]*?when[\s\x0b]*?[0-9]+[\s\x0b]*?then|[\"'`][\s\x0b]*?(?:[#\{]|--)|/\*![\s\x0b]?[0-9]+|\b(?:(?:binary|cha?r)[\s\x0b]*?\([\s\x0b]*?[0-9]|(?:and|n(?:and|ot)|(?:xx?)?or|div|like|between|r(?:egexp|like))[\s\x0b]+[0-9A-Z_a-z]+\()|(?:\|\||&&)[\s\x0b]*?[0-9A-Z_a-z]+\(" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:(?:n(?:and|ot)|(?:x?x)?or|between|\|\||like|and|div|&&)\s+\s*?\w+\(|\)\s*?when\s*?\d+\s*?then|[\"'`]\s*?(?:--|\{|#)|cha?r\s*?\(\s*?\d|\/\*!\s?\d+))" \ "id:942300,\ phase:2,\ block,\ @@ -922,21 +770,24 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942310.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942310 +# Regexp generated from util/regexp-assemble/regexp-942310.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942310.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:\([\s\x0b]*?select[\s\x0b]*?[0-9A-Z_a-z]+|coalesce|order[\s\x0b]+by[\s\x0b]+if[0-9A-Z_a-z]*?)[\s\x0b]*?\(|\*/from|\+[\s\x0b]*?[0-9]+[\s\x0b]*?\+[\s\x0b]*?@|[0-9A-Z_a-z][\"'`][\s\x0b]*?(?:(?:[\+\-=@\|]+[\s\x0b]+?)+|[\+\-=@\|]+)[\(0-9]|@@[0-9A-Z_a-z]+[\s\x0b]*?[^\s\x0b0-9A-Z_a-z]|[^0-9A-Z_a-z]!+[\"'`][0-9A-Z_a-z]|[\"'`](?:;[\s\x0b]*?(?:if|while|begin)|[\s\x0b0-9]+=[\s\x0b]*?[0-9])|[\s\x0b\(]+case[0-9]*?[^0-9A-Z_a-z].+[tw]hen[\s\x0b\(]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:[\"'`](?:;\s*?(?:begin|while|if)|[\s\d]+=\s*?\d|\s+and\s*?=\W)|(?:\(\s*?select\s*?\w+|order\s+by\s+if\w*?|coalesce)\s*?\(|\w[\"'`]\s*?(?:(?:[-+=|@]+\s+?)+|[-+=|@]+)[\d(]|[\s(]+case\d*?\W.+[tw]hen[\s(]|\+\s*?\d+\s*?\+\s*?\@|\@\@\w+\s*?[^\w\s]|\W!+[\"'`]\w|\*\/from))" \ "id:942310,\ phase:2,\ block,\ @@ -948,14 +799,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # # -=[ SQL Injection Probings ]=- @@ -965,12 +816,15 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME # 942330 PL 2 # 942370 PL 2 # 942490 PL 3 -# Regular expression generated from regex-assembly/942330.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942330 +# Regexp generated from util/regexp-assemble/regexp-942330.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942330.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\"'`][\s\x0b]*?\b(?:x?or|div|like|between|and)\b[\s\x0b]*?[\"'`]?[0-9]|\x5cx(?:2[37]|3d)|^(?:.?[\"'`]$|[\"'\x5c`]*?(?:[\"'0-9`]+|[^\"'`]+[\"'`])[\s\x0b]*?\b(?:and|n(?:and|ot)|(?:xx?)?or|div|like|between|\|\||&&)\b[\s\x0b]*?[\"'0-9A-Z_-z][!&\(\)\+-\.@])|[^\s\x0b0-9A-Z_a-z][0-9A-Z_a-z]+[\s\x0b]*?[\-\|][\s\x0b]*?[\"'`][\s\x0b]*?[0-9A-Z_a-z]|@(?:[0-9A-Z_a-z]+[\s\x0b]+(?:and|x?or|div|like|between)\b[\s\x0b]*?[\"'0-9`]+|[\-0-9A-Z_a-z]+[\s\x0b](?:and|x?or|div|like|between)\b[\s\x0b]*?[^\s\x0b0-9A-Z_a-z])|[^\s\x0b0-:A-Z_a-z][\s\x0b]*?[0-9][^0-9A-Z_a-z]+[^\s\x0b0-9A-Z_a-z][\s\x0b]*?[\"'`].|[^0-9A-Z_a-z]information_schema|table_name[^0-9A-Z_a-z]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:^(?:[\"'`\\\\]*?(?:[^\"'`]+[\"'`]|[\d\"'`]+)\s*?(?:n(?:and|ot)|(?:x?x)?or|between|\|\||like|and|div|&&)\s*?[\w\"'`][+&!@(),.-]|.?[\"'`]$)|\@(?:[\w-]+\s(?:between|like|x?or|and|div)\s*?[^\w\s]|\w+\s+(?:between|like|x?or|and|div)\s*?[\"'`\d]+)|[\"'`]\s*?(?:between|like|x?or|and|div)\s*?[\"'`]?\d|[^\w\s:]\s*?\d\W+[^\w\s]\s*?[\"'`].|[^\w\s]\w+\s*?[|-]\s*?[\"'`]\s*?\w|\Winformation_schema|\\\\x(?:23|27|3d)|table_name\W))" \ "id:942330,\ phase:2,\ block,\ @@ -982,24 +836,26 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942340.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942340 +# Regexp generated from util/regexp-assemble/regexp-942340.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942340.data +# Note that part of regexp-942340.data is already optimized, to avoid a +# Regexp::Assemble behaviour, where the regex is not optimized very nicely. +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -# Note that part of 942340.data is already optimized, to avoid a -# Regexp::Assemble behaviour, where the regex is not optimized very nicely. -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)in[\s\x0b]*?\(+[\s\x0b]*?select|(?:(?:N?AND|X?X?OR|DIV|LIKE|BETWEEN|NOT)[\s\x0b]+|(?:\|\||&&)[\s\x0b]*)[\s\x0b\+0-9A-Z_a-z]+(?:regexp[\s\x0b]*?\(|sounds[\s\x0b]+like[\s\x0b]*?[\"'`]|[0-9=]+x)|[\"'`](?:[\s\x0b]*?(?:[0-9][\s\x0b]*?(?:--|#)|is[\s\x0b]*?(?:[0-9].+[\"'`]?[0-9A-Z_a-z]|[\.0-9]+[\s\x0b]*?[^0-9A-Z_a-z].*?[\"'`]))|[%&<->\^]+[0-9][\s\x0b]*?(?:=|x?or|div|like|between|and)|(?:[^0-9A-Z_a-z]+[\+\-0-9A-Z_a-z]+[\s\x0b]*?=[\s\x0b]*?[0-9][^0-9A-Z_a-z]+|\|?[\-0-9A-Z_a-z]{3,}[^\s\x0b,\.0-9A-Z_a-z]+)[\"'`]|[\s\x0b]*(?:(?:N?AND|X?X?OR|DIV|LIKE|BETWEEN|NOT)[\s\x0b]+|(?:\|\||&&)[\s\x0b]*)(?:array[\s\x0b]*\[|[0-9A-Z_a-z]+(?:[\s\x0b]*!?~|[\s\x0b]+(?:not[\s\x0b]+)?similar[\s\x0b]+to[\s\x0b]+)|(?:tru|fals)e\b))|\bexcept[\s\x0b]+(?:select\b|values[\s\x0b]*?\()" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:[\"'`](?:\s*?(?:is\s*?(?:[\d.]+\s*?\W.*?[\"'`]|\d.+[\"'`]?\w)|\d\s*?(?:--|#))|(?:\W+[\w+-]+\s*?=\s*?\d\W+|\|?[\w-]{3,}[^\w\s.,]+)[\"'`]|[\%&<>^=]+\d\s*?(?:between|like|x?or|and|div|=))|(?i:n?and|x?x?or|div|like|between|not|\|\||\&\&)\s+[\s\w+]+(?:sounds\s+like\s*?[\"'`]|regexp\s*?\(|[=\d]+x)|in\s*?\(+\s*?select))" \ "id:942340,\ phase:2,\ block,\ @@ -1011,14 +867,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # This rule is a stricter sibling of 942360. # The keywords 'alter' and 'union' led to false positives. @@ -1036,57 +892,29 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# This rule is a stricter sibling of 942360. -# The loose word boundaries and light context led to false positives. -# Because the stricter variant does miss quite a few legitimate payloads, the loose version was moved to PL2. -# -# Regular expression generated from regex-assembly/942362.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942362 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)(?:alter|(?:(?:cre|trunc|upd)at|renam)e|de(?:lete|sc)|(?:inser|selec)t|load)[\s\x0b]+(?:char|group_concat|load_file)[\s\x0b]?\(?|end[\s\x0b]*?\);|[\s\x0b\(]load_file[\s\x0b]*?\(|[\"'`][\s\x0b]+regexp[^0-9A-Z_a-z]|[^A-Z_a-z][\s\x0b]+as\b[\s\x0b]*[\"'0-9A-Z_-z]+[\s\x0b]*\bfrom|^[^A-Z_a-z]+[\s\x0b]*?(?:create[\s\x0b]+[0-9A-Z_a-z]+|(?:d(?:e(?:lete|sc)|rop)|(?:inser|selec)t|load|(?:renam|truncat)e|u(?:pdate|nion[\s\x0b]*(?:all|(?:sele|distin)ct))|alter[\s\x0b]*(?:a(?:(?:ggregat|pplication[\s\x0b]*rol)e|s(?:sembl|ymmetric[\s\x0b]*ke)y|u(?:dit|thorization)|vailability[\s\x0b]*group)|b(?:roker[\s\x0b]*priority|ufferpool)|c(?:ertificate|luster|o(?:l(?:latio|um)|nversio)n|r(?:edential|yptographic[\s\x0b]*provider))|d(?:atabase|efault|i(?:mension|skgroup)|omain)|e(?:(?:ndpoi|ve)nt|xte(?:nsion|rnal))|f(?:lashback|oreign|u(?:lltext|nction))|hi(?:erarchy|stogram)|group|in(?:dex(?:type)?|memory|stance)|java|l(?:a(?:ngua|r)ge|ibrary|o(?:ckdown|g(?:file[\s\x0b]*group|in)))|m(?:a(?:s(?:k|ter[\s\x0b]*key)|terialized)|e(?:ssage[\s\x0b]*type|thod)|odule)|(?:nicknam|queu)e|o(?:perator|utline)|p(?:a(?:ckage|rtition)|ermission|ro(?:cedur|fil)e)|r(?:e(?:mot|sourc)e|o(?:l(?:e|lback)|ute))|s(?:chema|e(?:arch|curity|rv(?:er|ice)|quence|ssion)|y(?:mmetric[\s\x0b]*key|nonym)|togroup)|t(?:able(?:space)?|ext|hreshold|r(?:igger|usted)|ype)|us(?:age|er)|view|w(?:ork(?:load)?|rapper)|x(?:ml[\s\x0b]*schema|srobject)))\b)" \ - "id:942362,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Detects concatenated basic SQL injection and SQLLFI attempts',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # This rule is a sibling of 942330. See that rule for a description and overview. # # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/942370.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942370 +# Regexp generated from util/regexp-assemble/regexp-942370.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942370.data +# Note that after assemble an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS:Referer|REQUEST_HEADERS:User-Agent|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\"'`](?:[\s\x0b]*?(?:(?:\*.+(?:x?or|div|like|between|(?:an|i)d)[^0-9A-Z_a-z]*?[\"'`]|(?:x?or|div|like|between|and)[\s\x0b][^0-9]+[\-0-9A-Z_a-z]+.*?)[0-9]|[^\s\x0b0-9\?A-Z_a-z]+[\s\x0b]*?[^\s\x0b0-9A-Z_a-z]+[\s\x0b]*?[\"'`]|[^\s\x0b0-9A-Z_a-z]+[\s\x0b]*?[^A-Z_a-z].*?(?:#|--))|.*?\*[\s\x0b]*?[0-9])|\^[\"'`]|[%\(-\+\-<>][\-0-9A-Z_a-z]+[^\s\x0b0-9A-Z_a-z]+[\"'`][^,]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:[\"'`](?:\s*?(?:(?:\*.+(?:(?:an|i)d|between|like|x?or|div)\W*?[\"'`]|(?:between|like|x?or|and|div)\s[^\d]+[\w-]+.*?)\d|[^\w\s?]+\s*?[^\w\s]+\s*?[\"'`]|[^\w\s]+\s*?[\W\d].*?(?:--|#))|.*?\*\s*?\d)|[()\*<>%+-][\w-]+[^\w\s]+[\"'`][^,]|\^[\"'`])" \ "id:942370,\ phase:2,\ block,\ @@ -1098,21 +926,21 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_H tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942380.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942380 +# Regexp generated from util/regexp-assemble/regexp-942380.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942380.data # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:having\b(?:[\s\x0b]+(?:[0-9]{1,10}|'[^=]{1,10}')[\s\x0b]*?[<->]| ?(?:[0-9]{1,10} ?[<->]+|[\"'][^=]{1,10}[ \"'<-\?\[]+))|ex(?:ecute(?:\(|[\s\x0b]{1,5}[\$\.0-9A-Z_a-z]{1,5}[\s\x0b]{0,3})|ists[\s\x0b]*?\([\s\x0b]*?select\b)|(?:create[\s\x0b]+?table.{0,20}?|like[^0-9A-Z_a-z]*?char[^0-9A-Z_a-z]*?)\()|select.*?case|from.*?limit|order[\s\x0b]by|exists[\s\x0b](?:[\s\x0b]select|s(?:elect[^\s\x0b](?:if(?:null)?[\s\x0b]\(|top|concat)|ystem[\s\x0b]\()|\bhaving\b[\s\x0b]+[0-9]{1,10}|'[^=]{1,10}')" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:\b(?:having\b ?(?:[\'\"][^=]{1,10}[\'\" ?[=<>]+|\d{1,10} ?[=<>]+)|(?i:having)\b\s+(?:'[^=]{1,10}'|\d{1,10})\s*?[=<>])|exists\s(?:s(?:elect\S(?:if(?:null)?\s\(|concat|top)|ystem\s\()|\b(?i:having)\b\s+\d{1,10}|'[^=]{1,10}'|\sselect)|(?i:\bexecute\s{1,5}[\w\.$]{1,5}\s{0,3})|(?i:\bcreate\s+?table.{0,20}?\()|(?i:\blike\W*?char\W*?\()|(?i:select.*?case)|(?i:from.*?limit)|(?i:\bexecute\()|(?i:order\sby))" \ "id:942380,\ phase:2,\ block,\ @@ -1124,21 +952,22 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942390.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942390 +# Regexp generated from util/regexp-assemble/regexp-942390.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942390.data # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:or\b(?:[\s\x0b]?(?:[0-9]{1,10}|[\"'][^=]{1,10}[\"'])[\s\x0b]?[<->]+|[\s\x0b]+(?:[0-9]{1,10}|'[^=]{1,10}')(?:[\s\x0b]*?[<->])?)|xor\b[\s\x0b]+(?:[0-9]{1,10}|'[^=]{1,10}')(?:[\s\x0b]*?[<->])?)|'[\s\x0b]+x?or[\s\x0b]+.{1,20}[!\+\-<->]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:\b(?:(?i:xor)\b\s+(?:'[^=]{1,10}'(?:\s*?[=<>])?|\d{1,10}(?:\s*?[=<>])?)|(?i:or)\b\s+(?:'[^=]{1,10}'(?:\s*?[=<>])?|\d{1,10}(?:\s*?[=<>])?))|(?i:\bor\b ?[\'\"][^=]{1,10}[\'\"] ?[=<>]+)|(?i:'\s+xor\s+.{1,20}[+\-!<>=])|(?i:'\s+or\s+.{1,20}[+\-!<>=])|(?i:\bor\b ?\d{1,10} ?[=<>]+))" \ "id:942390,\ phase:2,\ block,\ @@ -1150,21 +979,25 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942400.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942400 +# Regexp generated from util/regexp-assemble/regexp-942400.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942400.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\band\b(?:[\s\x0b]+(?:[0-9]{1,10}[\s\x0b]*?[<->]|'[^=]{1,10}')| ?(?:[0-9]{1,10}|[\"'][^=]{1,10}[\"']) ?[<->]+)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:\band\b(?:\s+(?:'[^=]{1,10}'(?:\s*?[=<>])?|\d{1,10}(?:\s*?[=<>])?)| ?(?:[\'\"][^=]{1,10}[\'\"]|\d{1,10}) ?[=<>]+))" \ "id:942400,\ phase:2,\ block,\ @@ -1176,26 +1009,32 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # The former rule id 942410 was split into three new rules: 942410, 942470, 942480 # # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] # -# Regular expression generated from regex-assembly/942410.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942410 +# Regexp generated from util/regexp-assemble/regexp-942410.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942410.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output. +# And a word boundary is added before and a non-word character with an opening bracket +# is added after the Regexp::Assemble output: +# (?i:\bASSEMBLE_OUTPUT\W*?\() # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:a(?:(?:b|co)s|dd(?:dat|tim)e|es_(?:de|en)crypt|s(?:in|cii(?:str)?)|tan2?|vg)|b(?:enchmark|i(?:n(?:_to_num)?|t_(?:and|count|length|x?or)))|c(?:ast|h(?:ar(?:(?:acter)?_length|set)?|r)|iel(?:ing)?|o(?:alesce|ercibility|(?:mpres)?s|n(?:cat(?:_ws)?|nection_id|v(?:ert(?:_tz)?)?)|(?:un)?t)|r32|ur(?:(?:dat|tim)e|rent_(?:date|time(?:stamp)?|user)))|d(?:a(?:t(?:abase|e(?:_(?:add|format|sub)|diff)?)|y(?:name|of(?:month|week|year))?)|count|e(?:code|(?:faul|s_(?:de|en)cryp)t|grees)|ump)|e(?:lt|nc(?:ode|rypt)|x(?:p(?:ort_set)?|tract(?:value)?))|f(?:i(?:eld(?:_in_set)?|nd_in_set)|loor|o(?:rmat|und_rows)|rom_(?:base64|days|unixtime))|g(?:et_(?:format|lock)|r(?:eates|oup_conca)t)|h(?:ex(?:toraw)?|our)|i(?:f(?:null)?|n(?:et6?_(?:aton|ntoa)|s(?:ert|tr)|terval)?|s(?:_(?:(?:free|used)_lock|ipv(?:4(?:_(?:compat|mapped))?|6)|n(?:ot(?:_null)?|ull))|null)?)|l(?:ast(?:_(?:day|insert_id))?|case|e(?:(?:as|f)t|ngth)|n|o(?:ad_file|ca(?:l(?:timestamp)?|te)|g(?:10|2)?|wer)|pad|trim)|m(?:a(?:ke(?:date|_set)|ster_pos_wait|x)|d5|i(?:(?:crosecon)?d|n(?:ute)?)|o(?:d|nth(?:name)?))|n(?:ame_const|o(?:t_in|w)|ullif)|o(?:ct(?:et_length)?|(?:ld_passwo)?rd)|p(?:assword|eriod_(?:add|diff)|g_sleep|i|o(?:sition|w(?:er)?)|rocedure_analyse)|qu(?:arter|ote)|r(?:a(?:dians|nd|wto(?:hex|nhex(?:toraw)?))|e(?:lease_lock|p(?:eat|lace)|verse)|ight|o(?:und|w_count)|pad|trim)|s(?:chema|e(?:c(?:ond|_to_time)|ssion_user)|ha[12]?|ig?n|leep|oundex|pace|qrt|t(?:d(?:dev(?:_(?:po|sam)p)?)?|r(?:cmp|_to_date))|u(?:b(?:(?:dat|tim)e|str(?:ing(?:_index)?)?)|m)|ys(?:date|tem_user))|t(?:an|ime(?:diff|_(?:format|to_sec)|stamp(?:add|diff)?)?|o_(?:base64|n?char|(?:day|second)s)|r(?:im|uncate))|u(?:case|n(?:compress(?:ed_length)?|hex|ix_timestamp)|p(?:datexml|per)|ser|tc_(?:date|time(?:stamp)?)|uid(?:_short)?)|v(?:a(?:lues|r(?:iance|_(?:po|sam)p))|ersion)|we(?:ek(?:day|ofyear)?|ight_string)|xmltype|year(?:week)?)[^0-9A-Z_a-z]*?\(" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:\b(?:c(?:o(?:n(?:v(?:ert(?:_tz)?)?|cat(?:_ws)?|nection_id)|(?:mpres)?s|ercibility|(?:un)?t|alesce)|ur(?:rent_(?:time(?:stamp)?|date|user)|(?:dat|tim)e)|h(?:ar(?:(?:acter)?_length|set)?|r)|iel(?:ing)?|ast|r32)|s(?:t(?:d(?:dev(?:_(?:sam|po)p)?)?|r(?:_to_date|cmp))|u(?:b(?:str(?:ing(?:_index)?)?|(?:dat|tim)e)|m)|e(?:c(?:_to_time|ond)|ssion_user)|ys(?:tem_user|date)|ha[12]?|oundex|chema|ig?n|leep|pace|qrt)|i(?:s(?:_(?:ipv(?:4(?:_(?:compat|mapped))?|6)|n(?:ot(?:_null)?|ull)|(?:free|used)_lock)|null)?|n(?:et(?:6_(?:aton|ntoa)|_(?:aton|ntoa))|s(?:ert|tr)|terval)?|f(?:null)?)|d(?:a(?:t(?:e(?:_(?:format|add|sub)|diff)?|abase)|y(?:of(?:month|week|year)|name)?)|e(?:(?:s_(?:de|en)cryp|faul)t|grees|code)|count|ump)|l(?:o(?:ca(?:l(?:timestamp)?|te)|g(?:10|2)?|ad_file|wer)|ast(?:_(?:insert_id|day))?|e(?:(?:as|f)t|ngth)|case|trim|pad|n)|u(?:n(?:compress(?:ed_length)?|ix_timestamp|hex)|tc_(?:time(?:stamp)?|date)|p(?:datexml|per)|uid(?:_short)?|case|ser)|r(?:a(?:wto(?:nhex(?:toraw)?|hex)|dians|nd)|e(?:p(?:lace|eat)|lease_lock|verse)|o(?:w_count|und)|ight|trim|pad)|t(?:ime(?:_(?:format|to_sec)|stamp(?:diff|add)?|diff)?|o_(?:(?:second|day)s|base64|n?char)|r(?:uncate|im)|an)|m(?:a(?:ke(?:_set|date)|ster_pos_wait|x)|i(?:(?:crosecon)?d|n(?:ute)?)|o(?:nth(?:name)?|d)|d5)|f(?:i(?:eld(?:_in_set)?|nd_in_set)|rom_(?:unixtime|base64|days)|o(?:und_rows|rmat)|loor)|p(?:o(?:w(?:er)?|sition)|eriod_(?:diff|add)|rocedure_analyse|assword|g_sleep|i)|a(?:s(?:cii(?:str)?|in)|es_(?:de|en)crypt|dd(?:dat|tim)e|(?:co|b)s|tan2?|vg)|b(?:i(?:t_(?:length|count|x?or|and)|n(?:_to_num)?)|enchmark)|e(?:x(?:tract(?:value)?|p(?:ort_set)?)|nc(?:rypt|ode)|lt)|g(?:r(?:oup_conca|eates)t|et_(?:format|lock))|v(?:a(?:r(?:_(?:sam|po)p|iance)|lues)|ersion)|o(?:(?:ld_passwo)?rd|ct(?:et_length)?)|we(?:ek(?:ofyear|day)?|ight_string)|n(?:o(?:t_in|w)|ame_const|ullif)|h(?:ex(?:toraw)?|our)|qu(?:arter|ote)|year(?:week)?|xmltype)\W*?\()" \ "id:942410,\ phase:2,\ block,\ @@ -1207,24 +1046,28 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # The former rule id 942410 was split into three new rules: 942410, 942470, 942480 # -# Regular expression generated from regex-assembly/942470.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942470 +# Regexp generated from util/regexp-assemble/regexp-942470.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942470.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)autonomous_transaction|(?:current_use|n?varcha|tbcreato)r|db(?:a_users|ms_java)|open(?:owa_util|query|rowset)|s(?:p_(?:(?:addextendedpro|sqlexe)c|execute(?:sql)?|help|is_srvrolemember|makewebtask|oacreate|p(?:assword|repare)|replwritetovarbin)|ql_(?:longvarchar|variant))|utl_(?:file|http)|xp_(?:availablemedia|(?:cmdshel|servicecontro)l|dirtree|e(?:numdsn|xecresultset)|filelist|loginconfig|makecab|ntsec(?:_enumdomains)?|reg(?:addmultistring|delete(?:key|value)|enum(?:key|value)s|re(?:ad|movemultistring)|write)|terminate(?:_process)?)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:xp_(?:reg(?:re(?:movemultistring|ad)|delete(?:value|key)|enum(?:value|key)s|addmultistring|write)|(?:servicecontro|cmdshel)l|e(?:xecresultset|numdsn)|ntsec(?:_enumdomains)?|terminate(?:_process)?|availablemedia|loginconfig|filelist|dirtree|makecab)|s(?:p_(?:(?:addextendedpro|sqlexe)c|p(?:assword|repare)|replwritetovarbin|is_srvrolemember|execute(?:sql)?|makewebtask|oacreate|help)|ql_(?:longvarchar|variant))|open(?:owa_util|rowset|query)|(?:n?varcha|tbcreato)r|autonomous_transaction|db(?:a_users|ms_java)|utl_(?:file|http)))" \ "id:942470,\ phase:2,\ block,\ @@ -1236,24 +1079,28 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # The former rule id 942410 was split into three new rules: 942410, 942470, 942480 # -# Regular expression generated from regex-assembly/942480.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942480 +# Regexp generated from util/regexp-assemble/regexp-942480.data using Regexp::Assemble. +# To rebuild the regexp: +# cd util/regexp-assemble +# ./regexp-assemble.pl regexp-942480.data +# Note that after assemble an outer bracket with an ignore case flag is added +# to the Regexp::Assemble output: +# (?i:ASSEMBLE_OUTPUT) # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\b(?:(?:d(?:bms_[0-9A-Z_a-z]+\.|elete\b[^0-9A-Z_a-z]*?\bfrom)|(?:group\b.*?\bby\b.{1,100}?\bhav|overlay\b[^0-9A-Z_a-z]*?\(.*?\b[^0-9A-Z_a-z]*?plac)ing|in(?:ner\b[^0-9A-Z_a-z]*?\bjoin|sert\b[^0-9A-Z_a-z]*?\binto|to\b[^0-9A-Z_a-z]*?\b(?:dump|out)file)|load\b[^0-9A-Z_a-z]*?\bdata\b.*?\binfile|s(?:elect\b.{1,100}?\b(?:(?:.*?\bdump\b.*|(?:count|length)\b.{1,100}?)\bfrom|(?:data_typ|from\b.{1,100}?\bwher)e|instr|to(?:_(?:cha|numbe)r|p\b.{1,100}?\bfrom))|ys_context)|u(?:nion\b.{1,100}?\bselect|tl_inaddr))\b|print\b[^0-9A-Z_a-z]*?@@)|(?:collation[^0-9A-Z_a-z]*?\(a|@@version|;[^0-9A-Z_a-z]*?\b(?:drop|shutdown))\b|'(?:dbo|msdasql|s(?:a|qloledb))'" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:(?:\b(?:(?:s(?:elect\b.{1,100}?\b(?:(?:(?:length|count)\b.{1,100}?|.*?\bdump\b.*)\bfrom|to(?:p\b.{1,100}?\bfrom|_(?:numbe|cha)r)|(?:from\b.{1,100}?\bwher|data_typ)e|instr)|ys_context)|in(?:to\b\W*?\b(?:dump|out)file|sert\b\W*?\binto|ner\b\W*?\bjoin)|u(?:nion\b.{1,100}?\bselect|tl_inaddr)|group\b.*?\bby\b.{1,100}?\bhaving|d(?:elete\b\W*?\bfrom|bms_\w+\.)|load\b\W*?\bdata\b.*?\binfile)\b|print\b\W*?\@\@)|(?:;\W*?\b(?:shutdown|drop)|collation\W*?\(a|\@\@version)\b|'(?:s(?:qloledb|a)|msdasql|dbo)'))" \ "id:942480,\ phase:2,\ block,\ @@ -1265,14 +1112,15 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # @@ -1306,44 +1154,15 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx ((?:[~!@#\$%\^&\*\(\)\-\+=\{\}\[\]\|:;\"'´ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.warning_anomaly_score}',\ + setvar:'tx.anomaly_score_pl2=+%{tx.warning_anomaly_score}',\ setvar:'tx.sql_injection_score=+%{tx.warning_anomaly_score}'" -# -# -=[ Exclusion rule for 942440 ]=- -# -# Prevent FPs against Facebook click identifier -# -SecRule ARGS_GET:fbclid "@rx [a-zA-Z0-9_-]{61,61}" \ - "id:942441,\ - phase:2,\ - pass,\ - t:none,t:urlDecodeUni,\ - nolog,\ - tag:'OWASP_CRS',\ - ctl:ruleRemoveTargetById=942440;ARGS:fbclid,\ - ver:'OWASP_CRS/4.6.0'" - -# -# -=[ Exclusion rule for 942440 ]=- -# -# Prevent FPs against Google click identifier -# -SecRule ARGS_GET:gclid "@rx [a-zA-Z0-9_-]{91,91}" \ - "id:942442,\ - phase:2,\ - pass,\ - t:none,t:urlDecodeUni,\ - nolog,\ - tag:'OWASP_CRS',\ - ctl:ruleRemoveTargetById=942440;ARGS:gclid,\ - ver:'OWASP_CRS/4.6.0'" # # -=[ Detect SQL Comment Sequences ]=- @@ -1354,7 +1173,7 @@ SecRule ARGS_GET:gclid "@rx [a-zA-Z0-9_-]{91,91}" \ # DROP sampletable;-- # admin'-- # DROP/*comment*/sampletable -# DR/**/OP/*bypass deny listing*/sampletable +# DR/**/OP/*bypass blacklisting*/sampletable # SELECT/*avoid-spaces*/password/**/FROM/**/Members # SELECT /*!32302 1/0, */ 1 FROM tablename # ‘ or 1=1# @@ -1367,21 +1186,7 @@ SecRule ARGS_GET:gclid "@rx [a-zA-Z0-9_-]{91,91}" \ # 0/**/union/*!50000select*/table_name`foo`/**/ # ------------------------- # -# The chained rule is designed to prevent false positives by specifically -# targeting JWT tokens. Starting with 'ey' targets JWT tokens, where the 'ey' -# prefix corresponds to the beginning of the Base64-encoded header section. -# -# example: -# $ echo '{"' | base64 -# eyIK -# -# Regular expressions generated from regex-assembly/942440.ra and regex-assembly/942440-chain1.ra. -# To update the regular expressions run the following shell scripts -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942440 -# crs-toolchain regex update 942440-chain1 -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx /\*!?|\*/|[';]--|--(?:[\s\x0b]|[^\-]*?-)|[^&\-]#.*?[\s\x0b]|;?\x00" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:/\*!?|\*/|[';]--|--[\s\r\n\v\f]|--[^-]*?-|[^&-]#.*?[\s\r\n\v\f]|;?\\x00)" \ "id:942440,\ phase:2,\ block,\ @@ -1393,25 +1198,19 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - chain" - SecRule MATCHED_VARS "!@rx ^ey[\-0-9A-Z_a-z]+\.ey[\-0-9A-Z_a-z]+\.[\-0-9A-Z_a-z]+$" \ - "t:none,\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" # # -=[ SQL Hex Evasion Methods ]=- # -# Hex encoding detection: -# (?i:\b0x[a-f\d]{3,}) will match any 3 or more hex bytes after "0x", together forming a hexadecimal payload(e.g 0xf00, 0xf00d and so on) -# SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i:\b0x[a-f\d]{3,})" \ "id:942450,\ phase:2,\ @@ -1424,14 +1223,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # @@ -1455,11 +1254,13 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU # # The minimal string that triggers this regexp is: `if` # +# The rule 942510 is related to 942110 which catches a single ' or ` +# # The rule 942511 is similar to this rule, but triggers on normal quotes # ('if'). That rule runs in paranoia level 3 or higher since it is prone to # false positives in natural text. # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:`(?:(?:[\w\s=_\-+{}()<@]){2,29}|(?:[A-Za-z0-9+/]{4})+(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?)`)" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:`((?:[\w\s=_\-+{}()<@]){2,29}|(?:[A-Za-z0-9+\/]{4})+(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?)`)" \ "id:942510,\ phase:2,\ block,\ @@ -1471,209 +1272,20 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/942520.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942520 +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:942015,phase:1,pass,nolog,skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:942016,phase:2,pass,nolog,skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)[\"'`][\s\x0b]*?(?:(?:is[\s\x0b]+not|not[\s\x0b]+(?:like|glob|(?:betwee|i)n|null|regexp|match)|mod|div|sounds[\s\x0b]+like)\b|[%&\*\+\-/<->\^\|])" \ - "id:942520,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Detects basic SQL authentication bypass attempts 4.0/4',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# Complementary rule to PL2 942520 that block and/or-based bypasses. -# It blocks data with odd number of quotes and then (and|or). -# -# The rule uses the expression ^b*a*(b*a*b*a*)* to odd number of a's. It's not -# vulnerable to ReDos as it executes linearly many steps compared to input size. -# -# Regular expression generated from regex-assembly/942521.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942521 -# -SecRule REQUEST_HEADERS:User-Agent|REQUEST_HEADERS:Referer|ARGS_NAMES|ARGS|XML:/* "@rx (?i)^(?:[^']*?(?:'[^']*?'[^']*?)*?'|[^\"]*?(?:\"[^\"]*?\"[^\"]*?)*?\"|[^`]*?(?:`[^`]*?`[^`]*?)*?`)[\s\x0b]*([0-9A-Z_a-z]+)\b" \ - "id:942521,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Detects basic SQL authentication bypass attempts 4.1/4',\ - logdata:'Matched Data: %{TX.0} found within %{TX.942521_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.942521_matched_var_name=%{matched_var_name}',\ - chain" - SecRule TX:1 "@rx ^(?:and|or)$" \ - "t:none,\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# Complementary rule to PL2 942521 that block escaped quotes followed by (and|or) -# -SecRule ARGS_NAMES|ARGS|XML:/* "@rx ^.*?\x5c['\"`](?:.*?['\"`])?\s*(?:and|or)\b" \ - "id:942522,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Detects basic SQL authentication bypass attempts 4.1/4',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# -# This is a sibling of rule 942100 that adds checking of the path. -# -# REQUEST_BASENAME provides the last url segment (slash excluded). -# This segment is the most likely to be used for injections. Stripping out -# the slash permits libinjection to do not consider it as a payload starting -# with not unary arithmetical operators (not a valid SQL command, e.g. -# '/9 union all'). The latter would lead to do not detect malicious payloads. -# -# REQUEST_FILENAME matches SQLi payloads inside (or across) other segments -# of the path. Here, libinjection will detect a true positive only if -# the url leading slash is considered as part of a comment block or part -# of a string (with a quote or double quote after it). In these circumstances, -# previous slashes do not affect libinjection result, making it able to detect -# some SQLi inside the path. -# -SecRule REQUEST_BASENAME|REQUEST_FILENAME "@detectSQLi" \ - "id:942101,\ - phase:1,\ - block,\ - capture,\ - t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,\ - msg:'SQL Injection Attack Detected via libinjection',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -# -=[ SQL Function Names ]=- -# -# This rule is a stricter sibling of 942151. -# This rule 942152 checks for the same regex in request headers referer and user-agent. -# -# Regular expression generated from regex-assembly/942152.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942152 -# -SecRule REQUEST_HEADERS:Referer|REQUEST_HEADERS:User-Agent "@rx (?i)\b(?:a(?:dd(?:dat|tim)e|es_(?:de|en)crypt|s(?:cii(?:str)?|in)|tan2?)|b(?:enchmark|i(?:n_to_num|t_(?:and|count|length|x?or)))|c(?:har(?:acter)?_length|iel(?:ing)?|o(?:alesce|ercibility|llation|(?:mpres)?s|n(?:cat(?:_ws)?|nection_id|v(?:ert(?:_tz)?)?)|t)|r32|ur(?:(?:dat|tim)e|rent_(?:date|setting|time(?:stamp)?|user)))|d(?:a(?:t(?:abase(?:_to_xml)?|e(?:_(?:add|format|sub)|diff))|y(?:name|of(?:month|week|year)))|count|e(?:code|grees|s_(?:de|en)crypt)|ump)|e(?:lt|n(?:c(?:ode|rypt)|ds_?with)|x(?:p(?:ort_set)?|tract(?:value)?))|f(?:i(?:el|n)d_in_set|ound_rows|rom_(?:base64|days|unixtime))|g(?:e(?:ometrycollection|t(?:_(?:format|lock)|pgusername))|(?:r(?:eates|oup_conca)|tid_subse)t)|hex(?:toraw)?|i(?:fnull|n(?:et6?_(?:aton|ntoa)|s(?:ert|tr)|terval)|s(?:_(?:(?:free|used)_lock|ipv(?:4(?:_(?:compat|mapped))?|6)|n(?:ot(?:_null)?|ull)|superuser)|null))|json(?:_(?:a(?:gg|rray(?:_(?:elements(?:_text)?|length))?)|build_(?:array|object)|e(?:ac|xtract_pat)h(?:_text)?|object(?:_(?:agg|keys))?|populate_record(?:set)?|strip_nulls|t(?:o_record(?:set)?|ypeof))|b(?:_(?:array(?:_(?:elements(?:_text)?|length))?|build_(?:array|object)|object(?:_(?:agg|keys))?|e(?:ac|xtract_pat)h(?:_text)?|insert|p(?:ath_(?:(?:exists|match)(?:_tz)?|query(?:_(?:(?:array|first)(?:_tz)?|tz))?)|opulate_record(?:set)?|retty)|s(?:et(?:_lax)?|trip_nulls)|t(?:o_record(?:set)?|ypeof)))?|path)?|l(?:ast_(?:day|inser_id)|case|e(?:as|f)t|i(?:kel(?:ihood|y)|nestring)|o(?:_(?:from_bytea|put)|ad_file|ca(?:ltimestamp|te)|g(?:10|2)|wer)|pad|trim)|m(?:a(?:ke(?:_set|date)|ster_pos_wait)|d5|i(?:crosecon)?d|onthname|ulti(?:linestring|po(?:int|lygon)))|n(?:ame_const|ot_in|ullif)|o(?:ct(?:et_length)?|(?:ld_passwo)?rd)|p(?:eriod_(?:add|diff)|g_(?:client_encoding|(?:databas|read_fil)e|l(?:argeobject|s_dir)|sleep|user)|o(?:(?:lyg|siti)on|w)|rocedure_analyse)|qu(?:arter|ery_to_xml|ote)|r(?:a(?:dians|nd|wtohex)|elease_lock|ow_(?:count|to_json)|pad|trim)|s(?:chema|e(?:c_to_time|ssion_user)|ha[12]?|in|oundex|pace|q(?:lite_(?:compileoption_(?:get|used)|source_id)|rt)|t(?:arts_?with|d(?:dev_(?:po|sam)p)?|r(?:_to_date|cmp))|ub(?:(?:dat|tim)e|str(?:ing(?:_index)?)?)|ys(?:date|tem_user))|t(?:ime(?:_(?:format|to_sec)|diff|stamp(?:add|diff)?)|o(?:_(?:base64|jsonb?)|n?char|(?:day|second)s)|r(?:im|uncate))|u(?:case|n(?:compress(?:ed_length)?|hex|i(?:str|x_timestamp)|likely)|(?:pdatexm|se_json_nul)l|tc_(?:date|time(?:stamp)?)|uid(?:_short)?)|var(?:_(?:po|sam)p|iance)|we(?:ek(?:day|ofyear)|ight_string)|xmltype|yearweek)[^0-9A-Z_a-z]*\(" \ - "id:942152,\ - phase:1,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'SQL Injection Attack: SQL function name detected',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - -# -# This rule is a stricter sibling of 942320. -# It checks for the same regex in request headers referer and user-agent. -# -# Regular expression generated from regex-assembly/942321.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 942321 -# -SecRule REQUEST_HEADERS:Referer|REQUEST_HEADERS:User-Agent "@rx (?i)create[\s\x0b]+(?:function|procedure)[\s\x0b]*?[0-9A-Z_a-z]+[\s\x0b]*?\([\s\x0b]*?\)[\s\x0b]*?-|d(?:eclare[^0-9A-Z_a-z]+[#@][\s\x0b]*?[0-9A-Z_a-z]+|iv[\s\x0b]*?\([\+\-]*[\s\x0b\.0-9]+,[\+\-]*[\s\x0b\.0-9]+\))|exec[\s\x0b]*?\([\s\x0b]*?@|(?:lo_(?:impor|ge)t|procedure[\s\x0b]+analyse)[\s\x0b]*?\(|;[\s\x0b]*?(?:declare|open)[\s\x0b]+[\-0-9A-Z_a-z]+|::(?:b(?:igint|ool)|double[\s\x0b]+precision|int(?:eger)?|numeric|oid|real|(?:tex|smallin)t)" \ - "id:942321,\ - phase:1,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'Detects MySQL and PostgreSQL stored procedure/function injections',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:942015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:942016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" -# -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # @@ -1687,7 +1299,7 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:942016,phase:2,pass,nolog,tag:'O # # This is a stricter sibling of rule 942250. # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\W+\d*?\s*?\bhaving\b\s*?[^\s\-]" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?i)\W+\d*?\s*?having\s*?[^\s\-]" \ "id:942251,\ phase:2,\ block,\ @@ -1699,14 +1311,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # This rule is a stricter sibling of 942330. See that rule for a # description and overview. @@ -1723,14 +1335,14 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # # [ SQL Injection Character Anomaly Usage ] @@ -1753,7 +1365,7 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES "@rx ((?:[~!@#\$%\^&\*\(\)\-\+=\{\}\[\]\|:;\"'´’‘`<>][^~!@#\$%\^&\*\(\)\-\+=\{\}\[\]\|:;\"'´’‘`<>]*?){8})" \ "id:942420,\ - phase:1,\ + phase:2,\ block,\ capture,\ t:none,t:urlDecodeUni,\ @@ -1763,13 +1375,13 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.warning_anomaly_score}',\ + setvar:'tx.anomaly_score_pl3=+%{tx.warning_anomaly_score}',\ setvar:'tx.sql_injection_score=+%{tx.warning_anomaly_score}'" @@ -1792,13 +1404,13 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx ((?:[~!@#\$%\^&\*\(\)\-\+=\{\}\[\]\|:;\"'´ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.warning_anomaly_score}',\ + setvar:'tx.anomaly_score_pl3=+%{tx.warning_anomaly_score}',\ setvar:'tx.sql_injection_score=+%{tx.warning_anomaly_score}'" @@ -1822,14 +1434,48 @@ SecRule ARGS "@rx \W{4}" \ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ setvar:'tx.sql_injection_score=+%{tx.warning_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.warning_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.warning_anomaly_score}'" + + +# +# This is a sibling of rule 942100 that adds checking of the last path segment. +# +# libinjection is more likely to fail when passing the full path. E.g. the following +# string produces a match: +# 999999.1 union select unhex(hex(version())) -- and 1=1 +# while this doesn't: +# /999999.1 union select unhex(hex(version())) -- and 1=1\. +# Therefore, we capture the last segment of the path and only match that with +# libinjection. Incidentally, the last path segment is also the most likely +# to be used for injection, other segments will most likely not be affected. +# +SecRule REQUEST_BASENAME "@detectSQLi" \ + "id:942101,\ + phase:2,\ + block,\ + capture,\ + t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,\ + msg:'SQL Injection Attack Detected via libinjection',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-sqli',\ + tag:'OWASP_CRS',\ + tag:'capec/1000/152/248/66',\ + tag:'PCI/6.5.2',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" # @@ -1853,12 +1499,14 @@ SecRule ARGS "@rx \W{4}" \ # # The minimal string that triggers this regexp is: 'if' # +# The rule 942511 is related to 942110 which catches a single ' or ` +# # The rule 942510 is similar to this rule, but triggers on backticks # (`if`). That rule runs in paranoia level 2 or higher since the risk of # false positives in natural text is still present but lower than this # rule. # -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:'(?:(?:[\w\s=_\-+{}()<@]){2,29}|(?:[A-Za-z0-9+/]{4})+(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?)')" \ +SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx (?:'((?:[\w\s=_\-+{}()<@]){2,29}|(?:[A-Za-z0-9+\/]{4})+(?:[A-Za-z0-9+\/]{2}==|[A-Za-z0-9+\/]{3}=)?)')" \ "id:942511,\ phase:2,\ block,\ @@ -1870,49 +1518,19 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - -# Detects '; -# ' Single quote. Used to delineate a query with an unmatched quote. -# ; Terminate a query. A prematurely terminated query creates an error. -# Explanation source: -# https://hwang.cisdept.cpp.edu/swanew/Text/SQL-Injection.htm -# -# Bug Bounty example: email=admin@juice-sh.op';&password=foo -# -SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* "@rx ';" \ - "id:942530,\ - phase:2,\ - block,\ - capture,\ - t:none,t:urlDecodeUni,\ - msg:'SQLi query termination detected',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-multi',\ - tag:'platform-multi',\ - tag:'attack-sqli',\ tag:'paranoia-level/3',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248/66',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:942017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:942018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:942017,phase:1,pass,nolog,skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:942018,phase:2,pass,nolog,skipAfter:END-REQUEST-942-APPLICATION-ATTACK-SQLI" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # # @@ -1923,7 +1541,7 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:942018,phase:2,pass,nolog,tag:'O SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQUEST_COOKIES_NAMES "@rx ((?:[~!@#\$%\^&\*\(\)\-\+=\{\}\[\]\|:;\"'´’‘`<>][^~!@#\$%\^&\*\(\)\-\+=\{\}\[\]\|:;\"'´’‘`<>]*?){3})" \ "id:942421,\ - phase:1,\ + phase:2,\ block,\ capture,\ t:none,t:urlDecodeUni,\ @@ -1933,13 +1551,13 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|REQU tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/4',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/4',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.warning_anomaly_score}',\ + setvar:'tx.anomaly_score_pl4=+%{tx.warning_anomaly_score}',\ setvar:'tx.sql_injection_score=+%{tx.warning_anomaly_score}'" @@ -1962,13 +1580,13 @@ SecRule ARGS_NAMES|ARGS|XML:/* "@rx ((?:[~!@#\$%\^&\*\(\)\-\+=\{\}\[\]\|:;\"'´ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-sqli',\ - tag:'paranoia-level/4',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248/66',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/4',\ + ver:'OWASP_CRS/3.3.7',\ severity:'WARNING',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.warning_anomaly_score}',\ + setvar:'tx.anomaly_score_pl4=+%{tx.warning_anomaly_score}',\ setvar:'tx.sql_injection_score=+%{tx.warning_anomaly_score}'" diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf index 733187f0d..86559a370 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -14,10 +14,10 @@ -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:943011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:943012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:943011,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:943012,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # @@ -43,10 +43,11 @@ SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAME tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/225/21/593/61',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsession|phpsessid|weblogicsession|session_id|session-id|cfid|cftoken|cfsid|jservsession|jwsession)$" \ @@ -54,9 +55,9 @@ SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsessio phase:2,\ block,\ capture,\ - t:none,t:lowercase,\ + t:none,t:urlDecodeUni,t:lowercase,\ msg:'Possible Session Fixation Attack: SessionID Parameter Name with Off-Domain Referer',\ - logdata:'Matched Data: %{TX.0} found within %{TX.943110_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ @@ -64,16 +65,16 @@ SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsessio tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/225/21/593/61',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.943110_matched_var_name=%{matched_var_name}',\ chain" - SecRule REQUEST_HEADERS:Referer "@rx ^(?:ht|f)tps?://(.*?)/" \ + SecRule REQUEST_HEADERS:Referer "@rx ^(?:ht|f)tps?://(.*?)\/" \ "capture,\ chain" SecRule TX:1 "!@endsWith %{request_headers.host}" \ - "setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + "ctl:auditLogParts=+E,\ + setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsession|phpsessid|weblogicsession|session_id|session-id|cfid|cftoken|cfsid|jservsession|jwsession)$" \ @@ -81,9 +82,9 @@ SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsessio phase:2,\ block,\ capture,\ - t:none,t:lowercase,\ + t:none,t:urlDecodeUni,t:lowercase,\ msg:'Possible Session Fixation Attack: SessionID Parameter Name with No Referer',\ - logdata:'Matched Data: %{TX.0} found within %{TX.943120_MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ @@ -91,37 +92,37 @@ SecRule ARGS_NAMES "@rx ^(?:jsessionid|aspsessionid|asp\.net_sessionid|phpsessio tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/225/21/593/61',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.943120_matched_var_name=%{matched_var_name}',\ chain" SecRule &REQUEST_HEADERS:Referer "@eq 0" \ - "setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + "ctl:auditLogParts=+E,\ + setvar:'tx.session_fixation_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:943013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:943014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:943013,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:943014,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:943015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:943016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:943015,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:943016,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:943017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:943018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:943017,phase:1,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:943018,phase:2,pass,nolog,skipAfter:END-REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf index c3ced4f59..b10f0610f 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -13,10 +13,10 @@ # # Many rules check request bodies, use "SecRequestBodyAccess On" to enable it on main modsecurity configuration file. -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:944011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:944012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:944011,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:944012,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # This rule is also triggered by an Apache Struts exploit: # [ Apache Struts vulnerability CVE-2017-5638 - Exploit tested: https://github.com/xsscx/cve-2017-5638 ] @@ -36,20 +36,21 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES phase:2,\ block,\ t:none,t:lowercase,\ + log,\ msg:'Remote Command Execution: Suspicious Java class detected',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/137/6',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/1',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # This rule is also triggered by the following exploit(s): # [ Apache Struts vulnerability CVE-2017-5638 - Exploit tested: https://github.com/xsscx/cve-2017-5638 ] @@ -69,22 +70,23 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES phase:2,\ block,\ t:none,t:lowercase,\ + log,\ msg:'Remote Command Execution: Java process spawn (CVE-2017-9805)',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/1',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ chain" SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?:unmarshaller|base64data|java\.)" \ "setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # Magic bytes detected and payload included possibly RCE vulnerable classes detected and process execution methods detected # anomaly score set to critical as all conditions indicate the request try to perform RCE. @@ -94,22 +96,24 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES phase:2,\ block,\ t:none,t:lowercase,\ + log,\ msg:'Remote Command Execution: Java serialization (CVE-2015-4852)',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/1',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ chain" SecRule MATCHED_VARS "@rx (?:runtime|processbuilder)" \ - "setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + "t:none,t:lowercase,\ + setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" # This rule is also triggered by the following exploit(s): # [ Apache Struts vulnerability CVE-2017-5638 - Exploit tested: https://github.com/mazen160/struts-pwn ] @@ -125,146 +129,29 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES "id:944130,\ phase:2,\ block,\ - t:none,\ + t:none,t:lowercase,\ + log,\ msg:'Suspicious Java class detected',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -# -# [ Java Script Uploads ] -# -# Block file uploads with filenames ending in Java scripts (.jsp, .jspx) -# -# Many application contain Unrestricted File Upload vulnerabilities. -# https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload -# -# Attackers may use such a vulnerability to achieve remote code execution -# by uploading a script file. If the upload storage location is predictable -# and not adequately protected, the attacker may then request the uploaded -# file and have the code within it executed on the server. -# -# Some AJAX uploaders use the nonstandard request headers X-Filename, -# X_Filename, or X-File-Name to transmit the file name to the server; -# scan these request headers as well as multipart/form-data file names. -# -SecRule FILES|REQUEST_HEADERS:X-Filename|REQUEST_HEADERS:X_Filename|REQUEST_HEADERS:X.Filename|REQUEST_HEADERS:X-File-Name "@rx .*\.(?:jsp|jspx)\.*$" \ - "id:944140,\ - phase:2,\ - block,\ - capture,\ - t:none,t:lowercase,\ - msg:'Java Injection Attack: Java Script File Upload Found',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ - tag:'application-multi',\ - tag:'language-java',\ - tag:'platform-multi',\ - tag:'attack-injection-java',\ tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/242',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Log4J / Log4Shell Defense +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:944013,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:944014,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" # -# This addresses exploits against the Log4J library described in several CVEs: -# * CVE-2021-44228 -# * CVE-2021-44832 -# * CVE-2021-45046 -# * CVE-2021-45105 +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -# See https://coreruleset.org/20211213/crs-and-log4j-log4shell-cve-2021-44228/ -# -# This rule attempts to detect two things: -# * Nested use of ${ -# * use of ${jndi:... without the closing bracket -# -# Rule 932130 is also essential for defense since there are certain -# bypasses of the log4j rules that can be caught by 932130. -# -# The payload is not displayed in the alert message since log4j could -# potentially be executed on the logviewer. -# -# This rule has stricter siblings: 944151 (PL2), 944152 (PL4) -# -# Regular expression generated from regex-assembly/944150.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 944150 -# -SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?i)(?:\$|$?)(?:\{|&l(?:brace|cub);?)(?:[^\}]{0,15}(?:\$|$?)(?:\{|&l(?:brace|cub);?)|jndi|ctx)" \ - "id:944150,\ - phase:2,\ - block,\ - t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,\ - log,\ - msg:'Potential Remote Command Execution: Log4j / Log4shell',\ - tag:'application-multi',\ - tag:'language-java',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/137/6',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:944013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:944014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" -# -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) -# - -# This is a stricter sibling of 944150. -# It is a re-iteration of said rule without the curly bracket distance limiter -# between the nested "${". This is prone to backtracking and therefore a potential -# DoS problem for backtracking regular expression engines (e.g. PCRE2), but it also avoids evasions that fill the space between the nested -# elements with arbitrary data. -# -# Regular expression generated from regex-assembly/944151.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 944151 -# -SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?i)(?:\$|$?)(?:\{|&l(?:brace|cub);?)(?:[^\}]*(?:\$|$?)(?:\{|&l(?:brace|cub);?)|jndi|ctx)" \ - "id:944151,\ - phase:2,\ - block,\ - t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,\ - log,\ - msg:'Potential Remote Command Execution: Log4j / Log4shell',\ - tag:'application-multi',\ - tag:'language-java',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/137/6',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - # [ Java deserialization vulnerability/Apache Commons (CVE-2015-4852) ] # # Detect exploitation of "Java deserialization" Apache Commons. @@ -282,20 +169,21 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES "id:944200,\ phase:2,\ block,\ + log,\ msg:'Magic bytes Detected, probable java serialization in use',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # Detecting possible base64 text to match encoded magic bytes \xac\xed\x00\x05 with padding encoded in base64 strings are rO0ABQ KztAAU Cs7QAF SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \ @@ -303,20 +191,21 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES "id:944210,\ phase:2,\ block,\ + log,\ msg:'Magic bytes Detected Base64 Encoded, probable java serialization in use',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \ "@rx (?:clonetransformer|forclosure|instantiatefactory|instantiatetransformer|invokertransformer|prototypeclonefactory|prototypeserializationfactory|whileclosure|getproperty|filewriter|xmldecoder)" \ @@ -324,20 +213,21 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES phase:2,\ block,\ t:none,t:lowercase,\ + log,\ msg:'Remote Command Execution: Java serialization (CVE-2015-4852)',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/2',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" # This rule is also triggered by the following exploit(s): # [ SAP CRM Java vulnerability CVE-2018-2380 - Exploit tested: https://www.exploit-db.com/exploits/44292 ] @@ -348,51 +238,28 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES phase:2,\ block,\ t:lowercase,\ + log,\ msg:'Remote Command Execution: Suspicious Java method detected',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" - - -# This rule is also triggered by the following exploit(s): -# - https://www.rapid7.com/blog/post/2022/03/30/spring4shell-zero-day-vulnerability-in-spring-framework/ -# -SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|REQUEST_BODY|REQUEST_HEADERS|XML:/*|XML://@* \ - "@rx (?:class\.module\.classLoader\.resources\.context\.parent\.pipeline|springframework\.context\.support\.FileSystemXmlApplicationContext)" \ - "id:944260,\ - phase:2,\ - block,\ - t:urlDecodeUni,\ - msg:'Remote Command Execution: Malicious class-loading payload',\ - logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ - tag:'application-multi',\ - tag:'language-java',\ - tag:'platform-multi',\ - tag:'attack-rce',\ tag:'paranoia-level/2',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/248',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl2=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:944015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:944016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:944015,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:944016,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # # Interesting keywords for possibly RCE on vulnerable classes and methods base64 encoded # Keywords = ['runtime', 'processbuilder', 'clonetransformer', 'forclosure', 'instantiatefactory', 'instantiatetransformer', 'invokertransformer', 'prototypeclonefactory', 'prototypeserializationfactory', 'whileclosure'] @@ -407,56 +274,29 @@ SecRule ARGS|ARGS_NAMES|REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES phase:2,\ block,\ t:none,\ + log,\ msg:'Base64 encoded string matched suspicious keyword',\ logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ tag:'attack-rce',\ - tag:'paranoia-level/3',\ tag:'OWASP_CRS',\ tag:'capec/1000/152/248',\ tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ + tag:'paranoia-level/3',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl3=+%{tx.critical_anomaly_score}'" + setvar:'tx.anomaly_score_pl3=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:944017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:944018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:944017,phase:1,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:944018,phase:2,pass,nolog,skipAfter:END-REQUEST-944-APPLICATION-ATTACK-JAVA" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # -# This is a stricter sibling of 944150. -# It simply checks for the existence of `${`, taking into account the same encoding evasions -# as 944150. -# -# Regular expression generated from regex-assembly/944152.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 944152 -# -SecRule REQUEST_LINE|ARGS|ARGS_NAMES|REQUEST_COOKIES|REQUEST_COOKIES_NAMES|REQUEST_HEADERS|XML:/*|XML://@* "@rx (?i)(?:\$|$?)(?:\{|&l(?:brace|cub);?)" \ - "id:944152,\ - phase:2,\ - block,\ - t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,\ - log,\ - msg:'Potential Remote Command Execution: Log4j / Log4shell',\ - tag:'application-multi',\ - tag:'language-java',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/4',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/152/137/6',\ - tag:'PCI/6.5.2',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.rce_score=+%{tx.critical_anomaly_score}',\ - setvar:'tx.inbound_anomaly_score_pl4=+%{tx.critical_anomaly_score}'" # # -= Paranoia Levels Finished =- diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-949-BLOCKING-EVALUATION.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-949-BLOCKING-EVALUATION.conf index 469d8e26b..c054f61f3 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-949-BLOCKING-EVALUATION.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/REQUEST-949-BLOCKING-EVALUATION.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -12,254 +12,117 @@ # -= Paranoia Level 0 (empty) =- (apply unconditionally) # -# Summing up the blocking and detection anomaly scores in phase 1 -# even when early blocking is disabled, we need to sum up the scores in phase 1 -# this prevents bugs in phase 5 if Apache skips phases because of error handling -# See: https://github.com/coreruleset/coreruleset/issues/2319#issuecomment-1047503932 +# Summing up the anomaly score. -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 1" \ - "id:949052,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 1" \ - "id:949152,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'" - -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 2" \ - "id:949053,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 2" \ - "id:949153,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'" - -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 3" \ - "id:949054,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 3" \ - "id:949154,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'" - -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 4" \ - "id:949055,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 4" \ - "id:949155,\ - phase:1,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'" - -# at start of phase 2, we reset the aggregate scores to 0 to prevent duplicate counting of per-PL scores -# this is necessary because the per-PL scores are counted across phases -SecAction \ - "id:949059,\ - phase:2,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=0'" - -SecAction \ - "id:949159,\ - phase:2,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=0'" - -# Summing up the blocking and detection anomaly scores in phase 2 - -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 1" \ +# NOTE: tx.anomaly_score should not be set initially, but masking would lead to difficult bugs. +# So we add to it. +SecRule TX:PARANOIA_LEVEL "@ge 1" \ "id:949060,\ phase:2,\ pass,\ t:none,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'" + setvar:'tx.anomaly_score=+%{tx.anomaly_score_pl1}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 1" \ - "id:949160,\ - phase:2,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl1}'" - -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 2" \ +SecRule TX:PARANOIA_LEVEL "@ge 2" \ "id:949061,\ phase:2,\ pass,\ t:none,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'" + setvar:'tx.anomaly_score=+%{tx.anomaly_score_pl2}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 2" \ - "id:949161,\ - phase:2,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl2}'" - -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 3" \ +SecRule TX:PARANOIA_LEVEL "@ge 3" \ "id:949062,\ phase:2,\ pass,\ t:none,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'" + setvar:'tx.anomaly_score=+%{tx.anomaly_score_pl3}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 3" \ - "id:949162,\ - phase:2,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl3}'" - -SecRule TX:BLOCKING_PARANOIA_LEVEL "@ge 4" \ +SecRule TX:PARANOIA_LEVEL "@ge 4" \ "id:949063,\ phase:2,\ pass,\ t:none,\ nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.blocking_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@ge 4" \ - "id:949163,\ - phase:2,\ - pass,\ - t:none,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - setvar:'tx.detection_inbound_anomaly_score=+%{tx.inbound_anomaly_score_pl4}'" + setvar:'tx.anomaly_score=+%{tx.anomaly_score_pl4}'" SecMarker "BEGIN-REQUEST-BLOCKING-EVAL" +# These rules use the anomaly score settings specified in the 10 config file. +# You should also set the desired disruptive action (deny, redirect, etc...). +# +# -=[ IP Reputation Checks ]=- +# +# Block based on variable IP.REPUT_BLOCK_FLAG and TX.DO_REPUT_BLOCK +# +SecRule IP:REPUT_BLOCK_FLAG "@eq 1" \ + "id:949100,\ + phase:2,\ + deny,\ + log,\ + msg:'Request Denied by IP Reputation Enforcement',\ + logdata:'Previous Block Reason: %{ip.reput_block_reason}',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-reputation-ip',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + chain" + SecRule TX:DO_REPUT_BLOCK "@eq 1" \ + "setvar:'tx.inbound_anomaly_score=%{tx.anomaly_score}'" + # # -=[ Anomaly Mode: Overall Transaction Anomaly Score ]=- # - -# if early blocking is active, check threshold in phase 1 -SecRule TX:BLOCKING_INBOUND_ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \ - "id:949111,\ - phase:1,\ - deny,\ - t:none,\ - msg:'Inbound Anomaly Score Exceeded in phase 1 (Total Score: %{TX.BLOCKING_INBOUND_ANOMALY_SCORE})',\ - tag:'anomaly-evaluation',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - chain" - SecRule TX:EARLY_BLOCKING "@eq 1" - -# always check threshold in phase 2 -SecRule TX:BLOCKING_INBOUND_ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \ +SecRule TX:ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \ "id:949110,\ phase:2,\ deny,\ t:none,\ - msg:'Inbound Anomaly Score Exceeded (Total Score: %{TX.BLOCKING_INBOUND_ANOMALY_SCORE})',\ - tag:'anomaly-evaluation',\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0'" + log,\ + msg:'Inbound Anomaly Score Exceeded (Total Score: %{TX.ANOMALY_SCORE})',\ + tag:'application-multi',\ + tag:'language-multi',\ + tag:'platform-multi',\ + tag:'attack-generic',\ + ver:'OWASP_CRS/3.3.7',\ + severity:'CRITICAL',\ + setvar:'tx.inbound_anomaly_score=%{tx.anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:949011,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:949012,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" + + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:949011,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:949012,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:949013,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:949014,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:949013,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:949014,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:949015,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:949016,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:949015,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:949016,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:949017,phase:1,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:949018,phase:2,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:949017,phase:1,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:949018,phase:2,pass,nolog,skipAfter:END-REQUEST-949-BLOCKING-EVALUATION" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-950-DATA-LEAKAGES.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-950-DATA-LEAKAGES.conf index 4a481dff1..385047b0e 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-950-DATA-LEAKAGES.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-950-DATA-LEAKAGES.conf @@ -1,53 +1,41 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ -# We reused paranoia level skip rules 950010, 950011, and 950018. -# These rule identifiers were in use in CRSv2, so we used different -# identifiers in CRSv3 to avoid conflicts (950020, 950021 and 950022). -# In CRSv4, for the sake of a consistent structure, we use these -# identifiers again, so that the skip rules of PL can be defined in the -# same way for all files. -# Rule id 950130 has been kept - this ID also was introduced at first -# rule to avoid the collision. +# The paranoia level skip rules 950020, 950021 and 950022 have odd +# numbers not in sync with other paranoia level skip rules in other +# files. This is done to avoid rule id collisions with CRSv2. +# This is also true for rule 950130. # # -= Paranoia Level 0 (empty) =- (apply unconditionally) # -# Skip all rules if RESPONSE_BODY is compressed. -SecRule RESPONSE_HEADERS:Content-Encoding "@pm gzip compress deflate br zstd" \ - "id:950010,\ - phase:4,\ - pass,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - skipAfter:END-RESPONSE-950-DATA-LEAKAGES" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:950011,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:950012,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:950020,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:950021,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # # -=[ Directory Listing ]=- # -SecRule RESPONSE_BODY "@rx (?:<(?:TITLE>Index of.*?Index of.*?Index of|>\[To Parent Directory\]
)" \ +SecRule RESPONSE_BODY "@rx (?:<(?:TITLE>Index of.*?Index of.*?Index of|>\[To Parent Directory\]<\/[Aa]>
)" \ "id:950130,\ phase:4,\ block,\ capture,\ t:none,\ msg:'Directory Listing',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ @@ -56,9 +44,11 @@ SecRule RESPONSE_BODY "@rx (?:<(?:TITLE>Index of.*?Index of.*?Inde tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54/127',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" # # -=[ CGI Source Code Leakage ]=- @@ -79,7 +69,7 @@ SecRule RESPONSE_BODY "@rx ^#\!\s?/" \ capture,\ t:none,\ msg:'CGI source code leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ @@ -88,15 +78,17 @@ SecRule RESPONSE_BODY "@rx ^#\!\s?/" \ tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:950013,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:950014,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:950013,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:950014,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # # @@ -104,38 +96,40 @@ SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:950014,phase:4,pass,nolog,tag:'O # SecRule RESPONSE_STATUS "@rx ^5\d{2}$" \ "id:950100,\ - phase:3,\ + phase:4,\ block,\ capture,\ t:none,\ msg:'The Application Returned a 500-Level Status Code',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-multi',\ tag:'attack-disclosure',\ + tag:'PCI/6.5.6',\ tag:'paranoia-level/2',\ tag:'OWASP_CRS',\ tag:'capec/1000/152',\ - tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl2=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl2=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl2=+%{tx.error_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:950015,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:950016,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:950015,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:950016,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:950017,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:950018,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-950-DATA-LEAKAGES" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:950017,phase:3,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:950022,phase:4,pass,nolog,skipAfter:END-RESPONSE-950-DATA-LEAKAGES" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf index 54e427893..7403d8f5f 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -12,29 +12,21 @@ # -= Paranoia Level 0 (empty) =- (apply unconditionally) # -# Skip all rules if RESPONSE_BODY is compressed. -SecRule RESPONSE_HEADERS:Content-Encoding "@pm gzip compress deflate br zstd" \ - "id:951010,\ - phase:4,\ - pass,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:951011,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:951012,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:951011,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:951012,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # # -=[ SQL Error Leakages ]=- # -# Ref: https://github.com/sqlmapproject/sqlmap +# Ref: https://raw.github.com/sqlmapproject/sqlmap/master/xml/errors.xml # Ref: https://github.com/Arachni/arachni/tree/master/components/checks/active/sql_injection/regexps # -SecRule RESPONSE_BODY "!@pmFromFile sql-errors.data" \ +SecRule RESPONSE_BODY "@pmFromFile sql-errors.data" \ "id:951100,\ phase:4,\ pass,\ @@ -46,17 +38,17 @@ SecRule RESPONSE_BODY "!@pmFromFile sql-errors.data" \ tag:'attack-disclosure',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ - skipAfter:END-SQL-ERROR-MATCH-PL1" + ver:'OWASP_CRS/3.3.7',\ + setvar:'tx.sql_error_match=1'" -SecRule RESPONSE_BODY "@rx (?i:JET Database Engine|Access Database Engine|\[Microsoft\]\[ODBC Microsoft Access Driver\])" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951110,\ phase:4,\ block,\ capture,\ t:none,\ msg:'Microsoft Access SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-msaccess',\ @@ -64,24 +56,24 @@ SecRule RESPONSE_BODY "@rx (?i:JET Database Engine|Access Database Engine|\[Micr tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:JET Database Engine|Access Database Engine|\[Microsoft\]\[ODBC Microsoft Access Driver\])" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/951120.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 951120 -# -SecRule RESPONSE_BODY "@rx (?i)\bORA-[0-9][0-9][0-9][0-9][0-9]:|java\.sql\.SQLException|Oracle(?: erro|[^\(\)]{0,20}Drive)r|Warning.{1,10}o(?:ci_.{1,30}|ra_.{1,20})" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951120,\ phase:4,\ block,\ capture,\ t:none,\ msg:'Oracle SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-oracle',\ @@ -89,19 +81,24 @@ SecRule RESPONSE_BODY "@rx (?i)\bORA-[0-9][0-9][0-9][0-9][0-9]:|java\.sql\.SQLEx tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:ORA-[0-9][0-9][0-9][0-9]|java\.sql\.SQLException|Oracle error|Oracle.*Driver|Warning.*oci_.*|Warning.*ora_.*)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i:DB2 SQL error:|\[IBM\]\[CLI Driver\]\[DB2/6000\]|CLI Driver.*DB2|DB2 SQL error|db2_\w+\()" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951130,\ phase:4,\ block,\ capture,\ t:none,\ msg:'DB2 SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-db2',\ @@ -109,19 +106,24 @@ SecRule RESPONSE_BODY "@rx (?i:DB2 SQL error:|\[IBM\]\[CLI Driver\]\[DB2/6000\]| tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:DB2 SQL error:|\[IBM\]\[CLI Driver\]\[DB2/6000\]|CLI Driver.*DB2|DB2 SQL error|db2_\w+\()" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i:\[DM_QUERY_E_SYNTAX\]|has occurred in the vicinity of:)" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951140,\ phase:4,\ block,\ capture,\ t:none,\ msg:'EMC SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-emc',\ @@ -129,19 +131,24 @@ SecRule RESPONSE_BODY "@rx (?i:\[DM_QUERY_E_SYNTAX\]|has occurred in the vicinit tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:\[DM_QUERY_E_SYNTAX\]|has occurred in the vicinity of:)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i)Dynamic SQL Error" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951150,\ phase:4,\ block,\ capture,\ t:none,\ msg:'firebird SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-firebird',\ @@ -149,19 +156,25 @@ SecRule RESPONSE_BODY "@rx (?i)Dynamic SQL Error" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i)Dynamic SQL Error" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i)Exception (?:condition )?\d+\. Transaction rollback\." \ + +SecRule TX:sql_error_match "@eq 1" \ "id:951160,\ phase:4,\ block,\ capture,\ t:none,\ msg:'Frontbase SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-frontbase',\ @@ -169,19 +182,24 @@ SecRule RESPONSE_BODY "@rx (?i)Exception (?:condition )?\d+\. Transaction rollba tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i)Exception (?:condition )?\d+\. Transaction rollback\." \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i)org\.hsqldb\.jdbc" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951170,\ phase:4,\ block,\ capture,\ t:none,\ msg:'hsqldb SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-hsqldb',\ @@ -189,19 +207,24 @@ SecRule RESPONSE_BODY "@rx (?i)org\.hsqldb\.jdbc" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i)org\.hsqldb\.jdbc" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i:An illegal character has been found in the statement|com\.informix\.jdbc|Exception.*Informix)" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951180,\ phase:4,\ block,\ capture,\ t:none,\ msg:'informix SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-informix',\ @@ -209,19 +232,25 @@ SecRule RESPONSE_BODY "@rx (?i:An illegal character has been found in the statem tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:An illegal character has been found in the statement|com\.informix\.jdbc|Exception.*Informix)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i:Warning.*ingres_|Ingres SQLSTATE|Ingres\W.*Driver)" \ + +SecRule TX:sql_error_match "@eq 1" \ "id:951190,\ phase:4,\ block,\ capture,\ t:none,\ msg:'ingres SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-ingres',\ @@ -229,19 +258,25 @@ SecRule RESPONSE_BODY "@rx (?i:Warning.*ingres_|Ingres SQLSTATE|Ingres\W.*Driver tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:Warning.*ingres_|Ingres SQLSTATE|Ingres\W.*Driver)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i:Warning: ibase_|Unexpected end of command in statement)" \ + +SecRule TX:sql_error_match "@eq 1" \ "id:951200,\ phase:4,\ block,\ capture,\ t:none,\ msg:'interbase SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-interbase',\ @@ -249,19 +284,24 @@ SecRule RESPONSE_BODY "@rx (?i:Warning: ibase_|Unexpected end of command tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:Warning: ibase_|Unexpected end of command in statement)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i:SQL error.*POS[0-9]+.*|Warning.*maxdb.*)" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951210,\ phase:4,\ block,\ capture,\ t:none,\ msg:'maxDB SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-maxdb',\ @@ -269,19 +309,24 @@ SecRule RESPONSE_BODY "@rx (?i:SQL error.*POS[0-9]+.*|Warning.*maxdb.*)" \ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:SQL error.*POS[0-9]+.*|Warning.*maxdb.*)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i)(?:System\.Data\.OleDb\.OleDbException|\[Microsoft\]\[ODBC SQL Server Driver\]|\[Macromedia\]\[SQLServer JDBC Driver\]|\[SqlException|System\.Data\.SqlClient\.SqlException|Unclosed quotation mark after the character string|'80040e14'|mssql_query\(\)|Microsoft OLE DB Provider for ODBC Drivers|Microsoft OLE DB Provider for SQL Server|Incorrect syntax near|Sintaxis incorrecta cerca de|Syntax error in string in query expression|Procedure or function .* expects parameter|Unclosed quotation mark before the character string|Syntax error .* in query expression|Data type mismatch in criteria expression\.|ADODB\.Field \(0x800A0BCD\)|the used select statements have different number of columns|OLE DB.*SQL Server|Warning.*mssql_.*|Driver.*SQL[ _-]*Server|SQL Server.*Driver|SQL Server.*[0-9a-fA-F]{8}|Exception.*\WSystem\.Data\.SqlClient\.|Conversion failed when converting the varchar value .*? to data type int\.)" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951220,\ phase:4,\ block,\ capture,\ t:none,\ msg:'mssql SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-mssql',\ @@ -289,24 +334,24 @@ SecRule RESPONSE_BODY "@rx (?i)(?:System\.Data\.OleDb\.OleDbException|\[Microsof tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i)(?:System\.Data\.OleDb\.OleDbException|\[Microsoft\]\[ODBC SQL Server Driver\]|\[Macromedia\]\[SQLServer JDBC Driver\]|\[SqlException|System\.Data\.SqlClient\.SqlException|Unclosed quotation mark after the character string|'80040e14'|mssql_query\(\)|Microsoft OLE DB Provider for ODBC Drivers|Microsoft OLE DB Provider for SQL Server|Incorrect syntax near|Sintaxis incorrecta cerca de|Syntax error in string in query expression|Procedure or function .* expects parameter|Unclosed quotation mark before the character string|Syntax error .* in query expression|Data type mismatch in criteria expression\.|ADODB\.Field \(0x800A0BCD\)|the used select statements have different number of columns|OLE DB.*SQL Server|Warning.*mssql_.*|Driver.*SQL[ _-]*Server|SQL Server.*Driver|SQL Server.*[0-9a-fA-F]{8}|Exception.*\WSystem\.Data\.SqlClient\.)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/951230.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 951230 -# -SecRule RESPONSE_BODY "@rx (?i)(?:supplied argument is not a valid |SQL syntax.*)MySQL|Column count doesn't match(?: value count at row)?|mysql_fetch_array\(\)|on MySQL result index|You have an error in your SQL syntax(?:;| near)|MyS(?:QL server version for the right syntax to use|qlClient\.)|\[MySQL\]\[ODBC|(?:Table '[^']+' doesn't exis|valid MySQL resul)t|Warning.{1,10}mysql_(?:[\(\)_a-z]{1,26})?|(?:ERROR [0-9]{4} \([0-9a-z]{5}\)|XPATH syntax error):" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951230,\ phase:4,\ block,\ capture,\ t:none,\ msg:'mysql SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-mysql',\ @@ -314,24 +359,24 @@ SecRule RESPONSE_BODY "@rx (?i)(?:supplied argument is not a valid |SQL syntax.* tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i)(?:supplied argument is not a valid MySQL|Column count doesn't match value count at row|mysql_fetch_array\(\)|on MySQL result index|You have an error in your SQL syntax;|You have an error in your SQL syntax near|MySQL server version for the right syntax to use|\[MySQL\]\[ODBC|Column count doesn't match|Table '[^']+' doesn't exist|SQL syntax.*MySQL|Warning.*mysql_.*|valid MySQL result|MySqlClient\.)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -# Regular expression generated from regex-assembly/951240.ra. -# To update the regular expression run the following shell script -# (consult https://coreruleset.org/docs/development/regex_assembly/ for details): -# crs-toolchain regex update 951240 -# -SecRule RESPONSE_BODY "@rx (?i)P(?:ostgreSQL(?: query failed:|.{1,20}ERROR)|G::[a-z]*Error)|(?:pg_(?:query|exec)\(\) \[|org\.postgresql\.util\.PSQLException):|Warning.{1,20}\bpg_.*|valid PostgreSQL result|Npgsql\.|Supplied argument is not a valid PostgreSQL .*? resource|(?:Unable to connect to PostgreSQL serv|invalid input syntax for integ)er" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951240,\ phase:4,\ block,\ capture,\ t:none,\ msg:'postgres SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-pgsql',\ @@ -339,19 +384,24 @@ SecRule RESPONSE_BODY "@rx (?i)P(?:ostgreSQL(?: query failed:|.{1,20}ERROR)|G::[ tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i:PostgreSQL query failed:|pg_query\(\) \[:|pg_exec\(\) \[:|PostgreSQL.*ERROR|Warning.*pg_.*|valid PostgreSQL result|Npgsql\.|PG::[a-zA-Z]*Error|Supplied argument is not a valid PostgreSQL .*? resource|Unable to connect to PostgreSQL server)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i)(?:Warning.*sqlite_.*|Warning.*SQLite3::|SQLite/JDBCDriver|SQLite\.Exception|System\.Data\.SQLite\.SQLiteException)" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951250,\ phase:4,\ block,\ capture,\ t:none,\ msg:'sqlite SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-sqlite',\ @@ -359,19 +409,24 @@ SecRule RESPONSE_BODY "@rx (?i)(?:Warning.*sqlite_.*|Warning.*SQLite3::|SQLite/J tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" + chain" + SecRule RESPONSE_BODY "@rx (?i)(?:Warning.*sqlite_.*|Warning.*SQLite3::|SQLite/JDBCDriver|SQLite\.Exception|System\.Data\.SQLite\.SQLiteException)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule RESPONSE_BODY "@rx (?i)(?:Sybase message:|Warning.{2,20}sybase|Sybase.*Server message.*)" \ +SecRule TX:sql_error_match "@eq 1" \ "id:951260,\ phase:4,\ block,\ capture,\ t:none,\ msg:'Sybase SQL Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-sybase',\ @@ -379,34 +434,38 @@ SecRule RESPONSE_BODY "@rx (?i)(?:Sybase message:|Warning.{2,20}sybase|Sybase.*S tag:'paranoia-level/1',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116/54',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ - setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}'" - -SecMarker "END-SQL-ERROR-MATCH-PL1" + chain" + SecRule RESPONSE_BODY "@rx (?i)(?:Sybase message:|Warning.*sybase.*|Sybase.*Server message.*)" \ + "capture,\ + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}',\ + setvar:'tx.sql_injection_score=+%{tx.critical_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:951013,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:951014,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:951013,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:951014,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:951015,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:951016,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:951015,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:951016,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:951017,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:951018,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:951017,phase:3,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:951018,phase:4,pass,nolog,skipAfter:END-RESPONSE-951-DATA-LEAKAGES-SQL" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf index 90ebe7816..7e47c38cf 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -12,20 +12,12 @@ # -= Paranoia Level 0 (empty) =- (apply unconditionally) # -# Skip all rules if RESPONSE_BODY is compressed. -SecRule RESPONSE_HEADERS:Content-Encoding "@pm gzip compress deflate br zstd" \ - "id:952010,\ - phase:4,\ - pass,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:952011,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:952012,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:952011,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:952012,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # @@ -38,7 +30,7 @@ SecRule RESPONSE_BODY "@pmFromFile java-code-leakages.data" \ capture,\ t:none,\ msg:'Java Source Code Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ @@ -47,9 +39,11 @@ SecRule RESPONSE_BODY "@pmFromFile java-code-leakages.data" \ tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" # # -=[ Java Errors ]=- @@ -63,7 +57,7 @@ SecRule RESPONSE_BODY "@pmFromFile java-errors.data" \ capture,\ t:none,\ msg:'Java Errors',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-java',\ tag:'platform-multi',\ @@ -72,32 +66,34 @@ SecRule RESPONSE_BODY "@pmFromFile java-errors.data" \ tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:952013,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:952014,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:952013,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:952014,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:952015,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:952016,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:952015,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:952016,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:952017,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:952018,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:952017,phase:3,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:952018,phase:4,pass,nolog,skipAfter:END-RESPONSE-952-DATA-LEAKAGES-JAVA" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf index 05f4dcb55..6ba20e5b8 100644 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf +++ b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf @@ -1,9 +1,9 @@ # ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 +# OWASP ModSecurity Core Rule Set ver.3.3.7 # Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. +# Copyright (c) 2021-2024 Core Rule Set project. All rights reserved. # -# The OWASP CRS is distributed under +# The OWASP ModSecurity Core Rule Set is distributed under # Apache Software License (ASL) version 2 # Please see the enclosed LICENSE file for full details. # ------------------------------------------------------------------------ @@ -12,20 +12,12 @@ # -= Paranoia Level 0 (empty) =- (apply unconditionally) # -# Skip all rules if RESPONSE_BODY is compressed. -SecRule RESPONSE_HEADERS:Content-Encoding "@pm gzip compress deflate br zstd" \ - "id:953010,\ - phase:4,\ - pass,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:953011,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:953012,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP" + +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:953011,phase:3,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 1" "id:953012,phase:4,pass,nolog,skipAfter:END-RESPONSE-953-DATA-LEAKAGES-PHP" # -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) +# -= Paranoia Level 1 (default) =- (apply only when tx.executing_paranoia_level is sufficiently high: 1 or higher) # # @@ -38,7 +30,7 @@ SecRule RESPONSE_BODY "@pmFromFile php-errors.data" \ capture,\ t:none,\ msg:'PHP Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ @@ -47,9 +39,11 @@ SecRule RESPONSE_BODY "@pmFromFile php-errors.data" \ tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" # # -=[ PHP source code leakage ]=- @@ -63,7 +57,7 @@ SecRule RESPONSE_BODY "@rx (?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scan capture,\ t:none,\ msg:'PHP source code leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-php',\ tag:'platform-multi',\ @@ -72,24 +66,29 @@ SecRule RESPONSE_BODY "@rx (?:\b(?:f(?:tp_(?:nb_)?f?(?:ge|pu)t|get(?:s?s|c)|scan tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" -# Detect the presence of the PHP open tag ".{1,20}?error '800(?:04005|40e31)'.{1,40}?Timeout expired| \(0x80040e31\)
Timeout expired
)|

internal server error

.*?

part of the server has crashed or it has a configuration error\.

|cannot connect to the server: timed out)" \ +SecRule RESPONSE_BODY "@rx (?:Microsoft OLE DB Provider for SQL Server(?:<\/font>.{1,20}?error '800(?:04005|40e31)'.{1,40}?Timeout expired| \(0x80040e31\)
Timeout expired
)|

internal server error<\/h1>.*?

part of the server has crashed or it has a configuration error\.<\/h2>|cannot connect to the server: timed out)" \ "id:954110,\ phase:4,\ block,\ capture,\ t:none,\ msg:'Application Availability Error',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-iis',\ tag:'platform-windows',\ tag:'attack-disclosure',\ tag:'paranoia-level/1',\ + tag:'PCI/6.5.6',\ tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ - tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" # # IIS Errors leakage # -SecRule RESPONSE_BODY "@pmFromFile iis-errors.data" \ +SecRule RESPONSE_BODY "@rx (?:\b(?:A(?:DODB\.Command\b.{0,100}?\b(?:Application uses a value of the wrong type for the current operation\b|error')| trappable error occurred in an external object\. The script cannot continue running\b)|Microsoft VBScript (?:compilation (?:\(0x8|error)|runtime (?:Error|\(0x8))\b|Object required: '|error '800)|Version Information:<\/b>(?: |\s)(?:Microsoft \.NET Framework|ASP\.NET) Version:|>error 'ASP\b|An Error Has Occurred|>Syntax error in string in query expression|\/[Ee]rror[Mm]essage\.aspx?\?[Ee]rror\b)" \ "id:954120,\ phase:4,\ block,\ capture,\ t:none,\ msg:'IIS Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-iis',\ @@ -90,9 +86,11 @@ SecRule RESPONSE_BODY "@pmFromFile iis-errors.data" \ tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ctl:auditLogParts=+E,\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" SecRule RESPONSE_STATUS "!@rx ^404$" \ @@ -102,7 +100,7 @@ SecRule RESPONSE_STATUS "!@rx ^404$" \ capture,\ t:none,\ msg:'IIS Information Leakage',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ + logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\ tag:'application-multi',\ tag:'language-multi',\ tag:'platform-iis',\ @@ -112,36 +110,38 @@ SecRule RESPONSE_STATUS "!@rx ^404$" \ tag:'OWASP_CRS',\ tag:'capec/1000/118/116',\ tag:'PCI/6.5.6',\ - ver:'OWASP_CRS/4.6.0',\ + ver:'OWASP_CRS/3.3.7',\ severity:'ERROR',\ chain" SecRule RESPONSE_BODY "@rx \bServer Error in.{0,50}?\bApplication\b" \ "capture,\ t:none,\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}'" + ctl:auditLogParts=+E,\ + setvar:'tx.outbound_anomaly_score_pl1=+%{tx.error_anomaly_score}',\ + setvar:'tx.anomaly_score_pl1=+%{tx.error_anomaly_score}'" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:954013,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 2" "id:954014,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:954013,phase:3,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 2" "id:954014,phase:4,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" # -# -= Paranoia Level 2 =- (apply only when tx.detection_paranoia_level is sufficiently high: 2 or higher) +# -= Paranoia Level 2 =- (apply only when tx.executing_paranoia_level is sufficiently high: 2 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:954015,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 3" "id:954016,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:954015,phase:3,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 3" "id:954016,phase:4,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" # -# -= Paranoia Level 3 =- (apply only when tx.detection_paranoia_level is sufficiently high: 3 or higher) +# -= Paranoia Level 3 =- (apply only when tx.executing_paranoia_level is sufficiently high: 3 or higher) # -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:954017,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 4" "id:954018,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:954017,phase:3,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" +SecRule TX:EXECUTING_PARANOIA_LEVEL "@lt 4" "id:954018,phase:4,pass,nolog,skipAfter:END-RESPONSE-954-DATA-LEAKAGES-IIS" # -# -= Paranoia Level 4 =- (apply only when tx.detection_paranoia_level is sufficiently high: 4 or higher) +# -= Paranoia Level 4 =- (apply only when tx.executing_paranoia_level is sufficiently high: 4 or higher) # diff --git a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-955-WEB-SHELLS.conf b/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-955-WEB-SHELLS.conf deleted file mode 100644 index 506994b37..000000000 --- a/src/common/core/modsecurity/files/coreruleset-v3/rules/RESPONSE-955-WEB-SHELLS.conf +++ /dev/null @@ -1,558 +0,0 @@ -# ------------------------------------------------------------------------ -# OWASP CRS ver.4.6.0 -# Copyright (c) 2006-2020 Trustwave and contributors. (not) All rights reserved. -# Copyright (c) 2021-2024 CRS project. All rights reserved. -# -# The OWASP CRS is distributed under -# Apache Software License (ASL) version 2 -# Please see the enclosed LICENSE file for full details. -# ------------------------------------------------------------------------ - -# -# -= Paranoia Level 0 (empty) =- (apply unconditionally) -# - -# Skip all rules if RESPONSE_BODY is compressed. -SecRule RESPONSE_HEADERS:Content-Encoding "@pm gzip compress deflate br zstd" \ - "id:955010,\ - phase:4,\ - pass,\ - nolog,\ - tag:'OWASP_CRS',\ - ver:'OWASP_CRS/4.6.0',\ - skipAfter:END-RESPONSE-955-WEB-SHELLS" - -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:955011,phase:3,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-955-WEB-SHELLS" -SecRule TX:DETECTION_PARANOIA_LEVEL "@lt 1" "id:955012,phase:4,pass,nolog,tag:'OWASP_CRS',ver:'OWASP_CRS/4.6.0',skipAfter:END-RESPONSE-955-WEB-SHELLS" -# -# -= Paranoia Level 1 (default) =- (apply only when tx.detection_paranoia_level is sufficiently high: 1 or higher) -# - -# For performance reasons, most of the shells are matched using this rule. -# This rule is intended for PHP web shells. -SecRule RESPONSE_BODY "@pmFromFile web-shells-php.data" \ - "id:955100,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Web shell detected',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# r57 web shell -SecRule RESPONSE_BODY "@rx (r57 Shell Version [0-9.]+|r57 shell)" \ - "id:955110,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'r57 web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# WSO web shell -SecRule RESPONSE_BODY "@rx ^.*? - WSO [0-9.]+" \ - "id:955120,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'WSO web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# b4tm4n web shell (https://github.com/k4mpr3t/b4tm4n) -SecRule RESPONSE_BODY "@rx B4TM4N SH3LL.*" \ - "id:955130,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'b4tm4n web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# Mini Shell web shell -SecRule RESPONSE_BODY "@rx Mini Shell.*Developed By LameHacker" \ - "id:955140,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Mini Shell web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# Ashiyane web shell -SecRule RESPONSE_BODY "@rx \.:: .* ~ Ashiyane V [0-9.]+ ::\." \ - "id:955150,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Ashiyane web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# Symlink_Sa web shell -SecRule RESPONSE_BODY "@rx Symlink_Sa [0-9.]+" \ - "id:955160,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Symlink_Sa web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# CasuS web shell -SecRule RESPONSE_BODY "@rx CasuS [0-9.]+ by MafiABoY" \ - "id:955170,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'CasuS web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# GRP WebShell -SecRule RESPONSE_BODY "@rx ^\r\n\r\nGRP WebShell [0-9.]+ " \ - "id:955180,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'GRP WebShell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# NGHshell web shell -SecRule RESPONSE_BODY "@rx <small>NGHshell [0-9.]+ by Cr4sh</body></html>\n$" \ - "id:955190,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'NGHshell web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# SimAttacker web shell -SecRule RESPONSE_BODY "@rx <title>SimAttacker - (?:Version|Vrsion) : [0-9.]+ - " \ - "id:955200,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'SimAttacker web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# Unknown web shell -SecRule RESPONSE_BODY "@rx ^<!DOCTYPE html>\n<html>\n<!-- By Artyum .*<title>Web Shell" \ - "id:955210,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Unknown web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# lama's'hell web shell -SecRule RESPONSE_BODY "@rx lama's'hell v. [0-9.]+" \ - "id:955220,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'lama\'s\'hell web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# lostDC web shell -SecRule RESPONSE_BODY "@rx ^ *\n[ ]+\n[ ]+lostDC - " \ - "id:955230,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'lostDC web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# Unknown web shell -SecRule RESPONSE_BODY "@rx ^<title>PHP Web Shell\r\n\r\n\r\n " \ - "id:955240,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Unknown web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# Unknown web shell -SecRule RESPONSE_BODY "@rx ^\n\n
Input command :
\n
" \ - "id:955250,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Unknown web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# Ru24PostWebShell web shell -# Removed '- ' from the end of the pattern so this file won't get detected as -# malware by Windows Defender. -SecRule RESPONSE_BODY "@rx ^\n\nRu24PostWebShell " \ - "id:955260,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'Ru24PostWebShell web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# s72 Shell web shell -SecRule RESPONSE_BODY "@rx <title>s72 Shell v[0-9.]+ Codinf by Cr@zy_King" \ - "id:955270,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'s72 Shell web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# PhpSpy web shell -SecRule RESPONSE_BODY "@rx ^\r\n\r\n\r\nPhpSpy Ver [0-9]+" \ - "id:955280,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'PhpSpy web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# g00nshell web shell -SecRule RESPONSE_BODY "@rx ^ \n\n\n\ng00nshell v[0-9.]+ " \ - "id:955290,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'g00nshell web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# PuNkHoLic shell web shell -# Various versions has this text written little differently so we need to do -# t:removeWhitespace and t:lowercase. -SecRule RESPONSE_BODY "@contains <title>punkholicshell" \ - "id:955300,\ - phase:4,\ - block,\ - capture,\ - t:none,t:removeWhitespace,t:lowercase,\ - msg:'PuNkHoLic shell web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# azrail web shell -SecRule RESPONSE_BODY "@rx ^\n \n azrail [0-9.]+ by C-W-M" \ - "id:955310,\ - phase:4,\ - block,\ - capture,\ - t:none,\ - msg:'azrail web shell',\ - logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}',\ - tag:'language-php',\ - tag:'platform-multi',\ - tag:'attack-rce',\ - tag:'paranoia-level/1',\ - tag:'OWASP_CRS',\ - tag:'capec/1000/225/122/17/650',\ - ver:'OWASP_CRS/4.6.0',\ - severity:'CRITICAL',\ - setvar:'tx.outbound_anomaly_score_pl1=+%{tx.critical_anomaly_score}'" - -# SmEvK_PaThAn Shell web shell -SecRule RESPONSE_BODY "@rx >SmEvK_PaThAn Shell v[0-9]+ coded by \n.*? ~ Shell I\n\n