Transform OWASP CRS rules into a modern, abstract representation 🚀
The code in this repository aims to generate a new representation for the OWASP CRS rules, making them more accessible and maintainable.
The goal is to abstract OWASP CRS from the specifics of the Seclang language in which it is currently written. This abstraction provides:
- 🔄 Better maintainability - Easier to understand and modify rules
- 🎯 Language independence - Not tied to Seclang syntax
- 🚀 Enhanced tooling - Better support for analysis and transformation
- 📊 Improved readability - Cleaner representation of security rules
- 🔧 Extended ANTLR Listener - Extends the listener generated by the ANTLR Seclang parser
- 📝 Complete Rule Loading - Loads Seclang rule information stored in the CRS files, including comments
- 🎨 New Representation - Defines a new representation for the rules and translates them into it
- 🔄 Bidirectional Conversion - Convert between Seclang and CRSLang formats
Initialize the repo:
git clone https://github.com/coreruleset/crslang.git
cd crslangGenerate the ANTLR parser code and build the project:
go buildLoad and translate the Seclang OWASP CRS files to the new representation:
./crslang -o crs seclang_parser/testdata/crsLoad and translate the CRSLang back to Seclang:
./crslang -s crs.yamlRun the tests to ensure everything works correctly:
go test -vFor detailed information about the project structure and API, check out the source code and test files.
- kind: rule
metadata:
comment: ...
phase: "1"
id: 920300
message: Request Missing an Accept Header
severity: NOTICE
tags:
- application-multi
- language-multi
- platform-multi
- attack-protocol
- paranoia-level/3
- OWASP_CRS
- capec/1000/210/272
- PCI/6.5.10
version: OWASP_CRS/4.0.1-dev
conditions:
- collections:
- name: REQUEST_HEADERS
arguments:
- Accept
count: true
operator:
eq: "0"
transformations:
- none
- variables:
- REQUEST_METHOD
operator:
negate: true
rx: ^(?:OPTIONS|CONNECT)$
- collections:
- name: REQUEST_HEADERS
arguments:
- User-Agent
operator:
negate: true
pm: AppleWebKit Android
transformations:
- none
actions:
disruptive: pass
non-disruptive:
- setvar:
collection: TX
operation: =+
assignments:
- inbound_anomaly_score_pl3: "%{tx.notice_anomaly_score}"
flow:
- chain- kind: rule
metadata:
comment: ...
phase: "1"
id: 920170
message: GET or HEAD Request with Body Content
severity: CRITICAL
tags:
- application-multi
- language-multi
- platform-multi
- attack-protocol
- paranoia-level/1
- OWASP_CRS
- capec/1000/210/272
version: OWASP_CRS/4.0.1-dev
conditions:
- variables:
- REQUEST_METHOD
operator:
rx: ^(?:GET|HEAD)$
transformations:
- none
actions:
disruptive: block
non-disruptive:
- logdata: "%{MATCHED_VAR}"
flow:
- chain
chained-rule:
kind: rule
conditions:
- collections:
- name: REQUEST_HEADERS
arguments:
- Content-Length
operator:
negate: true
rx: ^0?$
transformations:
- none
actions:
non-disruptive:
- setvar:
collection: TX
operation: =+
assignments:
- inbound_anomaly_score_pl1: "%{tx.critical_anomaly_score}"- kind: rule
metadata:
comment: ...
phase: "1"
id: 901200
tags:
- OWASP_CRS
version: OWASP_CRS/4.0.1-dev
conditions:
- alwaysMatch: true
transformations:
- none
actions:
disruptive: pass
non-disruptive:
- nolog
- setvar:
- blocking_inbound_anomaly_score: "0"
- detection_inbound_anomaly_score: "0"
- inbound_anomaly_score_pl1: "0"
- inbound_anomaly_score_pl2: "0"
- inbound_anomaly_score_pl3: "0"
- inbound_anomaly_score_pl4: "0"
- sql_injection_score: "0"
- xss_score: "0"
- rfi_score: "0"
- lfi_score: "0"
- rce_score: "0"
- php_injection_score: "0"
- http_violation_score: "0"
- session_fixation_score: "0"
- blocking_outbound_anomaly_score: "0"
- detection_outbound_anomaly_score: "0"
- outbound_anomaly_score_pl1: "0"
- outbound_anomaly_score_pl2: "0"
- outbound_anomaly_score_pl3: "0"
- outbound_anomaly_score_pl4: "0"
- anomaly_score: "0"We welcome contributions! Please feel free to submit issues and pull requests.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.