import Oracle_OSS grafana-10.2.6-23.el9_8.2
This commit is contained in:
parent
515f74ed16
commit
da1cc8dfae
@ -1,28 +1,29 @@
|
||||
From 82ef13993059351bf21de35b8488bbd9b42df4f4 Mon Sep 17 00:00:00 2001
|
||||
From: Mariell Hoversholm <mariell.hoversholm@grafana.com>
|
||||
Date: Tue, 16 Jun 2026 09:54:34 +0200
|
||||
Subject: [PATCH] fix(web/bind): cap the request body size and validate
|
||||
public dashboard access
|
||||
From db2af7de91c43c0b94b5a0a834e99c52a5da87b1 Mon Sep 17 00:00:00 2001
|
||||
From: RHEL Packaging Agent <redhat-ymir-agent@redhat.com>
|
||||
Date: Thu, 30 Jul 2026 09:48:07 +0000
|
||||
Subject: [PATCH] fix(web/bind): cap the request body size and validate public
|
||||
dashboard access
|
||||
|
||||
Cap request body size in Bind() with MaxBytesReader (100 MiB limit).
|
||||
Add specific body size limits (10 KiB) for public dashboard create,
|
||||
update, and query endpoints. Validate access token before processing
|
||||
query request body.
|
||||
|
||||
Backported from upstream grafana/grafana commit
|
||||
82ef13993059351bf21de35b8488bbd9b42df4f4 (PR #125789), taking the
|
||||
VUL-2026-0074 / VUL-2026-0077 changes only and adapting them to the
|
||||
10.2.6 tree, where the public dashboards API lives in
|
||||
pkg/services/publicdashboards/api and its models are not yet in a
|
||||
separate package.
|
||||
|
||||
GL-Vuln: VUL-2026-0074
|
||||
GL-Vuln: VUL-2026-0077
|
||||
---
|
||||
pkg/services/publicdashboards/api/api.go | 10 ++++
|
||||
pkg/services/publicdashboards/api/query.go | 7 +++
|
||||
.../publicdashboards/api/query_test.go | 2 +
|
||||
pkg/web/binding.go | 6 +-
|
||||
pkg/web/binding_test.go | 58 +++++++++++++++++++
|
||||
5 files changed, 82 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pkg/services/publicdashboards/api/api.go b/pkg/services/publicdashboards/api/api.go
|
||||
index 3713e7d8c5..4464cc8ca0 100644
|
||||
--- a/pkg/services/publicdashboards/api/api.go
|
||||
+++ b/pkg/services/publicdashboards/api/api.go
|
||||
@@ -20,6 +20,12 @@
|
||||
@@ -20,6 +20,12 @@ import (
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
@ -35,7 +36,7 @@ diff --git a/pkg/services/publicdashboards/api/api.go b/pkg/services/publicdashb
|
||||
type Api struct {
|
||||
PublicDashboardService publicdashboards.Service
|
||||
RouteRegister routing.RouteRegister
|
||||
@@ -176,6 +182,8 @@
|
||||
@@ -176,6 +182,8 @@ func (api *Api) CreatePublicDashboard(c *contextmodel.ReqContext) response.Respo
|
||||
return response.Err(ErrInvalidUid.Errorf("CreatePublicDashboard: invalid Uid %s", dashboardUid))
|
||||
}
|
||||
|
||||
@ -44,7 +45,7 @@ diff --git a/pkg/services/publicdashboards/api/api.go b/pkg/services/publicdashb
|
||||
pdDTO := &PublicDashboardDTO{}
|
||||
if err := web.Bind(c.Req, pdDTO); err != nil {
|
||||
return response.Err(ErrBadRequest.Errorf("CreatePublicDashboard: bad request data %v", err))
|
||||
@@ -235,6 +243,8 @@
|
||||
@@ -235,6 +243,8 @@ func (api *Api) UpdatePublicDashboard(c *contextmodel.ReqContext) response.Respo
|
||||
return response.Err(ErrInvalidUid.Errorf("UpdatePublicDashboard: invalid Uid %s", uid))
|
||||
}
|
||||
|
||||
@ -54,9 +55,10 @@ diff --git a/pkg/services/publicdashboards/api/api.go b/pkg/services/publicdashb
|
||||
if err := web.Bind(c.Req, pdDTO); err != nil {
|
||||
return response.Err(ErrBadRequest.Errorf("UpdatePublicDashboard: bad request data %v", err))
|
||||
diff --git a/pkg/services/publicdashboards/api/query.go b/pkg/services/publicdashboards/api/query.go
|
||||
index e6dabff13d..28161c087c 100644
|
||||
--- a/pkg/services/publicdashboards/api/query.go
|
||||
+++ b/pkg/services/publicdashboards/api/query.go
|
||||
@@ -57,6 +57,13 @@
|
||||
@@ -57,6 +57,13 @@ func (api *Api) QueryPublicDashboard(c *contextmodel.ReqContext) response.Respon
|
||||
return response.Err(ErrInvalidAccessToken.Errorf("QueryPublicDashboard: invalid access token"))
|
||||
}
|
||||
|
||||
@ -71,9 +73,10 @@ diff --git a/pkg/services/publicdashboards/api/query.go b/pkg/services/publicdas
|
||||
if err != nil {
|
||||
return response.Err(ErrInvalidPanelId.Errorf("QueryPublicDashboard: error parsing panelId %v", err))
|
||||
diff --git a/pkg/services/publicdashboards/api/query_test.go b/pkg/services/publicdashboards/api/query_test.go
|
||||
index 2dcaaa7561..d1d244b67a 100644
|
||||
--- a/pkg/services/publicdashboards/api/query_test.go
|
||||
+++ b/pkg/services/publicdashboards/api/query_test.go
|
||||
@@ -98,6 +98,7 @@
|
||||
@@ -98,6 +98,7 @@ func TestAPIViewPublicDashboard(t *testing.T) {
|
||||
for _, test := range testCases {
|
||||
t.Run(test.Name, func(t *testing.T) {
|
||||
service := publicdashboards.NewFakePublicDashboardService(t)
|
||||
@ -81,7 +84,7 @@ diff --git a/pkg/services/publicdashboards/api/query_test.go b/pkg/services/publ
|
||||
service.On("GetPublicDashboardForView", mock.Anything, mock.AnythingOfType("string")).
|
||||
Return(test.DashboardResult, test.Err).Maybe()
|
||||
|
||||
@@ -202,6 +203,7 @@
|
||||
@@ -202,6 +203,7 @@ func TestAPIQueryPublicDashboard(t *testing.T) {
|
||||
|
||||
setup := func(enabled bool) (*web.Mux, *publicdashboards.FakePublicDashboardService) {
|
||||
service := publicdashboards.NewFakePublicDashboardService(t)
|
||||
@ -90,9 +93,10 @@ diff --git a/pkg/services/publicdashboards/api/query_test.go b/pkg/services/publ
|
||||
|
||||
testServer := setupTestServer(
|
||||
diff --git a/pkg/web/binding.go b/pkg/web/binding.go
|
||||
index ef5d580e25..6ce059b3a7 100644
|
||||
--- a/pkg/web/binding.go
|
||||
+++ b/pkg/web/binding.go
|
||||
@@ -10,6 +10,9 @@
|
||||
@@ -10,6 +10,9 @@ import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
@ -102,7 +106,7 @@ diff --git a/pkg/web/binding.go b/pkg/web/binding.go
|
||||
// Bind deserializes JSON payload from the request
|
||||
func Bind(req *http.Request, v any) error {
|
||||
if req.Body != nil {
|
||||
@@ -21,7 +24,8 @@
|
||||
@@ -21,7 +24,8 @@ func Bind(req *http.Request, v any) error {
|
||||
return errors.New("bad content type")
|
||||
}
|
||||
defer func() { _ = req.Body.Close() }()
|
||||
@ -113,9 +117,10 @@ diff --git a/pkg/web/binding.go b/pkg/web/binding.go
|
||||
return err
|
||||
}
|
||||
diff --git a/pkg/web/binding_test.go b/pkg/web/binding_test.go
|
||||
index 4c5d9550f4..f269b93cbf 100644
|
||||
--- a/pkg/web/binding_test.go
|
||||
+++ b/pkg/web/binding_test.go
|
||||
@@ -2,6 +2,10 @@
|
||||
@@ -2,6 +2,10 @@ package web
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@ -126,7 +131,7 @@ diff --git a/pkg/web/binding_test.go b/pkg/web/binding_test.go
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -61,6 +65,60 @@
|
||||
@@ -61,6 +65,60 @@ func (sv *StructWithPointerValidation) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
45
SOURCES/0018-fix-CVE-2026-33376.patch
Normal file
45
SOURCES/0018-fix-CVE-2026-33376.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 1030d08fadb0cde0cf0a70429ab7f6aff5722021 Mon Sep 17 00:00:00 2001
|
||||
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
|
||||
Date: Wed, 11 Mar 2026 13:59:53 +0000
|
||||
Subject: [PATCH] patch(security): patch(security): fix auth proxy IPv6 bare
|
||||
whitelist parsing (main)
|
||||
|
||||
GL-Vuln: VUL-2026-0045 https://ops.grafana-ops.net/a/grafana-vulnerabilityobs-app/first-party/77
|
||||
GL-Partner-Rel: 2026-04-09
|
||||
GL-Public-After: 2026-05-12
|
||||
GL-Partner-Ack: 2026-03-30
|
||||
---
|
||||
pkg/services/authn/clients/proxy.go | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/pkg/services/authn/clients/proxy.go b/pkg/services/authn/clients/proxy.go
|
||||
index 06abe1d..80a7909 100644
|
||||
--- a/pkg/services/authn/clients/proxy.go
|
||||
+++ b/pkg/services/authn/clients/proxy.go
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"fmt"
|
||||
"hash/fnv"
|
||||
"net"
|
||||
- "path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -189,7 +188,17 @@ func parseAcceptList(s string) ([]*net.IPNet, error) {
|
||||
func coerceProxyAddress(proxyAddr string) (*net.IPNet, error) {
|
||||
proxyAddr = strings.TrimSpace(proxyAddr)
|
||||
if !strings.Contains(proxyAddr, "/") {
|
||||
- proxyAddr = path.Join(proxyAddr, "32")
|
||||
+ ip := net.ParseIP(proxyAddr)
|
||||
+ if ip == nil {
|
||||
+ return nil, fmt.Errorf("could not parse the network: invalid IP address")
|
||||
+ }
|
||||
+
|
||||
+ mask := 32
|
||||
+ if ip.To4() == nil {
|
||||
+ mask = 128
|
||||
+ }
|
||||
+
|
||||
+ proxyAddr = fmt.Sprintf("%s/%d", proxyAddr, mask)
|
||||
}
|
||||
|
||||
_, network, err := net.ParseCIDR(proxyAddr)
|
||||
30
SOURCES/0019-fix-CVE-2026-33377.patch
Normal file
30
SOURCES/0019-fix-CVE-2026-33377.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 2270fa620efc17221bde881c5b6987cb6460c42e Mon Sep 17 00:00:00 2001
|
||||
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
|
||||
Date: Thu, 19 Mar 2026 16:54:46 +0000
|
||||
Subject: [PATCH] patch(security): [11.6.14] Dashboards: Fix /import permission
|
||||
setting
|
||||
|
||||
GL-Vuln: VUL-2026-0058 https://ops.grafana-ops.net/a/grafana-vulnerabilityobs-app/first-party/90
|
||||
GL-Partner-Rel: 2026-04-09
|
||||
GL-Public-After: 2026-05-12
|
||||
GL-Partner-Ack: 2026-03-24
|
||||
---
|
||||
pkg/services/dashboards/service/dashboard_service.go | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go
|
||||
index 49ee617..913c479 100644
|
||||
--- a/pkg/services/dashboards/service/dashboard_service.go
|
||||
+++ b/pkg/services/dashboards/service/dashboard_service.go
|
||||
@@ -482,7 +482,10 @@ func (dr *DashboardServiceImpl) ImportDashboard(ctx context.Context, dto *dashbo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
- dr.setDefaultPermissions(ctx, dto, dash, false)
|
||||
+ // new dashboard created
|
||||
+ if dto.Dashboard.ID == 0 {
|
||||
+ dr.setDefaultPermissions(ctx, dto, dash, false)
|
||||
+ }
|
||||
|
||||
return dash, nil
|
||||
}
|
||||
25
SOURCES/0020-fix-CVE-2026-8609.patch
Normal file
25
SOURCES/0020-fix-CVE-2026-8609.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 5284c45953228aeb3c13efe13f6f72f70a3e9b96 Mon Sep 17 00:00:00 2001
|
||||
From: lmchilton <lauren.chilton26@gmail.com>
|
||||
Date: Fri, 14 Aug 2026 13:15:10 -0400
|
||||
Subject: [PATCH] Fix CVE-2026-8609
|
||||
|
||||
---
|
||||
pkg/services/authn/authnimpl/service.go | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pkg/services/authn/authnimpl/service.go b/pkg/services/authn/authnimpl/service.go
|
||||
index b72fc43600a..f242d7068d9 100644
|
||||
--- a/pkg/services/authn/authnimpl/service.go
|
||||
+++ b/pkg/services/authn/authnimpl/service.go
|
||||
@@ -279,7 +279,7 @@ func (s *Service) Login(ctx context.Context, client string, r *authn.Request) (i
|
||||
|
||||
c, ok := s.clients[client]
|
||||
if !ok {
|
||||
- s.metrics.failedLogin.WithLabelValues(client).Inc()
|
||||
+ s.metrics.failedLogin.WithLabelValues("unknown").Inc()
|
||||
return nil, authn.ErrClientNotConfigured.Errorf("client not configured: %s", client)
|
||||
}
|
||||
|
||||
--
|
||||
2.54.0
|
||||
|
||||
96
SOURCES/0021-fix-CVE-2026-33382.patch
Normal file
96
SOURCES/0021-fix-CVE-2026-33382.patch
Normal file
@ -0,0 +1,96 @@
|
||||
From 537a7969ce1198b969e623ecc866739e5bcb3175 Mon Sep 17 00:00:00 2001
|
||||
From: lmchilton <lauren.chilton26@gmail.com>
|
||||
Date: Tue, 18 Aug 2026 11:37:34 -0400
|
||||
Subject: [PATCH] fix CVE-33382
|
||||
|
||||
---
|
||||
pkg/api/login.go | 3 +++
|
||||
pkg/api/org_invite.go | 2 ++
|
||||
pkg/api/password.go | 4 ++++
|
||||
pkg/api/signup.go | 7 +++++++
|
||||
4 files changed, 16 insertions(+)
|
||||
|
||||
diff --git a/pkg/api/login.go b/pkg/api/login.go
|
||||
index e9e88cf3841..80884c99410 100644
|
||||
--- a/pkg/api/login.go
|
||||
+++ b/pkg/api/login.go
|
||||
@@ -204,6 +204,9 @@ func (hs *HTTPServer) LoginAPIPing(c *contextmodel.ReqContext) response.Response
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) LoginPost(c *contextmodel.ReqContext) response.Response {
|
||||
+ // Cap the request body-front so any downstream consumer inherits the limit.
|
||||
+ c.Req.Body = http.MaxBytesReader(c.Resp, c.Req.Body, maxPreAuthFormBodySize)
|
||||
+
|
||||
identity, err := hs.authnService.Login(c.Req.Context(), authn.ClientForm, &authn.Request{HTTPRequest: c.Req, Resp: c.Resp})
|
||||
if err != nil {
|
||||
tokenErr := &auth.CreateTokenErr{}
|
||||
diff --git a/pkg/api/org_invite.go b/pkg/api/org_invite.go
|
||||
index ab4f1b944b9..437f95594ba 100644
|
||||
--- a/pkg/api/org_invite.go
|
||||
+++ b/pkg/api/org_invite.go
|
||||
@@ -235,6 +235,8 @@ func (hs *HTTPServer) GetInviteInfoByCode(c *contextmodel.ReqContext) response.R
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) CompleteInvite(c *contextmodel.ReqContext) response.Response {
|
||||
+ c.Req.Body = http.MaxBytesReader(c.Resp, c.Req.Body, maxPreAuthFormBodySize)
|
||||
+
|
||||
completeInvite := dtos.CompleteInviteForm{}
|
||||
var err error
|
||||
if err = web.Bind(c.Req, &completeInvite); err != nil {
|
||||
diff --git a/pkg/api/password.go b/pkg/api/password.go
|
||||
index 5567c9af3f9..0ca9c281c78 100644
|
||||
--- a/pkg/api/password.go
|
||||
+++ b/pkg/api/password.go
|
||||
@@ -16,6 +16,8 @@ import (
|
||||
)
|
||||
|
||||
func (hs *HTTPServer) SendResetPasswordEmail(c *contextmodel.ReqContext) response.Response {
|
||||
+ c.Req.Body = http.MaxBytesReader(c.Resp, c.Req.Body, maxPreAuthFormBodySize)
|
||||
+
|
||||
form := dtos.SendResetPasswordEmailForm{}
|
||||
if err := web.Bind(c.Req, &form); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
@@ -54,6 +56,8 @@ func (hs *HTTPServer) SendResetPasswordEmail(c *contextmodel.ReqContext) respons
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) ResetPassword(c *contextmodel.ReqContext) response.Response {
|
||||
+ c.Req.Body = http.MaxBytesReader(c.Resp, c.Req.Body, maxPreAuthFormBodySize)
|
||||
+
|
||||
form := dtos.ResetUserPasswordForm{}
|
||||
if err := web.Bind(c.Req, &form); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
diff --git a/pkg/api/signup.go b/pkg/api/signup.go
|
||||
index 0f9310d35f6..b5d20c28651 100644
|
||||
--- a/pkg/api/signup.go
|
||||
+++ b/pkg/api/signup.go
|
||||
@@ -19,6 +19,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
+// maxPreAuthFormBodySize caps pre-auth form-shaped request bodies (signup, password reset, invite completion, login).
|
||||
+const maxPreAuthFormBodySize = 100 * 1024 // 100 KiB
|
||||
+
|
||||
// GET /api/user/signup/options
|
||||
func (hs *HTTPServer) GetSignUpOptions(c *contextmodel.ReqContext) response.Response {
|
||||
return response.JSON(http.StatusOK, util.DynMap{
|
||||
@@ -29,6 +32,8 @@ func (hs *HTTPServer) GetSignUpOptions(c *contextmodel.ReqContext) response.Resp
|
||||
|
||||
// POST /api/user/signup
|
||||
func (hs *HTTPServer) SignUp(c *contextmodel.ReqContext) response.Response {
|
||||
+ c.Req.Body = http.MaxBytesReader(c.Resp, c.Req.Body, maxPreAuthFormBodySize)
|
||||
+
|
||||
form := dtos.SignUpForm{}
|
||||
var err error
|
||||
if err = web.Bind(c.Req, &form); err != nil {
|
||||
@@ -82,6 +87,8 @@ func (hs *HTTPServer) SignUp(c *contextmodel.ReqContext) response.Response {
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) SignUpStep2(c *contextmodel.ReqContext) response.Response {
|
||||
+ c.Req.Body = http.MaxBytesReader(c.Resp, c.Req.Body, maxPreAuthFormBodySize)
|
||||
+
|
||||
form := dtos.SignUpStep2Form{}
|
||||
if err := web.Bind(c.Req, &form); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "bad request data", err)
|
||||
--
|
||||
2.54.0
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
|
||||
Name: grafana
|
||||
Version: 10.2.6
|
||||
Release: 23%{?dist}.1
|
||||
Release: 23%{?dist}.2
|
||||
Summary: Metrics dashboard and graph editor
|
||||
License: AGPL-3.0-only
|
||||
URL: https://grafana.org
|
||||
@ -78,6 +78,10 @@ Patch15: 0015-Fix-CVE-2026-27877.patch
|
||||
Patch16: 0016-fix-x-net-CVE.patch
|
||||
# https://github.com/grafana/grafana/commit/82ef13993059351bf21de35b8488bbd9b42df4f4
|
||||
Patch17: 0017-fix-CVE-2026-42127.patch
|
||||
Patch18: 0018-fix-CVE-2026-33376.patch
|
||||
Patch19: 0019-fix-CVE-2026-33377.patch
|
||||
Patch20: 0020-fix-CVE-2026-8609.patch
|
||||
Patch21: 0021-fix-CVE-2026-33382.patch
|
||||
|
||||
# Patches affecting the vendor tarball
|
||||
Patch1001: 1001-vendor-patch-removed-backend-crypto.patch
|
||||
@ -778,6 +782,10 @@ rm -r plugins-bundled
|
||||
%patch -P 15 -p1
|
||||
%patch -P 16 -p1
|
||||
%patch -P 17 -p1
|
||||
%patch -P 18 -p1
|
||||
%patch -P 19 -p1
|
||||
%patch -P 20 -p1
|
||||
%patch -P 21 -p1
|
||||
|
||||
%patch -P 1001 -p1
|
||||
%if %{enable_fips_mode}
|
||||
@ -1024,10 +1032,15 @@ done
|
||||
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/*/active/modules/200/grafana
|
||||
|
||||
%changelog
|
||||
* Wed Aug 12 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 10.2.6-23.1
|
||||
- fix(web/bind): cap the request body size and validate public dashboard access
|
||||
Backport of upstream grafana/grafana commit 82ef1399 (PR #125789),
|
||||
VUL-2026-0074 / VUL-2026-0077. Fixes CVE-2026-42127.
|
||||
* Aug 20 2026 Lauren Chilton <lchilton@redhat.com> - 10.2.6-23.2
|
||||
- Resolves RHEL-210991: CVE-2026-33376
|
||||
- Resolves RHEL-211022: CVE-2026-33377
|
||||
- Resolves RHEL-242865: CVE-2026-8609
|
||||
- Resolves RHEL-242866: CVE-2026-33382
|
||||
|
||||
* Thu Jul 30 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 10.2.6-23.1
|
||||
- fix CVE-2026-42127: cap request body size and validate public dashboard access
|
||||
- Resolves RHEL-219382
|
||||
|
||||
* Thu Jul 02 2026 Sam Feifer <sfeifer@redhat.com> 10.2.6-23
|
||||
- Resolves RHEL-183803: CVE-2026-39821
|
||||
|
||||
Loading…
Reference in New Issue
Block a user