Skip to content

Commit

Permalink
Improve report (#226)
Browse files Browse the repository at this point in the history
* Improve report

* Fix true-positive and true-negative

* Fix true-positive and true-negative in console report

* Fix variable naming

* Fix json report

* go mod tidy
  • Loading branch information
svkirillov authored Jan 25, 2024
1 parent 9fe44e8 commit 4cf7f2d
Show file tree
Hide file tree
Showing 10 changed files with 422 additions and 405 deletions.
8 changes: 0 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,6 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down Expand Up @@ -386,14 +384,10 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -402,8 +396,6 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down
168 changes: 84 additions & 84 deletions internal/db/statistics.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type Statistics struct {

TestCasesFingerprint string

NegativeTests struct {
TruePositiveTests struct {
SummaryTable []*SummaryTableRow
Blocked []*TestDetails
Bypasses []*TestDetails
Expand All @@ -31,7 +31,7 @@ type Statistics struct {
FailedRequestsPercentage float64
}

PositiveTests struct {
TrueNegativeTests struct {
SummaryTable []*SummaryTableRow
FalsePositive []*TestDetails
TruePositive []*TestDetails
Expand All @@ -53,14 +53,14 @@ type Statistics struct {

Score struct {
ApiSec struct {
TrueNegative float64
TruePositive float64
TrueNegative float64
Average float64
}

AppSec struct {
TrueNegative float64
TruePositive float64
TrueNegative float64
Average float64
}

Expand Down Expand Up @@ -206,60 +206,60 @@ func (db *DB) GetStatistics(ignoreUnresolved, nonBlockedAsPassed bool) *Statisti
// If positive set - move to another table (remove from general cases)
if isFalsePositive {
// False positive - blocked by the WAF (bad behavior, blockedRequests)
s.PositiveTests.BlockedRequestsNumber += blockedRequests
s.TrueNegativeTests.BlockedRequestsNumber += blockedRequests
// True positive - bypassed (good behavior, passedRequests)
s.PositiveTests.BypassedRequestsNumber += passedRequests
s.PositiveTests.UnresolvedRequestsNumber += unresolvedRequests
s.PositiveTests.FailedRequestsNumber += failedRequests
s.TrueNegativeTests.BypassedRequestsNumber += passedRequests
s.TrueNegativeTests.UnresolvedRequestsNumber += unresolvedRequests
s.TrueNegativeTests.FailedRequestsNumber += failedRequests

passedRequestsPercentage := CalculatePercentage(passedRequests, totalResolvedRequests)
row.Percentage = passedRequestsPercentage

s.PositiveTests.SummaryTable = append(s.PositiveTests.SummaryTable, row)
s.TrueNegativeTests.SummaryTable = append(s.TrueNegativeTests.SummaryTable, row)
} else {
s.NegativeTests.BlockedRequestsNumber += blockedRequests
s.NegativeTests.BypassedRequestsNumber += passedRequests
s.NegativeTests.UnresolvedRequestsNumber += unresolvedRequests
s.NegativeTests.FailedRequestsNumber += failedRequests
s.TruePositiveTests.BlockedRequestsNumber += blockedRequests
s.TruePositiveTests.BypassedRequestsNumber += passedRequests
s.TruePositiveTests.UnresolvedRequestsNumber += unresolvedRequests
s.TruePositiveTests.FailedRequestsNumber += failedRequests

blockedRequestsPercentage := CalculatePercentage(blockedRequests, totalResolvedRequests)
row.Percentage = blockedRequestsPercentage

s.NegativeTests.SummaryTable = append(s.NegativeTests.SummaryTable, row)
s.TruePositiveTests.SummaryTable = append(s.TruePositiveTests.SummaryTable, row)

}
}
}

// Number of all negative requests
s.NegativeTests.AllRequestsNumber = s.NegativeTests.BlockedRequestsNumber +
s.NegativeTests.BypassedRequestsNumber +
s.NegativeTests.UnresolvedRequestsNumber +
s.NegativeTests.FailedRequestsNumber
s.TruePositiveTests.AllRequestsNumber = s.TruePositiveTests.BlockedRequestsNumber +
s.TruePositiveTests.BypassedRequestsNumber +
s.TruePositiveTests.UnresolvedRequestsNumber +
s.TruePositiveTests.FailedRequestsNumber

// Number of negative resolved requests
s.NegativeTests.ResolvedRequestsNumber = s.NegativeTests.BlockedRequestsNumber +
s.NegativeTests.BypassedRequestsNumber
s.TruePositiveTests.ResolvedRequestsNumber = s.TruePositiveTests.BlockedRequestsNumber +
s.TruePositiveTests.BypassedRequestsNumber

// Number of all negative requests
s.PositiveTests.AllRequestsNumber = s.PositiveTests.BlockedRequestsNumber +
s.PositiveTests.BypassedRequestsNumber +
s.PositiveTests.UnresolvedRequestsNumber +
s.PositiveTests.FailedRequestsNumber
s.TrueNegativeTests.AllRequestsNumber = s.TrueNegativeTests.BlockedRequestsNumber +
s.TrueNegativeTests.BypassedRequestsNumber +
s.TrueNegativeTests.UnresolvedRequestsNumber +
s.TrueNegativeTests.FailedRequestsNumber

// Number of positive resolved requests
s.PositiveTests.ResolvedRequestsNumber = s.PositiveTests.BlockedRequestsNumber +
s.PositiveTests.BypassedRequestsNumber
s.TrueNegativeTests.ResolvedRequestsNumber = s.TrueNegativeTests.BlockedRequestsNumber +
s.TrueNegativeTests.BypassedRequestsNumber

s.NegativeTests.UnresolvedRequestsPercentage = CalculatePercentage(s.NegativeTests.UnresolvedRequestsNumber, s.NegativeTests.AllRequestsNumber)
s.NegativeTests.ResolvedBlockedRequestsPercentage = CalculatePercentage(s.NegativeTests.BlockedRequestsNumber, s.NegativeTests.ResolvedRequestsNumber)
s.NegativeTests.ResolvedBypassedRequestsPercentage = CalculatePercentage(s.NegativeTests.BypassedRequestsNumber, s.NegativeTests.ResolvedRequestsNumber)
s.NegativeTests.FailedRequestsPercentage = CalculatePercentage(s.NegativeTests.FailedRequestsNumber, s.NegativeTests.AllRequestsNumber)
s.TruePositiveTests.UnresolvedRequestsPercentage = CalculatePercentage(s.TruePositiveTests.UnresolvedRequestsNumber, s.TruePositiveTests.AllRequestsNumber)
s.TruePositiveTests.ResolvedBlockedRequestsPercentage = CalculatePercentage(s.TruePositiveTests.BlockedRequestsNumber, s.TruePositiveTests.ResolvedRequestsNumber)
s.TruePositiveTests.ResolvedBypassedRequestsPercentage = CalculatePercentage(s.TruePositiveTests.BypassedRequestsNumber, s.TruePositiveTests.ResolvedRequestsNumber)
s.TruePositiveTests.FailedRequestsPercentage = CalculatePercentage(s.TruePositiveTests.FailedRequestsNumber, s.TruePositiveTests.AllRequestsNumber)

s.PositiveTests.UnresolvedRequestsPercentage = CalculatePercentage(s.PositiveTests.UnresolvedRequestsNumber, s.PositiveTests.AllRequestsNumber)
s.PositiveTests.ResolvedFalseRequestsPercentage = CalculatePercentage(s.PositiveTests.BlockedRequestsNumber, s.PositiveTests.ResolvedRequestsNumber)
s.PositiveTests.ResolvedTrueRequestsPercentage = CalculatePercentage(s.PositiveTests.BypassedRequestsNumber, s.PositiveTests.ResolvedRequestsNumber)
s.PositiveTests.FailedRequestsPercentage = CalculatePercentage(s.PositiveTests.FailedRequestsNumber, s.PositiveTests.AllRequestsNumber)
s.TrueNegativeTests.UnresolvedRequestsPercentage = CalculatePercentage(s.TrueNegativeTests.UnresolvedRequestsNumber, s.TrueNegativeTests.AllRequestsNumber)
s.TrueNegativeTests.ResolvedFalseRequestsPercentage = CalculatePercentage(s.TrueNegativeTests.BlockedRequestsNumber, s.TrueNegativeTests.ResolvedRequestsNumber)
s.TrueNegativeTests.ResolvedTrueRequestsPercentage = CalculatePercentage(s.TrueNegativeTests.BypassedRequestsNumber, s.TrueNegativeTests.ResolvedRequestsNumber)
s.TrueNegativeTests.FailedRequestsPercentage = CalculatePercentage(s.TrueNegativeTests.FailedRequestsNumber, s.TrueNegativeTests.AllRequestsNumber)

for _, blockedTest := range db.blockedTests {
sort.Strings(blockedTest.AdditionalInfo)
Expand All @@ -276,9 +276,9 @@ func (db *DB) GetStatistics(ignoreUnresolved, nonBlockedAsPassed bool) *Statisti
}

if isFalsePositiveTest(blockedTest.Set) {
s.PositiveTests.FalsePositive = append(s.PositiveTests.FalsePositive, testDetails)
s.TrueNegativeTests.FalsePositive = append(s.TrueNegativeTests.FalsePositive, testDetails)
} else {
s.NegativeTests.Blocked = append(s.NegativeTests.Blocked, testDetails)
s.TruePositiveTests.Blocked = append(s.TruePositiveTests.Blocked, testDetails)
}
}

Expand All @@ -297,9 +297,9 @@ func (db *DB) GetStatistics(ignoreUnresolved, nonBlockedAsPassed bool) *Statisti
}

if isFalsePositiveTest(passedTest.Set) {
s.PositiveTests.TruePositive = append(s.PositiveTests.TruePositive, testDetails)
s.TrueNegativeTests.TruePositive = append(s.TrueNegativeTests.TruePositive, testDetails)
} else {
s.NegativeTests.Bypasses = append(s.NegativeTests.Bypasses, testDetails)
s.TruePositiveTests.Bypasses = append(s.TruePositiveTests.Bypasses, testDetails)
}
}

Expand All @@ -319,15 +319,15 @@ func (db *DB) GetStatistics(ignoreUnresolved, nonBlockedAsPassed bool) *Statisti

if ignoreUnresolved || nonBlockedAsPassed {
if isFalsePositiveTest(unresolvedTest.Set) {
s.PositiveTests.FalsePositive = append(s.PositiveTests.FalsePositive, testDetails)
s.TrueNegativeTests.FalsePositive = append(s.TrueNegativeTests.FalsePositive, testDetails)
} else {
s.NegativeTests.Bypasses = append(s.NegativeTests.Bypasses, testDetails)
s.TruePositiveTests.Bypasses = append(s.TruePositiveTests.Bypasses, testDetails)
}
} else {
if isFalsePositiveTest(unresolvedTest.Set) {
s.PositiveTests.Unresolved = append(s.PositiveTests.Unresolved, testDetails)
s.TrueNegativeTests.Unresolved = append(s.TrueNegativeTests.Unresolved, testDetails)
} else {
s.NegativeTests.Unresolved = append(s.NegativeTests.Unresolved, testDetails)
s.TruePositiveTests.Unresolved = append(s.TruePositiveTests.Unresolved, testDetails)
}
}
}
Expand All @@ -344,9 +344,9 @@ func (db *DB) GetStatistics(ignoreUnresolved, nonBlockedAsPassed bool) *Statisti
}

if isFalsePositiveTest(failedTest.Set) {
s.PositiveTests.Failed = append(s.PositiveTests.Failed, testDetails)
s.TrueNegativeTests.Failed = append(s.TrueNegativeTests.Failed, testDetails)
} else {
s.NegativeTests.Failed = append(s.NegativeTests.Failed, testDetails)
s.TruePositiveTests.Failed = append(s.TruePositiveTests.Failed, testDetails)
}
}

