Use cleanhttp.PrintablePathCheckHandler to handle non-printable chara… (#3697)

This commit is contained in:
Calvin Leung Huang 2017-12-15 20:19:37 -05:00 committed by Jeff Mitchell
parent 098c66a624
commit d4f17b8f86
5 changed files with 73 additions and 5 deletions

View file

@ -10,6 +10,7 @@ import (
"time"
"github.com/hashicorp/errwrap"
cleanhttp "github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/vault/helper/consts"
"github.com/hashicorp/vault/helper/jsonutil"
"github.com/hashicorp/vault/helper/parseutil"
@ -90,7 +91,11 @@ func Handler(core *vault.Core) http.Handler {
// handler
genericWrappedHandler := wrapGenericHandler(corsWrappedHandler)
return genericWrappedHandler
// Wrap the handler with PrintablePathCheckHandler to check for non-printable
// characters in the request path.
printablePathCheckHandler := cleanhttp.PrintablePathCheckHandler(genericWrappedHandler, nil)
return printablePathCheckHandler
}
// wrapGenericHandler wraps the handler with an extra layer of handler where

View file

@ -378,5 +378,24 @@ func TestHandler_error(t *testing.T) {
if w3.Code != 503 {
t.Fatalf("expected 503, got %d", w3.Code)
}
}
func TestHandler_nonPrintableChars(t *testing.T) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
defer ln.Close()
req, err := http.NewRequest("GET", addr+"/v1/sys/mounts\n", nil)
if err != nil {
t.Fatalf("err: %s", err)
}
req.Header.Set(AuthHeaderName, token)
client := cleanhttp.DefaultClient()
resp, err := client.Do(req)
if err != nil {
t.Fatalf("err: %s", err)
}
testResponseStatus(t, resp, 400)
}

View file

@ -26,6 +26,7 @@ func DefaultPooledTransport() *http.Transport {
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
DualStack: true,
}).DialContext,
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,

43
vendor/github.com/hashicorp/go-cleanhttp/handlers.go generated vendored Normal file
View file

@ -0,0 +1,43 @@
package cleanhttp
import (
"net/http"
"strings"
"unicode"
)
// HandlerInput provides input options to cleanhttp's handlers
type HandlerInput struct {
ErrStatus int
}
// PrintablePathCheckHandler is a middleware that ensures the request path
// contains only printable runes.
func PrintablePathCheckHandler(next http.Handler, input *HandlerInput) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Nil-check on input to make it optional
if input == nil {
input = &HandlerInput{
ErrStatus: http.StatusBadRequest,
}
}
// Default to http.StatusBadRequest on error
if input.ErrStatus == 0 {
input.ErrStatus = http.StatusBadRequest
}
// Check URL path for non-printable characters
idx := strings.IndexFunc(r.URL.Path, func(c rune) bool {
return !unicode.IsPrint(c)
})
if idx != -1 {
w.WriteHeader(input.ErrStatus)
return
}
next.ServeHTTP(w, r)
return
})
}

6
vendor/vendor.json vendored
View file

@ -985,10 +985,10 @@
"revisionTime": "2014-10-28T05:47:10Z"
},
{
"checksumSHA1": "b8F628srIitj5p7Y130xc9k0QWs=",
"checksumSHA1": "b3Y4wgMvMco62K4DfX0Sdoug4+k=",
"path": "github.com/hashicorp/go-cleanhttp",
"revision": "3573b8b52aa7b37b9358d966a898feb387f62437",
"revisionTime": "2017-02-11T01:34:15Z"
"revision": "33f138d01ac027decb9a5bd76ad6e7c7c701b0c4",
"revisionTime": "2017-12-16T01:18:02Z"
},
{
"checksumSHA1": "AA0aYmdg4pb5gPCUSXg8iPzxLag=",