From ae369037cc75150edef7fbb7799933b48fcc1183 Mon Sep 17 00:00:00 2001 From: Michael Tibben Date: Thu, 7 May 2020 15:10:55 +1000 Subject: [PATCH] Check the host header to mitigate a DNS rebinding attack --- server/server.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/server/server.go b/server/server.go index 40d23416d..a4736c74c 100644 --- a/server/server.go +++ b/server/server.go @@ -13,6 +13,7 @@ import ( ) const ( + metadataIP = "169.254.169.254" metadataBind = "169.254.169.254:80" awsTimeFormat = "2006-01-02T15:04:05Z" localServerURL = "http://127.0.0.1:9099" @@ -50,7 +51,13 @@ func indexHandler(w http.ResponseWriter, r *http.Request) { } func credentialsHandler(w http.ResponseWriter, r *http.Request) { - resp, err := http.Get(localServerURL) + req, err := http.NewRequest("GET", localServerURL, nil) + if err != nil { + log.Fatal(err) + } + req.Host = r.Host // pass through the host so we can check for the DNS rebinding attack + + resp, err := http.DefaultClient.Do(req) if err != nil { http.Error(w, err.Error(), http.StatusGatewayTimeout) return @@ -109,6 +116,14 @@ func credsHandler(creds *credentials.Credentials) http.HandlerFunc { return } + // Check that the request is to 169.254.169.254 + // Without this it's possible for an attacker to mount a DNS rebinding attack + // See https://github.com/99designs/aws-vault/issues/578 + if r.Host != metadataIP { + http.Error(w, fmt.Sprintf("Access denied for host '%s'", r.Host), http.StatusUnauthorized) + return + } + log.Printf("RemoteAddr = %v", r.RemoteAddr) log.Printf("Credentials.IsExpired() = %#v", creds.IsExpired())