Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Management.Automation.Internal;
using System.Management.Automation.Language;
using System.Management.Automation.Remoting;
using System.Management.Automation.Runspaces;
using System.Threading;
Expand Down Expand Up @@ -63,9 +64,9 @@ public class EnterPSSessionCommand : PSRemotingBaseCmdlet
/// </summary>
[Parameter(ParameterSetName = PSRemotingBaseCmdlet.SSHHostParameterSet)]
[ValidateNotNullOrEmpty]
public override Hashtable Options
{
get
public override Hashtable Options
{
get
{
return base.Options;
}
Expand Down Expand Up @@ -1174,12 +1175,21 @@ private void SetRunspacePrompt(RemoteRunspace remoteRunspace)
Dbg.Assert(false, "Unrecognized parameter set.");
break;
}

// Check if the remoteRunspace targetName contains potentially unwanted PowerShell code, test this against an allowed list of commonly used PowerShell code that doesn't pose a security risk and redact it if necessary, omitting a Warning message if the targetName is redacted.
string targetNameRedacted = RedactIfPowerShellCode(targetName);
if (!string.Equals(targetName, targetNameRedacted, StringComparison.Ordinal))
{
WriteWarning(
StringUtil.Format(
RemotingErrorIdStrings.RemotePromptTargetNameRedacted,
targetName,
targetNameRedacted));
}
string escapedTargetName = CodeGeneration.EscapeSingleQuotedStringContent(targetNameRedacted);
string promptFn = StringUtil.Format(RemotingErrorIdStrings.EnterVMSessionPrompt,
@"function global:prompt { """,
targetName,
@"PS $($executionContext.SessionState.Path.CurrentLocation)> "" }");

@"function global:prompt { '",
escapedTargetName,
@"PS ' + $executionContext.SessionState.Path.CurrentLocation + '> ' }");
// Set prompt in pushed named pipe runspace.
using (System.Management.Automation.PowerShell ps = System.Management.Automation.PowerShell.Create())
{
Expand Down Expand Up @@ -1395,6 +1405,27 @@ internal static void ContinueCommand(RemoteRunspace remoteRunspace, Pipeline cmd
}
}

internal static string RedactIfPowerShellCode(string input)
{
if (string.IsNullOrEmpty(input))
{
return input;
}

bool startsWithOrContainsDangerousToken =
input.StartsWith('$') ||
input.StartsWith("@{") ||
input.StartsWith('(') ||
input.StartsWith('"') ||
input.StartsWith('@') ||
input.StartsWith('\'') ||
input.Contains('$');

return startsWithOrContainsDangerousToken
? "REDACTED"
: input;
}

#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1734,4 +1734,7 @@ SSH client process terminated before connection could be established.</value>
<data name="HyperVNegotiationFailed" xml:space="preserve">
<value>Negotiating a secure connection to Hyper-V failed. Make sure the Host and Guest are updated with all relevant Microsoft Updates.</value>
</data>
<data name="RemotePromptTargetNameRedacted" xml:space="preserve">
<value>The following prompt Target Name '{0}' has been redacted to '{1}' for security reasons.</value>
</data>
</root>