Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Jul 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 13 additions & 5 deletions command/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"`
Expand Down Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
21 changes: 18 additions & 3 deletions http/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}
}
17 changes: 12 additions & 5 deletions http/testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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)
Expand Down
5 changes: 3 additions & 2 deletions vault/request_handling.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down