!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:
openeuler-ci-bot 2022-03-30 06:49:35 +00:00 committed by Gitee
commit 4097b66fe4
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 198 additions and 1 deletions

191
CVE-2022-21702.patch Normal file
View 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")
+}

View File

@ -7,7 +7,7 @@
Name: grafana Name: grafana
Version: 7.5.11 Version: 7.5.11
Release: 4 Release: 5
Summary: Metrics dashboard and graph editor Summary: Metrics dashboard and graph editor
License: Apache 2.0 License: Apache 2.0
URL: https://grafana.org URL: https://grafana.org
@ -32,6 +32,8 @@ Patch6: 006-remove-unused-frontend-crypto.patch
Patch7: 007-patch-unused-backend-crypto.patch Patch7: 007-patch-unused-backend-crypto.patch
Patch8: CVE-2021-43813.patch Patch8: CVE-2021-43813.patch
Patch9: CVE-2022-21673.patch Patch9: CVE-2022-21673.patch
#https://github.com/grafana/grafana/commit/27726868b3d7c613844b55cd209ca93645c99b85
Patch10: CVE-2022-21702.patch
BuildRequires: git, systemd, golang BuildRequires: git, systemd, golang
@ -402,6 +404,7 @@ rm -r plugins-bundled
%patch7 -p1 %patch7 -p1
%patch8 -p1 %patch8 -p1
%patch9 -p1 %patch9 -p1
%patch10 -p1
# Set up build subdirs and links # Set up build subdirs and links
@ -566,6 +569,9 @@ rm -r pkg/macaron
%changelog %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 * Thu Jan 27 2022 wangkai <wangkai385@huawei.com> 7.5.11-4
- Fix CVE-2022-21673 - Fix CVE-2022-21673