[AUTO-CHERRYPICK] patch CVE-2022-21698 in application-gateway-kubernetes-ingress - branch main (#7548)
This is an auto-generated pull request to cherry-pick commit f0d5827
to main. Original PR: #7542
Co-authored-by: Tobias Brick <39196763+tobiasb-ms@users.noreply.github.com>
This commit is contained in:
parent
46a4d292cd
commit
790ebdc946
|
@ -0,0 +1,364 @@
|
|||
From 253029f7ffbade99588df59a8b89a35d99197fe0 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Brick <tobiasb@microsoft.com>
|
||||
Date: Tue, 18 Jan 2022 10:19:28 +0100
|
||||
Subject: [PATCH] Port upstream patch
|
||||
https://github.com/prometheus/client_golang/commit/9075cdf61646b5adf54d3ba77a0e4f6c65cb4fd7
|
||||
|
||||
Differences:
|
||||
- Removed tests
|
||||
- Removed some comments that don't merge
|
||||
- Line numbers and such
|
||||
|
||||
Based on:
|
||||
|
||||
From 9075cdf61646b5adf54d3ba77a0e4f6c65cb4fd7 Mon Sep 17 00:00:00 2001
|
||||
From: Kemal Akkoyun <kakkoyun@users.noreply.github.com>
|
||||
Date: Tue, 18 Jan 2022 10:19:28 +0100
|
||||
Subject: [PATCH] promhttp: Check validity of method and code label values
|
||||
(#962)
|
||||
|
||||
* Check validity of method and code label values
|
||||
|
||||
Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
|
||||
|
||||
* Use more flexibly functional option pattern for configuration
|
||||
|
||||
Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
|
||||
|
||||
* Update documentation
|
||||
|
||||
Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
|
||||
|
||||
* Simplify
|
||||
|
||||
Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
|
||||
|
||||
* Fix inconsistent method naming
|
||||
|
||||
Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
|
||||
---
|
||||
prometheus/promhttp/instrument_client.go | 28 ++++++--
|
||||
prometheus/promhttp/instrument_server.go | 82 ++++++++++++++++++------
|
||||
prometheus/promhttp/option.go | 31 +++++++++
|
||||
3 files changed, 116 insertions(+), 25 deletions(-)
|
||||
create mode 100644 prometheus/promhttp/option.go
|
||||
|
||||
diff --git a/prometheus/promhttp/instrument_client.go b/prometheus/promhttp/instrument_client.go
|
||||
index 83c49b6..861b4d2 100644
|
||||
--- a/prometheus/promhttp/instrument_client.go
|
||||
+++ b/prometheus/promhttp/instrument_client.go
|
||||
@@ -49,7 +49,10 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
|
||||
// http.RoundTripper to observe the request result with the provided CounterVec.
|
||||
// The CounterVec must have zero, one, or two non-const non-curried labels. For
|
||||
// those, the only allowed label names are "code" and "method". The function
|
||||
-// panics otherwise. Partitioning of the CounterVec happens by HTTP status code
|
||||
+// panics otherwise. For the "method" label a predefined default label value set
|
||||
+// is used to filter given values. Values besides predefined values will count
|
||||
+// as `unknown` method.`WithExtraMethods` can be used to add more
|
||||
+// methods to the set. Partitioning of the CounterVec happens by HTTP status code
|
||||
// and/or HTTP method if the respective instance label names are present in the
|
||||
// CounterVec. For unpartitioned counting, use a CounterVec with zero labels.
|
||||
//
|
||||
@@ -57,13 +60,18 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
|
||||
// is not incremented.
|
||||
//
|
||||
// See the example for ExampleInstrumentRoundTripperDuration for example usage.
|
||||
-func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper) RoundTripperFunc {
|
||||
+func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
|
||||
+ rtOpts := &option{}
|
||||
+ for _, o := range opts {
|
||||
+ o(rtOpts)
|
||||
+ }
|
||||
+
|
||||
code, method := checkLabels(counter)
|
||||
|
||||
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||
resp, err := next.RoundTrip(r)
|
||||
if err == nil {
|
||||
- counter.With(labels(code, method, r.Method, resp.StatusCode)).Inc()
|
||||
+ counter.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Inc()
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
@@ -73,7 +81,10 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou
|
||||
// http.RoundTripper to observe the request duration with the provided
|
||||
// ObserverVec. The ObserverVec must have zero, one, or two non-const
|
||||
// non-curried labels. For those, the only allowed label names are "code" and
|
||||
-// "method". The function panics otherwise. The Observe method of the Observer
|
||||
+// "method". The function panics otherwise. For the "method" label a predefined
|
||||
+// default label value set is used to filter given values. Values besides
|
||||
+// predefined values will count as `unknown` method. `WithExtraMethods`
|
||||
+// can be used to add more methods to the set. The Observe method of the Observer
|
||||
// in the ObserverVec is called with the request duration in
|
||||
// seconds. Partitioning happens by HTTP status code and/or HTTP method if the
|
||||
// respective instance label names are present in the ObserverVec. For
|
||||
@@ -85,14 +96,19 @@ func InstrumentRoundTripperCounter(counter *prometheus.CounterVec, next http.Rou
|
||||
//
|
||||
// Note that this method is only guaranteed to never observe negative durations
|
||||
// if used with Go1.9+.
|
||||
-func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper) RoundTripperFunc {
|
||||
+func InstrumentRoundTripperDuration(obs prometheus.ObserverVec, next http.RoundTripper, opts ...Option) RoundTripperFunc {
|
||||
+ rtOpts := &option{}
|
||||
+ for _, o := range opts {
|
||||
+ o(rtOpts)
|
||||
+ }
|
||||
+
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
return RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
|
||||
start := time.Now()
|
||||
resp, err := next.RoundTrip(r)
|
||||
if err == nil {
|
||||
- obs.With(labels(code, method, r.Method, resp.StatusCode)).Observe(time.Since(start).Seconds())
|
||||
+ obs.With(labels(code, method, r.Method, resp.StatusCode, rtOpts.extraMethods...)).Observe(time.Since(start).Seconds())
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
diff --git a/prometheus/promhttp/instrument_server.go b/prometheus/promhttp/instrument_server.go
|
||||
index 9db2438..91802f8 100644
|
||||
--- a/prometheus/promhttp/instrument_server.go
|
||||
+++ b/prometheus/promhttp/instrument_server.go
|
||||
@@ -58,7 +58,12 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
|
||||
//
|
||||
// Note that this method is only guaranteed to never observe negative durations
|
||||
// if used with Go1.9+.
|
||||
-func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
|
||||
+func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
+ mwOpts := &option{}
|
||||
+ for _, o := range opts {
|
||||
+ o(mwOpts)
|
||||
+ }
|
||||
+
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
if code {
|
||||
@@ -67,14 +72,14 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
|
||||
- obs.With(labels(code, method, r.Method, d.Status())).Observe(time.Since(now).Seconds())
|
||||
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||||
})
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
next.ServeHTTP(w, r)
|
||||
- obs.With(labels(code, method, r.Method, 0)).Observe(time.Since(now).Seconds())
|
||||
+ obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -91,20 +96,25 @@ func InstrumentHandlerDuration(obs prometheus.ObserverVec, next http.Handler) ht
|
||||
// If the wrapped Handler panics, the Counter is not incremented.
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
-func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler) http.HandlerFunc {
|
||||
+func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
+ mwOpts := &option{}
|
||||
+ for _, o := range opts {
|
||||
+ o(mwOpts)
|
||||
+ }
|
||||
+
|
||||
code, method := checkLabels(counter)
|
||||
|
||||
if code {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
- counter.With(labels(code, method, r.Method, d.Status())).Inc()
|
||||
+ counter.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Inc()
|
||||
})
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
next.ServeHTTP(w, r)
|
||||
- counter.With(labels(code, method, r.Method, 0)).Inc()
|
||||
+ counter.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Inc()
|
||||
})
|
||||
}
|
||||
|
||||
@@ -126,13 +136,18 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler)
|
||||
// if used with Go1.9+.
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
-func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
|
||||
+func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
+ mwOpts := &option{}
|
||||
+ for _, o := range opts {
|
||||
+ o(mwOpts)
|
||||
+ }
|
||||
+
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
d := newDelegator(w, func(status int) {
|
||||
- obs.With(labels(code, method, r.Method, status)).Observe(time.Since(now).Seconds())
|
||||
+ obs.With(labels(code, method, r.Method, status, mwOpts.extraMethods...)).Observe(time.Since(now).Seconds())
|
||||
})
|
||||
next.ServeHTTP(d, r)
|
||||
})
|
||||
@@ -154,7 +169,12 @@ func InstrumentHandlerTimeToWriteHeader(obs prometheus.ObserverVec, next http.Ha
|
||||
// If the wrapped Handler panics, no values are reported.
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
-func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler) http.HandlerFunc {
|
||||
+func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.HandlerFunc {
|
||||
+ mwOpts := &option{}
|
||||
+ for _, o := range opts {
|
||||
+ o(mwOpts)
|
||||
+ }
|
||||
+
|
||||
code, method := checkLabels(obs)
|
||||
|
||||
if code {
|
||||
@@ -162,14 +182,14 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
size := computeApproximateRequestSize(r)
|
||||
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(size))
|
||||
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(size))
|
||||
})
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
next.ServeHTTP(w, r)
|
||||
size := computeApproximateRequestSize(r)
|
||||
- obs.With(labels(code, method, r.Method, 0)).Observe(float64(size))
|
||||
+ obs.With(labels(code, method, r.Method, 0, mwOpts.extraMethods...)).Observe(float64(size))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -189,12 +209,18 @@ func InstrumentHandlerRequestSize(obs prometheus.ObserverVec, next http.Handler)
|
||||
// If the wrapped Handler panics, no values are reported.
|
||||
//
|
||||
// See the example for InstrumentHandlerDuration for example usage.
|
||||
-func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler) http.Handler {
|
||||
+func InstrumentHandlerResponseSize(obs prometheus.ObserverVec, next http.Handler, opts ...Option) http.Handler {
|
||||
+ mwOpts := &option{}
|
||||
+ for _, o := range opts {
|
||||
+ o(mwOpts)
|
||||
+ }
|
||||
+
|
||||
code, method := checkLabels(obs)
|
||||
+
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
d := newDelegator(w, nil)
|
||||
next.ServeHTTP(d, r)
|
||||
- obs.With(labels(code, method, r.Method, d.Status())).Observe(float64(d.Written()))
|
||||
+ obs.With(labels(code, method, r.Method, d.Status(), mwOpts.extraMethods...)).Observe(float64(d.Written()))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -279,7 +305,7 @@ func isLabelCurried(c prometheus.Collector, label string) bool {
|
||||
// unnecessary allocations on each request.
|
||||
var emptyLabels = prometheus.Labels{}
|
||||
|
||||
-func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
|
||||
+func labels(code, method bool, reqMethod string, status int, extraMethods ...string) prometheus.Labels {
|
||||
if !(code || method) {
|
||||
return emptyLabels
|
||||
}
|
||||
@@ -289,7 +315,7 @@ func labels(code, method bool, reqMethod string, status int) prometheus.Labels {
|
||||
labels["code"] = sanitizeCode(status)
|
||||
}
|
||||
if method {
|
||||
- labels["method"] = sanitizeMethod(reqMethod)
|
||||
+ labels["method"] = sanitizeMethod(reqMethod, extraMethods...)
|
||||
}
|
||||
|
||||
return labels
|
||||
@@ -319,7 +345,12 @@ func computeApproximateRequestSize(r *http.Request) int {
|
||||
return s
|
||||
}
|
||||
|
||||
-func sanitizeMethod(m string) string {
|
||||
+// If the wrapped http.Handler has a known method, it will be sanitized and returned.
|
||||
+// Otherwise, "unknown" will be returned. The known method list can be extended
|
||||
+// as needed by using extraMethods parameter.
|
||||
+func sanitizeMethod(m string, extraMethods ...string) string {
|
||||
+ // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for
|
||||
+ // the methods chosen as default.
|
||||
switch m {
|
||||
case "GET", "get":
|
||||
return "get"
|
||||
@@ -337,15 +368,25 @@ func sanitizeMethod(m string) string {
|
||||
return "options"
|
||||
case "NOTIFY", "notify":
|
||||
return "notify"
|
||||
+ case "TRACE", "trace":
|
||||
+ return "trace"
|
||||
+ case "PATCH", "patch":
|
||||
+ return "patch"
|
||||
default:
|
||||
- return strings.ToLower(m)
|
||||
+ for _, method := range extraMethods {
|
||||
+ if strings.EqualFold(m, method) {
|
||||
+ return strings.ToLower(m)
|
||||
+ }
|
||||
+ }
|
||||
+ return "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
// If the wrapped http.Handler has not set a status code, i.e. the value is
|
||||
-// currently 0, santizeCode will return 200, for consistency with behavior in
|
||||
+// currently 0, sanitizeCode will return 200, for consistency with behavior in
|
||||
// the stdlib.
|
||||
func sanitizeCode(s int) string {
|
||||
+ // See for accepted codes https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
switch s {
|
||||
case 100:
|
||||
return "100"
|
||||
@@ -442,6 +483,9 @@ func sanitizeCode(s int) string {
|
||||
return "511"
|
||||
|
||||
default:
|
||||
- return strconv.Itoa(s)
|
||||
+ if s >= 100 && s <= 599 {
|
||||
+ return strconv.Itoa(s)
|
||||
+ }
|
||||
+ return "unknown"
|
||||
}
|
||||
}
|
||||
diff --git a/prometheus/promhttp/option.go b/prometheus/promhttp/option.go
|
||||
new file mode 100644
|
||||
index 0000000..35e41bd
|
||||
--- /dev/null
|
||||
+++ b/prometheus/promhttp/option.go
|
||||
@@ -0,0 +1,31 @@
|
||||
+// Copyright 2022 The Prometheus Authors
|
||||
+// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
+// you may not use this file except in compliance with the License.
|
||||
+// You may obtain a copy of the License at
|
||||
+//
|
||||
+// http://www.apache.org/licenses/LICENSE-2.0
|
||||
+//
|
||||
+// Unless required by applicable law or agreed to in writing, software
|
||||
+// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+// See the License for the specific language governing permissions and
|
||||
+// limitations under the License.
|
||||
+
|
||||
+package promhttp
|
||||
+
|
||||
+// Option are used to configure a middleware or round tripper..
|
||||
+type Option func(*option)
|
||||
+
|
||||
+type option struct {
|
||||
+ extraMethods []string
|
||||
+}
|
||||
+
|
||||
+// WithExtraMethods adds additional HTTP methods to the list of allowed methods.
|
||||
+// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods for the default list.
|
||||
+//
|
||||
+// See the example for ExampleInstrumentHandlerWithExtraMethods for example usage.
|
||||
+func WithExtraMethods(methods ...string) Option {
|
||||
+ return func(o *option) {
|
||||
+ o.extraMethods = methods
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.33.8
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
Summary: Application Gateway Ingress Controller
|
||||
Name: application-gateway-kubernetes-ingress
|
||||
Version: 1.4.0
|
||||
Release: 16%{?dist}
|
||||
Release: 17%{?dist}
|
||||
License: MIT
|
||||
Vendor: Microsoft Corporation
|
||||
Distribution: Mariner
|
||||
|
@ -24,7 +24,8 @@ Source0: %{name}-%{version}.tar.gz
|
|||
# -cf %%{name}-%%{version}-vendor.tar.gz vendor
|
||||
#
|
||||
Source1: %{name}-%{version}-vendor.tar.gz
|
||||
|
||||
# If upstream ever upgrades client_goland to 1.11.1, we can get rid of this patch.
|
||||
Patch0: CVE-2022-21698.patch
|
||||
BuildRequires: golang >= 1.13
|
||||
|
||||
%description
|
||||
|
@ -32,12 +33,12 @@ This is an ingress controller that can be run on Azure Kubernetes Service (AKS)
|
|||
to act as the ingress for an AKS cluster.
|
||||
|
||||
%prep
|
||||
%autosetup
|
||||
|
||||
%build
|
||||
%autosetup -N
|
||||
rm -rf vendor
|
||||
tar -xf %{SOURCE1} --no-same-owner
|
||||
%patch 0 -p1 -d vendor/github.com/prometheus/client_golang
|
||||
|
||||
%build
|
||||
export VERSION=%{version}
|
||||
export VERSION_PATH=github.com/Azure/application-gateway-kubernetes-ingress/pkg/version
|
||||
|
||||
|
@ -54,6 +55,10 @@ cp appgw-ingress %{buildroot}%{_bindir}/
|
|||
%{_bindir}/appgw-ingress
|
||||
|
||||
%changelog
|
||||
* Mon Jan 01 2024 Tobias Brick <tobiasb@microsoft.com> - 1.4.0-17
|
||||
- Patch for CVE-2022-21698
|
||||
- Moved vendored tarball extraction into %prep and changed from %autosetup to %setup
|
||||
|
||||
* Mon Oct 16 2023 CBL-Mariner Servicing Account <cblmargh@microsoft.com> - 1.4.0-16
|
||||
- Bump release to rebuild with go 1.20.9
|
||||
|
||||
|
|
Loading…
Reference in New Issue