Skip to content

Commit

Permalink
Fix test case hashing (#229)
Browse files Browse the repository at this point in the history
* Fix test case hashing

* Update README.md

* Fix report preview
  • Loading branch information
svkirillov authored Feb 9, 2024
1 parent 267c987 commit 45f26cd
Show file tree
Hide file tree
Showing 22 changed files with 194 additions and 126 deletions.
128 changes: 64 additions & 64 deletions README.md

Large diffs are not rendered by default.

Binary file modified docs/report_preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 9 additions & 15 deletions internal/db/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,9 @@ package db
import (
"bytes"
"crypto/sha256"
"encoding/gob"
"encoding/hex"
"sort"
"sync"

"github.com/pkg/errors"

"github.com/wallarm/gotestwaf/internal/payload/placeholder"
)

type DB struct {
Expand All @@ -36,10 +32,7 @@ func NewDB(tests []*Case) (*DB, error) {
tests: tests,
}

var encodedCase bytes.Buffer

enc := gob.NewEncoder(&encodedCase)
gob.Register(placeholder.RawRequestConfig{})
var hashSums [][]byte
sha256hash := sha256.New()

for _, test := range tests {
Expand All @@ -52,13 +45,14 @@ func NewDB(tests []*Case) (*DB, error) {

db.NumberOfTests += uint(len(test.Payloads) * len(test.Encoders) * len(test.Placeholders))

err := enc.Encode(*test)
if err != nil {
return nil, errors.Wrap(err, "couldn't encode test case")
}
hashSums = append(hashSums, test.Hash())
}

sort.Slice(hashSums, func(i, j int) bool { return bytes.Compare(hashSums[i], hashSums[j]) < 0 })

sha256hash.Write(encodedCase.Bytes())
encodedCase.Reset()
sha256hash.Reset()
for i := range hashSums {
sha256hash.Write(hashSums[i])
}

db.Hash = hex.EncodeToString(sha256hash.Sum(nil)[:16])
Expand Down
52 changes: 51 additions & 1 deletion internal/db/models.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package db

import (
"crypto/sha256"

"github.com/wallarm/gotestwaf/internal/helpers"
"github.com/wallarm/gotestwaf/internal/payload/placeholder"
)

type Info struct {
Payload string
Encoder string
Expand Down Expand Up @@ -29,7 +36,50 @@ type Case struct {
IsTruePositive bool
}

var _ helpers.Hash = (*Case)(nil)

func (p *Case) Hash() []byte {
sha256sum := sha256.New()

for i := range p.Payloads {
sha256sum.Write([]byte(p.Payloads[i]))
}

for i := range p.Encoders {
sha256sum.Write([]byte(p.Encoders[i]))
}

for i := range p.Placeholders {
if p.Placeholders[i] != nil {
sha256sum.Write(p.Placeholders[i].Hash())
}
}

sha256sum.Write([]byte(p.Type))
sha256sum.Write([]byte(p.Set))
sha256sum.Write([]byte(p.Name))

if p.IsTruePositive {
sha256sum.Write([]byte{0x01})
} else {
sha256sum.Write([]byte{0x00})
}

return sha256sum.Sum(nil)
}

type Placeholder struct {
Name string
Config any
Config placeholder.PlaceholderConfig
}

var _ helpers.Hash = (*Placeholder)(nil)

func (p *Placeholder) Hash() []byte {
sha256sum := sha256.New()
sha256sum.Write([]byte(p.Name))
if p.Config != nil {
sha256sum.Write(p.Config.Hash())
}
return sha256sum.Sum(nil)
}
5 changes: 5 additions & 0 deletions internal/helpers/hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package helpers

type Hash interface {
Hash() []byte
}
4 changes: 2 additions & 2 deletions internal/payload/placeholder/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ var DefaultGRPC = GRPC{name: "gRPC"}

var _ Placeholder = (*GRPC)(nil)

func (enc GRPC) newConfig(_ map[any]any) (any, error) {
func (enc GRPC) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (enc GRPC) GetName() string {
return enc.name
}

func (enc GRPC) CreateRequest(string, string, any) (*http.Request, error) {
func (enc GRPC) CreateRequest(string, string, PlaceholderConfig) (*http.Request, error) {
return nil, nil
}
4 changes: 2 additions & 2 deletions internal/payload/placeholder/header.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ var DefaultHeader = Header{name: "Header"}

var _ Placeholder = (*Header)(nil)

func (p Header) newConfig(_ map[any]any) (any, error) {
func (p Header) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p Header) GetName() string {
return p.name
}

func (p Header) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p Header) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions internal/payload/placeholder/htmlform.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ var DefaultHTMLForm = HTMLForm{name: "HTMLForm"}

var _ Placeholder = (*HTMLForm)(nil)

func (p HTMLForm) newConfig(_ map[any]any) (any, error) {
func (p HTMLForm) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p HTMLForm) GetName() string {
return p.name
}

func (p HTMLForm) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p HTMLForm) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions internal/payload/placeholder/htmlmultpartform.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ var DefaultHTMLMultipartForm = HTMLMultipartForm{name: "HTMLMultipartForm"}

var _ Placeholder = (*HTMLMultipartForm)(nil)

func (p HTMLMultipartForm) newConfig(_ map[any]any) (any, error) {
func (p HTMLMultipartForm) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p HTMLMultipartForm) GetName() string {
return p.name
}

func (p HTMLMultipartForm) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p HTMLMultipartForm) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions internal/payload/placeholder/jsonbody.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ var DefaultJSONBody = JSONBody{name: "JSONBody"}

var _ Placeholder = (*JSONBody)(nil)

func (p JSONBody) newConfig(_ map[any]any) (any, error) {
func (p JSONBody) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p JSONBody) GetName() string {
return p.name
}

func (p JSONBody) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p JSONBody) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand Down
4 changes: 2 additions & 2 deletions internal/payload/placeholder/jsonrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ var DefaultJSONRequest = JSONRequest{name: "JSONRequest"}

var _ Placeholder = (*JSONRequest)(nil)

func (p JSONRequest) newConfig(_ map[any]any) (any, error) {
func (p JSONRequest) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p JSONRequest) GetName() string {
return p.name
}

func (p JSONRequest) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p JSONRequest) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand Down
16 changes: 8 additions & 8 deletions internal/payload/placeholder/noncrud.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,15 @@ var _ Placeholder = (*NonCrudUrlParam)(nil)
var _ Placeholder = (*NonCRUDHeader)(nil)
var _ Placeholder = (*NonCRUDRequestBody)(nil)

func (p NonCrudUrlPath) newConfig(_ map[any]any) (any, error) {
func (p NonCrudUrlPath) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p NonCrudUrlPath) GetName() string {
return p.name
}

func (p NonCrudUrlPath) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p NonCrudUrlPath) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand All @@ -65,15 +65,15 @@ func (p NonCrudUrlPath) CreateRequest(requestURL, payload string, _ any) (*http.
return req, nil
}

func (p NonCrudUrlParam) newConfig(_ map[any]any) (any, error) {
func (p NonCrudUrlParam) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p NonCrudUrlParam) GetName() string {
return p.name
}

func (p NonCrudUrlParam) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p NonCrudUrlParam) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
param, err := RandomHex(Seed)
if err != nil {
return nil, err
Expand Down Expand Up @@ -109,15 +109,15 @@ func (p NonCrudUrlParam) CreateRequest(requestURL, payload string, _ any) (*http
return req, err
}

func (p NonCRUDHeader) newConfig(_ map[any]any) (any, error) {
func (p NonCRUDHeader) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p NonCRUDHeader) GetName() string {
return p.name
}

func (p NonCRUDHeader) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p NonCRUDHeader) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand All @@ -137,15 +137,15 @@ func (p NonCRUDHeader) CreateRequest(requestURL, payload string, _ any) (*http.R
return req, nil
}

func (p NonCRUDRequestBody) newConfig(_ map[any]any) (any, error) {
func (p NonCRUDRequestBody) newConfig(map[any]any) (PlaceholderConfig, error) {
return nil, nil
}

func (p NonCRUDRequestBody) GetName() string {
return p.name
}

func (p NonCRUDRequestBody) CreateRequest(requestURL, payload string, _ any) (*http.Request, error) {
func (p NonCRUDRequestBody) CreateRequest(requestURL, payload string, _ PlaceholderConfig) (*http.Request, error) {
reqURL, err := url.Parse(requestURL)
if err != nil {
return nil, err
Expand Down
14 changes: 10 additions & 4 deletions internal/payload/placeholder/placeholder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package placeholder
import (
"net/http"

"github.com/wallarm/gotestwaf/internal/helpers"

"github.com/pkg/errors"
)

Expand All @@ -13,10 +15,14 @@ const (
)

type Placeholder interface {
newConfig(conf map[any]any) (any, error)
newConfig(conf map[any]any) (PlaceholderConfig, error)

GetName() string
CreateRequest(url, data string, config any) (*http.Request, error)
CreateRequest(url, data string, config PlaceholderConfig) (*http.Request, error)
}

type PlaceholderConfig interface {
helpers.Hash
}

var Placeholders map[string]Placeholder
Expand All @@ -42,7 +48,7 @@ func init() {
Placeholders[DefaultRawRequest.GetName()] = DefaultRawRequest
}

func GetPlaceholderConfig(name string, conf any) (any, error) {
func GetPlaceholderConfig(name string, conf any) (PlaceholderConfig, error) {
ph, ok := Placeholders[name]
if !ok {
return nil, &UnknownPlaceholderError{name: name}
Expand All @@ -67,7 +73,7 @@ func GetPlaceholderConfig(name string, conf any) (any, error) {
return phConf, err
}

func Apply(url, data, placeholder string, config any) (*http.Request, error) {
func Apply(url, data, placeholder string, config PlaceholderConfig) (*http.Request, error) {
ph, ok := Placeholders[placeholder]
if !ok {
return nil, &UnknownPlaceholderError{name: placeholder}
Expand Down
22 changes: 20 additions & 2 deletions internal/payload/placeholder/rawrequest.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package placeholder

import (
"crypto/sha256"
"io"
"net/http"
"strings"
Expand All @@ -22,8 +23,9 @@ type RawRequestConfig struct {
var DefaultRawRequest = RawRequest{name: "RawRequest"}

var _ Placeholder = (*RawRequest)(nil)
var _ PlaceholderConfig = (*RawRequestConfig)(nil)

func (p RawRequest) newConfig(conf map[any]any) (any, error) {
func (p RawRequest) newConfig(conf map[any]any) (PlaceholderConfig, error) {
result := &RawRequestConfig{}

method, ok := conf["method"]
Expand Down Expand Up @@ -104,7 +106,7 @@ func (p RawRequest) GetName() string {

// CreateRequest creates a new request from config.
// config must be a RawRequestConfig struct.
func (p RawRequest) CreateRequest(requestURL, payload string, config any) (*http.Request, error) {
func (p RawRequest) CreateRequest(requestURL, payload string, config PlaceholderConfig) (*http.Request, error) {
conf, ok := config.(*RawRequestConfig)
if !ok {
return nil, &BadPlaceholderConfigError{
Expand Down Expand Up @@ -141,3 +143,19 @@ func (p RawRequest) CreateRequest(requestURL, payload string, config any) (*http

return req, nil
}

func (r *RawRequestConfig) Hash() []byte {
sha256sum := sha256.New()

sha256sum.Write([]byte(r.Method))
sha256sum.Write([]byte(r.Path))

for header, value := range r.Headers {
sha256sum.Write([]byte(header))
sha256sum.Write([]byte(value))
}

sha256sum.Write([]byte(r.Body))

return sha256sum.Sum(nil)
}
Loading

0 comments on commit 45f26cd

Please sign in to comment.