CVE-2023-37918: Improper Authentication (CWE-287)
value: Dapr is a portable, event-driven, runtime for building distributed applications across cloud and edge. A vulnerability has been found in Dapr that allows bypassing API token authentication, which is used by the Dapr sidecar to authenticate calls coming from the application, with a well-crafted HTTP request. Users who leverage API token authentication are encouraged to upgrade Dapr to 1.10.9 or to 1.11.2. This vulnerability impacts Dapr users who have configured API token authentication. An attacker could craft a request that is always allowed by the Dapr sidecar over HTTP, even if the `dapr-api-token` in the request is invalid or missing. The issue has been fixed in Dapr 1.10.9 or to 1.11.2. There are no known workarounds for this vulnerability.

CWE description: When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.
CVSS v3 base score: 7.5
Published: 2023-07-21T21:15Z
Repository: https://github.com/dapr/dapr
Language: Go
Files changed: docs/release_notes/v1.11.2.md, pkg/http/server.go, pkg/runtime/security/token.go, pkg/runtime/security/token_test.go
Commit date: 2023-07-20 15:33:57 -0700
Commit message: Fixed API token authentication bypassed when path contains `/healthz`

The APITokenAuthMiddleware allowed bypassing the check if the path included `/healthz`. An attacker only needed to include `/healthz` in the URL, even the querystring, to bypass the API token check, for example `/v1.0/invoke/myapp/method/something?foo=/healthz`.

Additionally, this was not checking the method of the request, so requests to `POST /healthz` would cause a service invocation to happen.

This fixes the issue by making the check a lot more strict. The API token check can be bypassed only if:

- The path is exactly `/v1.0/healthz` or `/v1.0/healthz/outbound` (slashes are trimmed on each side)
- The method is `GET`

Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>

Diff: diff --git a/docs/release_notes/v1.11.2.md b/docs/release_notes/v1.11.2.md
index fe54bb4a..fdddcd70 100644
--- a/docs/release_notes/v1.11.2.md
+++ b/docs/release_notes/v1.11.2.md
@@ -1,17 +1,38 @@
 # Dapr 1.11.2 [security]
 
 This update contains security fixes:
 
