CVE-2021-3684 (published 2023-03-24T20:15Z)

A vulnerability was found in OpenShift Assisted Installer. During generation of the Discovery ISO, image pull secrets were leaked as plaintext in the installation logs. An authenticated user could exploit this by re-using the image pull secret to pull container images from the registry as the associated user.

CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N)

Weakness information:
cwe_id: CWE-532
cwe_name: Insertion of Sensitive Information into Log File
description: Information written to log files can be of a sensitive nature and give valuable guidance to an attacker or expose sensitive user information.
extended_description: 
            While logging all information may be helpful during development stages, it is important that logging levels be set appropriately before a product ships so that sensitive user data and system information are not accidentally exposed to potential attackers.
            Different log files may be produced and stored for:
            
               Server log files (e.g. server.log).  This can give information on whatever application left the file. Usually this can give full path names and system information, and sometimes usernames and passwords.
               log files that are used for debugging
            
         
         

Fix information:
repo_url: https://github.com/openshift/assisted-installer
commit_details: repo_url: https://github.com/openshift/assisted-installer
author: Igal Tsoiref
author_date: 2021-08-09 12:42:34+03:00
msg: MGMT-7450: Removing pull secret token from failure logs (#340)

Adding function that will change token value to <SECRET>
repository: repo_url: https://github.com/openshift/assisted-installer
repo_name: openshift/assisted-installer
repo_language: Go
owner: openshift
file_changes: filename: ops.go
change_type: ModificationType.MODIFY
diff: @@ -101,17 +101,20 @@ type ExecCommandError struct {
 	WaitStatus int
 }
 
+func removePullSecret(s []string) []string {
+	return strings.Split(strings.ReplaceAll(strings.Join(s, " "), config.GlobalConfig.PullSecretToken, "<SECRET>"), " ")
+}
+
 func (e *ExecCommandError) Error() string {
 	lastOutput := e.Output
 	if len(e.Output) > 200 {
 		lastOutput = "... " + e.Output[len(e.Output)-200:]
 	}
-
-	return fmt.Sprintf("failed executing %s %v, Error %s, LastOutput \"%s\"", e.Command, e.Args, e.ExitErr, lastOutput)
+	return fmt.Sprintf("failed executing %s %v, Error %s, LastOutput \"%s\"", e.Command, removePullSecret(e.Args), e.ExitErr, lastOutput)
 }
 
 func (e *ExecCommandError) DetailedError() string {
-	return fmt.Sprintf("failed executing %s %v, env vars %v, error %s, waitStatus %d, Output \"%s\"", e.Command, e.Args, e.Env, e.ExitErr, e.WaitStatus, e.Output)
+	return fmt.Sprintf("failed executing %s %v, env vars %v, error %s, waitStatus %d, Output \"%s\"", e.Command, removePullSecret(e.Args), removePullSecret(e.Env), e.ExitErr, e.WaitStatus, e.Output)
 }
 
 // ExecCommand executes command.
@@ -156,7 +159,7 @@ func (o *ops) ExecCommand(liveLogger io.Writer, command string, args ...string)
 		}
 		return output, execErr
 	}
-	o.log.Debug("Command executed:", " command", command, " arguments", args, "env vars", cmd.Env, "output", output)
+	o.log.Debug("Command executed:", " command", command, " arguments", removePullSecret(args), "env vars", removePullSecret(cmd.Env), "output", output)
 	return output, err
 }
 

