Skip to content
Permalink
Browse files Browse the repository at this point in the history
[release-1.13] pilot: limit reads from untrusted inputs (#37792)
* pilot: limit reads from untrusted inputs

* revert jwks

Co-authored-by: John Howard <howardjohn@google.com>
  • Loading branch information
istio-testing and howardjohn committed Mar 8, 2022
1 parent ba2b674 commit 6ca5055
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
6 changes: 4 additions & 2 deletions pkg/kube/inject/webhook.go
Expand Up @@ -19,7 +19,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"os"
"strconv"
Expand Down Expand Up @@ -827,8 +826,11 @@ func (wh *Webhook) serveInject(w http.ResponseWriter, r *http.Request) {
totalInjections.Increment()
var body []byte
if r.Body != nil {
if data, err := io.ReadAll(r.Body); err == nil {
if data, err := kube.HTTPConfigReader(r); err == nil {
body = data
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
if len(body) == 0 {
Expand Down
26 changes: 26 additions & 0 deletions pkg/kube/util.go
Expand Up @@ -16,12 +16,15 @@ package kube

import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"

kubeApiCore "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
Expand Down Expand Up @@ -265,3 +268,26 @@ func GetDeployMetaFromPod(pod *kubeApiCore.Pod) (metav1.ObjectMeta, metav1.TypeM

return deployMeta, typeMetadata
}

// MaxRequestBodyBytes represents the max size of Kubernetes objects we read. Kubernetes allows a 2x
// buffer on the max etcd size
// (https://github.com/kubernetes/kubernetes/blob/0afa569499d480df4977568454a50790891860f5/staging/src/k8s.io/apiserver/pkg/server/config.go#L362).
// We allow an additional 2x buffer, as it is still fairly cheap (6mb)
const MaxRequestBodyBytes = int64(6 * 1024 * 1024)

// HTTPConfigReader is reads an HTTP request, imposing size restrictions aligned with Kubernetes limits
func HTTPConfigReader(req *http.Request) ([]byte, error) {
defer req.Body.Close()
lr := &io.LimitedReader{
R: req.Body,
N: MaxRequestBodyBytes + 1,
}
data, err := io.ReadAll(lr)
if err != nil {
return nil, err
}
if lr.N <= 0 {
return nil, errors.NewRequestEntityTooLargeError(fmt.Sprintf("limit is %d", MaxRequestBodyBytes))
}
return data, nil
}
6 changes: 4 additions & 2 deletions pkg/webhooks/validation/server/server.go
Expand Up @@ -19,7 +19,6 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"

multierror "github.com/hashicorp/go-multierror"
Expand Down Expand Up @@ -131,8 +130,11 @@ type admitFunc func(*kube.AdmissionRequest) *kube.AdmissionResponse
func serve(w http.ResponseWriter, r *http.Request, admit admitFunc) {
var body []byte
if r.Body != nil {
if data, err := io.ReadAll(r.Body); err == nil {
if data, err := kube.HTTPConfigReader(r); err == nil {
body = data
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
if len(body) == 0 {
Expand Down

0 comments on commit 6ca5055

Please sign in to comment.