engine

package module
v1.0.0-beta.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 29, 2021 License: Apache-2.0 Imports: 23 Imported by: 2

README

Coraza Web Application Firewall

Build Status CodeQL Maintainability Rating Coverage GoDoc

Welcome to Coraza Web Application Firewall, this project is a Golang port of ModSecurity with the goal to become the first enterprise-grade Open Source Web Application Firewall, flexible and powerful enough to serve as the baseline for many projects.

Prerequisites

  • Linux distribution (Debian and Centos are recommended, Windows is not supported)
  • Golang compiler v1.16
  • libpcre-dev (apt install libpcre++-dev for Ubuntu)
  • CGO_ENABLED environmental variable must be set to 1
  • libinjection must be installed and linked

You may install libinjection with the following command:

# Must be run as root
sudo make deps

Note this command will compile and install libinjection to your LIBRARY_PATH and LD_LIBRARY_PATH.

Running the test suite

Run the go tests:

go test ./...
go test -race ./...
Run the test suite against OWASP CRS

You can run the testsuite using our OWASP CRS test docker image, it will run a Coraza instance using Caddy and go-ftw

git clone https://github.com/jptosso/coraza-ruleset
cd coraza-ruleset
docker build . -t crs
docker run crs -name crs

Your first Coraza WAF project

Make sure CGO_ENABLED=1 env is set before compiling and all dependencies are met.

package main
import(
	"fmt"
	engine"github.com/jptosso/coraza-waf"
	"github.com/jptosso/coraza-waf/seclang"
)

func main() {
	// First we initialize our waf and our seclang parser
	waf := engine.NewWaf()
	parser := seclang.NewParser(waf)

	// Now we parse our rules
	parser.FromString(`SecRule REMOTE_ADDR "@rx .*" "id:1,phase:1,drop"`)

	// Then we create a transaction and assign some variables
	tx := waf.NewTransaction()
	tx.ProcessConnection("127.0.0.1", 8080, "127.0.0.1", 12345)

	tx.ProcessRequestHeaders()

	// Finally we check the transaction status
	if tx.Interrupted() {
		fmt.Println("Transaction was interrupted")
	}
}
Integrate with any framework

Using the standard net/http library:

package main
import(
	engine"github.com/jptosso/coraza-waf"
	"github.com/jptosso/coraza-waf/seclang"
	"net/http"
)

func SomeErrorPage(w http.ResponseWriter) {
	w.WriteHeader(403)
	w.Write([]byte("WAF ERROR")
}

func someHandler(waf *engine.Waf) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    tx := waf.NewTransaction()
	tx.ProcessRequest(r)
	if tx.Interruption != nil {
		SomeErrorPage(w)
	}
  })
}

Responses are harder to handle, because we must intercept the response writers and integrate them with the Coraza BodyReader.

Handling HTTP responses with Coraza

Responses are usually long buffers, so duplicating the response or buffering it in memory is hard. In order to avoid issues while handling long buffers Coraza provides the engine.BodyReader struct, it will handle long buffers storing them to temporary files if needed.

func someHandler(waf *engine.Waf) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		tx := waf.NewTransaction()
		tx.ProcessRequest(r)
		if tx.Interruption != nil {
			SomeErrorPage(w)
		}
		// We will use the Coraza response reader:
		tx.ProcessResponseHeaders()
		tx.ResponseBuffer.Write([]byte("Some of the response body"))
		tx.ProcessResponseBody()
		// We will dump the buffered response into the response writer:
		io.Copy(w, tx.ResponseBuffer)
	})
}

Compatibility status

We have currently achieved a 91% compatibility with OWASP CRS, some features are under development, like:

  • Persistent Collections
  • Some operators: fuzzyHash
  • Lua is still being tested, it may be replaced with WASM

Why Coraza WAF?

Philosophy
  • Simplicity: Anyone should be able to understand and modify Coraza WAF's source code
  • Extensibility: It should be easy to extend Coraza WAF with new functionalities
  • Innovation: Coraza WAF isn't just a ModSecurity port, it must include awesome new functions (in the meantime it's just a port 😅)
  • Community: Coraza WAF is a community project and everyone's idea will be heard
