77using System . ComponentModel . Composition ;
88#endif
99using System . Globalization ;
10+ using System . Linq ;
1011using System . Management . Automation . Language ;
1112using Microsoft . Windows . PowerShell . ScriptAnalyzer . Generic ;
1213
1314namespace Microsoft . Windows . PowerShell . ScriptAnalyzer . BuiltinRules
1415{
1516 /// <summary>
16- /// AvoidSecretDisclosure: Checks whether a plaintext secret is being retrieved which can lead to
17- /// security vulnerabilities such as memory trails or logging trails.
18- /// The general approach of dealing with credentials is to avoid them and instead rely on other means
19- /// to authenticate, such as certificates or Windows authentication.
17+ /// AvoidSecretDisclosure: Checks whether a plaintext secret is being retrieved which can lead
18+ /// to security vulnerabilities such as memory trails or logging trails.
19+ /// The general approach of dealing with credentials is to avoid them and instead rely on other
20+ /// means to authenticate, such as certificates or Windows authentication.
2021 /// </summary>
2122#if ! CORECLR
2223 [ Export ( typeof ( IScriptRule ) ) ]
@@ -42,12 +43,12 @@ public override IEnumerable<DiagnosticRecord> AnalyzeScript(Ast ast, string file
4243 if ( ast == null ) throw new ArgumentNullException ( Strings . NullAstErrorMessage ) ;
4344
4445 // Check for ConvertFrom-SecureString with -AsPlainText parameter
45- IEnumerable < Ast > convertFromSecureStringAsts = ast . FindAll ( testAst =>
46+ IEnumerable < CommandAst > convertFromSecureStringAsts = ast . FindAll ( testAst =>
4647 testAst is CommandAst cmdAst &&
4748 cmdAst . GetCommandName ( ) != null &&
4849 cmdAst . GetCommandName ( ) . Equals ( "ConvertFrom-SecureString" , StringComparison . OrdinalIgnoreCase ) ,
4950 true
50- ) ;
51+ ) . Cast < CommandAst > ( ) ;
5152
5253 foreach ( CommandAst cmdAst in convertFromSecureStringAsts )
5354 {
@@ -59,8 +60,8 @@ testAst is CommandAst cmdAst &&
5960 // This is ok because the rule should still trigger in that case since the value of the
6061 // variable could be true at runtime, and we want to catch all potential violations
6162 if (
62- bindingResult . BoundParameters . ContainsKey ( "AsPlainText" ) &&
63- bindingResult . BoundParameters [ "AsPlainText" ] . ConstantValue is bool constantValue &&
63+ bindingResult . BoundParameters . TryGetValue ( "AsPlainText" , out ParameterBindingResult asPlainTextBinding ) &&
64+ asPlainTextBinding . ConstantValue is bool constantValue &&
6465 constantValue == true
6566 ) {
6667 yield return GetDiagnosticRecord ( cmdAst . Extent , fileName , "AsPlainText" ) ;
@@ -69,12 +70,12 @@ testAst is CommandAst cmdAst &&
6970
7071 // Check for any invocation of a method that starts with "SecureStringTo"
7172 // (e.g. SecureStringToBSTR, SecureStringToCoTaskMemAnsi, etc.)
72- IEnumerable < Ast > secureStringToAsts = ast . FindAll ( testAst =>
73+ IEnumerable < InvokeMemberExpressionAst > secureStringToAsts = ast . FindAll ( testAst =>
7374 testAst is InvokeMemberExpressionAst invokeAst &&
7475 invokeAst . Member != null &&
7576 invokeAst . Member . ToString ( ) . StartsWith ( "SecureStringTo" , StringComparison . OrdinalIgnoreCase ) ,
7677 true
77- ) ;
78+ ) . Cast < InvokeMemberExpressionAst > ( ) ;
7879
7980 foreach ( InvokeMemberExpressionAst secureStringToAst in secureStringToAsts ) {
8081 yield return GetDiagnosticRecord ( secureStringToAst . Extent , fileName , secureStringToAst . Member . ToString ( ) ) ;
@@ -87,12 +88,12 @@ testAst is InvokeMemberExpressionAst invokeAst &&
8788 // However, it is too complex to reliably determine whether a Password
8889 // property is a result of e.g. a PSCredential.GetNetworkCredential() call.
8990 // Anyways, this is still a useful common check to have.
90- IEnumerable < Ast > passwordAsts = ast . FindAll ( testAst =>
91+ IEnumerable < MemberExpressionAst > passwordAsts = ast . FindAll ( testAst =>
9192 testAst is MemberExpressionAst memberAst &&
9293 memberAst . Member != null &&
9394 string . Equals ( memberAst . Member . ToString ( ) , "Password" , StringComparison . OrdinalIgnoreCase ) ,
9495 true
95- ) ;
96+ ) . Cast < MemberExpressionAst > ( ) ;
9697
9798 foreach ( MemberExpressionAst passwordAst in passwordAsts ) {
9899 yield return GetDiagnosticRecord ( passwordAst . Extent , fileName , passwordAst . Member . ToString ( ) ) ;
0 commit comments