diff --git a/CHANGES.txt b/CHANGES.txt index aeaa9c62..224b451f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,10 @@ +5.12.7 (Jun 30, 2026) +- Fixed vulnerabilities (4 High, 35 Low): + - H: CVE-2026-45447, CVE-2026-7383, CVE-2026-9076, CVE-2026-34180 + - L: CVE-2026-45446, CVE-2026-45445, CVE-2026-42770, CVE-2026-42769, CVE-2026-42768, CVE-2026-42767, CVE-2026-42764, CVE-2026-34183, CVE-2026-34182, CVE-2026-34181, CVE-2010-0928, CVE-2019-9192, CVE-2019-1010025, CVE-2019-1010024, CVE-2019-1010023, CVE-2019-1010022, CVE-2018-20796, CVE-2010-4756, CVE-2026-53614, CVE-2026-53612, CVE-2025-14104, CVE-2022-0563, CVE-2023-31439, CVE-2023-31438, CVE-2023-31437, CVE-2013-4392, CVE-2025-70873, CVE-2021-45346, CVE-2026-48961, CVE-2011-4116, CVE-2025-5278, CVE-2017-18018, CVE-2005-2541, CVE-2007-5686, CVE-2011-3374 + - Updated Docker base image from debian:13 to debian:trixie-20260623-slim +- Updated log level from error to info when reading snapshots to populate caches for splits, segments, and rule-based segments + 5.12.6 (Jun 19, 2026) - Updated snapshot validation to warn on configuration mismatches instead of blocking proxy initialization. diff --git a/docker/Dockerfile.proxy b/docker/Dockerfile.proxy index a8b87e23..d01ad778 100644 --- a/docker/Dockerfile.proxy +++ b/docker/Dockerfile.proxy @@ -18,7 +18,7 @@ RUN bash -c 'if [[ "${FIPS_MODE}" = "enabled" ]]; \ fi' # Runner stage -FROM debian:13 AS runner +FROM debian:trixie-20260623-slim AS runner RUN apt update -y && \ apt upgrade -y && \ diff --git a/docker/Dockerfile.synchronizer b/docker/Dockerfile.synchronizer index 3e9866f7..6c8611a7 100644 --- a/docker/Dockerfile.synchronizer +++ b/docker/Dockerfile.synchronizer @@ -18,7 +18,7 @@ RUN bash -c 'if [[ "${FIPS_MODE}" = "enabled" ]]; \ fi' # Runner stage -FROM debian:13 AS runner +FROM debian:trixie-20260623-slim AS runner RUN apt update -y && \ apt upgrade -y && \ diff --git a/splitio/commitversion.go b/splitio/commitversion.go index 02e55e0d..e76d280c 100644 --- a/splitio/commitversion.go +++ b/splitio/commitversion.go @@ -5,4 +5,4 @@ This file is created automatically, please do not edit */ // CommitVersion is the version of the last commit previous to release -const CommitVersion = "aeef5f7" +const CommitVersion = "602b2c6" diff --git a/splitio/proxy/storage/rulebasedsegments.go b/splitio/proxy/storage/rulebasedsegments.go index 81c985e6..87820e17 100644 --- a/splitio/proxy/storage/rulebasedsegments.go +++ b/splitio/proxy/storage/rulebasedsegments.go @@ -69,7 +69,11 @@ func snapshotFromDiskRB( ) int64 { all, err := src.FetchAll() if err != nil { - logger.Error("error parsing feature flags from snapshot. No data will be available!: ", err) + if err.Error() == "Bucket not found" { + logger.Warning("Rule-based segments snapshot could not be loaded; proceeding with an empty cache: ", err) + } else { + logger.Error("error parsing rule-based segments from snapshot. No data will be available!: ", err) + } return -1 } diff --git a/splitio/proxy/storage/rulebasedsegments_test.go b/splitio/proxy/storage/rulebasedsegments_test.go index 2104891f..efeb71d4 100644 --- a/splitio/proxy/storage/rulebasedsegments_test.go +++ b/splitio/proxy/storage/rulebasedsegments_test.go @@ -151,3 +151,33 @@ func TestRBSChangesSince(t *testing.T) { } assert.ElementsMatch(t, expectedChanges, changes.RuleBasedSegments) } + +func TestRBSnapshotFromDiskWithBucketNotFoundError(t *testing.T) { + logger := logging.NewLogger(nil) + + dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil) + assert.Nil(t, err) + + rbsStorage := NewProxyRuleBasedSegmentsStorage(dbw, logger, true) + + assert.Empty(t, rbsStorage.All()) + assert.Equal(t, int64(-1), rbsStorage.oldestKnownCN) +} + +func TestRBSnapshotFromDiskWithOtherError(t *testing.T) { + logger := logging.NewLogger(nil) + + dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil) + assert.Nil(t, err) + + disk := persistent.NewRBChangesCollection(dbw, logger) + disk.Update([]dtos.RuleBasedSegmentDTO{ + {Name: "rbs1", ChangeNumber: 10, Status: "ACTIVE", TrafficTypeName: "user"}, + }, nil, 10) + + rbsStorage := NewProxyRuleBasedSegmentsStorage(dbw, logger, true) + + assert.NotEmpty(t, rbsStorage.All()) + assert.Equal(t, int64(10), rbsStorage.oldestKnownCN) +} + diff --git a/splitio/proxy/storage/segments.go b/splitio/proxy/storage/segments.go index 343afd20..f6be00e8 100644 --- a/splitio/proxy/storage/segments.go +++ b/splitio/proxy/storage/segments.go @@ -197,7 +197,12 @@ func populateCachesFromDisk( ) { all, err := src.FetchAll() if err != nil { - logger.Error("error popoulating segment cache from disk. Cache will be empty!: ", err) + if err.Error() == "Bucket not found" { + logger.Warning("Segment cache could not be restored from disk; proceeding with an empty cache: ", err) + } else { + logger.Error("Segment cache could not be restored from disk; proceeding with an empty cache: ", err) + } + return } diff --git a/splitio/proxy/storage/segments_test.go b/splitio/proxy/storage/segments_test.go index fb6d687f..923ccb95 100644 --- a/splitio/proxy/storage/segments_test.go +++ b/splitio/proxy/storage/segments_test.go @@ -114,3 +114,31 @@ func TestSegmentStorageUpdateErrorHandling(t *testing.T) { psm.AssertExpectations(t) }) } + +func TestSegmentSnapshotFromDiskWithBucketNotFoundError(t *testing.T) { + logger := logging.NewLogger(nil) + + dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil) + assert.Nil(t, err) + + segmentStorage := NewProxySegmentStorage(dbw, logger, true) + + namesAndCount := segmentStorage.NamesAndCount() + assert.Empty(t, namesAndCount) +} + +func TestSegmentSnapshotFromDiskWithSuccess(t *testing.T) { + logger := logging.NewLogger(nil) + + dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil) + assert.Nil(t, err) + + disk := persistent.NewSegmentChangesCollection(dbw, logger) + disk.Update("segment1", set.NewSet("key1", "key2"), set.NewSet(), 10) + + segmentStorage := NewProxySegmentStorage(dbw, logger, true) + + namesAndCount := segmentStorage.NamesAndCount() + assert.Contains(t, namesAndCount, "segment1") + assert.Equal(t, 2, namesAndCount["segment1"]) +} diff --git a/splitio/proxy/storage/splits.go b/splitio/proxy/storage/splits.go index 28207bec..b69d80dc 100644 --- a/splitio/proxy/storage/splits.go +++ b/splitio/proxy/storage/splits.go @@ -220,7 +220,11 @@ func snapshotFromDisk( ) int64 { all, err := src.FetchAll() if err != nil { - logger.Error("error parsing feature flags from snapshot. No data will be available!: ", err) + if err.Error() == "Bucket not found" { + logger.Warning("Feature flags snapshot could not be loaded; proceeding without preloaded feature flags: ", err) + } else { + logger.Error("error parsing feature flags from snapshot. No data will be available!: ", err) + } return -1 } diff --git a/splitio/proxy/storage/splits_test.go b/splitio/proxy/storage/splits_test.go index 8b0b3edd..3fbdead5 100644 --- a/splitio/proxy/storage/splits_test.go +++ b/splitio/proxy/storage/splits_test.go @@ -371,3 +371,34 @@ func TestGetAllFlagSetNames(t *testing.T) { t.Errorf("setNames len should be 4. Actual %v", len(setNames)) } } + +func TestSplitSnapshotFromDiskWithBucketNotFoundError(t *testing.T) { + logger := logging.NewLogger(nil) + + dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil) + assert.Nil(t, err) + + splitStorage := NewProxySplitStorage(dbw, logger, flagsets.NewFlagSetFilter(nil), true) + + assert.Empty(t, splitStorage.All()) + assert.Equal(t, int64(-1), splitStorage.oldestKnownCN) +} + +func TestSplitSnapshotFromDiskWithSuccess(t *testing.T) { + logger := logging.NewLogger(nil) + + dbw, err := persistent.NewBoltWrapper(persistent.BoltInMemoryMode, nil) + assert.Nil(t, err) + + disk := persistent.NewSplitChangesCollection(dbw, logger) + splits := []dtos.SplitDTO{ + {Name: "split1", ChangeNumber: 10, Status: "ACTIVE", TrafficTypeName: "user"}, + {Name: "split2", ChangeNumber: 10, Status: "ACTIVE", TrafficTypeName: "user"}, + } + disk.Update(splits, nil, 10) + + splitStorage := NewProxySplitStorage(dbw, logger, flagsets.NewFlagSetFilter(nil), true) + + assert.ElementsMatch(t, splits, splitStorage.All()) + assert.Equal(t, int64(10), splitStorage.oldestKnownCN) +} diff --git a/splitio/version.go b/splitio/version.go index ed9425e8..11a04172 100644 --- a/splitio/version.go +++ b/splitio/version.go @@ -2,4 +2,4 @@ package splitio // Version is the version of this Agent -const Version = "5.12.6" +const Version = "5.12.7"