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

Disable forwarding redirect for peer's HTTP communication #16969

Closed
ahrtr opened this issue Nov 20, 2023 · 13 comments · Fixed by #17066
Closed

Disable forwarding redirect for peer's HTTP communication #16969

ahrtr opened this issue Nov 20, 2023 · 13 comments · Fixed by #17066

Comments

@ahrtr
Copy link
Member

ahrtr commented Nov 20, 2023

What would you like to be added?

It's possible that 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 other unexpected internal URL when getting the new member's version,

addr := u + "/version"

We should disable the forwarding redirect for the endpoint /version, as there is no need to support it.

client := &http.Client{
    Transport: rt,
    Timeout:   timeout,
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
        return http.ErrUseLastResponse
    },
}

We should also evaluate all peer's HTTP communication, and disable the redirect as well if needed.

mux.Handle(rafthttp.RaftPrefix, raftHandler)
mux.Handle(rafthttp.RaftPrefix+"/", raftHandler)
mux.Handle(peerMembersPath, peerMembersHandler)
mux.Handle(peerMemberPromotePrefix, peerMemberPromoteHandler)
if leaseHandler != nil {
mux.Handle(leasehttp.LeasePrefix, leaseHandler)
mux.Handle(leasehttp.LeaseInternalPrefix, leaseHandler)
}
if downgradeEnabledHandler != nil {
mux.Handle(etcdserver.DowngradeEnabledPath, downgradeEnabledHandler)
}
if hashKVHandler != nil {
mux.Handle(etcdserver.PeerHashKVPath, hashKVHandler)
}
mux.HandleFunc(versionPath, versionHandler(s, serveVersion))

Why is this needed?

Improve security

@jmhbnz
Copy link
Member

jmhbnz commented Nov 23, 2023

Discussed during sig etcd triage meeting on 23/11/2023. Assigned to @ivanvc to investigate remaining etcd peer http interactions.

@ivanvc
Copy link
Member

ivanvc commented Nov 23, 2023

Happy to help. Can you assign it to me? Thanks

@lavacat
Copy link

lavacat commented Nov 23, 2023

Another area to check out are endpoints from Transport.Hander
https://github.com/etcd-io/etcd/blob/904c0769e9aaf4b676bda8ff2a866e558a40270b/server/etcdserver/api/rafthttp/transport.go#L157C1-L166C12

@ivanvc
Copy link
Member

ivanvc commented Nov 27, 2023

If I understand correctly, we need to update the HTTP client from the following locations:

As for the raft routes, I think they're safe as http.RoundTripper doesn't follow redirects, and the checkPostResponse from raft's utils (https://github.com/etcd-io/etcd/blob/3b37afe/server/etcdserver/api/rafthttp/util.go#L85-L117), doesn't handle redirects, so it shouldn't follow a redirection.

There's also a request in cluster_util.go, to get the cluster from remote peers (https://github.com/etcd-io/etcd/blob/3b37afe/server/etcdserver/cluster_util.go#L72-75). Should we disallow redirections there too?

@jmhbnz
Copy link
Member

jmhbnz commented Nov 28, 2023

Thanks @ivanvc - I can't see how these additional http clients could be abused but I also don't see the harm in just disabling following redirects for them as to the best of my knowledge they should not be needed by etcd.

My vote would go to raising a pull request to update all of these instances to not follow redirects. Perhaps leave it a few days to see if maintainers or other contributors have any different views on it.

@ivanvc
Copy link
Member

ivanvc commented Nov 29, 2023

@ahrtr, @lavacat, any thoughts on this? Else, I'll go ahead and implement as @jmhbnz suggested :)

@ivanvc
Copy link
Member

ivanvc commented Dec 5, 2023

Hey @jmhbnz, I saw you added the backport v3.5 label. Should I cherry-pick my commit and create a new PR targeting the release-3.5 branch?

@jmhbnz
Copy link
Member

jmhbnz commented Dec 5, 2023

Hey @ivanvc - Yes given this was a security concern my view is we should backport this to release-3.5.

Note - the codebase structure can be quite different going back to release-3.5 and particularly release-3.4 so we generally avoid any automated cherry pick and just add a manual commit as normal to complete backports.

I will re-open until we get the backport merged, thanks for your help on this @ivanvc 🙏🏻

@ivanvc
Copy link
Member

ivanvc commented Dec 6, 2023

@jmhbnz I think we can close the ticket now unless we want to backport it to another version.

@jmhbnz
Copy link
Member

jmhbnz commented Dec 7, 2023

Hey @ahrtr do you think we should be trying to backport an update for this to 3.4? It is security related so probably, but defer to you as release manager for the branch.

@ahrtr
Copy link
Member Author

ahrtr commented Dec 8, 2023

Hey @ahrtr do you think we should be trying to backport an update for this to 3.4? It is security related so probably, but defer to you as release manager for the branch.

Yes, please backport the fix to 3.4 as well. Thanks.

@ivanvc
Copy link
Member

ivanvc commented Dec 13, 2023

Yes, please backport the fix to 3.4 as well. Thanks.

Oops I didn't see this before. I will do it.

@ivanvc
Copy link
Member

ivanvc commented Dec 13, 2023

@jmhbnz, I included the change you did to getVersion in my commit: 838cd9a.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

4 participants