CVE-2021-21270 (published 2021-01-22T18:15Z)

OctopusDSC is a PowerShell module with DSC resources that can be used to install and configure an Octopus Deploy Server and Tentacle agent. In OctopusDSC version 4.0.977 and earlier a customer API key used to connect to Octopus Server is exposed via logging in plaintext. This vulnerability is patched in version 4.0.1002.

Severity: LOW
CVSS v2 base score: 2.1 (AV:L/AC:L/Au:N/C:P/I:N/A:N)
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-319
cwe_name: Cleartext Transmission of Sensitive Information
description: The product transmits sensitive or security-critical data in cleartext in a communication channel that can be sniffed by unauthorized actors.
extended_description: 
	 Many communication channels can be "sniffed" (monitored) by adversaries during data transmission. For example, in networking, packets can traverse many intermediary nodes from the source to the destination, whether across the internet, an internal network, the cloud, etc. Some actors might have privileged access to a network interface or any link along the channel, such as a router, but they might not be authorized to collect the underlying data. As a result, network traffic could be sniffed by adversaries, spilling security-critical data.
	 Applicable communication channels are not limited to software products. Applicable channels include hardware-specific technologies such as internal hardware networks and external debug channels, supporting remote JTAG debugging. When mitigations are not applied to combat adversaries within the product's threat model, this weakness significantly lowers the difficulty of exploitation by such adversaries.
	 When full communications are recorded or logged, such as with a packet dump, an adversary could attempt to obtain the dump long after the transmission has occurred and try to "sniff" the cleartext from the recorded communications in the dump itself. Even if the information is encoded in a way that is not human-readable, certain techniques could determine which encoding is being used, then decode the information.

         
         

Fix information:
repo_url: https://github.com/OctopusDeploy/OctopusDSC
commit_details: repo_url: https://github.com/OctopusDeploy/OctopusDSC
author: Paul Gradie
author_date: 2021-01-20 15:09:30+11:00
msg: [Bug fix] Prevent exposing API key secret in stdout logging (#270)

* remove Write-Verbose line

* use masking function in commands

* simplify masking function
repository: repo_url: https://github.com/OctopusDeploy/OctopusDSC
repo_name: OctopusDeploy/OctopusDSC
description: | Public |  A PowerShell DSC resource for installing Octopus Deploy & Tentacles
repo_language: PowerShell
owner: OctopusDeploy
file_changes: filename: cTentacleAgent.psm1
change_type: ModificationType.MODIFY
diff: @@ -1278,6 +1278,5 @@ function Register-Tentacle {
         $registerArguments += @("--tenanted-deployment-participation", $TenantedDeploymentParticipation)
     }
 
-    Write-Verbose "Registering with arguments: $registerArguments"
     Invoke-TentacleCommand $registerArguments
 }

programming_language: PowerShell
filename: OctopusDSCHelpers.ps1
change_type: ModificationType.MODIFY
diff: @@ -153,46 +153,35 @@ Function Invoke-WithRetries {
     return $returnvalue
 }
 
-Function Get-MaskedOutput
-{
+function Get-MaskedOutput {
     [CmdletBinding()]
     param($arguments)
 
-    $reg = [System.Text.RegularExpressions.RegEx]::new("--masterkey|--password|--license",
-                [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)
+    $singleAsterixArgs = "--masterkey|--license|--licence|--trust|--password|--remove-trust|--apikey|--pw|--pfx-password|--proxyPassword";
+    $connectionStringArgs = "--connectionstring";
 
-    if(($arguments -match "--masterkey|--password|--license"))
-    {
-        for($x=0;$x -lt $arguments.count; $x++)
-        {
-            if(($arguments[$x] -match "--masterkey|--password|--license|--trust|--remove-trust|--apikey|--password|--pw|--pfx-password|--proxyPassword"))
-            {
-                $arguments[$x+1] = $arguments[$x+1] -replace ".", "*"
-            }
+    # Scrub sensitive values
+    for($x=0; $x -lt $arguments.count; $x++) {
+        if($arguments[$x] -match $singleAsterixArgs) {
+            $arguments[$x+1] = "**********"
+        } elseif($arguments[$x] -match $connectionStringArgs) {
+            $arguments[$x+1] = $arguments[$x+1] -replace "(password|pwd)=[^;|`"]*", "`$1=********"
         }
-        $out = $arguments
-    }
-    elseif(($arguments -match "password|pwd"))
-    {
-        $out = $arguments -replace "(password|pwd)=[^;|`"]*", "`$1=********"
-    }
-    else
-    {
-        $out = @("************************")
     }
-    return $out
+    return $arguments
+}
+
+function Write-VerboseWithMaskedCommand ($cmdArgs) {
+    $copiedarguments = @() # hack to pass a copy of the array, not a reference
+    $copiedarguments += $cmdArgs
+    $maskedarguments = Get-MaskedOutput $copiedarguments
+    Write-Verbose "Executing command '$octopusServerExePath $($maskedarguments -join ' ')'"
 }
 
 function Invoke-OctopusServerCommand ($cmdArgs) {
-    # todo: fix this up
-    if ((($cmdArgs -match "masterkey|password|license|pwd=").Count -eq 0)) {
-        Write-Verbose "Executing command '$octopusServerExePath $($cmdArgs -join ' ')'"
-    } else {
-        $copiedarguments = @() # hack to pass a copy of the array, not a reference
-        $copiedarguments += $cmdArgs
-        $maskedarguments = Get-MaskedOutput $copiedarguments
-        Write-Verbose "Executing command '$octopusServerExePath $($maskedarguments -join ' ')'"
-    }
+
+    Write-VerboseWithMaskedCommand($cmdArgs);
+
     $LASTEXITCODE = 0
     $output = & $octopusServerExePath $cmdArgs 2>&1
 
@@ -210,15 +199,9 @@ function Test-TentacleExecutableExists {
 }
 
 function Invoke-TentacleCommand ($cmdArgs) {
-    # todo: fix this up
-    if ((($cmdArgs -match "masterkey|password|license|pwd=").Count -eq 0)) {
-        Write-Verbose "Executing command '$tentacleExePath $($cmdArgs -join ' ')'"
-    } else {
-        $copiedarguments = @() # hack to pass a copy of the array, not a reference
-        $copiedarguments += $cmdArgs
-        $maskedarguments = Get-MaskedOutput $copiedarguments
-        Write-Verbose "Executing command '$tentacleExePath $($maskedarguments -join ' ')'"
-    }
+
+    Write-VerboseWithMaskedCommand($cmdArgs);
+
     $LASTEXITCODE = 0
     $output = & $tentacleExePath $cmdArgs 2>&1
 

programming_language: PowerShell