Skip to content
Permalink
Browse files Browse the repository at this point in the history
do not allow filesystem fallback in server download (#15429)
It is possible for anyone with admin access to relatively
to get any content of any random OS location by simply
providing the file with 'mc admin update alias/ /etc/passwd`.

Workaround is to disable 'admin:ServiceUpdate' action. Everyone
is advised to upgrade to this patch.

Thanks to @Alevsk for finding this bug.
  • Loading branch information
harshavardhana committed Jul 29, 2022
1 parent 5e0776e commit bc72e42
Showing 1 changed file with 33 additions and 46 deletions.
79 changes: 33 additions & 46 deletions cmd/update.go
Expand Up @@ -291,63 +291,50 @@ func getUserAgent(mode string) string {
}

func downloadReleaseURL(u *url.URL, timeout time.Duration, mode string) (content string, err error) {
var reader io.ReadCloser
if u.Scheme == "https" || u.Scheme == "http" {
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Message: err.Error(),
StatusCode: http.StatusInternalServerError,
}
req, err := http.NewRequest(http.MethodGet, u.String(), nil)
if err != nil {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Message: err.Error(),
StatusCode: http.StatusInternalServerError,
}
req.Header.Set("User-Agent", getUserAgent(mode))
}
req.Header.Set("User-Agent", getUserAgent(mode))

client := &http.Client{Transport: getUpdateTransport(timeout)}
resp, err := client.Do(req)
if err != nil {
if xnet.IsNetworkOrHostDown(err, false) {
return content, AdminError{
Code: AdminUpdateURLNotReachable,
Message: err.Error(),
StatusCode: http.StatusServiceUnavailable,
}
}
client := &http.Client{Transport: getUpdateTransport(timeout)}
resp, err := client.Do(req)
if err != nil {
if xnet.IsNetworkOrHostDown(err, false) {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Code: AdminUpdateURLNotReachable,
Message: err.Error(),
StatusCode: http.StatusInternalServerError,
StatusCode: http.StatusServiceUnavailable,
}
}
if resp == nil {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Message: fmt.Sprintf("No response from server to download URL %s", u),
StatusCode: http.StatusInternalServerError,
}
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Message: err.Error(),
StatusCode: http.StatusInternalServerError,
}
reader = resp.Body
defer xhttp.DrainBody(resp.Body)

if resp.StatusCode != http.StatusOK {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Message: fmt.Sprintf("Error downloading URL %s. Response: %v", u, resp.Status),
StatusCode: resp.StatusCode,
}
}
if resp == nil {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Message: fmt.Sprintf("No response from server to download URL %s", u),
StatusCode: http.StatusInternalServerError,
}
} else {
reader, err = os.Open(u.Path)
if err != nil {
return content, AdminError{
Code: AdminUpdateURLNotReachable,
Message: err.Error(),
StatusCode: http.StatusServiceUnavailable,
}
}
defer xhttp.DrainBody(resp.Body)

if resp.StatusCode != http.StatusOK {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Message: fmt.Sprintf("Error downloading URL %s. Response: %v", u, resp.Status),
StatusCode: resp.StatusCode,
}
}

contentBytes, err := ioutil.ReadAll(reader)
contentBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return content, AdminError{
Code: AdminUpdateUnexpectedFailure,
Expand Down

0 comments on commit bc72e42

Please sign in to comment.