Roadmap (long term)
  • WASM scripts support, Lua was removed
  • Performance improvements
  • More tests and documentation
  • Integrated DDOS protection and directives with iptables(And others) integration
  • Integrated protocol validations (rfc2616)
  • Integrated CSRF protection
  • Integrated bot detection with captcha
  • More loggers and persistence engines
  • More integrations (traefik, gin and buffalo)
  • Open Policy Agent package (OPA)
  • Online sandbox
  • HTTP/2 and HTTP/3 support
  • Enhanced rule profiling
  • Native antivirus integration (maybe)
  • Automatic coreruleset integration (download and setup) (maybe)
  • Enhanced data masking features
  • Enhanced data signing features (cookies, forms, etc)
  • OpenAPI enforcement
  • JWT enforcement
  • JSON and YAML query

Coraza WAF implementations

Some useful tools

Troubleshooting

How to contribute

Contributions are welcome, there are so many TODOs, also functionalities, fixes, bug reports and any help you can provide. Just send your PR.

cd /path/to/coraza
egrep -Rin "TODO|FIXME" -R --exclude-dir=vendor *

Special thanks

  • Modsecurity team for creating SecLang
  • OWASP Coreruleset team for the CRS and their feedback

About

The name Coraza is trademarked, Coraza is a registered trademark of Juan Pablo Tosso.

Documentation

Overview

Copyright 2021 Juan Pablo Tosso

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Index

Constants