programming_language: Go
filename: ops_test.go
change_type: ModificationType.MODIFY
diff: @@ -5,9 +5,13 @@ import (
 
 	. "github.com/onsi/ginkgo"
 	. "github.com/onsi/gomega"
+	"github.com/openshift/assisted-installer/src/config"
 )
 
 var _ = Describe("ExecCommandError", func() {
+	pullSecret := "TEST-TOKEN"
+	config.GlobalConfig.PullSecretToken = pullSecret
+
 	It("Creates the correct error for mkdir", func() {
 		err := &ExecCommandError{
 			Command: "mkdir",
@@ -26,15 +30,15 @@ var _ = Describe("ExecCommandError", func() {
 	It("Creates the correct error for ignition extract", func() {
 		err := &ExecCommandError{
 			Command:    "nsenter",
-			Args:       []string{"-t", "1", "-m", "-i", "--", "podman", "run", "--net", "host", "--volume", "/:/rootfs:rw", "--volume", "/usr/bin/rpm-ostree:/usr/bin/rpm-ostree", "--privileged", "--entrypoint", "/usr/bin/machine-config-daemon", "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221", "start", "--node-name", "localhost", "--root-mount", "/rootfs", "--once-from", "/opt/install-dir/bootstrap.ign", "--skip-reboot"},
-			Env:        []string{"HOME=/home/userZ"},
+			Args:       []string{"-t", "1", "-m", "-i", "--", "podman", "run", "--net", "host", "--volume", "/:/rootfs:rw", "--volume", "/usr/bin/rpm-ostree:/usr/bin/rpm-ostree", "--privileged", "--entrypoint", "/usr/bin/machine-config-daemon", "quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221", "start", "--node-name", "localhost", "--root-mount", "/rootfs", "--once-from", "/opt/install-dir/bootstrap.ign", "--skip-reboot", "--pull-secret", pullSecret},
+			Env:        []string{"HOME=/home/userZ", fmt.Sprintf("PULL_SECRET_TOKEN=%s", pullSecret)},
 			ExitErr:    fmt.Errorf("exit status 255"),
 			WaitStatus: 255,
 			Output:     "Trying to pull quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221...\nGetting image source signatures\nCopying blob sha256:74cbb6607642df5f9f70e8588e3c56d6de795d1a9af22866ea4cc82f2dad4f14\nCopying blob sha256:c9fa7d57b9028d4bd02b51cef3c3039fa7b23a8b2d9d26a6ce66b3428f6e2457\nCopying blob sha256:c676df4ac84e718ecee4f8129e43e9c2b7492942606cc65f1fc5e6f3da413160\nCopying blob sha256:b147db91a07555d29ed6085e4733f34dbaa673076488caa8f95f4677f55b3a5c\nCopying blob sha256:ad956945835b7630565fc23fcbd8194eef32b4300c28546d574b2a377fe5d0a5\nCopying config sha256:c4356549f53a30a1baefc5d1515ec1ab8b3786a4bf1738c0abaedc0e44829498\nWriting manifest to image destination\nStoring signatures\nI1019 19:03:28.797092 1 start.go:108] Version: v4.6.0-202008262209.p0-dirty (16d243c4bed178f5d4fd400c0518ebf1dbaface8)\nI1019 19:03:28.797227 1 start.go:118] Calling chroot(\"/rootfs\")\nI1019 19:03:28.797307 1 rpm-ostree.go:261] Running captured: rpm-ostree status --json\nerror: Timeout was reached\nF1019 19:04:35.869592 1 start.go:147] Failed to initialize single run daemon: error reading osImageURL from rpm-ostree: error running rpm-ostree status --json: : exit status 1)",
 		}
-		wantError := `failed executing nsenter [-t 1 -m -i -- podman run --net host --volume /:/rootfs:rw --volume /usr/bin/rpm-ostree:/usr/bin/rpm-ostree --privileged --entrypoint /usr/bin/machine-config-daemon quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221 start --node-name localhost --root-mount /rootfs --once-from /opt/install-dir/bootstrap.ign --skip-reboot], Error exit status 255, LastOutput "... or: Timeout was reached
+		wantError := `failed executing nsenter [-t 1 -m -i -- podman run --net host --volume /:/rootfs:rw --volume /usr/bin/rpm-ostree:/usr/bin/rpm-ostree --privileged --entrypoint /usr/bin/machine-config-daemon quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221 start --node-name localhost --root-mount /rootfs --once-from /opt/install-dir/bootstrap.ign --skip-reboot --pull-secret <SECRET>], Error exit status 255, LastOutput "... or: Timeout was reached
 F1019 19:04:35.869592 1 start.go:147] Failed to initialize single run daemon: error reading osImageURL from rpm-ostree: error running rpm-ostree status --json: : exit status 1)"`
-		wantDetailedError := `failed executing nsenter [-t 1 -m -i -- podman run --net host --volume /:/rootfs:rw --volume /usr/bin/rpm-ostree:/usr/bin/rpm-ostree --privileged --entrypoint /usr/bin/machine-config-daemon quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221 start --node-name localhost --root-mount /rootfs --once-from /opt/install-dir/bootstrap.ign --skip-reboot], env vars [HOME=/home/userZ], error exit status 255, waitStatus 255, Output "Trying to pull quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221...
+		wantDetailedError := `failed executing nsenter [-t 1 -m -i -- podman run --net host --volume /:/rootfs:rw --volume /usr/bin/rpm-ostree:/usr/bin/rpm-ostree --privileged --entrypoint /usr/bin/machine-config-daemon quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221 start --node-name localhost --root-mount /rootfs --once-from /opt/install-dir/bootstrap.ign --skip-reboot --pull-secret <SECRET>], env vars [HOME=/home/userZ PULL_SECRET_TOKEN=<SECRET>], error exit status 255, waitStatus 255, Output "Trying to pull quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:dc1a34f55c712b2b9c5e5a14dd85e67cbdae11fd147046ac2fef9eaf179ab221...
 Getting image source signatures
 Copying blob sha256:74cbb6607642df5f9f70e8588e3c56d6de795d1a9af22866ea4cc82f2dad4f14
 Copying blob sha256:c9fa7d57b9028d4bd02b51cef3c3039fa7b23a8b2d9d26a6ce66b3428f6e2457

programming_language: Go
repo_url: https://github.com/openshift/assisted-installer
commit_details: repo_url: https://github.com/openshift/assisted-installer
author: Igal Tsoiref
author_date: 2021-08-05 12:40:56+03:00
msg: MGMT-7452: Remove token from assisted-installer-controller log (#338)
repository: repo_url: https://github.com/openshift/assisted-installer
repo_name: openshift/assisted-installer
repo_language: Go
owner: openshift
file_changes: filename: assisted_installer_controller.go
change_type: ModificationType.MODIFY
diff: @@ -70,9 +70,9 @@ var (
 // as a first step it will wait till nodes are added to cluster and update their status to Done
 
 type ControllerConfig struct {
-	ClusterID             string `envconfig:"CLUSTER_ID" required:"true" `
+	ClusterID             string `envconfig:"CLUSTER_ID" required:"true"`
 	URL                   string `envconfig:"INVENTORY_URL" required:"true"`
-	PullSecretToken       string `envconfig:"PULL_SECRET_TOKEN" required:"true"`
+	PullSecretToken       string `envconfig:"PULL_SECRET_TOKEN" required:"true" secret:"true"`
 	SkipCertVerification  bool   `envconfig:"SKIP_CERT_VERIFICATION" required:"false" default:"false"`
 	CACertPath            string `envconfig:"CA_CERT_PATH" required:"false" default:""`
 	Namespace             string `envconfig:"NAMESPACE" required:"false" default:"assisted-installer"`

programming_language: Go
filename: ops.go
change_type: ModificationType.MODIFY
diff: @@ -238,7 +238,7 @@ func (o *ops) SetBootOrder(device string) error {
 }
 
 func (o *ops) ExtractFromIgnition(ignitionPath string, fileToExtract string) error {
-	o.log.Infof("Getting pull secret from %s", ignitionPath)
+	o.log.Infof("Getting data from %s", ignitionPath)
 	ignitionData, err := ioutil.ReadFile(ignitionPath)
 	if err != nil {
 		o.log.Errorf("Error occurred while trying to read %s : %e", ignitionPath, err)

programming_language: Go