!36 [sync] PR-33: Fix CVE-2022-21702
From: @openeuler-sync-bot Reviewed-by: @small_leek Signed-off-by: @small_leek
This commit is contained in:
commit
4097b66fe4
191
CVE-2022-21702.patch
Normal file
191
CVE-2022-21702.patch
Normal file
@ -0,0 +1,191 @@
|
||||
From 27726868b3d7c613844b55cd209ca93645c99b85 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Efraimsson <marcus.efraimsson@gmail.com>
|
||||
Date: Fri, 21 Jan 2022 16:43:04 +0100
|
||||
Subject: [PATCH] [v7.5.x] Fix for CVE-2022-21702 (#226)
|
||||
|
||||
Fix for CVE-2022-21702
|
||||
---
|
||||
pkg/api/pluginproxy/ds_proxy.go | 1 +
|
||||
pkg/api/pluginproxy/ds_proxy_test.go | 12 +++++++
|
||||
pkg/api/pluginproxy/pluginproxy.go | 8 ++++-
|
||||
pkg/api/pluginproxy/pluginproxy_test.go | 44 +++++++++++++++++++++++
|
||||
pkg/plugins/backendplugin/manager.go | 1 +
|
||||
pkg/plugins/backendplugin/manager_test.go | 9 ++++-
|
||||
pkg/util/proxyutil/proxyutil.go | 6 ++++
|
||||
7 files changed, 79 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/pkg/api/pluginproxy/ds_proxy.go b/pkg/api/pluginproxy/ds_proxy.go
|
||||
index e5cf53dacc958..b5537ba6eb941 100644
|
||||
--- a/pkg/api/pluginproxy/ds_proxy.go
|
||||
+++ b/pkg/api/pluginproxy/ds_proxy.go
|
||||
@@ -49,6 +49,7 @@ func (t *handleResponseTransport) RoundTrip(req *http.Request) (*http.Response,
|
||||
return nil, err
|
||||
}
|
||||
res.Header.Del("Set-Cookie")
|
||||
+ proxyutil.SetProxyResponseHeaders(res.Header)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
diff --git a/pkg/api/pluginproxy/ds_proxy_test.go b/pkg/api/pluginproxy/ds_proxy_test.go
|
||||
index 4f61e2055c471..be4bd8b38e7db 100644
|
||||
--- a/pkg/api/pluginproxy/ds_proxy_test.go
|
||||
+++ b/pkg/api/pluginproxy/ds_proxy_test.go
|
||||
@@ -605,6 +605,18 @@ func TestDataSourceProxy_requestHandling(t *testing.T) {
|
||||
assert.Equal(t, "important_cookie=important_value", proxy.ctx.Resp.Header().Get("Set-Cookie"))
|
||||
})
|
||||
|
||||
+ t.Run("When response should set Content-Security-Policy header", func(t *testing.T) {
|
||||
+ ctx, ds := setUp(t)
|
||||
+ dsPlugin := &plugins.DataSourcePlugin{}
|
||||
+ proxy, err := NewDataSourceProxy(ds, dsPlugin, ctx, "/render", &setting.Cfg{})
|
||||
+ require.NoError(t, err)
|
||||
+
|
||||
+ proxy.HandleRequest()
|
||||
+
|
||||
+ require.NoError(t, writeErr)
|
||||
+ assert.Equal(t, "sandbox", proxy.ctx.Resp.Header().Get("Content-Security-Policy"))
|
||||
+ })
|
||||
+
|
||||
t.Run("Data source returns status code 401", func(t *testing.T) {
|
||||
ctx, ds := setUp(t, setUpCfg{
|
||||
writeCb: func(w http.ResponseWriter, r *http.Request) {
|
||||
diff --git a/pkg/api/pluginproxy/pluginproxy.go b/pkg/api/pluginproxy/pluginproxy.go
|
||||
index 34e88459ef37b..5b0c3e436c25d 100644
|
||||
--- a/pkg/api/pluginproxy/pluginproxy.go
|
||||
+++ b/pkg/api/pluginproxy/pluginproxy.go
|
||||
@@ -71,5 +71,11 @@ func NewApiPluginProxy(ctx *models.ReqContext, proxyPath string, route *plugins.
|
||||
}
|
||||
}
|
||||
|
||||
- return &httputil.ReverseProxy{Director: director}
|
||||
+ return &httputil.ReverseProxy{Director: director, ModifyResponse: modifyResponse}
|
||||
+}
|
||||
+
|
||||
+func modifyResponse(resp *http.Response) error {
|
||||
+ proxyutil.SetProxyResponseHeaders(resp.Header)
|
||||
+
|
||||
+ return nil
|
||||
}
|
||||
diff --git a/pkg/api/pluginproxy/pluginproxy_test.go b/pkg/api/pluginproxy/pluginproxy_test.go
|
||||
index 7b538139bbc14..b9873ef4f3973 100644
|
||||
--- a/pkg/api/pluginproxy/pluginproxy_test.go
|
||||
+++ b/pkg/api/pluginproxy/pluginproxy_test.go
|
||||
@@ -2,6 +2,7 @@ package pluginproxy
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
+ "net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/bus"
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
+ macaron "gopkg.in/macaron.v1"
|
||||
)
|
||||
|
||||
func TestPluginProxy(t *testing.T) {
|
||||
@@ -148,6 +150,48 @@ func TestPluginProxy(t *testing.T) {
|
||||
)
|
||||
assert.Equal(t, "https://example.com", req.URL.String())
|
||||
})
|
||||
+
|
||||
+ t.Run("When proxying a request should set expected response headers", func(t *testing.T) {
|
||||
+ requestHandled := false
|
||||
+ backendServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
+ w.WriteHeader(200)
|
||||
+ _, _ = w.Write([]byte("I am the backend"))
|
||||
+ requestHandled = true
|
||||
+ }))
|
||||
+
|
||||
+ responseRecorder := &closeNotifierResponseRecorder{
|
||||
+ ResponseRecorder: httptest.NewRecorder(),
|
||||
+ }
|
||||
+ responseWriter := macaron.NewResponseWriter("GET", responseRecorder)
|
||||
+
|
||||
+ t.Cleanup(responseRecorder.Close)
|
||||
+ t.Cleanup(backendServer.Close)
|
||||
+
|
||||
+ route := &plugins.AppPluginRoute{
|
||||
+ Path: "/",
|
||||
+ URL: backendServer.URL,
|
||||
+ }
|
||||
+
|
||||
+ ctx := &models.ReqContext{
|
||||
+ SignedInUser: &models.SignedInUser{},
|
||||
+ Context: &macaron.Context{
|
||||
+ Req: macaron.Request{
|
||||
+ Request: httptest.NewRequest("GET", "/", nil),
|
||||
+ },
|
||||
+ Resp: responseWriter,
|
||||
+ },
|
||||
+ }
|
||||
+ proxy := NewApiPluginProxy(ctx, "", route, "", &setting.Cfg{})
|
||||
+ proxy.ServeHTTP(ctx.Resp, ctx.Req.Request)
|
||||
+
|
||||
+ for {
|
||||
+ if requestHandled {
|
||||
+ break
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ require.Equal(t, "sandbox", ctx.Resp.Header().Get("Content-Security-Policy"))
|
||||
+ })
|
||||
}
|
||||
|
||||
// getPluginProxiedRequest is a helper for easier setup of tests based on global config and ReqContext.
|
||||
diff --git a/pkg/plugins/backendplugin/manager.go b/pkg/plugins/backendplugin/manager.go
|
||||
index 600e5c40acb2b..cc0c902fb6cdf 100644
|
||||
--- a/pkg/plugins/backendplugin/manager.go
|
||||
+++ b/pkg/plugins/backendplugin/manager.go
|
||||
@@ -406,6 +406,7 @@ func flushStream(plugin Plugin, stream CallResourceClientResponseStream, w http.
|
||||
}
|
||||
}
|
||||
|
||||
+ proxyutil.SetProxyResponseHeaders(w.Header())
|
||||
w.WriteHeader(resp.Status)
|
||||
}
|
||||
|
||||
diff --git a/pkg/plugins/backendplugin/manager_test.go b/pkg/plugins/backendplugin/manager_test.go
|
||||
index daa648e156c7a..e6155a00d949b 100644
|
||||
--- a/pkg/plugins/backendplugin/manager_test.go
|
||||
+++ b/pkg/plugins/backendplugin/manager_test.go
|
||||
@@ -177,7 +177,8 @@ func TestManager(t *testing.T) {
|
||||
t.Run("Call resource should return expected response", func(t *testing.T) {
|
||||
ctx.plugin.CallResourceHandlerFunc = backend.CallResourceHandlerFunc(func(ctx context.Context, req *backend.CallResourceRequest, sender backend.CallResourceResponseSender) error {
|
||||
return sender.Send(&backend.CallResourceResponse{
|
||||
- Status: http.StatusOK,
|
||||
+ Status: http.StatusOK,
|
||||
+ Headers: map[string][]string{},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -186,7 +187,13 @@ func TestManager(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
err = ctx.manager.callResourceInternal(w, req, backend.PluginContext{PluginID: testPluginID})
|
||||
require.NoError(t, err)
|
||||
+ for {
|
||||
+ if w.Flushed {
|
||||
+ break
|
||||
+ }
|
||||
+ }
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
+ require.Equal(t, "sandbox", w.Header().Get("Content-Security-Policy"))
|
||||
})
|
||||
})
|
||||
})
|
||||
diff --git a/pkg/util/proxyutil/proxyutil.go b/pkg/util/proxyutil/proxyutil.go
|
||||
index d6e3572133370..3db22a1426ed1 100644
|
||||
--- a/pkg/util/proxyutil/proxyutil.go
|
||||
+++ b/pkg/util/proxyutil/proxyutil.go
|
||||
@@ -42,3 +42,9 @@ func ClearCookieHeader(req *http.Request, keepCookiesNames []string) {
|
||||
req.AddCookie(c)
|
||||
}
|
||||
}
|
||||
+
|
||||
+// SetProxyResponseHeaders sets proxy response headers.
|
||||
+// Sets Content-Security-Policy: sandbox
|
||||
+func SetProxyResponseHeaders(header http.Header) {
|
||||
+ header.Set("Content-Security-Policy", "sandbox")
|
||||
+}
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
Name: grafana
|
||||
Version: 7.5.11
|
||||
Release: 4
|
||||
Release: 5
|
||||
Summary: Metrics dashboard and graph editor
|
||||
License: Apache 2.0
|
||||
URL: https://grafana.org
|
||||
@ -32,6 +32,8 @@ Patch6: 006-remove-unused-frontend-crypto.patch
|
||||
Patch7: 007-patch-unused-backend-crypto.patch
|
||||
Patch8: CVE-2021-43813.patch
|
||||
Patch9: CVE-2022-21673.patch
|
||||
#https://github.com/grafana/grafana/commit/27726868b3d7c613844b55cd209ca93645c99b85
|
||||
Patch10: CVE-2022-21702.patch
|
||||
|
||||
BuildRequires: git, systemd, golang
|
||||
|
||||
@ -402,6 +404,7 @@ rm -r plugins-bundled
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
%patch10 -p1
|
||||
|
||||
|
||||
# Set up build subdirs and links
|
||||
@ -566,6 +569,9 @@ rm -r pkg/macaron
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Mar 17 2022 yaoxin <yaoxin30@huawei.com> - 7.5.11-5
|
||||
- Fix CVE-2022-21702
|
||||
|
||||
* Thu Jan 27 2022 wangkai <wangkai385@huawei.com> 7.5.11-4
|
||||
- Fix CVE-2022-21673
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user