mirror of
https://github.com/PowerShell/PSReadLine
synced 2026-06-08 12:12:13 +00:00
Improve the sensitive history scrubbing to allow retrieving token from az, gcloud, and kubectl (#3641)
This commit is contained in:
+65
-8
@@ -128,7 +128,8 @@ namespace Microsoft.PowerShell
|
||||
"Set-SecretVaultDefault",
|
||||
"Test-SecretVault",
|
||||
"Unlock-SecretVault",
|
||||
"Unregister-SecretVault"
|
||||
"Unregister-SecretVault",
|
||||
"Get-AzAccessToken",
|
||||
};
|
||||
|
||||
private void ClearSavedCurrentLine()
|
||||
@@ -511,15 +512,32 @@ namespace Microsoft.PowerShell
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool IsRightSideOfAnAssignmentSafe(Ast rhs)
|
||||
{
|
||||
if (rhs is PipelineAst)
|
||||
{
|
||||
// Right hand side is a pipeline.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rhs is CommandExpressionAst cmdExprAst && cmdExprAst.Expression is MemberExpressionAst or InvokeMemberExpressionAst)
|
||||
{
|
||||
// Right hand side is a member access, or method invocation.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsSecretMgmtCommand(StringConstantExpressionAst strConst, out CommandAst command)
|
||||
{
|
||||
command = null;
|
||||
bool result = false;
|
||||
command = strConst.Parent as CommandAst;
|
||||
|
||||
if (command is not null)
|
||||
if (strConst.Parent is CommandAst cmdAst && ReferenceEquals(cmdAst.CommandElements[0], strConst) && s_SecretMgmtCommands.Contains(strConst.Value))
|
||||
{
|
||||
result = ReferenceEquals(command.CommandElements[0], strConst)
|
||||
&& s_SecretMgmtCommands.Contains(strConst.Value);
|
||||
result = true;
|
||||
command = cmdAst;
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -568,6 +586,45 @@ namespace Microsoft.PowerShell
|
||||
return null;
|
||||
}
|
||||
|
||||
private static bool IsCloudTokenOrSecretAccess(StringConstantExpressionAst arg2Ast, out CommandAst command)
|
||||
{
|
||||
bool result = false;
|
||||
command = arg2Ast.Parent as CommandAst;
|
||||
|
||||
if (command is not null && command.CommandElements.Count >= 3
|
||||
&& command.CommandElements[0] is StringConstantExpressionAst nameAst
|
||||
&& command.CommandElements[1] is StringConstantExpressionAst arg1Ast
|
||||
&& command.CommandElements[2] == arg2Ast)
|
||||
{
|
||||
string name = nameAst.Value;
|
||||
string arg1 = arg1Ast.Value;
|
||||
string arg2 = arg2Ast.Value;
|
||||
|
||||
if (string.Equals(name, "gcloud", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result = string.Equals(arg1, "auth", StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(arg2, "print-access-token", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else if (string.Equals(name, "az", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result = string.Equals(arg1, "account", StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(arg2, "get-access-token", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
else if (string.Equals(name, "kubectl", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result = (string.Equals(arg1, "get", StringComparison.OrdinalIgnoreCase) || string.Equals(arg1, "describe", StringComparison.OrdinalIgnoreCase))
|
||||
&& (string.Equals(arg2, "secrets", StringComparison.OrdinalIgnoreCase) || string.Equals(arg2, "secret", StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
command = null;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static AddToHistoryOption GetDefaultAddToHistoryOption(string line)
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
@@ -618,8 +675,7 @@ namespace Microsoft.PowerShell
|
||||
// If it appears on the left-hand-side of an assignment, and the right-hand-side is
|
||||
// not a command invocation, we consider it sensitive.
|
||||
// e.g. `$token = Get-Secret` vs. `$token = 'token-text'` or `$token, $url = ...`
|
||||
isSensitive = IsOnLeftSideOfAnAssignment(innerAst, out Ast rhs)
|
||||
&& rhs is not PipelineAst;
|
||||
isSensitive = IsOnLeftSideOfAnAssignment(innerAst, out Ast rhs) && !IsRightSideOfAnAssignmentSafe(rhs);
|
||||
|
||||
if (!isSensitive)
|
||||
{
|
||||
@@ -629,7 +685,8 @@ namespace Microsoft.PowerShell
|
||||
|
||||
case StringConstantExpressionAst strConst:
|
||||
isSensitive = true;
|
||||
if (IsSecretMgmtCommand(strConst, out CommandAst command))
|
||||
if (IsSecretMgmtCommand(strConst, out CommandAst command)
|
||||
|| IsCloudTokenOrSecretAccess(strConst, out command))
|
||||
{
|
||||
// If it's one of the secret management commands that we can ignore, we consider it safe.
|
||||
isSensitive = false;
|
||||
|
||||
@@ -212,6 +212,14 @@ namespace Test
|
||||
"$a.Password.Secret | Set-Value",
|
||||
"Write-Host $a.Password.Secret",
|
||||
"($a.Password, $b) = ('aa', 'bb')", // setting the 'Password' property with string value. Not saved to file.
|
||||
"kubectl get secrets",
|
||||
"kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode",
|
||||
"kubectl describe secret db-user-pass",
|
||||
"(Get-AzAccessToken -ResourceUrl 'https://abc.com').Token",
|
||||
"$token = (Get-AzAccessToken -ResourceUrl 'abc').Token",
|
||||
"az account get-access-token --resource=https://abc.com --query accessToken --output tsv",
|
||||
"curl -X GET --header \"Authorization: Bearer $token\" https://abc.com",
|
||||
"$env:PGPASS = gcloud auth print-access-token",
|
||||
};
|
||||
|
||||
string[] expectedSavedItems = new[] {
|
||||
@@ -232,6 +240,14 @@ namespace Test
|
||||
"$a.Secret = $secret",
|
||||
"$a.Password.Secret | Set-Value",
|
||||
"Write-Host $a.Password.Secret",
|
||||
"kubectl get secrets",
|
||||
"kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode",
|
||||
"kubectl describe secret db-user-pass",
|
||||
"(Get-AzAccessToken -ResourceUrl 'https://abc.com').Token",
|
||||
"$token = (Get-AzAccessToken -ResourceUrl 'abc').Token",
|
||||
"az account get-access-token --resource=https://abc.com --query accessToken --output tsv",
|
||||
"curl -X GET --header \"Authorization: Bearer $token\" https://abc.com",
|
||||
"$env:PGPASS = gcloud auth print-access-token",
|
||||
};
|
||||
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user