Skip to content

Commit 1e84d68

Browse files
authored
Improve the default sensitive history scrubbing to allow safe property access (#3630)
1 parent 8485855 commit 1e84d68

File tree

2 files changed

+42
-7
lines changed

2 files changed

+42
-7
lines changed

PSReadLine/History.cs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,22 @@ private static bool IsSecretMgmtCommand(StringConstantExpressionAst strConst, ou
525525
return result;
526526
}
527527

528+
private static bool IsSafePropertyUsage(Ast member)
529+
{
530+
bool result = false;
531+
532+
if (member.Parent is MemberExpressionAst memberExpr)
533+
{
534+
// - If the property is NOT on the left side of an assignment, then it's safe.
535+
// - Otherwise, if the right-hand side is a pipeline or a variable, then we consider it safe.
536+
result = !IsOnLeftSideOfAnAssignment(memberExpr, out Ast rhs)
537+
|| rhs is PipelineAst
538+
|| (rhs is CommandExpressionAst cmdExpr && cmdExpr.Expression is VariableExpressionAst);
539+
}
540+
541+
return result;
542+
}
543+
528544
private static ExpressionAst GetArgumentForParameter(CommandParameterAst param)
529545
{
530546
if (param.Argument is not null)
@@ -612,15 +628,20 @@ public static AddToHistoryOption GetDefaultAddToHistoryOption(string line)
612628
break;
613629

614630
case StringConstantExpressionAst strConst:
615-
// If it's not a command name, or it's not one of the secret management commands that
616-
// we can ignore, we consider it sensitive.
617-
isSensitive = !IsSecretMgmtCommand(strConst, out CommandAst command);
618-
619-
if (!isSensitive)
631+
isSensitive = true;
632+
if (IsSecretMgmtCommand(strConst, out CommandAst command))
620633
{
621-
// We can safely skip the whole command text.
634+
// If it's one of the secret management commands that we can ignore, we consider it safe.
635+
isSensitive = false;
636+
// And we can safely skip the whole command text in this case.
622637
match = s_sensitivePattern.Match(line, command.Extent.EndOffset);
623638
}
639+
else if (IsSafePropertyUsage(strConst))
640+
{
641+
isSensitive = false;
642+
match = match.NextMatch();
643+
}
644+
624645
break;
625646

626647
case CommandParameterAst param:

test/HistoryTest.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,16 @@ public void SensitiveHistoryDefaultBehavior_Two()
202202
"Set-SecretInfo -Name apikey; Set-SecretVaultDefault; Test-SecretVault; Unlock-SecretVault -password $pwd; Unregister-SecretVault -SecretVault vaultInfo",
203203
"Get-ResultFromTwo -Secret1 (Get-Secret -Name blah -AsPlainText) -Secret2 $secret2",
204204
"Get-ResultFromTwo -Secret1 (Get-Secret -Name blah -AsPlainText) -Secret2 sdv87ysdfayf798hfasd8f7ha", // '-Secret2' has expr-value argument. Not saved to file.
205-
"$environment -brand $brand -userBitWardenEmail $bwuser -userBitWardenPassword $bwpass" // '-userBitWardenPassword' matches sensitive pattern and it has parsing error. Not save to file.
205+
"$environment -brand $brand -userBitWardenEmail $bwuser -userBitWardenPassword $bwpass", // '-userBitWardenPassword' matches sensitive pattern and it has parsing error. Not save to file.
206+
"(Import-Clixml \"${Env:HOME}\\credential.clixml\").GetNetworkCredential().Password | Set-Clipboard", // 'Password' is a property not in assignment.
207+
"$a.Password = 'abcd'", // setting the 'Password' property with string value. Not saved to file.
208+
"$a.Password.Value = 'abcd'", // indirectly setting the 'Password' property with string value. Not saved to file.
209+
"$a.Secret = Get-Secret -Name github-token -Vault MySecret",
210+
"$a.Secret = $secret",
211+
"$a.Password = 'ab' + 'cd'", // setting the 'Password' property with string values. Not saved to file.
212+
"$a.Password.Secret | Set-Value",
213+
"Write-Host $a.Password.Secret",
214+
"($a.Password, $b) = ('aa', 'bb')", // setting the 'Password' property with string value. Not saved to file.
206215
};
207216

208217
string[] expectedSavedItems = new[] {
@@ -218,6 +227,11 @@ public void SensitiveHistoryDefaultBehavior_Two()
218227
"Get-SecretInfo -Name mytoken; Get-SecretVault; Register-SecretVault; Remove-Secret apikey",
219228
"Set-SecretInfo -Name apikey; Set-SecretVaultDefault; Test-SecretVault; Unlock-SecretVault -password $pwd; Unregister-SecretVault -SecretVault vaultInfo",
220229
"Get-ResultFromTwo -Secret1 (Get-Secret -Name blah -AsPlainText) -Secret2 $secret2",
230+
"(Import-Clixml \"${Env:HOME}\\credential.clixml\").GetNetworkCredential().Password | Set-Clipboard",
231+
"$a.Secret = Get-Secret -Name github-token -Vault MySecret",
232+
"$a.Secret = $secret",
233+
"$a.Password.Secret | Set-Value",
234+
"Write-Host $a.Password.Secret",
221235
};
222236

223237
try

0 commit comments

Comments
 (0)