Skip to content

Commit 99d6799

Browse files
ItalyPaleAleartursouza
authored andcommitted
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 <[email protected]>
1 parent 4ab981b commit 99d6799

File tree

4 files changed

+43
-32
lines changed

4 files changed

+43
-32
lines changed

docs/release_notes/v1.10.9.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,28 @@
22

33
This update contains security fixes:
44

5-
- [Security: Potential DoS in avro dependency (CVE-2023-37475)](#security-potential-dos-in-avro-dependency-cve-2023-37475)
5+
- [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))
6+
- [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))
7+
8+
## Security: API token authentication bypass in HTTP endpoints
9+
10+
### Problem
11+
12+
[Security advisory](https://github.com/dapr/dapr/security/advisories/GHSA-59m6-82qm-vqgj)
13+
14+
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.
15+
16+
### Impact
17+
18+
The vulnerability impacts all users on Dapr <=1.10.9 and <=1.11.2 who are using API token authentication.
19+
20+
### Root cause
21+
22+
The Dapr sidecar allowed all requests containing `/healthz` in the URL (including query string) to bypass API token authentication.
23+
24+
### Solution
25+
26+
We have changed the API token authentication middleware to allow bypassing the authentication only for healthcheck endpoints more strictly.
627

728
## Security: Potential DoS in avro dependency (CVE-2023-37475)
829

pkg/http/server.go

+21-4
Original file line numberDiff line numberDiff line change
@@ -287,12 +287,29 @@ func useAPIAuthentication(next fasthttp.RequestHandler) fasthttp.RequestHandler
287287

288288
return func(ctx *fasthttp.RequestCtx) {
289289
v := ctx.Request.Header.Peek(authConsts.APITokenHeader)
290-
if auth.ExcludedRoute(string(ctx.Request.URI().FullURI())) || string(v) == token {
291-
ctx.Request.Header.Del(authConsts.APITokenHeader)
292-
next(ctx)
293-
} else {
290+
if string(v) != token && !isRouteExcludedFromAPITokenAuth(string(ctx.Request.Header.Method()), string(ctx.Request.URI().FullURI())) {
294291
ctx.Error("invalid api token", http.StatusUnauthorized)
292+
return
295293
}
294+
295+
ctx.Request.Header.Del(authConsts.APITokenHeader)
296+
next(ctx)
297+
}
298+
}
299+
300+
func isRouteExcludedFromAPITokenAuth(method string, urlString string) bool {
301+
u, err := url.Parse(urlString)
302+
if err != nil {
303+
return false
304+
}
305+
path := strings.Trim(u.Path, "/")
306+
switch path {
307+
case apiVersionV1 + "/healthz":
308+
return method == http.MethodGet
309+
case apiVersionV1 + "/healthz/outbound":
310+
return method == http.MethodGet
311+
default:
312+
return false
296313
}
297314
}
298315

pkg/runtime/security/token.go

-13
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,10 @@ package security
1515

1616
import (
1717
"os"
18-
"strings"
1918

2019
"github.com/dapr/dapr/pkg/runtime/security/consts"
2120
)
2221

23-
var excludedRoutes = []string{"/healthz"}
24-
2522
// GetAPIToken returns the value of the api token from an environment variable.
2623
func GetAPIToken() string {
2724
return os.Getenv(consts.APITokenEnvVar)
@@ -31,13 +28,3 @@ func GetAPIToken() string {
3128
func GetAppToken() string {
3229
return os.Getenv(consts.AppAPITokenEnvVar)
3330
}
34-
35-
// ExcludedRoute returns whether a given route should be excluded from a token check.
36-
func ExcludedRoute(route string) bool {
37-
for _, r := range excludedRoutes {
38-
if strings.Contains(route, r) {
39-
return true
40-
}
41-
}
42-
return false
43-
}

pkg/runtime/security/token_test.go

-14
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,3 @@ func TestAppToken(t *testing.T) {
5454
assert.Equal(t, "", token)
5555
})
5656
}
57-
58-
func TestExcludedRoute(t *testing.T) {
59-
t.Run("healthz route is excluded", func(t *testing.T) {
60-
route := "v1.0/healthz"
61-
excluded := ExcludedRoute(route)
62-
assert.True(t, excluded)
63-
})
64-
65-
t.Run("custom route is not excluded", func(t *testing.T) {
66-
route := "v1.0/state"
67-
excluded := ExcludedRoute(route)
68-
assert.False(t, excluded)
69-
})
70-
}

0 commit comments

Comments
 (0)