CVE-2022-23538 (published 2023-01-17T21:15Z)

github.com/sylabs/scs-library-client is the Go client for the Singularity Container Services (SCS) Container Library Service. When the scs-library-client is used to pull a container image, with authentication, the HTTP Authorization header sent by the client to the library service may be incorrectly leaked to an S3 backing storage provider. This occurs in a specific flow, where the library service redirects the client to a backing S3 storage server, to perform a multi-part concurrent download. Depending on site configuration, the S3 service may be provided by a third party. An attacker with access to the S3 service may be able to extract user credentials, allowing them to impersonate the user. The vulnerable multi-part concurrent download flow, with redirect to S3, is only used when communicating with a Singularity Enterprise 1.x installation, or third party server implementing this flow. Interaction with Singularity Enterprise 2.x, and Singularity Container Services (cloud.sylabs.io), does not trigger the vulnerable flow. We encourage all users to update. Users who interact with a Singularity Enterprise 1.x installation, using a 3rd party S3 storage service, are advised to revoke and recreate their authentication tokens within Singularity Enterprise. There is no workaround available at this time.

CVSS v3 base score: 7.6, HIGH (CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:L/A:N)

Weakness information:
cwe_id: CWE-522
cwe_name: Insufficiently Protected Credentials
description: The product transmits or stores authentication credentials, but it uses an insecure method that is susceptible to unauthorized interception and/or retrieval.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/sylabs/scs-library-client
commit_details: repo_url: https://github.com/sylabs/scs-library-client
author: Dave Trudgian
author_date: 2023-01-17 11:50:52+00:00
msg: Merge pull request from GHSA-7p8m-22h4-9pj7

Add Authorization header when applicable
repository: repo_url: https://github.com/sylabs/scs-library-client
repo_name: sylabs/scs-library-client
description: Go client for the Singularity Container Services (SCS) Container Library Service
repo_language: Go
owner: sylabs
repo_url: https://github.com/sylabs/scs-library-client
commit_details: repo_url: https://github.com/sylabs/scs-library-client
author: Mike Frisch
author_date: 2023-01-06 09:47:09-05:00
msg: fix: omit credentials for redirected URLs
repository: repo_url: https://github.com/sylabs/scs-library-client
repo_name: sylabs/scs-library-client
description: Go client for the Singularity Container Services (SCS) Container Library Service
repo_language: Go
owner: sylabs
file_changes: filename: pull.go
change_type: ModificationType.MODIFY
diff: @@ -236,13 +236,28 @@ func (c *Client) legacyDownloadImage(ctx context.Context, arch, name, tag string
 		return err
 	}
 
+	redirectURL, err := url.Parse(res.Header.Get("Location"))
+	if err != nil {
+		return err
+	}
+
 	var creds credentials
-	if c.AuthToken != "" {
+	if c.AuthToken != "" && samehost(c.BaseURL, redirectURL) {
+		// Only include credentials if redirected to same host as base URL
 		creds = bearerTokenCredentials{authToken: c.AuthToken}
 	}
 
-	// Use uri from Location header to download artifact
-	return c.multipartDownload(ctx, res.Header.Get("Location"), creds, dst, img.Size, spec, pb)
+	// Use redirect URL to download artifact
+	return c.multipartDownload(ctx, redirectURL.String(), creds, dst, img.Size, spec, pb)
+}
+
+// samehost returns true if host1 and host2 are, in fact, the same host by
+// comparing scheme (https == https) and host, including port.
+//
+// Hosts will be treated as dissimilar if one host includes domain suffix
+// and the other does not, even if the host names match.
+func samehost(host1, host2 *url.URL) bool {
+	return strings.EqualFold(host1.Scheme, host2.Scheme) && strings.EqualFold(host1.Host, host2.Host)
 }
 
 func parseContentLengthHeader(val string) (int64, error) {

programming_language: Go