View Source
const (
	ACTION_TYPE_METADATA      = 1
	ACTION_TYPE_DISRUPTIVE    = 2
	ACTION_TYPE_DATA          = 3
	ACTION_TYPE_NONDISRUPTIVE = 4
	ACTION_TYPE_FLOW          = 5

	ACTION_DISRUPTIVE_PASS     = 0
	ACTION_DISRUPTIVE_DROP     = 1
	ACTION_DISRUPTIVE_BLOCK    = 2
	ACTION_DISRUPTIVE_DENY     = 3
	ACTION_DISRUPTIVE_ALLOW    = 4
	ACTION_DISRUPTIVE_PROXY    = 5
	ACTION_DISRUPTIVE_REDIRECT = 6
)
View Source
const (
	// Single valua variables
	VARIABLE_URLENCODED_ERROR                 = 0x00
	VARIABLE_RESPONSE_CONTENT_TYPE            = 0x01
	VARIABLE_UNIQUE_ID                        = 0x02
	VARIABLE_ARGS_COMBINED_SIZE               = 0x03
	VARIABLE_AUTH_TYPE                        = 0x04
	VARIABLE_FILES_COMBINED_SIZE              = 0x05
	VARIABLE_FULL_REQUEST                     = 0x06
	VARIABLE_FULL_REQUEST_LENGTH              = 0x07
	VARIABLE_INBOUND_DATA_ERROR               = 0x08
	VARIABLE_MATCHED_VAR                      = 0x09
	VARIABLE_MATCHED_VAR_NAME                 = 0x0A
	VARIABLE_MULTIPART_BOUNDARY_QUOTED        = 0x0B
	VARIABLE_MULTIPART_BOUNDARY_WHITESPACE    = 0x0C
	VARIABLE_MULTIPART_CRLF_LF_LINES          = 0x0D
	VARIABLE_MULTIPART_DATA_AFTER             = 0x0E
	VARIABLE_MULTIPART_DATA_BEFORE            = 0x0F
	VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED    = 0x10
	VARIABLE_MULTIPART_HEADER_FOLDING         = 0x11
	VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 0x12
	VARIABLE_MULTIPART_INVALID_PART           = 0x13
	VARIABLE_MULTIPART_INVALID_QUOTING        = 0x14
	VARIABLE_MULTIPART_LF_LINE                = 0x15
	VARIABLE_MULTIPART_MISSING_SEMICOLON      = 0x16
	VARIABLE_MULTIPART_STRICT_ERROR           = 0x17
	VARIABLE_MULTIPART_UNMATCHED_BOUNDARY     = 0x18
	VARIABLE_OUTBOUND_DATA_ERROR              = 0x19
	VARIABLE_PATH_INFO                        = 0x1A
	VARIABLE_QUERY_STRING                     = 0x1B
	VARIABLE_REMOTE_ADDR                      = 0x1C
	VARIABLE_REMOTE_HOST                      = 0x1D
	VARIABLE_REMOTE_PORT                      = 0x1E
	VARIABLE_REQBODY_ERROR                    = 0x1F
	VARIABLE_REQBODY_ERROR_MSG                = 0x20
	VARIABLE_REQBODY_PROCESSOR_ERROR          = 0x21
	VARIABLE_REQBODY_PROCESSOR_ERROR_MSG      = 0x22
	VARIABLE_REQBODY_PROCESSOR                = 0x23
	VARIABLE_REQUEST_BASENAME                 = 0x24
	VARIABLE_REQUEST_BODY                     = 0x25
	VARIABLE_REQUEST_BODY_LENGTH              = 0x26
	VARIABLE_REQUEST_FILENAME                 = 0x27
	VARIABLE_REQUEST_LINE                     = 0x28
	VARIABLE_REQUEST_METHOD                   = 0x29
	VARIABLE_REQUEST_PROTOCOL                 = 0x2A
	VARIABLE_REQUEST_URI                      = 0x2B
	VARIABLE_REQUEST_URI_RAW                  = 0x2C
	VARIABLE_RESPONSE_BODY                    = 0x2D
	VARIABLE_RESPONSE_CONTENT_LENGTH          = 0x2E
	VARIABLE_RESPONSE_PROTOCOL                = 0x2F
	VARIABLE_RESPONSE_STATUS                  = 0x30
	VARIABLE_SERVER_ADDR                      = 0x31
	VARIABLE_SERVER_NAME                      = 0x32
	VARIABLE_SERVER_PORT                      = 0x33
	VARIABLE_SESSIONID                        = 0x34

	// Set Variables
	VARIABLE_RESPONSE_HEADERS_NAMES = 0x35
	VARIABLE_REQUEST_HEADERS_NAMES  = 0x36
	VARIABLE_USERID                 = 0x37
	VARIABLE_ARGS                   = 0x38
	VARIABLE_ARGS_GET               = 0x39
	VARIABLE_ARGS_POST              = 0x3A
	VARIABLE_FILES_SIZES            = 0x3B
	VARIABLE_FILES_NAMES            = 0x3C
	VARIABLE_FILES_TMP_CONTENT      = 0x3D
	VARIABLE_MULTIPART_FILENAME     = 0x3E
	VARIABLE_MULTIPART_NAME         = 0x3F
	VARIABLE_MATCHED_VARS_NAMES     = 0x40
	VARIABLE_MATCHED_VARS           = 0x41
	VARIABLE_FILES                  = 0x42
	VARIABLE_REQUEST_COOKIES        = 0x43
	VARIABLE_REQUEST_HEADERS        = 0x44
	VARIABLE_RESPONSE_HEADERS       = 0x45
	VARIABLE_GEO                    = 0x46
	VARIABLE_REQUEST_COOKIES_NAMES  = 0x47
	VARIABLE_FILES_TMPNAMES         = 0x48
	VARIABLE_ARGS_NAMES             = 0x49
	VARIABLE_ARGS_GET_NAMES         = 0x4A
	VARIABLE_ARGS_POST_NAMES        = 0x4B
	VARIABLE_TX                     = 0x4C

	VARIABLE_RULE               = 0x52 //TODO FIX
	VARIABLE_XML                = 0x53 //TODO FIX
	VARIABLE_JSON               = 0x54 //TODO FIX
	VARIABLE_INBOUND_ERROR_DATA = 0x55 //TODO FIX
	VARIABLE_DURATION           = 0x56 //TODO FIX

	// Persistent collections
	VARIABLE_GLOBAL   = 0x4D
	VARIABLE_IP       = 0x4E
	VARIABLE_SESSION  = 0x4F
	VARIABLE_USER     = 0x50
	VARIABLE_RESOURCE = 0x51
)
View Source
const (
	CONN_ENGINE_OFF        = 0
	CONN_ENGINE_ON         = 1
	CONN_ENGINE_DETECTONLY = 2

	AUDIT_LOG_CONCURRENT = 0
	AUDIT_LOG_HTTPS      = 1
	AUDIT_LOG_SCRIPT     = 2

	AUDIT_LOG_ENABLED  = 0
	AUDIT_LOG_DISABLED = 1
	AUDIT_LOG_RELEVANT = 2

	ERROR_PAGE_DEFAULT = 0
	ERROR_PAGE_SCRIPT  = 1
	ERROR_PAGE_FILE    = 2
	ERROR_PAGE_INLINE  = 3
	ERROR_PAGE_DEBUG   = 4

	REQUEST_BODY_PROCESSOR_DEFAULT    = 0
	REQUEST_BODY_PROCESSOR_URLENCODED = 1
	REQUEST_BODY_PROCESSOR_XML        = 2
	REQUEST_BODY_PROCESSOR_JSON       = 3
	REQUEST_BODY_PROCESSOR_MULTIPART  = 4

	REQUEST_BODY_LIMIT_ACTION_PROCESS_PARTIAL = 0
	REQUEST_BODY_LIMIT_ACTION_REJECT          = 1

	RULE_ENGINE_ON         = 0
	RULE_ENGINE_DETECTONLY = 1
	RULE_ENGINE_OFF        = 2
)
View Source
const VARIABLES_COUNT = 88

