server: disable redirects in peer communication
Disable following redirects from peer HTTP communication on the client's side. Etcd server may run into SSRF (Server-side request forgery) when adding a new member. If users provide a malicious peer URL, the existing etcd members may be redirected to another unexpected internal URL when getting the new member's version. Signed-off-by: Ivan Valdes <ivan@vald.es>
This commit is contained in:
parent
39b440caed
commit
838cd9aa00
@ -66,6 +66,9 @@ func getClusterFromRemotePeers(lg *zap.Logger, urls []string, timeout time.Durat
|
||||
cc := &http.Client{
|
||||
Transport: rt,
|
||||
Timeout: timeout,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
for _, u := range urls {
|
||||
addr := u + "/members"
|
||||
@ -301,6 +304,9 @@ func isCompatibleWithVers(lg *zap.Logger, vers map[string]*version.Versions, loc
|
||||
func getVersion(lg *zap.Logger, m *membership.Member, rt http.RoundTripper) (*version.Versions, error) {
|
||||
cc := &http.Client{
|
||||
Transport: rt,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
var (
|
||||
err error
|
||||
@ -359,7 +365,12 @@ func getVersion(lg *zap.Logger, m *membership.Member, rt http.RoundTripper) (*ve
|
||||
}
|
||||
|
||||
func promoteMemberHTTP(ctx context.Context, url string, id uint64, peerRt http.RoundTripper) ([]*membership.Member, error) {
|
||||
cc := &http.Client{Transport: peerRt}
|
||||
cc := &http.Client{
|
||||
Transport: peerRt,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
// TODO: refactor member http handler code
|
||||
// cannot import etcdhttp, so manually construct url
|
||||
requestUrl := url + "/members/promote/" + fmt.Sprintf("%d", id)
|
||||
|
@ -497,7 +497,12 @@ func (h *hashKVHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// getPeerHashKVHTTP fetch hash of kv store at the given rev via http call to the given url
|
||||
func (s *EtcdServer) getPeerHashKVHTTP(ctx context.Context, cid types.ID, url string, rev int64) (*pb.HashKVResponse, error) {
|
||||
cc := &http.Client{Transport: s.peerRt}
|
||||
cc := &http.Client{
|
||||
Transport: s.peerRt,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
hashReq := &pb.HashKVRequest{Revision: rev}
|
||||
hashReqBytes, err := json.Marshal(hashReq)
|
||||
if err != nil {
|
||||
|
@ -150,7 +150,12 @@ func RenewHTTP(ctx context.Context, id lease.LeaseID, url string, rt http.RoundT
|
||||
return -1, err
|
||||
}
|
||||
|
||||
cc := &http.Client{Transport: rt}
|
||||
cc := &http.Client{
|
||||
Transport: rt,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
req, err := http.NewRequest("POST", url, bytes.NewReader(lreq))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
@ -210,7 +215,12 @@ func TimeToLiveHTTP(ctx context.Context, id lease.LeaseID, keys bool, url string
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
cc := &http.Client{Transport: rt}
|
||||
cc := &http.Client{
|
||||
Transport: rt,
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
var b []byte
|
||||
// buffer errc channel so that errc don't block inside the go routinue
|
||||
resp, err := cc.Do(req)
|
||||
|
Loading…
Reference in New Issue
Block a user