diff --git a/src/core/metrics/sources/nginx_access_log.go b/src/core/metrics/sources/nginx_access_log.go
index f18dc9fb7..69d0dcf43 100644
--- a/src/core/metrics/sources/nginx_access_log.go
+++ b/src/core/metrics/sources/nginx_access_log.go
@@ -18,6 +18,10 @@ import (
"github.com/nginx/agent/v2/src/core/metrics/sources/tailer"
)
+const (
+ spaceDelim = " "
+)
+
// This metrics source is used to tail the NGINX access logs to retrieve http metrics.
type NginxAccessLog struct {
@@ -207,26 +211,30 @@ func (c *NginxAccessLog) logStats(ctx context.Context, logFile, logFormat string
}
if access.Request != "" {
- splitRequest := strings.Split(access.Request, " ")
- n := fmt.Sprintf("method.%s", strings.ToLower(splitRequest[0]))
+ method, _, protocol := getParsedRequest(access.Request)
+ n := fmt.Sprintf("method.%s", strings.ToLower(method))
if isOtherMethod(n) {
n = "method.others"
}
counters[n] = counters[n] + 1
if access.ServerProtocol == "" {
- httpProtocolVersion := strings.Split(splitRequest[2], "/")[1]
- httpProtocolVersion = strings.ReplaceAll(httpProtocolVersion, ".", "_")
- n = fmt.Sprintf("v%s", httpProtocolVersion)
- counters[n] = counters[n] + 1
+ if strings.Count(protocol, "/") == 1 {
+ httpProtocolVersion := strings.Split(protocol, "/")[1]
+ httpProtocolVersion = strings.ReplaceAll(httpProtocolVersion, ".", "_")
+ n = fmt.Sprintf("v%s", httpProtocolVersion)
+ counters[n] = counters[n] + 1
+ }
}
}
if access.ServerProtocol != "" {
- httpProtocolVersion := strings.Split(access.ServerProtocol, "/")[1]
- httpProtocolVersion = strings.ReplaceAll(httpProtocolVersion, ".", "_")
- n := fmt.Sprintf("v%s", httpProtocolVersion)
- counters[n] = counters[n] + 1
+ if strings.Count(access.ServerProtocol, "/") == 1 {
+ httpProtocolVersion := strings.Split(access.ServerProtocol, "/")[1]
+ httpProtocolVersion = strings.ReplaceAll(httpProtocolVersion, ".", "_")
+ n := fmt.Sprintf("v%s", httpProtocolVersion)
+ counters[n] = counters[n] + 1
+ }
}
// don't need the http status for NGINX Plus
@@ -294,6 +302,35 @@ func (c *NginxAccessLog) logStats(ctx context.Context, logFile, logFormat string
}
}
+func getParsedRequest(request string) (method string, uri string, protocol string) {
+ if len(request) == 0 {
+ return
+ }
+
+ startURIIdx := strings.Index(request, spaceDelim)
+ if startURIIdx == -1 {
+ return
+ }
+
+ endURIIdx := strings.LastIndex(request, spaceDelim)
+ // Ideally, endURIIdx should never be -1 here, as startURIIdx should have handled it already
+ if endURIIdx == -1 {
+ return
+ }
+
+ // For Example: GET /user/register?ahrefp' or ' HTTP/1.1
+
+ // method -> GET
+ method = request[:startURIIdx]
+
+ // uri -> /user/register?ahrefp' or '
+ uri = request[startURIIdx+1 : endURIIdx]
+
+ // protocol -> HTTP/1.1
+ protocol = request[endURIIdx+1:]
+ return
+}
+
func getRequestLengthMetricValue(requestLengths []float64) float64 {
value := 0.0
diff --git a/src/core/metrics/sources/nginx_access_log_test.go b/src/core/metrics/sources/nginx_access_log_test.go
index 5f650a500..0b46f7e8e 100644
--- a/src/core/metrics/sources/nginx_access_log_test.go
+++ b/src/core/metrics/sources/nginx_access_log_test.go
@@ -74,7 +74,7 @@ func TestAccessLogStats(t *testing.T) {
`$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"`,
[]string{
"127.0.0.1 - - [19/May/2022:09:30:39 +0000] \"GET /nginx_status HTTP/1.1\" 200 98 \"-\" \"Go-http-client/1.1\" \"-\"\n",
- "127.0.0.1 - - [19/May/2022:09:30:39 +0000] \"GET /nginx_status HTTP/1.1\" 200 98 \"-\" \"Go-http-client/1.1\" \"-\"\n",
+ `127.0.0.1 - - [19/May/2022:09:30:39 +0000] "GET /user/register?ahref HTTP/1.1" 200 98 "-" "-" "-"`,
},
make(chan *proto.StatsEntity, 1),
&proto.StatsEntity{
diff --git a/src/extensions/nginx-app-protect/monitoring/processor/nap.go b/src/extensions/nginx-app-protect/monitoring/processor/nap.go
index ea34ce712..4ee606406 100644
--- a/src/extensions/nginx-app-protect/monitoring/processor/nap.go
+++ b/src/extensions/nginx-app-protect/monitoring/processor/nap.go
@@ -81,7 +81,6 @@ var (
subViolations,
supportID,
threatCampaignNames,
- httpURI,
violationRating,
httpHostname,
xForwardedForHeaderVal,
@@ -97,6 +96,7 @@ var (
clientApplication,
clientApplicationVersion,
transportProtocol,
+ httpURI,
}
)
diff --git a/src/extensions/nginx-app-protect/monitoring/processor/testdata/expanded_nap_waf.log.txt b/src/extensions/nginx-app-protect/monitoring/processor/testdata/expanded_nap_waf.log.txt
index d2d9b3a78..3580c2d44 100644
--- a/src/extensions/nginx-app-protect/monitoring/processor/testdata/expanded_nap_waf.log.txt
+++ b/src/extensions/nginx-app-protect/monitoring/processor/testdata/expanded_nap_waf.log.txt
@@ -1 +1 @@
-N/A,80,127.0.0.1,,GET,app_protect_default_policy,HTTP,blocked,0,Critical,::,{Cross Site Scripting Signatures;High Accuracy Signatures}::{Cross Site Scripting Signatures;High Accuracy Signatures},61478,HTTP protocol compliance failed:Host header contains IP address,4355056874564592513,N/A,/,5,1-localhost:1-/,N/A,REJECTED,SECURITY_WAF_VIOLATION,HTTP protocol compliance failed::Illegal meta character in value::Attack signature detected::Violation Rating Threat detected::Bot Client Detected,410000000200c00-3a03030c30000072-8000000000000000-0477f0ffcbbd0fea-befbf35cb000007e-8000000000000000-00-20-0-00-0-0-042VIOL_ATTACK_SIGNATUREparameterglobalYQ==alpha-numericPHNjcmlwdD4=query*002000014753YT08c2NyaXB0Pg==372000000983YT08c2NyaXB0Pg==2714VIOL_HTTP_PROTOCOL20482048SG9zdCBoZWFkZXIgd2l0aCBJUCB2YWx1ZTogMTAuMTQ2LjE3OS4xMTk=24VIOL_PARAMETER_VALUE_METACHARglobalYQ==alpha-numericPHNjcmlwdD4=query*046062,curl,HTTP Library,N/A,N/A,Untrusted Bot,N/A,N/A,GET /?a=