Variables

This section is empty.

Functions

func NameToVariable

func NameToVariable(name string) (byte, error)

func VariableToName

func VariableToName(v byte) string

Types

type Action

type Action interface {
	Init(*Rule, string) error
	Evaluate(*Rule, *Transaction)
	GetType() int
}

type BodyBuffer

type BodyBuffer struct {
	io.Writer //OK?
	// contains filtered or unexported fields
}

BoddyReader is used to read RequestBody and ResponseBody objects It will handle memory usage for buffering and processing

func NewBodyReader

func NewBodyReader(tmpDir string, memLimit int64) *BodyBuffer

NewBodyReader Initializes a body reader After writing memLimit bytes to the memory buffer, data will be written to a temporary file Temporary files will be written to tmpDir

func (*BodyBuffer) Close

func (br *BodyBuffer) Close()

Close will close all readers and delete temporary files

func (*BodyBuffer) Reader

func (br *BodyBuffer) Reader() io.Reader

Reader Returns a working reader for the body buffer in memory or file

func (*BodyBuffer) Size

func (br *BodyBuffer) Size() int64

Size returns the current size of the body buffer

func (*BodyBuffer) String

func (br *BodyBuffer) String() string

String returns a string with the whole body buffer In some cases it will be needed for body processing

func (*BodyBuffer) Write

func (br *BodyBuffer) Write(data []byte) (n int, err error)

Write appends data to the body buffer by chunks You may dump io.Readers using io.Copy(br, reader)

type Collection

type Collection struct {
	// contains filtered or unexported fields
}

func NewCollection

func NewCollection(name string) *Collection

Creates a new collection

func (*Collection) Add

func (c *Collection) Add(key string, value string)

func (*Collection) AddUnique

func (c *Collection) AddUnique(key string, value string)

func (*Collection) Find

func (c *Collection) Find(key string, re *regex.Regexp, exceptions []string) []*MatchData

PCRE compatible collection with exceptions

func (*Collection) Get

func (c *Collection) Get(key string) []string

func (*Collection) GetData

func (c *Collection) GetData() map[string][]string

func (*Collection) GetFirstInt

func (c *Collection) GetFirstInt(key string) int

func (*Collection) GetFirstInt64

func (c *Collection) GetFirstInt64(key string) int64

func (*Collection) GetFirstString

func (c *Collection) GetFirstString(key string) string

func (*Collection) GetName

func (c *Collection) GetName() string

func (*Collection) Init

func (c *Collection) Init(name string)

func (*Collection) Remove

func (c *Collection) Remove(key string)

func (*Collection) Reset

func (c *Collection) Reset()

func (*Collection) Set

func (c *Collection) Set(key string, value []string)

func (*Collection) SetData

func (c *Collection) SetData(data map[string][]string)

type Interruption

type Interruption struct {
	// Rule that caused the interruption
	RuleId int

	// drop, deny, redirect
	Action string

	// Force this status code
	Status int

	// Parameters used by proxy and redirect
	Data string
}

type KeyValue

type KeyValue struct {
	Name       string
	Collection byte
	Key        string
}

type MatchData

type MatchData struct {
	Collection string
	Key        string
	Value      string
}

type MatchedRule

type MatchedRule struct {
	Messages    []string
	MatchedData []*MatchData
	Rule        *Rule
}

type Operator

type Operator interface {
	Init(string) error
	Evaluate(*Transaction, string) bool
}

type Rule

type Rule struct {
	Variables               []RuleVariable
	Operator                *RuleOperator
	Transformations         []transformations.Transformation
	ParentId                int
	Actions                 []Action
	SecMark                 string
	Raw                     string
	Chain                   *Rule
	DisruptiveAction        int
	DefaultDisruptiveAction string
	HasChain                bool
	AlwaysMatch             bool

	//METADATA
	// Rule unique sorted identifier
	Id int

	// Rule tag list
	Tags []string

	// Rule execution phase 1-5
	Phase int

	// Message text to be macro expanded and logged
	Msg string

	// Rule revision value
	Rev string

	// Rule maturity index
	Maturity string

	// Rule Set Version
	Version string

	// Used by deny to create disruption
	Status     int
	Log        bool
	MultiMatch bool
	Severity   string
	Skip       bool
}

func NewRule

func NewRule() *Rule

func (*Rule) AddNegateVariable

func (r *Rule) AddNegateVariable(collection byte, key string)

func (*Rule) AddVariable

func (r *Rule) AddVariable(count bool, collection byte, key string)

func (*Rule) Evaluate

func (r *Rule) Evaluate(tx *Transaction) []*MatchData

type RuleGroup

type RuleGroup struct {
	// contains filtered or unexported fields
}

func NewRuleGroup

func NewRuleGroup() *RuleGroup

func (*RuleGroup) Add

func (rg *RuleGroup) Add(rule *Rule) error

Adds a rule to the collection Will return an error if the ID is already used

func (*RuleGroup) Clear

func (rg *RuleGroup) Clear()

func (*RuleGroup) Count

func (rg *RuleGroup) Count() int

func (*RuleGroup) DeleteById

func (rg *RuleGroup) DeleteById(id int)

func (*RuleGroup) Evaluate

func (rg *RuleGroup) Evaluate(phase int, tx *Transaction) bool

Execute rules for the specified phase, between 1 and 5 Returns true if transaction is disrupted

func (*RuleGroup) FindById

func (rg *RuleGroup) FindById(id int) *Rule

func (*RuleGroup) FindByMsg

func (rg *RuleGroup) FindByMsg(msg string) []*Rule

func (*RuleGroup) FindByTag

func (rg *RuleGroup) FindByTag(tag string) []*Rule

func (*RuleGroup) GetRules

func (rg *RuleGroup) GetRules() []*Rule

type RuleOperator

type RuleOperator struct {
	Operator Operator
	Data     string
	Negation bool
}

type RuleVariable

type RuleVariable struct {
	Count      bool
	Collection byte
	Key        string
	Regex      *regex.Regexp //for performance
	Exceptions []string
}

type Transaction

type Transaction struct {
	// If true the transaction is going to be logged, it won't log if IsRelevantStatus() fails
	Log bool

	//Transaction Id
	Id string

	// Contains the list of matched rules and associated match information
	MatchedRules []*MatchedRule

	//True if the transaction has been disrupted by any rule
	Interruption *Interruption

	// Contains all collections, including persistent
	Collections []*Collection

	//Response data to be sent
	Status int `json:"status"`

	Logdata []string `json:"logdata"`

	// Rules will be skipped after a rule with this SecMarker is found
	SkipAfter string

	// Copies from the WafInstance that may be overwritten by the ctl action
	AuditEngine              int
	AuditLogParts            []rune
	ForceRequestBodyVariable bool
	RequestBodyAccess        bool
	RequestBodyLimit         int64
	RequestBodyProcessor     int
	ResponseBodyAccess       bool
	ResponseBodyLimit        int64
	RuleEngine               int
	HashEngine               bool
	HashEnforcement          bool

	LastPhase int

	RequestBodyBuffer  *BodyBuffer
	ResponseBodyBuffer *BodyBuffer

	// Rules with this id are going to be skipped
	RuleRemoveById []int

	// Used by ctl to remove rule targets by id during the transaction
	RuleRemoveTargetById map[int][]*KeyValue

	// Will skip this number of rules, this value will be decreased on each skip
	Skip int

	// Actions with capture features will read the capture state from this field
	Capture bool

	// Contains duration in useconds per phase
	StopWatches map[int]int

	// Contains de *engine.Waf instance for the current transaction
	Waf *Waf

	XmlDoc *xmlquery.Node

	Timestamp int64
}

func (*Transaction) AddArgument

func (tx *Transaction) AddArgument(orig string, key string, value string)

Add arguments GET or POST This will set ARGS_(GET|POST), ARGS, ARGS_NAMES, ARGS_COMBINED_SIZE and ARGS_(GET|POST)_NAMES

func (*Transaction) AddRequestHeader

