VYPR
High severityNVD Advisory· Published Dec 18, 2019· Updated Aug 5, 2024

CVE-2019-19724

CVE-2019-19724

Description

Insecure permissions (777) are set on $HOME/.singularity when it is newly created by Singularity (version from 3.3.0 to 3.5.1), which could lead to an information leak, and malicious redirection of operations performed against Sylabs cloud services.

AI Insight

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

Singularity 3.3.0–3.5.1 creates $HOME/.singularity with world-writable permissions (777), enabling local information leaks and potential cloud service redirection.

Vulnerability

The Singularity container runtime, versions 3.3.0 through 3.5.1, created the user configuration directory $HOME/.singularity with overly permissive file mode 0777 (world-readable, writable, and executable) when that directory did not already exist [1]. The root cause was the use of fs.Mkdir(confDir, os.ModePerm) in the configuration directory initialization code, which applied the Unix permission mask 0777 instead of the intended 0700 [2].

Exploitation

This issue is exploitable by any other user present on the same multi-user system where Singularity is used. Because the directory is world-writable, a local attacker can modify files inside $HOME/.singularity, such as the remote configuration file used to communicate with Sylabs cloud services. No authentication beyond local system access is required [1].

Impact

An attacker with write access to the victim's $HOME/.singularity directory could read sensitive information (information leak) or tamper with cloud service configuration, potentially redirecting operations performed against Sylabs cloud services (e.g., container pull/push) to a malicious endpoint [1].

Mitigation

The fix was implemented in Singularity commit 2cda498 and released in version 3.5.2 [2][4]. The patch changes the initial directory creation to use mode 0700 and adds a check that enforces 0700 permissions on existing directories, warning (but not failing) if the permissions cannot be corrected [2]. Users should upgrade to Singularity 3.5.2 or later; no workaround is provided for affected versions.

AI Insight generated on May 21, 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/singularityGo
>= 3.3.0, < 3.5.23.5.2

Affected products

4

Patches

1
2cda4981812c

Fix insecure permissions

https://github.com/sylabs/singularityCedric ClergetDec 11, 2019via ghsa
6 files changed · +27 9
  • cmd/internal/cli/singularity.go+13 1 modified
    @@ -297,9 +297,21 @@ func handleRemoteConf(remoteConfFile string) {
     // handleConfDir tries to create the user's configuration directory and handles
     // messages and/or errors.
     func handleConfDir(confDir string) {
    -	if err := fs.Mkdir(confDir, os.ModePerm); err != nil {
    +	if err := fs.Mkdir(confDir, 0700); err != nil {
     		if os.IsExist(err) {
     			sylog.Debugf("%s already exists. Not creating.", confDir)
    +			fi, err := os.Stat(confDir)
    +			if err != nil {
    +				sylog.Fatalf("Failed to retrieve information for %s: %s", confDir, err)
    +			}
    +			if fi.Mode().Perm() != 0700 {
    +				sylog.Debugf("Enforce permission 0700 on %s", confDir)
    +				// enforce permission on user configuration directory
    +				if err := os.Chmod(confDir, 0700); err != nil {
    +					// best effort as chmod could fail for various reasons (eg: readonly FS)
    +					sylog.Warningf("Couldn't enforce permission 0700 on %s: %s", confDir, err)
    +				}
    +			}
     		} else {
     			sylog.Debugf("Could not create %s: %s", confDir, err)
     		}
    
  • internal/app/singularity/oci_run_linux.go+1 1 modified
    @@ -25,7 +25,7 @@ func OciRun(ctx context.Context, containerID string, args *OciArgs) error {
     	if err != nil {
     		return err
     	}
    -	if err := os.MkdirAll(dir, 0755); err != nil {
    +	if err := os.MkdirAll(dir, 0700); err != nil {
     		return err
     	}
     	args.SyncSocketPath = filepath.Join(dir, "run.sock")
    
  • internal/app/singularity/registry.go+1 1 modified
    @@ -122,7 +122,7 @@ func (l *Library) Pull(ctx context.Context, from, to, arch string) error {
     	if dst != to {
     		os.Remove(to)
     		sylog.Debugf("Copying %s to %s", dst, to)
    -		if err := fs.CopyFile(dst, to, 0777); err != nil {
    +		if err := fs.CopyFile(dst, to, 0755); err != nil {
     			return fmt.Errorf("cannot copy cache element %s to final destination %s: %w", dst, to, err)
     		}
     	}
    
  • internal/pkg/client/cache/dir.go+8 2 modified
    @@ -269,13 +269,19 @@ func updateCacheSubdir(c *Handle, subdir string) (string, error) {
     }
     
     func initCacheDir(dir string) error {
    -	if _, err := os.Stat(dir); os.IsNotExist(err) {
    +	if fi, err := os.Stat(dir); os.IsNotExist(err) {
     		sylog.Debugf("Creating cache directory: %s", dir)
    -		if err := fs.MkdirAll(dir, 0755); err != nil {
    +		if err := fs.MkdirAll(dir, 0700); err != nil {
     			return fmt.Errorf("couldn't create cache directory %v: %v", dir, err)
     		}
     	} else if err != nil {
     		return fmt.Errorf("unable to stat %s: %s", dir, err)
    +	} else if fi.Mode().Perm() != 0700 {
    +		// enforce permission on cache directory to prevent
    +		// potential information leak
    +		if err := os.Chmod(dir, 0700); err != nil {
    +			return fmt.Errorf("couldn't enforce permission 0700 on %s: %s", dir, err)
    +		}
     	}
     
     	return nil
    
  • internal/pkg/instance/instance_linux.go+3 3 modified
    @@ -238,7 +238,7 @@ func (i *File) Update() error {
     	oldumask := syscall.Umask(0)
     	defer syscall.Umask(oldumask)
     
    -	if err := os.MkdirAll(path, 0755); err != nil {
    +	if err := os.MkdirAll(path, 0700); err != nil {
     		return err
     	}
     	file, err := os.OpenFile(i.Path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY|syscall.O_NOFOLLOW, 0644)
    @@ -267,10 +267,10 @@ func SetLogFile(name string, uid int, subDir string) (*os.File, *os.File, error)
     	oldumask := syscall.Umask(0)
     	defer syscall.Umask(oldumask)
     
    -	if err := os.MkdirAll(filepath.Dir(stderrPath), 0755); err != nil {
    +	if err := os.MkdirAll(filepath.Dir(stderrPath), 0700); err != nil {
     		return nil, nil, err
     	}
    -	if err := os.MkdirAll(filepath.Dir(stdoutPath), 0755); err != nil {
    +	if err := os.MkdirAll(filepath.Dir(stdoutPath), 0700); err != nil {
     		return nil, nil, err
     	}
     
    
  • internal/pkg/plugin/meta.go+1 1 modified
    @@ -112,7 +112,7 @@ func (m *Meta) config() (*os.File, error) {
     // install installs the plugin represented by m into the destination
     // directory. This should normally only be called in InstallFromSIF.
     func (m *Meta) install(dstdir string) error {
    -	if err := os.MkdirAll(m.Path, 0777); err != nil {
    +	if err := os.MkdirAll(m.Path, 0755); err != nil {
     		return err
     	}
     
    

Vulnerability mechanics

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

References

6

News mentions

0

No linked articles in our index yet.