-  - [Security: Potential DoS in avro dependency (CVE-2023-37475)](#security-potential-dos-in-avro-dependency-cve-2023-37475)
+  - [Security: API token authentication bypass in HTTP endpoints](#security-api-token-authentication-bypass-in-http-endpoints) ([Security advisory](https://github.com/dapr/dapr/security/advisories/GHSA-59m6-82qm-vqgj))
+  - [Security: Potential DoS in avro dependency](#security-potential-dos-in-avro-dependency-cve-2023-37475) ([CVE-2023-37475](https://github.com/hamba/avro/security/advisories/GHSA-9x44-9pgq-cf45))
 
 Additionally, this patch release contains bug fixes:
 
   - [Fixed: unbounded history batch save in Workflows](#fixed-unbounded-history-batch-save-in-workflows)
   - [Fixed: Workflows not working in some Kubernetes clusters](#fixed-workflows-not-working-in-some-kubernetes-clusters)
   - [Fixed a number of bugs in the gRPC Configuration Subscribe API](#fixed-a-number-of-bugs-in-the-grpc-configuration-subscribe-api)
 
+## Security: API token authentication bypass in HTTP endpoints
+
+### Problem
+
+[Security advisory](https://github.com/dapr/dapr/security/advisories/GHSA-59m6-82qm-vqgj)
+
+A high-severity vulnerability has been found in Dapr that allows bypassing [API token authentication](https://docs.dapr.io/operations/security/api-token/), which is used by the Dapr sidecar to authenticate calls coming from the application, with a well-crafted HTTP request.
+
+### Impact
+
+The vulnerability impacts all users on Dapr <=1.10.9 and <=1.11.2 who are using API token authentication.
+
+### Root cause
+
+The Dapr sidecar allowed all requests containing `/healthz` in the URL (including query string) to bypass API token authentication.
+
+### Solution
+
+We have changed the API token authentication middleware to allow bypassing the authentication only for healthcheck endpoints more strictly.
+
 ## Security: Potential DoS in avro dependency (CVE-2023-37475)
 
 ### Problem
 
 [CVE-2023-37475](https://github.com/hamba/avro/security/advisories/GHSA-9x44-9pgq-cf45)
diff --git a/pkg/http/server.go b/pkg/http/server.go
index 2a9513dd..d2d0b90a 100644
--- a/pkg/http/server.go
+++ b/pkg/http/server.go
@@ -285,16 +285,33 @@ func useAPIAuthentication(next fasthttp.RequestHandler) fasthttp.RequestHandler
 	}
 	log.Info("enabled token authentication on http server")
 
 	return func(ctx *fasthttp.RequestCtx) {
 		v := ctx.Request.Header.Peek(authConsts.APITokenHeader)
-		if auth.ExcludedRoute(string(ctx.Request.URI().FullURI())) || string(v) == token {
-			ctx.Request.Header.Del(authConsts.APITokenHeader)
-			next(ctx)
-		} else {
+		if string(v) != token && !isRouteExcludedFromAPITokenAuth(string(ctx.Request.Header.Method()), string(ctx.Request.URI().FullURI())) {
 			ctx.Error("invalid api token", http.StatusUnauthorized)
+			return
 		}
+
+		ctx.Request.Header.Del(authConsts.APITokenHeader)
+		next(ctx)
+	}
+}
+
+func isRouteExcludedFromAPITokenAuth(method string, urlString string) bool {
+	u, err := url.Parse(urlString)
+	if err != nil {
+		return false
+	}
+	path := strings.Trim(u.Path, "/")
+	switch path {
+	case apiVersionV1 + "/healthz":
+		return method == http.MethodGet
+	case apiVersionV1 + "/healthz/outbound":
+		return method == http.MethodGet
+	default:
+		return false
 	}
 }
 
 func (s *server) getCorsHandler(allowedOrigins []string) *cors.CorsHandler {
 	return cors.NewCorsHandler(cors.Options{
diff --git a/pkg/runtime/security/token.go b/pkg/runtime/security/token.go
index b93860ff..e12bfb5d 100644
--- a/pkg/runtime/security/token.go
+++ b/pkg/runtime/security/token.go
@@ -13,31 +13,18 @@ limitations under the License.
 
 package security
 
 import (
 	"os"
-	"strings"
 
 	"github.com/dapr/dapr/pkg/runtime/security/consts"
 )
 
-var excludedRoutes = []string{"/healthz"}
-
 // GetAPIToken returns the value of the api token from an environment variable.
 func GetAPIToken() string {
 	return os.Getenv(consts.APITokenEnvVar)
 }
 
 // GetAppToken returns the value of the app api token from an environment variable.
 func GetAppToken() string {
 	return os.Getenv(consts.AppAPITokenEnvVar)
 }
-
-// ExcludedRoute returns whether a given route should be excluded from a token check.
-func ExcludedRoute(route string) bool {
-	for _, r := range excludedRoutes {
-		if strings.Contains(route, r) {
-			return true
-		}
-	}
-	return false
-}
diff --git a/pkg/runtime/security/token_test.go b/pkg/runtime/security/token_test.go
index 52d81632..16bdde92 100644
--- a/pkg/runtime/security/token_test.go
+++ b/pkg/runtime/security/token_test.go
@@ -52,19 +52,5 @@ func TestAppToken(t *testing.T) {
 	t.Run("non-existent token", func(t *testing.T) {
 		token := GetAppToken()
 		assert.Equal(t, "", token)
 	})
 }
-
-func TestExcludedRoute(t *testing.T) {
-	t.Run("healthz route is excluded", func(t *testing.T) {
-		route := "v1.0/healthz"
-		excluded := ExcludedRoute(route)
-		assert.True(t, excluded)
-	})
-
-	t.Run("custom route is not excluded", func(t *testing.T) {
-		route := "v1.0/state"
-		excluded := ExcludedRoute(route)
-		assert.False(t, excluded)
-	})
-}

Vulnerable code:   - [Security: Potential DoS in avro dependency (CVE-2023-37475)](#security-potential-dos-in-avro-dependency-cve-2023-37475)
		if auth.ExcludedRoute(string(ctx.Request.URI().FullURI())) || string(v) == token {
			ctx.Request.Header.Del(authConsts.APITokenHeader)
			next(ctx)
		} else {
	"strings"
var excludedRoutes = []string{"/healthz"}


// ExcludedRoute returns whether a given route should be excluded from a token check.
func ExcludedRoute(route string) bool {
	for _, r := range excludedRoutes {
		if strings.Contains(route, r) {
			return true
		}
	}
	return false
}

func TestExcludedRoute(t *testing.T) {
	t.Run("healthz route is excluded", func(t *testing.T) {
		route := "v1.0/healthz"
		excluded := ExcludedRoute(route)
		assert.True(t, excluded)
	})

	t.Run("custom route is not excluded", func(t *testing.T) {
		route := "v1.0/state"
		excluded := ExcludedRoute(route)
		assert.False(t, excluded)
	})
}
Fixed code:   - [Security: API token authentication bypass in HTTP endpoints](#security-api-token-authentication-bypass-in-http-endpoints) ([Security advisory](https://github.com/dapr/dapr/security/advisories/GHSA-59m6-82qm-vqgj))
  - [Security: Potential DoS in avro dependency](#security-potential-dos-in-avro-dependency-cve-2023-37475) ([CVE-2023-37475](https://github.com/hamba/avro/security/advisories/GHSA-9x44-9pgq-cf45))
## Security: API token authentication bypass in HTTP endpoints

### Problem

[Security advisory](https://github.com/dapr/dapr/security/advisories/GHSA-59m6-82qm-vqgj)

A high-severity vulnerability has been found in Dapr that allows bypassing [API token authentication](https://docs.dapr.io/operations/security/api-token/), which is used by the Dapr sidecar to authenticate calls coming from the application, with a well-crafted HTTP request.

### Impact

The vulnerability impacts all users on Dapr <=1.10.9 and <=1.11.2 who are using API token authentication.

### Root cause

The Dapr sidecar allowed all requests containing `/healthz` in the URL (including query string) to bypass API token authentication.

### Solution

We have changed the API token authentication middleware to allow bypassing the authentication only for healthcheck endpoints more strictly.

		if string(v) != token && !isRouteExcludedFromAPITokenAuth(string(ctx.Request.Header.Method()), string(ctx.Request.URI().FullURI())) {
			return

		ctx.Request.Header.Del(authConsts.APITokenHeader)
		next(ctx)
	}
}

func isRouteExcludedFromAPITokenAuth(method string, urlString string) bool {
	u, err := url.Parse(urlString)
	if err != nil {
		return false
	}
	path := strings.Trim(u.Path, "/")
	switch path {
	case apiVersionV1 + "/healthz":
		return method == http.MethodGet
	case apiVersionV1 + "/healthz/outbound":
		return method == http.MethodGet
	default:
		return false