func (tx *Transaction) AddRequestHeader(key string, value string)

Adds a request header

With this method it is possible to feed Coraza with a request header. Note: Golang's *http.Request object will not contain a "Host" header and you might have to force it

func (*Transaction) AddResponseHeader

func (tx *Transaction) AddResponseHeader(key string, value string)

Adds a response header

With this method it is possible to feed Coraza with a response header.

func (*Transaction) AuditLog

func (tx *Transaction) AuditLog() *loggers.AuditLog

AuditLog returns an AuditLog struct

func (*Transaction) CaptureField

func (tx *Transaction) CaptureField(index int, value string)

Used to set the TX:[index] collection by operators

func (*Transaction) ExtractArguments

func (tx *Transaction) ExtractArguments(orig string, uri string)

ExtractArguments transforms an url encoded string to a map and creates ARGS_POST|GET

func (*Transaction) GetCollection

func (tx *Transaction) GetCollection(variable byte) *Collection

func (*Transaction) GetCollections

func (tx *Transaction) GetCollections() map[string]*Collection

This is for debug only

func (*Transaction) GetField

func (tx *Transaction) GetField(rv RuleVariable, exceptions []string) []*MatchData

Retrieve data from collections applying exceptions This function will apply xpath if the variable is XML

func (*Transaction) GetRemovedTargets

func (tx *Transaction) GetRemovedTargets(id int) []*KeyValue

func (*Transaction) GetStopWatch

func (tx *Transaction) GetStopWatch() string

func (*Transaction) Interrupted

func (tx *Transaction) Interrupted() bool

Interrupted will return true if the transaction was interrupted

func (*Transaction) IsProcessableResponseBody

func (tx *Transaction) IsProcessableResponseBody() bool

IsProcessableRequestBody returns true if the response body meets the criteria to be processed, response headers must be set before. The content-type response header must be in the SecRequestBodyMime This is used by webservers to stream response buffers directly to the client

func (*Transaction) MacroExpansion

func (tx *Transaction) MacroExpansion(data string) string

func (*Transaction) MatchRule

func (tx *Transaction) MatchRule(rule *Rule, msgs []string, match []*MatchData)

Matches a rule to be logged

func (*Transaction) MatchVars

func (tx *Transaction) MatchVars(match []*MatchData)

Creates the MATCHED_VAR* variables required by chains and macro expansion

func (*Transaction) ParseRequestString

func (tx *Transaction) ParseRequestString(data string) (*Interruption, error)

Parse binary request including body, does only supports http/1.1 and http/1.0 This function is only intended for testing and debugging

func (*Transaction) ProcessConnection

func (tx *Transaction) ProcessConnection(client string, cPort int, server string, sPort int)

This method should be called at very beginning of a request process, it is expected to be executed prior to the virtual host resolution, when the connection arrives on the server. Important: Remember to check for a possible intervention.

func (*Transaction) ProcessLogging

func (tx *Transaction) ProcessLogging()

Logging all information relative to this transaction.

At this point there is not need to hold the connection, the response can be delivered prior to the execution of this method.

func (*Transaction) ProcessRequest

func (tx *Transaction) ProcessRequest(req *http.Request) (*Interruption, error)

ProcessRequest Fill all transaction variables from an http.Request object Most implementations of Coraza will probably use http.Request objects so this will implement all phase 0, 1 and 2 variables Note: This function will stop after an interruption Note: Do not manually fill any request variables

func (*Transaction) ProcessRequestBody

func (tx *Transaction) ProcessRequestBody() (*Interruption, error)

Perform the request body (if any)

This method perform the analysis on the request body. It is optional to call that function. If this API consumer already know that there isn't a body for inspect it is recommended to skip this step.

Remember to check for a possible intervention.

func (*Transaction) ProcessRequestHeaders

func (tx *Transaction) ProcessRequestHeaders() *Interruption

Perform the analysis on the request readers.

This method perform the analysis on the request headers, notice however that the headers should be added prior to the execution of this function.

note: Remember to check for a possible intervention.

func (*Transaction) ProcessResponseBody

func (tx *Transaction) ProcessResponseBody() (*Interruption, error)

Perform the request body (if any)

This method perform the analysis on the request body. It is optional to call that method. If this API consumer already know that there isn't a body for inspect it is recommended to skip this step.

note Remember to check for a possible intervention.

