Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/fuzz/stats/simple.go
2070 views
1
package stats
2
3
import (
4
"fmt"
5
"net/http"
6
"net/url"
7
"strings"
8
"sync"
9
"sync/atomic"
10
)
11
12
type simpleStats struct {
13
totalComponentsTested atomic.Int64
14
totalEndpointsTested atomic.Int64
15
totalFuzzedRequests atomic.Int64
16
totalMatchedResults atomic.Int64
17
totalTemplatesTested atomic.Int64
18
totalErroredRequests atomic.Int64
19
20
statusCodes sync.Map
21
severityCounts sync.Map
22
23
componentsUniqueMap sync.Map
24
endpointsUniqueMap sync.Map
25
templatesUniqueMap sync.Map
26
errorGroupedStats sync.Map
27
}
28
29
func NewSimpleStats() (*simpleStats, error) {
30
return &simpleStats{
31
totalComponentsTested: atomic.Int64{},
32
totalEndpointsTested: atomic.Int64{},
33
totalMatchedResults: atomic.Int64{},
34
totalFuzzedRequests: atomic.Int64{},
35
totalTemplatesTested: atomic.Int64{},
36
totalErroredRequests: atomic.Int64{},
37
statusCodes: sync.Map{},
38
severityCounts: sync.Map{},
39
componentsUniqueMap: sync.Map{},
40
endpointsUniqueMap: sync.Map{},
41
templatesUniqueMap: sync.Map{},
42
errorGroupedStats: sync.Map{},
43
}, nil
44
}
45
46
func (s *simpleStats) Close() {}
47
48
func (s *simpleStats) InsertComponent(event ComponentEvent) error {
49
componentKey := fmt.Sprintf("%s_%s", event.ComponentName, event.ComponentType)
50
if _, ok := s.componentsUniqueMap.Load(componentKey); !ok {
51
s.componentsUniqueMap.Store(componentKey, true)
52
s.totalComponentsTested.Add(1)
53
}
54
55
parsedURL, err := url.Parse(event.URL)
56
if err != nil {
57
return err
58
}
59
60
endpointsKey := fmt.Sprintf("%s_%s", event.siteName, parsedURL.Path)
61
if _, ok := s.endpointsUniqueMap.Load(endpointsKey); !ok {
62
s.endpointsUniqueMap.Store(endpointsKey, true)
63
s.totalEndpointsTested.Add(1)
64
}
65
66
return nil
67
}
68
69
func (s *simpleStats) InsertMatchedRecord(event FuzzingEvent) error {
70
s.totalFuzzedRequests.Add(1)
71
72
s.incrementStatusCode(event.StatusCode)
73
if event.Matched {
74
s.totalMatchedResults.Add(1)
75
76
s.incrementSeverityCount(event.Severity)
77
}
78
79
if _, ok := s.templatesUniqueMap.Load(event.TemplateID); !ok {
80
s.templatesUniqueMap.Store(event.TemplateID, true)
81
s.totalTemplatesTested.Add(1)
82
}
83
return nil
84
}
85
86
func (s *simpleStats) InsertError(event ErrorEvent) error {
87
s.totalErroredRequests.Add(1)
88
89
value, _ := s.errorGroupedStats.LoadOrStore(event.Error, &atomic.Int64{})
90
if counter, ok := value.(*atomic.Int64); ok {
91
counter.Add(1)
92
}
93
return nil
94
}
95
96
type SimpleStatsResponse struct {
97
TotalMatchedResults int64
98
TotalComponentsTested int64
99
TotalEndpointsTested int64
100
TotalFuzzedRequests int64
101
TotalTemplatesTested int64
102
TotalErroredRequests int64
103
StatusCodes map[string]int64
104
SeverityCounts map[string]int64
105
ErrorGroupedStats map[string]int64
106
}
107
108
func (s *simpleStats) GetStatistics() SimpleStatsResponse {
109
statusStats := make(map[string]int64)
110
s.statusCodes.Range(func(key, value interface{}) bool {
111
if count, ok := value.(*atomic.Int64); ok {
112
statusStats[formatStatusCode(key.(int))] = count.Load()
113
}
114
return true
115
})
116
117
severityStats := make(map[string]int64)
118
s.severityCounts.Range(func(key, value interface{}) bool {
119
if count, ok := value.(*atomic.Int64); ok {
120
severityStats[key.(string)] = count.Load()
121
}
122
return true
123
})
124
125
errorStats := make(map[string]int64)
126
s.errorGroupedStats.Range(func(key, value interface{}) bool {
127
if count, ok := value.(*atomic.Int64); ok {
128
errorStats[key.(string)] = count.Load()
129
}
130
return true
131
})
132
133
return SimpleStatsResponse{
134
TotalMatchedResults: s.totalMatchedResults.Load(),
135
StatusCodes: statusStats,
136
SeverityCounts: severityStats,
137
TotalComponentsTested: s.totalComponentsTested.Load(),
138
TotalEndpointsTested: s.totalEndpointsTested.Load(),
139
TotalFuzzedRequests: s.totalFuzzedRequests.Load(),
140
TotalTemplatesTested: s.totalTemplatesTested.Load(),
141
TotalErroredRequests: s.totalErroredRequests.Load(),
142
ErrorGroupedStats: errorStats,
143
}
144
}
145
146
func (s *simpleStats) incrementStatusCode(statusCode int) {
147
value, _ := s.statusCodes.LoadOrStore(statusCode, &atomic.Int64{})
148
if counter, ok := value.(*atomic.Int64); ok {
149
counter.Add(1)
150
}
151
}
152
153
func (s *simpleStats) incrementSeverityCount(severity string) {
154
value, _ := s.severityCounts.LoadOrStore(severity, &atomic.Int64{})
155
if counter, ok := value.(*atomic.Int64); ok {
156
counter.Add(1)
157
}
158
}
159
160
func formatStatusCode(code int) string {
161
escapedText := strings.ToTitle(strings.ReplaceAll(http.StatusText(code), " ", "_"))
162
formatted := fmt.Sprintf("%d_%s", code, escapedText)
163
return formatted
164
}
165
166