VYPR
Moderate severityNVD Advisory· Published Jan 17, 2023· Updated Mar 10, 2025

User credentials leaked to third-party service via HTTP redirect in scs-library-client

CVE-2022-23538

Description

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.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

scs-library-client leaks HTTP Authorization header to S3 storage during redirect, allowing credential theft; patched in 1.3.4 and 1.4.2.

Vulnerability

Overview

The scs-library-client, a Go client for the Singularity Container Services (SCS) Container Library Service, contains a vulnerability that can leak the HTTP Authorization header to an S3 backing storage provider [1][4]. This occurs during a specific multi-part concurrent download flow where the library service redirects the client to an S3 server. The Authorization header, which contains user credentials, is inadvertently forwarded to the S3 service [1].

Exploitation

Prerequisites

Exploitation requires that the client communicates with a Singularity Enterprise 1.x installation or a third-party server implementing the same redirect flow [4]. The S3 storage service may be operated by a third party, and an attacker with access to that S3 service can capture the leaked credentials [1][4]. No additional authentication is needed beyond the ability to observe or intercept the S3 traffic.

Impact

An attacker who obtains the leaked credentials can impersonate the affected user, gaining unauthorized access to the container library service and potentially other resources [1][4]. The vulnerability does not affect interactions with Singularity Enterprise 2.x or the cloud.sylabs.io service [4].

Mitigation

Patches are available in scs-library-client versions 1.3.4 and 1.4.2 [4]. Users are strongly encouraged to update and, if they interact with a Singularity Enterprise 1.x installation using a third-party S3 service, to revoke and recreate their authentication tokens within Singularity Enterprise [4]. No workaround exists for the vulnerable flow [4].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/sylabs/scs-library-clientGo
>= 1.4.0, < 1.4.21.4.2
github.com/sylabs/scs-library-clientGo
< 1.3.41.3.4

Affected products

4

Patches

3
b5db2aacba6b

Merge pull request from GHSA-7p8m-22h4-9pj7

https://github.com/sylabs/scs-library-clientDave TrudgianJan 17, 2023via ghsa
1 file changed · +18 3
  • client/pull.go+18 3 modified
    @@ -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) {
    
eebd7caaab31

fix: omit credentials for redirected URLs

https://github.com/sylabs/scs-library-clientMike FrischJan 6, 2023via ghsa
1 file changed · +18 3
  • client/pull.go+18 3 modified
    @@ -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) {
    
68ac4cab5cda

fix: remove extraneous Authorization HTTP header in range request #153

https://github.com/sylabs/scs-library-clientMike FrischDec 13, 2022via ghsa
1 file changed · +5 1
  • client/pull.go+5 1 modified
    @@ -104,11 +104,15 @@ type Downloader struct {
     
     // httpGetRangeRequest performs HTTP GET range request to URL specified by 'u' in range start-end.
     func (c *Client) httpGetRangeRequest(ctx context.Context, url string, start, end int64) (*http.Response, error) {
    -	req, err := c.newRequestWithURL(ctx, http.MethodGet, url, nil)
    +	req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
     	if err != nil {
     		return nil, err
     	}
     
    +	if v := c.UserAgent; v != "" {
    +		req.Header.Set("User-Agent", v)
    +	}
    +
     	req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", start, end))
     
     	return c.HTTPClient.Do(req)
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

7

News mentions

0

No linked articles in our index yet.