VYPR
High severityNVD Advisory· Published Feb 22, 2022· Updated Apr 23, 2025

Unauthenticated control plane denial of service attack in Istio

CVE-2022-23635

Description

Istio is an open platform to connect, manage, and secure microservices. In affected versions the Istio control plane, istiod, is vulnerable to a request processing error, allowing a malicious attacker that sends a specially crafted message which results in the control plane crashing. This endpoint is served over TLS port 15012, but does not require any authentication from the attacker. For simple installations, Istiod is typically only reachable from within the cluster, limiting the blast radius. However, for some deployments, especially multicluster topologies, this port is exposed over the public internet. There are no effective workarounds, beyond upgrading. Limiting network access to Istiod to the minimal set of clients can help lessen the scope of the vulnerability to some extent.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
istio.io/istioGo
>= 1.13.0, < 1.13.11.13.1
istio.io/istioGo
>= 1.12.0, < 1.12.41.12.4
istio.io/istioGo
< 1.11.71.11.7

Affected products

1

Patches

1
5f3b5ed958ae

[release-1.13] Harden validation of untrusted inputs (#90) (#96)

https://github.com/istio/istiojacob-delgadoFeb 18, 2022via ghsa
9 files changed · +22 13
  • istio.deps+1 1 modified
    @@ -4,6 +4,6 @@
         "name": "PROXY_REPO_SHA",
         "repoName": "proxy",
         "file": "",
    -    "lastStableSHA": "9335502ad4a84f380d7d5e0f3ba35a088501ef02"
    +    "lastStableSHA": "a971bfa7fddce41c1795fe2ce279735131c08878"
       }
     ]
    
  • pilot/pkg/model/context.go+1 1 modified
    @@ -348,7 +348,7 @@ func (l StringList) MarshalJSON() ([]byte, error) {
     }
     
     func (l *StringList) UnmarshalJSON(data []byte) error {
    -	if len(data) == 0 || string(data) == `""` {
    +	if len(data) < 2 || string(data) == `""` {
     		*l = []string{}
     	} else {
     		*l = strings.Split(string(data[1:len(data)-1]), ",")
    
  • pilot/pkg/model/context_test.go+11 6 modified
    @@ -145,13 +145,15 @@ func TestNodeMetadata(t *testing.T) {
     
     func TestStringList(t *testing.T) {
     	cases := []struct {
    -		in     string
    -		expect model.StringList
    +		in          string
    +		expect      model.StringList
    +		noRoundTrip bool
     	}{
    -		{`"a,b,c"`, []string{"a", "b", "c"}},
    -		{`"a"`, []string{"a"}},
    -		{`""`, []string{}},
    -		{`"123,@#$#,abcdef"`, []string{"123", "@#$#", "abcdef"}},
    +		{in: `"a,b,c"`, expect: []string{"a", "b", "c"}},
    +		{in: `"a"`, expect: []string{"a"}},
    +		{in: `""`, expect: []string{}},
    +		{in: `"123,@#$#,abcdef"`, expect: []string{"123", "@#$#", "abcdef"}},
    +		{in: `1`, expect: []string{}, noRoundTrip: true},
     	}
     	for _, tt := range cases {
     		t.Run(tt.in, func(t *testing.T) {
    @@ -166,6 +168,9 @@ func TestStringList(t *testing.T) {
     			if err != nil {
     				t.Fatal(err)
     			}
    +			if tt.noRoundTrip {
    +				return
    +			}
     			if !reflect.DeepEqual(string(b), tt.in) {
     				t.Fatalf("Expected %v, got %v", tt.in, string(b))
     			}
    
  • pilot/pkg/networking/core/v1alpha3/cluster_builder_test.go+1 1 modified
    @@ -3055,7 +3055,7 @@ func TestApplyDestinationRuleOSCACert(t *testing.T) {
     				t.Errorf("Could not parse destination rule: %v", err)
     			}
     			dr := &networking.DestinationRule{}
    -			err = json.Unmarshal(byteArray, &dr)
    +			err = json.Unmarshal(byteArray, dr)
     			if err != nil {
     				t.Errorf("Could not unmarshal destination rule: %v", err)
     			}
    
  • security/pkg/server/ca/authenticate/oidc.go+1 1 modified
    @@ -92,7 +92,7 @@ func (j *JwtAuthenticator) authenticate(ctx context.Context, bearerToken string)
     		return nil, fmt.Errorf("failed to verify the JWT token (error %v)", err)
     	}
     
    -	sa := &JwtPayload{}
    +	sa := JwtPayload{}
     	// "aud" for trust domain, "sub" has "system:serviceaccount:$namespace:$serviceaccount".
     	// in future trust domain may use another field as a standard is defined.
     	if err := idToken.Claims(&sa); err != nil {
    
  • security/pkg/util/jwtutil.go+1 1 modified
    @@ -112,7 +112,7 @@ func ExtractJwtAud(jwt string) ([]string, bool) {
     		return nil, false
     	}
     
    -	structuredPayload := &jwtPayload{}
    +	structuredPayload := jwtPayload{}
     	err = json.Unmarshal(payloadBytes, &structuredPayload)
     	if err != nil {
     		return nil, false
    
  • security/pkg/util/jwtutil_test.go+4 2 modified
    @@ -133,7 +133,9 @@ func Test3p(t *testing.T) {
     			t.Error("Expecting bound token, detected unbound ", s)
     		}
     	}
    -	if !IsK8SUnbound(firstPartyJwt) {
    -		t.Error("Expecting unbound, detected bound ", firstPartyJwt)
    +	for _, s := range []string{firstPartyJwt, ".bnVsbM."} {
    +		if !IsK8SUnbound(s) {
    +			t.Error("Expecting unbound, detected bound ", s)
    +		}
     	}
     }
    
  • tests/fuzz/testdata/FuzzBNMUnmarshalJSON/4811475191988224+1 0 added
    @@ -0,0 +1 @@
    +{"INSTANCE_IPS":1}
    
  • tests/fuzz/testdata/FuzzJwtUtil/5085913745588224+1 0 added
    @@ -0,0 +1 @@
    +.bnVsbM.
    \ No newline at end of file
    

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

5

News mentions

0

No linked articles in our index yet.