Cilium with misconfigured toGroups in policies can lead to unrestricted egress traffic
Description
Cilium is a networking, observability, and security solution with an eBPF-based dataplane. Prior to versions 1.16.17, 1.17.10, and 1.18.4, CiliumNetworkPolicys which use egress.toGroups.aws.securityGroupsIds to reference AWS security group IDs that do not exist or are not attached to any network interface may unintentionally allow broader outbound access than intended by the policy authors. In such cases, the toCIDRset section of the derived policy is not generated, which means outbound traffic may be permitted to more destinations than originally intended. This issue has been patched in versions 1.16.17, 1.17.10, and 1.18.4. There are no workarounds for this issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/cilium/ciliumGo | >= 1.18.0, < 1.18.4 | 1.18.4 |
Ciliumgithub.com/cilium/ciliumGo | >= 1.17.0, < 1.17.10 | 1.17.10 |
github.com/cilium/ciliumGo | < 1.16.17 | 1.16.17 |
Affected products
1Patches
1a385856b59c8policy: fix {to,from}-groups derived policy creation for empty cidr sets
4 files changed · +105 −7
pkg/policy/api/egress.go+3 −3 modified@@ -54,7 +54,7 @@ type EgressCommonRule struct { // initiate connections to 10.2.3.0/24 except from IPs in subnet 10.2.3.0/28. // // +kubebuilder:validation:Optional - ToCIDRSet CIDRRuleSlice `json:"toCIDRSet,omitempty"` + ToCIDRSet CIDRRuleSlice `json:"toCIDRSet,omitzero"` // ToEntities is a list of special entities to which the endpoint subject // to the rule is allowed to initiate connections. Supported entities are @@ -243,7 +243,7 @@ func (e *EgressRule) CreateDerivative(ctx context.Context) (*EgressRule, error) if err != nil { return &EgressRule{}, err } - newRule.ToCIDRSet = append(e.ToCIDRSet, cidrSet...) + newRule.ToCIDRSet = append(newRule.ToCIDRSet, cidrSet...) newRule.ToGroups = nil return newRule, nil } @@ -262,7 +262,7 @@ func (e *EgressDenyRule) CreateDerivative(ctx context.Context) (*EgressDenyRule, if err != nil { return &EgressDenyRule{}, err } - newRule.ToCIDRSet = append(e.ToCIDRSet, cidrSet...) + newRule.ToCIDRSet = append(newRule.ToCIDRSet, cidrSet...) newRule.ToGroups = nil return newRule, nil }
pkg/policy/api/egress_test.go+52 −1 modified@@ -5,6 +5,7 @@ package api import ( "context" + "encoding/json" "fmt" "net/netip" "testing" @@ -102,7 +103,11 @@ func TestCreateDerivativeWithoutErrorAndNoIPs(t *testing.T) { newRule, err := eg.CreateDerivative(context.TODO()) require.NoError(t, err) - require.Equal(t, &EgressRule{}, newRule) + require.Equal(t, &EgressRule{ + EgressCommonRule: EgressCommonRule{ + ToCIDRSet: CIDRRuleSlice{}, + }, + }, newRule) } func TestEgressCommonRuleDeepEqual(t *testing.T) { @@ -220,3 +225,49 @@ func TestEgressCommonRuleDeepEqual(t *testing.T) { }) } } + +func TestEgressCommonRuleMarshalling(t *testing.T) { + testCases := []struct { + name string + in *EgressCommonRule + expected string + }{ + { + name: "ToCIDRSet is nil", + in: &EgressCommonRule{ + ToCIDRSet: nil, + }, + expected: `{}`, + }, + { + name: "ToCIDRSet is empty", + in: &EgressCommonRule{ + ToCIDRSet: []CIDRRule{}, + }, + expected: `{"toCIDRSet":[]}`, + }, + { + name: "ToCIDRSet has CIDR", + in: &EgressCommonRule{ + ToCIDRSet: []CIDRRule{ + { + Cidr: "192.168.1.0/24", + }, + }, + }, + expected: `{"toCIDRSet":[{"cidr":"192.168.1.0/24"}]}`, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + data, err := json.Marshal(tc.in) + require.NoError(t, err) + require.Equal(t, tc.expected, string(data)) + + rule := EgressCommonRule{} + err = json.Unmarshal(data, &rule) + require.NoError(t, err) + require.True(t, tc.in.DeepEqual(&rule)) + }) + } +}
pkg/policy/api/ingress.go+3 −3 modified@@ -55,7 +55,7 @@ type IngressCommonRule struct { // connections from 10.0.0.0/8 except from IPs in subnet 10.96.0.0/12. // // +kubebuilder:validation:Optional - FromCIDRSet CIDRRuleSlice `json:"fromCIDRSet,omitempty"` + FromCIDRSet CIDRRuleSlice `json:"fromCIDRSet,omitzero"` // FromEntities is a list of special entities which the endpoint subject // to the rule is allowed to receive connections from. Supported entities are @@ -225,7 +225,7 @@ func (e *IngressRule) CreateDerivative(ctx context.Context) (*IngressRule, error if err != nil { return &IngressRule{}, err } - newRule.FromCIDRSet = append(e.FromCIDRSet, cidrSet...) + newRule.FromCIDRSet = append(newRule.FromCIDRSet, cidrSet...) newRule.FromGroups = nil return newRule, nil } @@ -244,7 +244,7 @@ func (e *IngressDenyRule) CreateDerivative(ctx context.Context) (*IngressDenyRul if err != nil { return &IngressDenyRule{}, err } - newRule.FromCIDRSet = append(e.FromCIDRSet, cidrSet...) + newRule.FromCIDRSet = append(newRule.FromCIDRSet, cidrSet...) newRule.FromGroups = nil return newRule, nil }
pkg/policy/api/ingress_test.go+47 −0 modified@@ -5,6 +5,7 @@ package api import ( "context" + "encoding/json" "testing" "github.com/stretchr/testify/require" @@ -179,3 +180,49 @@ func TestIngressCommonRuleDeepEqual(t *testing.T) { }) } } + +func TestIngressCommonRuleMarshalling(t *testing.T) { + testCases := []struct { + name string + in *IngressCommonRule + expected string + }{ + { + name: "ToCIDRSet is nil", + in: &IngressCommonRule{ + FromCIDRSet: nil, + }, + expected: `{}`, + }, + { + name: "ToCIDRSet is empty", + in: &IngressCommonRule{ + FromCIDRSet: []CIDRRule{}, + }, + expected: `{"fromCIDRSet":[]}`, + }, + { + name: "ToCIDRSet has CIDR", + in: &IngressCommonRule{ + FromCIDRSet: []CIDRRule{ + { + Cidr: "192.168.1.0/24", + }, + }, + }, + expected: `{"fromCIDRSet":[{"cidr":"192.168.1.0/24"}]}`, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + data, err := json.Marshal(tc.in) + require.NoError(t, err) + require.Equal(t, tc.expected, string(data)) + + rule := IngressCommonRule{} + err = json.Unmarshal(data, &rule) + require.NoError(t, err) + require.True(t, tc.in.DeepEqual(&rule)) + }) + } +}
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-38pp-6gcp-rqvmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-64715ghsaADVISORY
- github.com/cilium/cilium/commit/a385856b59c8289cc7273fa3a3062bbf0ef96c97ghsax_refsource_MISCWEB
- github.com/cilium/cilium/releases/tag/v1.16.17ghsax_refsource_MISCWEB
- github.com/cilium/cilium/releases/tag/v1.17.10ghsax_refsource_MISCWEB
- github.com/cilium/cilium/releases/tag/v1.18.4ghsax_refsource_MISCWEB
- github.com/cilium/cilium/security/advisories/GHSA-38pp-6gcp-rqvmghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.