Add config flag to disable non-printable character check (#4917)

This commit is contained in:
Jeff Mitchell 2018-07-12 16:29:36 -04:00 committed by GitHub
parent 4c55d2843a
commit fc59d1e4e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 18 deletions

View File

@ -944,8 +944,9 @@ CLUSTER_SYNTHESIS_COMPLETE:
// Initialize the HTTP servers
for _, ln := range lns {
handler := vaulthttp.Handler(&vault.HandlerProperties{
Core: core,
MaxRequestSize: ln.maxRequestSize,
Core: core,
MaxRequestSize: ln.maxRequestSize,
DisablePrintableCheck: config.DisablePrintableCheck,
})
// We perform validation on the config earlier, we can just cast here

View File

@ -28,11 +28,13 @@ type Config struct {
Seal *Seal `hcl:"-"`
CacheSize int `hcl:"cache_size"`
DisableCache bool `hcl:"-"`
DisableCacheRaw interface{} `hcl:"disable_cache"`
DisableMlock bool `hcl:"-"`
DisableMlockRaw interface{} `hcl:"disable_mlock"`
CacheSize int `hcl:"cache_size"`
DisableCache bool `hcl:"-"`
DisableCacheRaw interface{} `hcl:"disable_cache"`
DisableMlock bool `hcl:"-"`
DisableMlockRaw interface{} `hcl:"disable_mlock"`
DisablePrintableCheck bool `hcl:"-"`
DisablePrintableCheckRaw interface{} `hcl:"disable_printable_check"`
EnableUI bool `hcl:"-"`
EnableUIRaw interface{} `hcl:"ui"`
@ -391,6 +393,12 @@ func ParseConfig(d string, logger log.Logger) (*Config, error) {
}
}
if result.DisablePrintableCheckRaw != nil {
if result.DisablePrintableCheck, err = parseutil.ParseBool(result.DisablePrintableCheckRaw); err != nil {
return nil, err
}
}
if result.EnableRawEndpointRaw != nil {
if result.EnableRawEndpoint, err = parseutil.ParseBool(result.EnableRawEndpointRaw); err != nil {
return nil, err

View File

@ -117,7 +117,10 @@ func Handler(props *vault.HandlerProperties) http.Handler {
// Wrap the handler with PrintablePathCheckHandler to check for non-printable
// characters in the request path.
printablePathCheckHandler := cleanhttp.PrintablePathCheckHandler(genericWrappedHandler, nil)
printablePathCheckHandler := genericWrappedHandler
if !props.DisablePrintableCheck {
printablePathCheckHandler = cleanhttp.PrintablePathCheckHandler(genericWrappedHandler, nil)
}
return printablePathCheckHandler
}

View File

@ -410,11 +410,22 @@ func TestHandler_error(t *testing.T) {
}
func TestHandler_nonPrintableChars(t *testing.T) {
testNonPrintable(t, false)
testNonPrintable(t, true)
}
func testNonPrintable(t *testing.T, disable bool) {
core, _, token := vault.TestCoreUnsealed(t)
ln, addr := TestServer(t, core)
ln, addr := TestListener(t)
props := &vault.HandlerProperties{
Core: core,
MaxRequestSize: DefaultMaxRequestSize,
DisablePrintableCheck: disable,
}
TestServerWithListenerAndProperties(t, ln, addr, core, props)
defer ln.Close()
req, err := http.NewRequest("GET", addr+"/v1/sys/mounts\n", nil)
req, err := http.NewRequest("PUT", addr+"/v1/cubbyhole/foo\u2028bar", strings.NewReader(`{"zip": "zap"}`))
if err != nil {
t.Fatalf("err: %s", err)
}
@ -426,5 +437,9 @@ func TestHandler_nonPrintableChars(t *testing.T) {
t.Fatalf("err: %s", err)
}
testResponseStatus(t, resp, 400)
if disable {
testResponseStatus(t, resp, 204)
} else {
testResponseStatus(t, resp, 400)
}
}

View File

@ -25,15 +25,12 @@ func TestListener(tb testing.TB) (net.Listener, string) {
return ln, addr
}
func TestServerWithListener(tb testing.TB, ln net.Listener, addr string, core *vault.Core) {
func TestServerWithListenerAndProperties(tb testing.TB, ln net.Listener, addr string, core *vault.Core, props *vault.HandlerProperties) {
// Create a muxer to handle our requests so that we can authenticate
// for tests.
mux := http.NewServeMux()
mux.Handle("/_test/auth", http.HandlerFunc(testHandleAuth))
mux.Handle("/", Handler(&vault.HandlerProperties{
Core: core,
MaxRequestSize: DefaultMaxRequestSize,
}))
mux.Handle("/", Handler(props))
server := &http.Server{
Addr: ln.Addr().String(),
@ -42,6 +39,16 @@ func TestServerWithListener(tb testing.TB, ln net.Listener, addr string, core *v
go server.Serve(ln)
}
func TestServerWithListener(tb testing.TB, ln net.Listener, addr string, core *vault.Core) {
// Create a muxer to handle our requests so that we can authenticate
// for tests.
props := &vault.HandlerProperties{
Core: core,
MaxRequestSize: DefaultMaxRequestSize,
}
TestServerWithListenerAndProperties(tb, ln, addr, core, props)
}
func TestServer(tb testing.TB, core *vault.Core) (net.Listener, string) {
ln, addr := TestListener(tb)
TestServerWithListener(tb, ln, addr, core)

View File

@ -29,8 +29,9 @@ const (
// HanlderProperties is used to seed configuration into a vaulthttp.Handler.
// It's in this package to avoid a circular dependency
type HandlerProperties struct {
Core *Core
MaxRequestSize int64
Core *Core
MaxRequestSize int64
DisablePrintableCheck bool
}
// fetchEntityAndDerivedPolicies returns the entity object for the given entity