func (*Transaction) ProcessResponseHeaders

func (tx *Transaction) ProcessResponseHeaders(code int, proto string) *Interruption

Perform the analysis on the response readers.

This method perform the analysis on the response headers, notice however that the headers should be added prior to the execution of this function.

note: Remember to check for a possible intervention.

func (*Transaction) ProcessUri

func (tx *Transaction) ProcessUri(uri string, method string, httpVersion string)

Perform the analysis on the URI and all the query string variables. This method should be called at very beginning of a request process, it is expected to be executed prior to the virtual host resolution, when the connection arrives on the server. note: There is no direct connection between this function and any phase of

the SecLanguage's phases. It is something that may occur between the
SecLanguage phase 1 and 2.

note: This function won't add GET arguments, they must be added with AddArgument

func (*Transaction) RemoveRuleTargetById

func (tx *Transaction) RemoveRuleTargetById(id int, col byte, key string)

Removes the VARIABLE/TARGET from the rule ID

func (*Transaction) ResetCapture

func (tx *Transaction) ResetCapture()

Reset the capture collection for further uses

func (*Transaction) SetFullRequest

func (tx *Transaction) SetFullRequest()

Creates the FULL_REQUEST variable based on every input It's a heavy operation and it's not used by OWASP CRS so it's optional

func (*Transaction) ToAuditJson

func (tx *Transaction) ToAuditJson() []byte

type Waf

type Waf struct {
	// RuleGroup object, contains all rules and helpers
	Rules *RuleGroup

	// Absolute path where rules are going to look for data files or scripts
	Datapath string

	// Audit mode status
	AuditEngine int

	// Array of logging parts to be used
	AuditLogParts []rune

	// If true, transactions will have access to the request body
	RequestBodyAccess bool

	// Request body page file limit
	RequestBodyLimit int64

	// Request body in memory limit
	RequestBodyInMemoryLimit int64

	// If true, transactions will have access to the response body
	ResponseBodyAccess bool

	// Response body memory limit
	ResponseBodyLimit int64

	// Defines if rules are going to be evaluated
	RuleEngine int

	// If true, transaction will fail if response size is bigger than the page limit
	RejectOnResponseBodyLimit bool

	// If true, transaction will fail if request size is bigger than the page limit
	RejectOnRequestBodyLimit bool

	// Responses will only be loaded if mime is listed here
	ResponseBodyMimeTypes []string

	// Web Application id, apps sharing the same id will share persistent collections
	WebAppId string

	// This signature is going to be reported in audit logs
	ComponentSignature string

	// Contains the regular expression for relevant status audit logging
	AuditLogRelevantStatus regex.Regexp

	// Contains the GeoIP2 database reader object
	GeoDb *geoip2.Reader

	// If true WAF engine will fail when remote rules cannot be loaded
	AbortOnRemoteRulesFail bool

	// Instructs the waf to change the Server response header
	ServerSignature string

	// This directory will be used to store page files
	TmpDir string

	// Persistence engine
	Persistence persistence.Persistence

	// Sensor ID tu, must be unique per cluster nodes
	SensorId string

	// Path to store data files
	DataDir string

	UploadKeepFiles         bool
	UploadFileMode          fs.FileMode
	UploadFileLimit         int
	UploadDir               string
	RequestBodyNoFilesLimit int64
	CollectionTimeout       int

	Unicode *utils.Unicode

	RequestBodyLimitAction int

	ArgumentSeparator string
	// contains filtered or unexported fields
}

func NewWaf

func NewWaf() *Waf

NewWaf creates a new WAF instance with default variables

func (*Waf) AddLogger

func (w *Waf) AddLogger(engine string, args []string) error

AddLogger creates a new logger for the current WAF instance You may add as many loggers as you want Keep in mind loggers may lock go routines

func (*Waf) Loggers

func (w *Waf) Loggers() []loggers.Logger

Logger returns the initiated loggers Coraza supports unlimited loggers, so you can write for example to syslog and a local drive at the same time

func (*Waf) NewTransaction

func (w *Waf) NewTransaction() *Transaction

Returns a new initialized transaction for this WAF instance

func (*Waf) SetGeoip

func (w *Waf) SetGeoip(path string) error

Initializes Geoip2 database

func (*Waf) SetPersistenceEngine

func (w *Waf) SetPersistenceEngine(args string) error

Initializes Persistence Engine

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL