8000 chore: implements remaining overrides by M4tteoP · Pull Request #148 · coreruleset/go-ftw · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

chore: implements remaining overrides #148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
< 8000 tr data-hunk="f6147c11d270ff6bd8b91ce10a862072cd0917eb1dbe2ea24b2b709bd8165c0a" class="show-top-border">
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ With the configuration, you can set paths for your environment, enable and disab
The config file has six basic settings:

* `logfile` : path to WAF log with alert messages, relative or absolute
* `testoverride` : a list of things to override (see "Overriding tests" below)>
* `testoverride` : a list of things to override (see [Overriding tests](https://github.com/coreruleset/go-ftw#overriding-tests) below)
* `mode` : "default" or "cloud" (only change it if you need "cloud")
* `logmarkerheadername` : name of a HTTP header used for marking log messages, usually `X-CRS-TEST` (see [How log parsing works](https://github.com/coreruleset/go-ftw#how-log-parsing-works) below)
* `maxmarkerretries` : the maximum number of times the search for log markers will be repeated; each time an additional request is sent to the web server, eventually forcing the log to be flushed
Expand Down Expand Up @@ -356,6 +356,7 @@ Or you can just run: `./ftw run --cloud`
## How log parsing works

The WAF's log file with the alert messages is parsed and compared to the expected output defined in the unit test under `log_contains` or `no_log_contains`.
Note that the expected output may contain multiple checks (E.g. `log_contains` and `status`). If any of the checks fail, the test will fail.

The problem with log files is that `go-ftw` is very, very fast and the log files are not updated in real time. Frequently, the
web server / WAF is not syncing the file fast enough. That results in a situation where `go-ftw` won't find the log messages it has triggered.
Expand Down
50 changes: 40 additions & 10 deletions runner/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,33 @@ func getRequestFromTest(testRequest test.Input) *ftwhttp.Request {
// applyInputOverride will check if config had global overrides and write that into the test.
func applyInputOverride(o config.FTWTestOverride, testRequest *test.Input) error {
overrides := o.Overrides

if overrides.DestAddr != nil {
testRequest.DestAddr = overrides.DestAddr
if testRequest.Headers == nil {
testRequest.Headers = ftwhttp.Header{}
}
if overrides.OverrideEmptyHostHeader && testRequest.Headers.Get("Host") == "" {
testRequest.Headers.Set("Host", *overrides.DestAddr)
}
}

if overrides.Port != nil {
testRequest.Port = overrides.Port
}

if overrides.Protocol != nil {
testRequest.Protocol = overrides.Protocol
}

if overrides.URI != nil {
testRequest.URI = overrides.URI
}

if overrides.Version != nil {
testRequest.Version = overrides.Version
}

if overrides.Headers != nil {
if testRequest.Headers == nil {
testRequest.Headers = ftwhttp.Header{}
Expand All @@ -393,17 +416,24 @@ func applyInputOverride(o config.FTWTestOverride, testRequest *test.Input) error
}
}

if overrides.DestAddr != nil {
testRequest.DestAddr = overrides.DestAddr
if testRequest.Headers == nil {
testRequest.Headers = ftwhttp.Header{}
}
if overrides.OverrideEmptyHostHeader && testRequest.Headers.Get("Host") == "" {
testRequest.Headers.Set("Host", *overrides.DestAddr)
}
if overrides.Method != nil {
testRequest.Method = overrides.Method
}
if overrides.Protocol != nil {
testRequest.Protocol = overrides.Protocol

if overrides.Data != nil {
testRequest.Data = overrides.Data
}

if overrides.StopMagic != nil {
testRequest.StopMagic = *overrides.StopMagic
}

if overrides.EncodedRequest != nil {
testRequest.EncodedRequest = *overrides.EncodedRequest
}

if overrides.RAWRequest != nil {
testRequest.RAWRequest = *overrides.RAWRequest
}

return nil
Expand Down
140 changes: 140 additions & 0 deletions runner/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,55 @@ testoverride:
unique_id: %s
`

var yamlConfigURIOverride = `
---
testoverride:
input:
uri: %s
`

var yamlConfigVersionOverride = `
---
testoverride:
input:
version: %s
`

var yamlConfigMethodOverride = `
---
testoverride:
input:
method: %s
`

var yamlConfigDataOverride = `
---
testoverride:
input:
data: %s
`

var yamlConfigStopMagicOverride = `
---
testoverride:
input:
stop_magic: %t
`

var yamlConfigEncodedRequestOverride = `
---
testoverride:
input:
encoded_request: %s
`

var yamlConfigRAWRequestOverride = `
---
testoverride:
input:
raw_request: %s
`

var yamlConfigOverride = `
---
testoverride:
Expand Down Expand Up @@ -865,6 +914,97 @@ func TestApplyInputOverrides(t *testing.T) {
assert.Equal(t, overrideHeaderValue, overriddenHeader, "Host header must be identical to overridden `Host` header.")
}

func TestApplyInputOverrideURI(t *testing.T) {
originalURI := "original.com"
overrideURI := "override.com"
testInput := test.Input{
URI: &originalURI,
}

cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigURIOverride, overrideURI))
assert.NoError(t, err1)
err := applyInputOverride(cfg.TestOverride, &testInput)
assert.NoError(t, err, "Failed to apply input overrides")
assert.Equal(t, overrideURI, *testInput.URI, "`URI` should have been overridden")
}

func TestApplyInputOverrideVersion(t *testing.T) {
originalVersion := "HTTP/0.9"
overrideVersion := "HTTP/1.1"
testInput := test.Input{
Version: &originalVersion,
}
cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigVersionOverride, overrideVersion))
assert 8000 .NoError(t, err1)
err := applyInputOverride(cfg.TestOverride, &testInput)
assert.NoError(t, err, "Failed to apply input overrides")
assert.Equal(t, overrideVersion, *testInput.Version, "`Version` should have been overridden")
}

func TestApplyInputOverrideMethod(t *testing.T) {
originalMethod := "original.com"
overrideMethod := "override.com"
testInput := test.Input{
Method: &originalMethod,
}
cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigMethodOverride, overrideMethod))
assert.NoError(t, err1)
err := applyInputOverride(cfg.TestOverride, &testInput)
assert.NoError(t, err, "Failed to apply input overrides")
assert.Equal(t, overrideMethod, *testInput.Method, "`Method` should have been overridden")
}

func TestApplyInputOverrideData(t *testing.T) {
originalData := "data"
overrideData := "new data"
testInput := test.Input{
Data: &originalData,
}
cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigDataOverride, overrideData))
assert.NoError(t, err1)
err := applyInputOverride(cfg.TestOverride, &testInput)
assert.NoError(t, err, "Failed to apply input overrides")
assert.Equal(t, overrideData, *testInput.Data, "`Data` should have been overridden")
}

func TestApplyInputOverrideStopMagic(t *testing.T) {
overrideStopMagic := true
testInput := test.Input{
StopMagic: false,
}
cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigStopMagicOverride, overrideStopMagic))
assert.NoError(t, err1)
err := applyInputOverride(cfg.TestOverride, &testInput)
assert.NoError(t, err, "Failed to apply input overrides")
assert.Equal(t, overrideStopMagic, testInput.StopMagic, "`StopMagic` should have been overridden")
}

func TestApplyInputOverrideEncodedRequest(t *testing.T) {
originalEncodedRequest := "originalbase64"
overrideEncodedRequest := "modifiedbase64"
testInput := test.Input{
EncodedRequest: originalEncodedRequest,
}
cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigEncodedRequestOverride, overrideEncodedRequest))
assert.NoError(t, err1)
err := applyInputOverride(cfg.TestOverride, &testInput)
assert.NoError(t, err, "Failed to apply input overrides")
assert.Equal(t, overrideEncodedRequest, testInput.EncodedRequest, "`EncodedRequest` should have been overridden")
}

func TestApplyInputOverrideRAWRequest(t *testing.T) {
originalRAWR 6D40 equest := "original"
overrideRAWRequest := "override"
testInput := test.Input{
RAWRequest: originalRAWRequest,
}
cfg, err1 := config.NewConfigFromString(fmt.Sprintf(yamlConfigRAWRequestOverride, overrideRAWRequest))
assert.NoError(t, err1)
err := applyInputOverride(cfg.TestOverride, &testInput)
assert.NoError(t, err, "Failed to apply input overrides")
assert.Equal(t, overrideRAWRequest, testInput.RAWRequest, "`RAWRequest` should have been overridden")
}

func TestIgnoredTestsRun(t *testing.T) {
cfg, err := config.NewConfigFromString(yamlConfigIgnoreTests)
dest, logFilePath := newTestServer(t, cfg, logText)
Expand Down
2 changes: 1 addition & 1 deletion test/defaults_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Host: localhost
Keep-Alive: 300
Proxy-Connection: keep-alive
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)
`,
`,
SaveCookie: false,
StopMagic: true,
}
Expand Down
26 changes: 13 additions & 13 deletions test/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ type Input struct {

// Overrides represents the overridden inputs that have to be applied to tests
type Overrides struct {
DestAddr *string `yaml:"dest_addr,omitempty" koanf:"dest_addr,omitempty"`
Port *int `yaml:"port,omitempty" koanf:"port,omitempty"`
Protocol *string `yaml:"protocol,omitempty" koanf:"protocol,omitempty"`
// URI *string `yaml:"uri,omitempty" koanf:"uri,omitempty"`
// Version *string `yaml:"version,omitempty" koanf:"version,omitempty"`
Headers ftwhttp.Header `yaml:"headers,omitempty" koanf:"headers,omitempty"`
// Method *string `yaml:"method,omitempty" koanf:"method,omitempty"`
// Data *string `yaml:"data,omitempty" koanf:"data,omitempty"`
// SaveCookie bool `yaml:"save_cookie,omitempty" koanf:"save_cookie,omitempty"`
// StopMagic bool `yaml:"stop_magic" koanf:"stop_magic,omitempty"`
// EncodedRequest string `yaml:"encoded_request,omitempty" koanf:"encoded_request,omitempty"`
// RAWRequest string `yaml:"raw_request,omitempty" koanf:"raw_request,omitempty"`
OverrideEmptyHostHeader bool `yaml:"override_empty_host_header,omitempty" koanf:"override_empty_host_header,omitempty"`
DestAddr *string `yaml:"dest_addr,omitempty" koanf:"dest_addr,omitempty"`
Port *int `yaml:"port,omitempty" koanf:"port,omitempty"`
Protocol *string `yaml:"protocol,omitempty" koanf:"protocol,omitempty"`
URI *string `yaml:"uri,omitempty" koanf:"uri,omitempty"`
Version *string `yaml:"version,omitempty" koanf:"version,omitempty"`
Headers ftwhttp.Header `yaml:"headers,omitempty" koanf:"headers,omitempty"`
Method *string `yaml:"method,omitempty" koanf:"method,omitempty"`
Data *string `yaml:"data,omitempty" koanf:"data,omitempty"`
//SaveCookie bool `yaml:"save_cookie,omitempty" koanf:"save_cookie,omitempty"`
StopMagic *bool `yaml:"stop_magic" koanf:"stop_magic,omitempty"`
EncodedRequest *string `yaml:"encoded_request,omitempty" koanf:"encoded_request,omitempty"`
RAWRequest *string `yaml:"raw_request,omitempty" koanf:"raw_request,omitempty"`
OverrideEmptyHostHeader bool `yaml:"override_empty_host_header,omitempty" koanf:"override_empty_host_header,omitempty"`
}

// Output is the response expected from the test
Expand Down
0