Skip to content

Commit

Permalink
chore: documentation sync (#824)
Browse files Browse the repository at this point in the history
* chore: update doc for matadata actions

* chore: update doc for flow action

* chore: update doc for remaining flow/metadata actions; wording

* chore: update doc for phase/severity/status actions

* chore: update doc for exec/expirevar/initcol/log/logdata actions

* chore: update doc for deny/multimatch/rev/setenv/t actions

* chore: update doc for auditlog/capture/noauditlog/nolog/redirect actions

* chore: update doc for drop/pass/setvar actions; wording

* chore: update doc for allow/block/ctl actions
  • Loading branch information
dextermallo committed Jun 22, 2023
1 parent 256da80 commit 82157f8
Show file tree
Hide file tree
Showing 32 changed files with 593 additions and 13 deletions.
37 changes: 25 additions & 12 deletions internal/actions/allow.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,31 @@ import (
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)

// 0 nothing, 1 phase, 2 request
// Action Group: Disruptive
//
// Description:
// Stops rule processing on a successful match and allows a transaction to be proceed.
//
// - Using solely: allow will affect the entire transaction.
// stopping processing of the current phase but also skipping over all other phases apart from the logging phase.
// (The logging phase is special; it is designed to be always execute.)
// - Using with parameter `phase`: the engine will stop processing the current phase, and the other phases will continue.
// - Using with parameter `request`: engine will stop processing the current phase, and the next phase to be processed will be phase `types.PhaseResponseHeaders`.
//
// Example:
// ```
// # Allow unrestricted access from 192.168.1.100
// SecRule REMOTE_ADDR "^192\.168\.1\.100$" phase:1,id:95,nolog,allow
//
// # Do not process request but process response
// SecAction phase:1,allow:request,id:96
//
// # Do not process transaction (request and response).
// SecAction phase:1,allow,id:97
//
// # If you want to allow a response through, put a rule in phase RESPONSE_HEADERS and use allow
// SecAction phase:3,allow,id:98
// ```
type allowFn struct {
allow corazatypes.AllowType
}
Expand All @@ -30,17 +54,6 @@ func (a *allowFn) Init(_ plugintypes.RuleMetadata, data string) error {
return nil
}

// Evaluate Allow has the following rules:
//
// Example: `SecRule REMOTE_ADDR "^192\.168\.1\.100$" "phase:1,id:95,nolog,allow"`
//
// - If used one its own, like in the example above, allow will affect the entire transaction,
// stopping processing of the current phase but also skipping over all other phases apart from the logging phase.
// (The logging phase is special; it is designed to always execute.)
// - If used with parameter "phase", allow will cause the engine to stop processing the current phase.
// Other phases will continue as normal.
// - If used with parameter "request", allow will cause the engine to stop processing the current phase.
// The next phase to be processed will be phase types.PhaseResponseHeaders.
func (a *allowFn) Evaluate(r plugintypes.RuleMetadata, txS plugintypes.TransactionState) {
tx := txS.(*corazawaf.Transaction)
tx.AllowType = a.allow
Expand Down
10 changes: 10 additions & 0 deletions internal/actions/auditlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ import (
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)

// Action Group: Non-disruptive
//
// Description:
// Marks the transaction for logging in the audit log.
//
// Example:
// ```
// # The action is explicit if the log is specified.
// SecRule REMOTE_ADDR "^192\.168\.1\.100$" "auditlog,phase:1,id:100,allow"
// ```
type auditlogFn struct{}

func (a *auditlogFn) Init(r plugintypes.RuleMetadata, data string) error {
Expand Down
39 changes: 39 additions & 0 deletions internal/actions/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,45 @@ import (
"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
)

// Action Group: Disruptive
//
// Description:
// Performs the disruptive action defined by the previous `SecDefaultAction`.
// This action is a placeholder to be used by rule writers to request a blocking action,
// but without specifying how the blocking is to be done.
// The idea is that such decisions are best left to rule users, as well as to allow users, to override blocking for their demands.
// In future versions of Coraza, more control and functionality will be added to define "how" to block.
//
// Example:
// ```
// # Specify how blocking is to be done
// SecDefaultAction "phase:2,deny,id:101,status:403,log,auditlog"
//
// # Detect attacks where we want to block
// SecRule ARGS "@rx attack1" "phase:2,block,id:102"
//
// # Detect attacks where we want only to warn
// SecRule ARGS "@rx attack2" "phase:2,pass,id:103"
//
// # It is possible to use the `SecRuleUpdateActionById` directive to override how a rule handles blocking.
// # This is useful in three cases:
//
// # 1. If a rule has blocking hard-coded, and you want it to use the policy you determine.
// # 2. If a rule was written to `block`, but you want it to warn only.
// # 3. If a rule was written to only `warn`, but you want it to block.
//
// # The following example demonstrates the first case,
// # in which the hard-coded block is removed in favor of the user-controllable block:
//
// # Specify how blocking is to be done
// SecDefaultAction "phase:2,deny,status:403,log,auditlog,id:104"
//
// # Detect attacks and block
// SecRule ARGS "@rx attack1" "phase:2,id:1,deny"
//
// # Change how rule ID 1 blocks
// SecRuleUpdateActionById 1 "block"
// ```
type blockFn struct{}

func (a *blockFn) Init(_ plugintypes.RuleMetadata, data string) error {
Expand Down
16 changes: 16 additions & 0 deletions internal/actions/capture.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@ import (
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)

// Action Group: Non-disruptive
//
// Description:
// > This action is being forced by now, it might be reused in the future.
//
// When used together with the regular expression operator `@rx`,
// `capture` creates a copy of the regular expression and places them into the transaction variable collection.
// Up to 10 captures will be copied on a successful pattern match, each with a name consisting of a digit from 0 to 9.
// The `TX.0` variable always contains the entire area that the regular expression matched.
// All the other variables contain the captured values, in the order in which the capturing parentheses appear in the regular expression.
//
// Example:
// ```
// SecRule REQUEST_BODY "^username=(\w{25,})" phase:2,capture,t:none,chain,id:105
// SecRule TX:1 "(?:(?:a(dmin|nonymous)))"
// ```
type captureFn struct{}

func (a *captureFn) Init(r plugintypes.RuleMetadata, data string) error {
Expand Down
35 changes: 35 additions & 0 deletions internal/actions/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,41 @@ import (
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)

// Action Group: Flow
//
// Description:
// Creating a rule chain - chains the current rule with the rule that immediately follows it.
//
// Noted that rule chains simulate **AND condition**.
// The disruptive actions specified in the first portion of the chained rule will be triggered only if all of the variable checks return positive hits.
// If one of the chained rule is negative, the entire rule chain will fail to match.
//
// These action can be specified only by the chain starter rule:
// - disruptive actions
// - execution phases
// - metadata actions (id, rev, msg, tag, severity, logdata)
// - skip
// - skipAfter
//
// The following directives can be used in rule chains:
// - `SecAction`
// - `SecRule`
// - `SecRuleScript`
//
// Special rules control the usage of actions in a chained rule:
// - An action which affects the rule flow (i.e., the disruptive actions, `skip` and `skipAfter`) can be used only in the chain starter. They will be executed only if the entire chain matches.
// - Non-disruptive rules can be used in any rule; they will be executed if the rule that contains them matches and not only when the entire chain matches.
// - The metadata actions (e.g., `id`, `rev`, `msg`) can be used only in the chain starter.
//
// Example:
// ```
// # Refuse to accept POST requests that do not contain a Content-Length header.
// # Noted that the rule should be preceded by a rule that verifies only valid request methods are used.
//
// SecRule REQUEST_METHOD "^POST$" "phase:1,chain,t:none,id:105"
// SecRule &REQUEST_HEADERS:Content-Length "@eq 0" "t:none"
//
// ```
type chainFn struct{}

func (a *chainFn) Init(r plugintypes.RuleMetadata, data string) error {
Expand Down
56 changes: 56 additions & 0 deletions internal/actions/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,62 @@ const (
ctlDebugLogLevel ctlFunctionType = iota
)

// Action Group: Non-disruptive
//
// Description:
// Change Coraza configuration on transient, per-transaction basis.
// Any changes made using this action will affect only the transaction in which the action is executed.
// The default configuration, as well as the other transactions running in parallel, will be unaffected.
//
// The following configuration options are supported:
// - `auditEngine`
// - `auditLogParts`
// - `debugLogLevel`
// - `forceRequestBodyVariable`
// - `requestBodyAccess`
// - `requestBodyLimit`
// - `requestBodyProcessor`
// - `responseBodyAccess`
// - `responseBodyLimit`
// - `ruleEngine`
// - `ruleRemoveById`
// - `ruleRemoveByMsg`
// - `ruleRemoveByTag`
// - `ruleRemoveTargetById`
// - `ruleRemoveTargetByMsg`
// - `ruleRemoveTargetByTag`
// - `hashEngine` (**Not Supported in Coraza (TBI)**)
// - `hashEnforcement` (**Not supported in Coraza (TBI)**)
//
// Here are some notes about the options:
//
// 1. Option `ruleRemoveTargetById`, `ruleRemoveTargetByMsg`, and `ruleRemoveTargetByTag`, users don't need to use the char ! before the target list.
//
// 2. Option `ruleRemoveById` is triggered at run time and should be specified before the rule in which it is disabling.
//
// 3. Option `requestBodyProcessor` allows you to configure the request body processor.
// By default, Coraza will use the `URLENCODED` and `MULTIPART` processors to process an `application/x-www-form-urlencoded` and a `multipart/form-data` body respectively.
// Other processors also supported: `JSON` and `XML`, but they are never used implicitly.
// Instead, you must tell Coraza to use it by placing a few rules in the `REQUEST_HEADERS` processing phase.
// After the request body is processed as XML, you will be able to use the XML-related features to inspect it.
// Request body processors will not interrupt a transaction if an error occurs during parsing.
// Instead, they will set the variables `REQBODY_PROCESSOR_ERROR` and `REQBODY_PROCESSOR_ERROR_MSG`.
// These variables should be inspected in the `REQUEST_BODY` phase and an appropriate action taken.
//
// 4. Option `forceRequestBodyVariable“ allows you to configure the `REQUEST_BODY` variable to be set when there is no request body processor configured.
// This allows for inspection of request bodies of unknown types.
//
// Example:
// ```
// # Parse requests with Content-Type "text/xml" as XML
// SecRule REQUEST_CONTENT_TYPE ^text/xml "nolog,pass,id:106,ctl:requestBodyProcessor=XML"
//
// # white-list the user parameter for rule #981260 when the REQUEST_URI is /index.php
//
// SecRule REQUEST_URI "@beginsWith /index.php" "phase:1,t:none,pass,\
// nolog,ctl:ruleRemoveTargetById=981260;ARGS:user"
//
// ```
type ctlFn struct {
action ctlFunctionType
value string
Expand Down
9 changes: 9 additions & 0 deletions internal/actions/deny.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ import (
"github.com/corazawaf/coraza/v3/types"
)

// Action Group: Disruptive
//
// Description:
// Stops rule processing and intercepts transaction.
//
// Example:
// ```
// SecRule REQUEST_HEADERS:User-Agent "nikto" "log,deny,id:107,msg:'Nikto Scanners Identified'"
// ```
type denyFn struct{}

func (a *denyFn) Init(_ plugintypes.RuleMetadata, data string) error {
Expand Down
18 changes: 18 additions & 0 deletions internal/actions/drop.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,24 @@ import (
"github.com/corazawaf/coraza/v3/types"
)

// Action Group: Disruptive
//
// Description:
// > This action depends on each implementation, the server is instructed to drop the connection.
//
// Initiates an immediate close of the TCP connection by sending a FIN packet.
// This action is extremely useful when responding to both Brute Force and Denial of Service attacks,
// which you may want to minimize the network bandwidth and the data returned to the client.
// This action causes error message to appear in the log `(9)Bad file descriptor: core_output_filter: writing data to the network`
//
// Example:
// ```
// # The following example initiates an IP collection for tracking Basic Authentication attempts.
// # If the client exceed the threshold of more than 25 attempts in 2 minutes, it will `DROP` the subsequent connections.
// SecAction phase:1,id:109,initcol:ip=%{REMOTE_ADDR},nolog
// SecRule ARGS:login "!^$" "nolog,phase:1,id:110,setvar:ip.auth_attempt=+1,deprecatevar:ip.auth_attempt=25/120"
// SecRule IP:AUTH_ATTEMPT "@gt 25" "log,drop,phase:1,id:111,msg:'Possible Brute Force Attack'"
// ```
type dropFn struct{}

func (a *dropFn) Init(_ plugintypes.RuleMetadata, data string) error {
Expand Down
22 changes: 22 additions & 0 deletions internal/actions/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@ import (
"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
)

// Action Group: Non-disruptive
//
// Description:
// Executes an external script/binary supplied as parameter.
// The `exec` action is executed independently from any disruptive actions specified.
// External scripts will always be called with no parameters.
// Some transaction information will be placed in environment variables.
// All the usual CGI environment variables will be there.
// You should be aware that forking a threaded process results in all threads being replicated in the new process.
// Forking can therefore incur larger overhead in a multithreaded deployment.
//
// > The script you execute must write something (anything) to stdout,
// > if it doesn’t, Coraza will assume that the script failed, and will record the failure.
//
// Example:
// ```
// # Run external program on rule match
// SecRule REQUEST_URI "^/cgi-bin/script\.pl" "phase:2,id:112,t:none,t:lowercase,t:normalizePath,block,\ exec:/usr/local/apache/bin/test.sh"

// # Run Lua script on rule match
// SecRule ARGS:p attack "phase:2,id:113,block,exec:/usr/local/apache/conf/exec.lua"
// ```
type execFn struct{}

func (a *execFn) Init(_ plugintypes.RuleMetadata, data string) error {
Expand Down
16 changes: 16 additions & 0 deletions internal/actions/expirevar.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ import (
"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
)

// Action Group: Non-disruptive
//
// Description:
// Configures a collection variable to expire after the given time period (in seconds).
// You should use the `expirevar` with `setvar` action to keep the intended expiration time.
// The expire time will be reset if they are used on their own (perhaps in a SecAction directive).
//
// Example:
// ```
//
// SecRule REQUEST_COOKIES:JSESSIONID "!^$" "nolog,phase:1,id:114,pass,setsid:%{REQUEST_COOKIES:JSESSIONID}"
//
// SecRule REQUEST_URI "^/cgi-bin/script\.pl" "phase:2,id:115,t:none,t:lowercase,t:normalizePath,log,allow,\
// setvar:session.suspicious=1,expirevar:session.suspicious=3600,phase:1"
//
// ```
type expirevarFn struct{}

func (a *expirevarFn) Init(_ plugintypes.RuleMetadata, data string) error {
Expand Down
10 changes: 10 additions & 0 deletions internal/actions/id.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ import (
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)

// Action Group: Metadata
//
// Description:
// > This action is mandatory for all `SecRule` and `SecAction`, and it must be numeric.
// Assigns a unique ID to the rule or chain in which it appears.
//
// Example:
// ```
// SecRule &REQUEST_HEADERS:Host "@eq 0" "log,id:60008,severity:2,msg:'Request Missing a Host Header'"
// ```
type idFn struct{}

func (a *idFn) Init(r plugintypes.RuleMetadata, data string) error {
Expand Down
14 changes: 13 additions & 1 deletion internal/actions/initcol.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,19 @@ import (
"github.com/corazawaf/coraza/v3/experimental/plugins/plugintypes"
)

// Initializes a persistent collection and add the data to the standard collections coraza.
// Action Group: Non-disruptive
//
// Description:
// Initializes a named persistent collection, either by loading data from storage or by creating a new collection in memory.
// Collections are loaded into memory on-demand, when the initcol action is executed.
// A collection will be persisted only if a change was made to it in the course of transaction processing.
// See the `Persistent Storage` section for further details.
//
// Example:
// ```
// # Initiates IP address tracking, which is best done in phase 1
// SecAction "phase:1,id:116,nolog,pass,initcol:ip=%{REMOTE_ADDR}"
// ```
type initcolFn struct {
collection string
variable byte
Expand Down
10 changes: 10 additions & 0 deletions internal/actions/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ import (
"github.com/corazawaf/coraza/v3/internal/corazawaf"
)

// Action Group: Non-disruptive
//
// Description:
// Indicates that a successful match of the rule needs to be logged.
//
// Example:
// ```
// # log matches from the error log file to the Coraza audit log.
// SecAction "phase:1,id:117,pass,initcol:ip=%{REMOTE_ADDR},log"
// ```
type logFn struct{}

func (a *logFn) Init(r plugintypes.RuleMetadata, data string) error {
Expand Down
Loading

0 comments on commit 82157f8

Please sign in to comment.