http: limit maximum request size
This commit is contained in:
parent
aac4f894c9
commit
c8dadb46ec
|
@ -26,6 +26,11 @@ const (
|
|||
// NoRequestForwardingHeaderName is the name of the header telling Vault
|
||||
// not to use request forwarding
|
||||
NoRequestForwardingHeaderName = "X-Vault-No-Request-Forwarding"
|
||||
|
||||
// MaxRequestSize is the maximum accepted request size. This is to prevent
|
||||
// a denial of service attack where no Content-Length is provided and the server
|
||||
// is fed ever more data until it exhausts memory.
|
||||
MaxRequestSize = 8 * 1024 * 1024
|
||||
)
|
||||
|
||||
// Handler returns an http.Handler for the API. This can be used on
|
||||
|
@ -109,7 +114,10 @@ func stripPrefix(prefix, path string) (string, bool) {
|
|||
}
|
||||
|
||||
func parseRequest(r *http.Request, out interface{}) error {
|
||||
err := jsonutil.DecodeJSONFromReader(r.Body, out)
|
||||
// Limit the maximum number of bytes to MaxRequestSize to protect
|
||||
// against an indefinite amount of data being read.
|
||||
limit := &io.LimitedReader{R: r.Body, N: MaxRequestSize}
|
||||
err := jsonutil.DecodeJSONFromReader(limit, out)
|
||||
if err != nil && err != io.EOF {
|
||||
return fmt.Errorf("Failed to parse JSON input: %s", err)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,11 @@ func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Reques
|
|||
return nil, http.StatusNotFound, nil
|
||||
}
|
||||
|
||||
// Verify the content length does not exceed the maximum size
|
||||
if r.ContentLength >= MaxRequestSize {
|
||||
return nil, http.StatusRequestEntityTooLarge, nil
|
||||
}
|
||||
|
||||
// Determine the operation
|
||||
var op logical.Operation
|
||||
switch r.Method {
|
||||
|
|
|
@ -231,3 +231,16 @@ func TestLogical_RawHTTP(t *testing.T) {
|
|||
t.Fatalf("Bad: %s", body.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogical_RequestSizeLimit(t *testing.T) {
|
||||
core, _, token := vault.TestCoreUnsealed(t)
|
||||
ln, addr := TestServer(t, core)
|
||||
defer ln.Close()
|
||||
TestServerAuth(t, addr, token)
|
||||
|
||||
// Write a very large object, should fail
|
||||
resp := testHttpPut(t, token, addr+"/v1/secret/foo", map[string]interface{}{
|
||||
"data": make([]byte, MaxRequestSize),
|
||||
})
|
||||
testResponseStatus(t, resp, 413)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue