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
- func NameToVariable(name string) (byte, error)
- func VariableToName(v byte) string
- type Action
- type BodyBuffer
- type Collection
- func (c *Collection) Add(key string, value string)
- func (c *Collection) AddUnique(key string, value string)
- func (c *Collection) Find(key string, re *regex.Regexp, exceptions []string) []*MatchData
- func (c *Collection) Get(key string) []string
- func (c *Collection) GetData() map[string][]string
- func (c *Collection) GetFirstInt(key string) int
- func (c *Collection) GetFirstInt64(key string) int64
- func (c *Collection) GetFirstString(key string) string
- func (c *Collection) GetName() string
- func (c *Collection) Init(name string)
- func (c *Collection) Remove(key string)
- func (c *Collection) Reset()
- func (c *Collection) Set(key string, value []string)
- func (c *Collection) SetData(data map[string][]string)
- type Interruption
- type KeyValue
- type MatchData
- type MatchedRule
- type Operator
- type Rule
- type RuleGroup
- func (rg *RuleGroup) Add(rule *Rule) error
- func (rg *RuleGroup) Clear()
- func (rg *RuleGroup) Count() int
- func (rg *RuleGroup) DeleteById(id int)
- func (rg *RuleGroup) Evaluate(phase int, tx *Transaction) bool
- func (rg *RuleGroup) FindById(id int) *Rule
- func (rg *RuleGroup) FindByMsg(msg string) []*Rule
- func (rg *RuleGroup) FindByTag(tag string) []*Rule
- func (rg *RuleGroup) GetRules() []*Rule
- type RuleOperator
- type RuleVariable
- type Transaction
- func (tx *Transaction) AddArgument(orig string, key string, value string)
- func (tx *Transaction) AddRequestHeader(key string, value string)
- func (tx *Transaction) AddResponseHeader(key string, value string)
- func (tx *Transaction) AuditLog() *loggers.AuditLog
- func (tx *Transaction) CaptureField(index int, value string)
- func (tx *Transaction) ExtractArguments(orig string, uri string)
- func (tx *Transaction) GetCollection(variable byte) *Collection
- func (tx *Transaction) GetCollections() map[string]*Collection
- func (tx *Transaction) GetField(rv RuleVariable, exceptions []string) []*MatchData
- func (tx *Transaction) GetRemovedTargets(id int) []*KeyValue
- func (tx *Transaction) GetStopWatch() string
- func (tx *Transaction) Interrupted() bool
- func (tx *Transaction) IsProcessableResponseBody() bool
- func (tx *Transaction) MacroExpansion(data string) string
- func (tx *Transaction) MatchRule(rule *Rule, msgs []string, match []*MatchData)
- func (tx *Transaction) MatchVars(match []*MatchData)
- func (tx *Transaction) ParseRequestString(data string) (*Interruption, error)
- func (tx *Transaction) ProcessConnection(client string, cPort int, server string, sPort int)
- func (tx *Transaction) ProcessLogging()
- func (tx *Transaction) ProcessRequest(req *http.Request) (*Interruption, error)
- func (tx *Transaction) ProcessRequestBody() (*Interruption, error)
- func (tx *Transaction) ProcessRequestHeaders() *Interruption
- func (tx *Transaction) ProcessResponseBody() (*Interruption, error)
- func (tx *Transaction) ProcessResponseHeaders(code int, proto string) *Interruption
- func (tx *Transaction) ProcessUri(uri string, method string, httpVersion string)
- func (tx *Transaction) RemoveRuleTargetById(id int, col byte, key string)
- func (tx *Transaction) ResetCapture()
- func (tx *Transaction) SetFullRequest()
- func (tx *Transaction) ToAuditJson() []byte
- type Waf
Constants ¶
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 )
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 )
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 )
const VARIABLES_COUNT = 88
Variables ¶
This section is empty.
Functions ¶
func NameToVariable ¶
func VariableToName ¶
Types ¶
type BodyBuffer ¶
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
type Collection ¶
type Collection struct {
// contains filtered or unexported fields
}
func (*Collection) Add ¶
func (c *Collection) Add(key string, value string)
func (*Collection) AddUnique ¶
func (c *Collection) AddUnique(key string, value string)
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 MatchedRule ¶
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 (*Rule) AddNegateVariable ¶
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 ¶
Adds a rule to the collection Will return an error if the ID is already used
func (*RuleGroup) DeleteById ¶
type RuleOperator ¶
type RuleVariable ¶
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 (*Waf) AddLogger ¶
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 ¶
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) SetPersistenceEngine ¶
Initializes Persistence Engine