Expand All @@ -366,68 +366,68 @@ func (db *DB) GetStatistics(ignoreUnresolved, nonBlockedAsPassed bool) *Statisti
s.Paths = paths
}

var apiSecNegBlockedNum int
var apiSecNegNum int
var appSecNegBlockedNum int
var appSecNegNum int
var apiSecTruePosBlockedNum int
var apiSecTruePosNum int
var appSecTruePosBlockedNum int
var appSecTruePosNum int

for _, test := range s.NegativeTests.Blocked {
for _, test := range s.TruePositiveTests.Blocked {
if isApiTest(test.TestSet) {
apiSecNegNum++
apiSecNegBlockedNum++
apiSecTruePosNum++
apiSecTruePosBlockedNum++
} else {
appSecNegNum++
appSecNegBlockedNum++
appSecTruePosNum++
appSecTruePosBlockedNum++
}
}
for _, test := range s.NegativeTests.Bypasses {
for _, test := range s.TruePositiveTests.Bypasses {
if isApiTest(test.TestSet) {
apiSecNegNum++
apiSecTruePosNum++
} else {
appSecNegNum++
appSecTruePosNum++
}
}

var apiSecPosBypassNum int
var apiSecPosNum int
var appSecPosBypassNum int
var appSecPosNum int
var apiSecTrueNegBypassNum int
var apiSecTrueNegNum int
var appSecTrueNegBypassNum int
var appSecTrueNegNum int

for _, test := range s.PositiveTests.TruePositive {
for _, test := range s.TrueNegativeTests.TruePositive {
if isApiTest(test.TestSet) {
apiSecPosNum++
apiSecPosBypassNum++
apiSecTrueNegNum++
apiSecTrueNegBypassNum++
} else {
appSecPosNum++
appSecPosBypassNum++
appSecTrueNegNum++
appSecTrueNegBypassNum++
}
}
for _, test := range s.PositiveTests.FalsePositive {
for _, test := range s.TrueNegativeTests.FalsePositive {
if isApiTest(test.TestSet) {
apiSecPosNum++
apiSecTrueNegNum++
} else {
appSecPosNum++
appSecTrueNegNum++
}
}

var divider int
var sum float64

s.Score.ApiSec.TrueNegative = CalculatePercentage(apiSecNegBlockedNum, apiSecNegNum)
s.Score.ApiSec.TruePositive = CalculatePercentage(apiSecPosBypassNum, apiSecPosNum)
s.Score.ApiSec.TruePositive = CalculatePercentage(apiSecTruePosBlockedNum, apiSecTruePosNum)
s.Score.ApiSec.TrueNegative = CalculatePercentage(apiSecTrueNegBypassNum, apiSecTrueNegNum)

if apiSecNegNum != 0 {
if apiSecTruePosNum != 0 {
divider++
sum += s.Score.ApiSec.TrueNegative
sum += s.Score.ApiSec.TruePositive
} else {
s.Score.ApiSec.TrueNegative = -1.0
s.Score.ApiSec.TruePositive = -1.0
}

if apiSecPosNum != 0 {
if apiSecTrueNegNum != 0 {
divider++
sum += s.Score.ApiSec.TruePositive
sum += s.Score.ApiSec.TrueNegative
} else {
s.Score.ApiSec.TruePositive = -1.0
s.Score.ApiSec.TrueNegative = -1.0
}

if divider != 0 {
Expand All @@ -439,21 +439,21 @@ func (db *DB) GetStatistics(ignoreUnresolved, nonBlockedAsPassed bool) *Statisti
divider = 0
sum = 0.0

s.Score.AppSec.TrueNegative = CalculatePercentage(appSecNegBlockedNum, appSecNegNum)
s.Score.AppSec.TruePositive = CalculatePercentage(appSecPosBypassNum, appSecPosNum)
s.Score.AppSec.TruePositive = CalculatePercentage(appSecTruePosBlockedNum, appSecTruePosNum)
s.Score.AppSec.TrueNegative = CalculatePercentage(appSecTrueNegBypassNum, appSecTrueNegNum)

if appSecNegNum != 0 {
if appSecTruePosNum != 0 {
divider++
sum += s.Score.AppSec.TrueNegative
sum += s.Score.AppSec.TruePositive
} else {
s.Score.AppSec.TrueNegative = -1.0
s.Score.AppSec.TruePositive = -1.0
}

if appSecPosNum != 0 {
if appSecTrueNegNum != 0 {
divider++
sum += s.Score.AppSec.TruePositive
sum += s.Score.AppSec.TrueNegative
} else {
s.Score.AppSec.TruePositive = -1.0
s.Score.AppSec.TrueNegative = -1.0
}

if divider != 0 {
Expand Down
Loading

0 comments on commit 4cf7f2d

Please sign in to comment.