public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); HazardousUsageEvaluatorCollection hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator("GetBytes", HazardousUsageCallback)); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemSecurityCryptographyRfc2898DeriveBytes, out var rfc2898DeriveBytesTypeSymbol)) { return; } var cancellationToken = compilationStartAnalysisContext.CancellationToken; var sufficientIterationCount = compilationStartAnalysisContext.Options.GetUnsignedIntegralOptionValue( optionName: EditorConfigOptionNames.SufficientIterationCountForWeakKDFAlgorithm, rule: DefinitelyUseWeakKDFInsufficientIterationCountRule, defaultValue: 100000, cancellationToken: cancellationToken); var constructorMapper = new ConstructorMapper( (IMethodSymbol constructorMethod, IReadOnlyList <ValueContentAbstractValue> argumentValueContentAbstractValues, IReadOnlyList <PointsToAbstractValue> argumentPointsToAbstractValues) => { var kind = DefaultIterationCount >= sufficientIterationCount ? PropertySetAbstractValueKind.Unflagged : PropertySetAbstractValueKind.Flagged; if (constructorMethod.Parameters.Length >= 3) { if (constructorMethod.Parameters[2].Name == "iterations" && constructorMethod.Parameters[2].Type.SpecialType == SpecialType.System_Int32) { kind = PropertySetAnalysis.EvaluateLiteralValues(argumentValueContentAbstractValues[2], o => Convert.ToInt32(o) < sufficientIterationCount); } } return(PropertySetAbstractValue.GetInstance(kind)); }); var propertyMappers = new PropertyMapperCollection( new PropertyMapper( "IterationCount", (ValueContentAbstractValue valueContentAbstractValue) => { return(PropertySetAnalysis.EvaluateLiteralValues(valueContentAbstractValue, o => Convert.ToInt32(o) < sufficientIterationCount)); })); var rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; if (rfc2898DeriveBytesTypeSymbol.Equals(invocationOperation.Instance?.Type) && invocationOperation.TargetMethod.Name == "GetBytes") { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((invocationOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Invocation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var argumentOperation = (IArgumentOperation)operationAnalysisContext.Operation; if (rfc2898DeriveBytesTypeSymbol.Equals(argumentOperation.Parameter.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((argumentOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Argument); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, WellKnownTypeNames.SystemSecurityCryptographyRfc2898DeriveBytes, constructorMapper, propertyMappers, hazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: cancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp in allResults) { DiagnosticDescriptor descriptor; switch (kvp.Value) { case HazardousUsageEvaluationResult.Flagged: descriptor = DefinitelyUseWeakKDFInsufficientIterationCountRule; break; case HazardousUsageEvaluationResult.MaybeFlagged: descriptor = MaybeUseWeakKDFInsufficientIterationCountRule; break; default: Debug.Fail($"Unhandled result value {kvp.Value}"); continue; } compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( descriptor, kvp.Key.Location, sufficientIterationCount)); } } finally { rootOperationsNeedingAnalysis.Free(); allResults?.Free(); } }); }); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemSecurityCryptographySymmetricAlgorithm, out var symmetricAlgorithmTypeSymbol)) { return; } var rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { var owningSymbol = operationBlockStartAnalysisContext.OwningSymbol; // TODO: Handle case when exactly one of the below rules is configured to skip analysis. if (operationBlockStartAnalysisContext.Options.IsConfiguredToSkipAnalysis(DefinitelyUseCreateEncryptorWithNonDefaultIVRule, owningSymbol, operationBlockStartAnalysisContext.Compilation, operationBlockStartAnalysisContext.CancellationToken) && operationBlockStartAnalysisContext.Options.IsConfiguredToSkipAnalysis(MaybeUseCreateEncryptorWithNonDefaultIVRule, owningSymbol, operationBlockStartAnalysisContext.Compilation, operationBlockStartAnalysisContext.CancellationToken)) { return; } operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; var methodSymbol = invocationOperation.TargetMethod; if (methodSymbol.ContainingType.GetBaseTypesAndThis().Contains(symmetricAlgorithmTypeSymbol) && methodSymbol.Name == "CreateEncryptor") { if (methodSymbol.Parameters.IsEmpty) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((invocationOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } else { operationAnalysisContext.ReportDiagnostic( invocationOperation.CreateDiagnostic( DefinitelyUseCreateEncryptorWithNonDefaultIVRule)); } } }, OperationKind.Invocation); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult>?allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, compilationAnalysisContext.Options, WellKnownTypeNames.SystemSecurityCryptographySymmetricAlgorithm, ConstructorMapper, PropertyMappers, HazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, rootOperationsNeedingAnalysis.First().Item1.Syntax.SyntaxTree, compilationAnalysisContext.Compilation, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult> kvp in allResults) { DiagnosticDescriptor descriptor; switch (kvp.Value) { case HazardousUsageEvaluationResult.Flagged: descriptor = DefinitelyUseCreateEncryptorWithNonDefaultIVRule; break; case HazardousUsageEvaluationResult.MaybeFlagged: descriptor = MaybeUseCreateEncryptorWithNonDefaultIVRule; break; default: Debug.Fail($"Unhandled result value {kvp.Value}"); continue; } RoslynDebug.Assert(kvp.Key.Method != null); // HazardousUsageEvaluations only for invocations. compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( descriptor, kvp.Key.Location, kvp.Key.Method.ToDisplayString( SymbolDisplayFormat.MinimallyQualifiedFormat))); } } finally { rootOperationsNeedingAnalysis.Free(compilationAnalysisContext.CancellationToken); allResults?.Free(compilationAnalysisContext.CancellationToken); } }); }); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); // If there are more classes implement IResponseCookies, add them here later. HazardousUsageEvaluatorCollection hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( WellKnownTypeNames.MicrosoftAspNetCoreHttpInternalResponseCookies, "Append", "options", HazardousUsageCallback)); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetTypeByMetadataName( WellKnownTypeNames.MicrosoftAspNetCoreHttpIResponseCookies, out var iResponseCookiesTypeSymbol)) { return; } wellKnownTypeProvider.TryGetTypeByMetadataName( WellKnownTypeNames.MicrosoftAspNetCoreHttpCookieOptions, out var cookieOptionsTypeSymbol); var rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; var methodSymbol = invocationOperation.TargetMethod; if (methodSymbol.ContainingType is INamedTypeSymbol namedTypeSymbol && namedTypeSymbol.Interfaces.Contains(iResponseCookiesTypeSymbol) && invocationOperation.TargetMethod.Name == "Append") { if (methodSymbol.Parameters.Length < 3) { operationAnalysisContext.ReportDiagnostic( invocationOperation.CreateDiagnostic( DefinitelyUseSecureCookiesASPNetCoreRule)); } else { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((invocationOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } } }, OperationKind.Invocation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var argumentOperation = (IArgumentOperation)operationAnalysisContext.Operation; if (argumentOperation.Parameter.Type.Equals(cookieOptionsTypeSymbol)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((argumentOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Argument); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, WellKnownTypeNames.MicrosoftAspNetCoreHttpCookieOptions, constructorMapper, PropertyMappers, hazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp in allResults) { DiagnosticDescriptor descriptor; switch (kvp.Value) { case HazardousUsageEvaluationResult.Flagged: descriptor = DefinitelyUseSecureCookiesASPNetCoreRule; break; case HazardousUsageEvaluationResult.MaybeFlagged: descriptor = MaybeUseSecureCookiesASPNetCoreRule; break; default: Debug.Fail($"Unhandled result value {kvp.Value}"); continue; } compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( descriptor, kvp.Key.Location, kvp.Key.Method.ToDisplayString( SymbolDisplayFormat.MinimallyQualifiedFormat))); } } finally { rootOperationsNeedingAnalysis.Free(); allResults?.Free(); } }); }); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { if (!compilationStartAnalysisContext.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebHttpCookie, out INamedTypeSymbol? httpCookieSymbol)) { return; } PooledHashSet <(IOperation Operation, ISymbol ContainingSymbol)> rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { ISymbol owningSymbol = operationBlockStartAnalysisContext.OwningSymbol; if (owningSymbol.IsConfiguredToSkipAnalysis( operationBlockStartAnalysisContext.Options, Rule, operationBlockStartAnalysisContext.Compilation, operationBlockStartAnalysisContext.CancellationToken)) { return; } operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { ISimpleAssignmentOperation simpleAssignmentOperation = (ISimpleAssignmentOperation)operationAnalysisContext.Operation; if (simpleAssignmentOperation.Target is IPropertyReferenceOperation propertyReferenceOperation && httpCookieSymbol.Equals(propertyReferenceOperation.Property.ContainingType) && propertyReferenceOperation.Property.Name == "HttpOnly" && simpleAssignmentOperation.Value.ConstantValue.HasValue && simpleAssignmentOperation.Value.ConstantValue.Value.Equals(false)) { operationAnalysisContext.ReportDiagnostic( simpleAssignmentOperation.CreateDiagnostic( Rule)); } }, OperationKind.SimpleAssignment); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IReturnOperation returnOperation = (IReturnOperation)operationAnalysisContext.Operation; if (httpCookieSymbol.Equals(returnOperation.ReturnedValue?.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add( (returnOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Return); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IArgumentOperation argumentOperation = (IArgumentOperation)operationAnalysisContext.Operation; if (httpCookieSymbol.Equals(argumentOperation.Value.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add( (argumentOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Argument); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult>?allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, compilationAnalysisContext.Options, WellKnownTypeNames.SystemWebHttpCookie, ConstructorMapper, PropertyMappers, HazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult> kvp in allResults) { if (kvp.Value == HazardousUsageEvaluationResult.Flagged) { compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( Rule, kvp.Key.Location)); } } } finally { rootOperationsNeedingAnalysis.Free(); allResults?.Free(); } }); }); }
public sealed override void Initialize(AnalysisContext context) { ImmutableHashSet <string> cachedDeserializationMethodNames = this.DeserializationMethodNames; Debug.Assert(!string.IsNullOrWhiteSpace(this.DeserializerTypeMetadataName)); Debug.Assert(!string.IsNullOrWhiteSpace(this.SerializationBinderPropertyMetadataName)); Debug.Assert(!cachedDeserializationMethodNames.IsEmpty); Debug.Assert(this.BinderDefinitelyNotSetDescriptor != null); Debug.Assert(this.BinderMaybeNotSetDescriptor != null); context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); // For PropertySetAnalysis dataflow analysis. PropertyMapperCollection propertyMappers = new PropertyMapperCollection( new PropertyMapper( this.SerializationBinderPropertyMetadataName, PropertySetCallbacks.FlagIfNull)); HazardousUsageEvaluatorCollection hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection( cachedDeserializationMethodNames.Select( methodName => new HazardousUsageEvaluator( methodName, PropertySetCallbacks.HazardousIfAllFlaggedOrAllUnknown))); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { if (!compilationStartAnalysisContext.Compilation.TryGetOrCreateTypeByMetadataName( this.DeserializerTypeMetadataName, out INamedTypeSymbol? deserializerTypeSymbol)) { return; } PooledHashSet <(IOperation Operation, ISymbol ContainingSymbol)> rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { var owningSymbol = operationBlockStartAnalysisContext.OwningSymbol; // TODO: Handle case when exactly one of the below rules is configured to skip analysis. if (owningSymbol.IsConfiguredToSkipAnalysis(operationBlockStartAnalysisContext.Options, BinderDefinitelyNotSetDescriptor !, operationBlockStartAnalysisContext.Compilation, operationBlockStartAnalysisContext.CancellationToken) && owningSymbol.IsConfiguredToSkipAnalysis(operationBlockStartAnalysisContext.Options, BinderMaybeNotSetDescriptor !, operationBlockStartAnalysisContext.Compilation, operationBlockStartAnalysisContext.CancellationToken)) { return; } operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IObjectCreationOperation creationOperation = (IObjectCreationOperation)operationAnalysisContext.Operation; if (deserializerTypeSymbol.Equals(creationOperation.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.ObjectCreation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; if (Equals(invocationOperation.Instance?.Type, deserializerTypeSymbol) && cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.Name)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Invocation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IMethodReferenceOperation methodReferenceOperation = (IMethodReferenceOperation)operationAnalysisContext.Operation; if (Equals(methodReferenceOperation.Instance?.Type, deserializerTypeSymbol) && cachedDeserializationMethodNames.Contains( methodReferenceOperation.Method.MetadataName)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.MethodReference); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult>?allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, compilationAnalysisContext.Options, this.DeserializerTypeMetadataName, DoNotUseInsecureDeserializerWithoutBinderBase.ConstructorMapper, propertyMappers, hazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, rootOperationsNeedingAnalysis.First().Operation.Syntax.SyntaxTree, compilationAnalysisContext.Compilation, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult> kvp in allResults) { DiagnosticDescriptor descriptor; switch (kvp.Value) { case HazardousUsageEvaluationResult.Flagged: descriptor = this.BinderDefinitelyNotSetDescriptor !; break; case HazardousUsageEvaluationResult.MaybeFlagged: descriptor = this.BinderMaybeNotSetDescriptor !; break; default: Debug.Fail($"Unhandled result value {kvp.Value}"); continue; } RoslynDebug.Assert(kvp.Key.Method != null); // HazardousUsageEvaluations only for invocations. compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( descriptor, kvp.Key.Location, kvp.Key.Method.ToDisplayString( SymbolDisplayFormat.MinimallyQualifiedFormat))); } } finally { rootOperationsNeedingAnalysis.Free(compilationAnalysisContext.CancellationToken); allResults?.Free(compilationAnalysisContext.CancellationToken); } }); }); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); HazardousUsageEvaluatorCollection hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection( SecurityHelpers.JavaScriptSerializerDeserializationMethods.Select( (string methodName) => new HazardousUsageEvaluator(methodName, HazardousUsageCallback))); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemWebScriptSerializationJavaScriptSerializer, out INamedTypeSymbol javaScriptSerializerSymbol) || !wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemWebScriptSerializationJavaScriptTypeResolver, out INamedTypeSymbol javaScriptTypeResolverSymbol) || !wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemWebScriptSerializationSimpleTypeResolver, out INamedTypeSymbol simpleTypeResolverSymbol)) { return; } // If JavaScriptSerializer is initialized with a SimpleTypeResolver, then that instance is flagged. ConstructorMapper constructorMapper = new ConstructorMapper( (IMethodSymbol constructorMethod, IReadOnlyList <PointsToAbstractValue> argumentPointsToAbstractValues) => { PropertySetAbstractValueKind kind; if (constructorMethod.Parameters.Length == 0) { kind = PropertySetAbstractValueKind.Unflagged; } else if (constructorMethod.Parameters.Length == 1 && javaScriptTypeResolverSymbol.Equals(constructorMethod.Parameters[0].Type)) { PointsToAbstractValue pointsTo = argumentPointsToAbstractValues[0]; switch (pointsTo.Kind) { case PointsToAbstractValueKind.Invalid: case PointsToAbstractValueKind.UnknownNull: case PointsToAbstractValueKind.Undefined: kind = PropertySetAbstractValueKind.Unflagged; break; case PointsToAbstractValueKind.KnownLocations: if (pointsTo.Locations.Any(l => !l.IsNull && simpleTypeResolverSymbol.Equals(l.LocationTypeOpt))) { kind = PropertySetAbstractValueKind.Flagged; } else if (pointsTo.Locations.Any(l => !l.IsNull && javaScriptTypeResolverSymbol.Equals(l.LocationTypeOpt) && (l.CreationOpt == null || l.CreationOpt.Kind != OperationKind.ObjectCreation))) { // Points to a JavaScriptTypeResolver, but we don't know if the instance is a SimpleTypeResolver. kind = PropertySetAbstractValueKind.MaybeFlagged; } else { kind = PropertySetAbstractValueKind.Unflagged; } break; case PointsToAbstractValueKind.UnknownNotNull: case PointsToAbstractValueKind.Unknown: kind = PropertySetAbstractValueKind.MaybeFlagged; break; default: Debug.Fail($"Unhandled PointsToAbstractValueKind {pointsTo.Kind}"); kind = PropertySetAbstractValueKind.Unflagged; break; } } else { Debug.Fail($"Unhandled JavaScriptSerializer constructor {constructorMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)}"); kind = PropertySetAbstractValueKind.Unflagged; } return(PropertySetAbstractValue.GetInstance(kind)); }); PooledHashSet <(IOperation Operation, ISymbol ContainingSymbol)> rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; if ((javaScriptSerializerSymbol.Equals(invocationOperation.Instance?.Type) && SecurityHelpers.JavaScriptSerializerDeserializationMethods.Contains(invocationOperation.TargetMethod.Name)) || simpleTypeResolverSymbol.Equals(invocationOperation.TargetMethod.ReturnType) || javaScriptTypeResolverSymbol.Equals(invocationOperation.TargetMethod.ReturnType)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((invocationOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Invocation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IMethodReferenceOperation methodReferenceOperation = (IMethodReferenceOperation)operationAnalysisContext.Operation; if (javaScriptSerializerSymbol.Equals(methodReferenceOperation.Instance?.Type) && SecurityHelpers.JavaScriptSerializerDeserializationMethods.Contains(methodReferenceOperation.Method.Name)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.MethodReference); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, WellKnownTypeNames.SystemWebScriptSerializationJavaScriptSerializer, constructorMapper, PropertyMappers, hazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp in allResults) { DiagnosticDescriptor descriptor; switch (kvp.Value) { case HazardousUsageEvaluationResult.Flagged: descriptor = DefinitelyWithSimpleTypeResolver; break; case HazardousUsageEvaluationResult.MaybeFlagged: descriptor = MaybeWithSimpleTypeResolver; break; default: Debug.Fail($"Unhandled result value {kvp.Value}"); continue; } compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( descriptor, kvp.Key.Location, kvp.Key.Method.ToDisplayString( SymbolDisplayFormat.MinimallyQualifiedFormat))); } } finally { rootOperationsNeedingAnalysis.Free(); allResults?.Free(); } }); }); }
public sealed override void Initialize(AnalysisContext context) { ImmutableHashSet <string> cachedDeserializationMethodNames = this.DeserializationMethodNames; Debug.Assert(!String.IsNullOrWhiteSpace(this.DeserializerTypeMetadataName)); Debug.Assert(!String.IsNullOrWhiteSpace(this.SerializationBinderPropertyMetadataName)); Debug.Assert(cachedDeserializationMethodNames != null); Debug.Assert(!cachedDeserializationMethodNames.IsEmpty); Debug.Assert(this.BinderDefinitelyNotSetDescriptor != null); Debug.Assert(this.BinderMaybeNotSetDescriptor != null); context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); // For PropertySetAnalysis dataflow analysis. PropertyMapperCollection propertyMappers = new PropertyMapperCollection( new PropertyMapper( this.SerializationBinderPropertyMetadataName, (PointsToAbstractValue pointsToAbstractValue) => { // A null SerializationBinder is what we want to flag as hazardous. switch (pointsToAbstractValue.NullState) { case NullAbstractValue.Null: return(PropertySetAbstractValueKind.Flagged); case NullAbstractValue.NotNull: return(PropertySetAbstractValueKind.Unflagged); default: return(PropertySetAbstractValueKind.MaybeFlagged); } })); HazardousUsageEvaluatorCollection hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection( cachedDeserializationMethodNames.Select( methodName => new HazardousUsageEvaluator(methodName, DoNotUseInsecureDeserializerWithoutBinderBase.HazardousIfNull))); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetTypeByMetadataName( this.DeserializerTypeMetadataName, out INamedTypeSymbol deserializerTypeSymbol)) { return; } PooledHashSet <(IOperation Operation, ISymbol ContainingSymbol)> rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IObjectCreationOperation creationOperation = (IObjectCreationOperation)operationAnalysisContext.Operation; if (deserializerTypeSymbol.Equals(creationOperation.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.ObjectCreation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; if (Equals(invocationOperation.Instance?.Type, deserializerTypeSymbol) && cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.Name)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Invocation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { IMethodReferenceOperation methodReferenceOperation = (IMethodReferenceOperation)operationAnalysisContext.Operation; if (Equals(methodReferenceOperation.Instance?.Type, deserializerTypeSymbol) && cachedDeserializationMethodNames.Contains( methodReferenceOperation.Method.MetadataName)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operationAnalysisContext.Operation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.MethodReference); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, this.DeserializerTypeMetadataName, DoNotUseInsecureDeserializerWithoutBinderBase.ConstructorMapper, propertyMappers, hazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp in allResults) { DiagnosticDescriptor descriptor; switch (kvp.Value) { case HazardousUsageEvaluationResult.Flagged: descriptor = this.BinderDefinitelyNotSetDescriptor; break; case HazardousUsageEvaluationResult.MaybeFlagged: descriptor = this.BinderMaybeNotSetDescriptor; break; default: Debug.Fail($"Unhandled result value {kvp.Value}"); continue; } compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( descriptor, kvp.Key.Location, kvp.Key.Method.ToDisplayString( SymbolDisplayFormat.MinimallyQualifiedFormat))); } } finally { rootOperationsNeedingAnalysis.Free(); allResults?.Free(); } }); }); }
public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); // Security analyzer - analyze and report diagnostics on generated code. context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); HazardousUsageEvaluatorCollection hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator("Add", HazardousUsageCallback)); context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartAnalysisContext.Compilation); if (!wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemSecurityCryptographyX509CertificatesX509Store, out var x509TypeSymbol)) { return; } if (!wellKnownTypeProvider.TryGetTypeByMetadataName(WellKnownTypeNames.SystemSecurityCryptographyX509CertificatesStoreName, out var storeNameTypeSymbol)) { return; } // If X509Store is initialized with Root store, then that instance is flagged. var constructorMapper = new ConstructorMapper( (IMethodSymbol constructorMethod, IReadOnlyList <ValueContentAbstractValue> argumentValueContentAbstractValues, IReadOnlyList <PointsToAbstractValue> argumentPointsToAbstractValues) => { var kind = PropertySetAbstractValueKind.Unflagged; if (constructorMethod.Parameters.Length > 0) { if (constructorMethod.Parameters[0].Type.Equals(storeNameTypeSymbol)) { kind = PropertySetCallbacks.EvaluateLiteralValues(argumentValueContentAbstractValues[0], o => o.Equals(6)); } else if (constructorMethod.Parameters[0].Type.SpecialType == SpecialType.System_String) { kind = PropertySetCallbacks.EvaluateLiteralValues( argumentValueContentAbstractValues[0], s => string.Equals(s.ToString(), "root", StringComparison.OrdinalIgnoreCase)); } } return(PropertySetAbstractValue.GetInstance(kind)); }); var rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( (OperationBlockStartAnalysisContext operationBlockStartAnalysisContext) => { operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation; if (x509TypeSymbol.Equals(invocationOperation.Instance?.Type) && invocationOperation.TargetMethod.Name == "Add") { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((invocationOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Invocation); operationBlockStartAnalysisContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var argumentOperation = (IArgumentOperation)operationAnalysisContext.Operation; if (x509TypeSymbol.Equals(argumentOperation.Parameter.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((argumentOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Argument); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } allResults = PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, WellKnownTypeNames.SystemSecurityCryptographyX509CertificatesX509Store, constructorMapper, PropertyMappers, hazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken)); } if (allResults == null) { return; } foreach (KeyValuePair <(Location Location, IMethodSymbol Method), HazardousUsageEvaluationResult> kvp in allResults) { DiagnosticDescriptor descriptor; switch (kvp.Value) { case HazardousUsageEvaluationResult.Flagged: descriptor = DefinitelyInstallRootCertRule; break; case HazardousUsageEvaluationResult.MaybeFlagged: descriptor = MaybeInstallRootCertRule; break; default: Debug.Fail($"Unhandled result value {kvp.Value}"); continue; } compilationAnalysisContext.ReportDiagnostic( Diagnostic.Create( descriptor, kvp.Key.Location, kvp.Key.Method.ToDisplayString( SymbolDisplayFormat.MinimallyQualifiedFormat))); } } finally { rootOperationsNeedingAnalysis.Free(); allResults?.Free(); } }); }); }
public override void Initialize(AnalysisContext context) { if (!Debugger.IsAttached) // prefer single thread for debugging in development { context.EnableConcurrentExecution(); } if (context.IsAuditMode()) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics); } else { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); } context.RegisterCompilationStartAction( (CompilationStartAnalysisContext compilationStartAnalysisContext) => { Compilation compilation = compilationStartAnalysisContext.Compilation; var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation); if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(ValidatorTypeName, out var validatorType)) { return; } var rootOperationsNeedingAnalysis = PooledHashSet <(IOperation, ISymbol)> .GetInstance(); compilationStartAnalysisContext.RegisterOperationBlockStartAction( operationBlockStartContext => { ISymbol owningSymbol = operationBlockStartContext.OwningSymbol; AnalyzerOptions options = operationBlockStartContext.Options; CancellationToken cancellationToken = operationBlockStartContext.CancellationToken; if (options.IsConfiguredToSkipAnalysis(RuleRequiredPasswordValidators, owningSymbol, compilation, cancellationToken)) { return; } operationBlockStartContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var returnOperation = (IReturnOperation)operationAnalysisContext.Operation; if (validatorType.Equals(returnOperation.ReturnedValue?.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add( (returnOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Return); operationBlockStartContext.RegisterOperationAction( (OperationAnalysisContext operationAnalysisContext) => { var argumentOperation = (IArgumentOperation)operationAnalysisContext.Operation; if (argumentOperation.Parameter.Type.Equals(validatorType)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((argumentOperation.GetRoot(), operationAnalysisContext.ContainingSymbol)); } } }, OperationKind.Argument); operationBlockStartContext.RegisterOperationAction( ctx => { var operation = (IObjectCreationOperation)ctx.Operation; if (validatorType.Equals(operation.Type)) { lock (rootOperationsNeedingAnalysis) { rootOperationsNeedingAnalysis.Add((operation.GetRoot(), ctx.ContainingSymbol)); } } }, OperationKind.ObjectCreation); }); compilationStartAnalysisContext.RegisterCompilationEndAction( (CompilationAnalysisContext compilationAnalysisContext) => { PooledDictionary <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult>?allResults = null; try { lock (rootOperationsNeedingAnalysis) { if (!rootOperationsNeedingAnalysis.Any()) { return; } PooledDictionary <(Location Location, IMethodSymbol?Method), HazardousUsageEvaluationResult>?GetHazardousUsages( ConstructorMapper constructorMapper, PropertyMapperCollection propertyMappers, HazardousUsageEvaluatorCollection hazardousUsageEvaluators) { return(PropertySetAnalysis.BatchGetOrComputeHazardousUsages( compilationAnalysisContext.Compilation, rootOperationsNeedingAnalysis, compilationAnalysisContext.Options, ValidatorTypeName, constructorMapper, propertyMappers, hazardousUsageEvaluators, InterproceduralAnalysisConfiguration.Create( compilationAnalysisContext.Options, SupportedDiagnostics, rootOperationsNeedingAnalysis.First().Item1, compilationAnalysisContext.Compilation, defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive, cancellationToken: compilationAnalysisContext.CancellationToken))); } var configuration = Configuration.GetOrCreate(compilationStartAnalysisContext); foreach (var requiredProperty in configuration.PasswordValidatorRequiredProperties) { allResults?.Free(compilationAnalysisContext.CancellationToken); allResults = null; (PropertyMapperCollection propertyMappers, ConstructorMapper constructorMapper) = BuildRequiredPropertiesMappers((x) => PropertySetToTrueCallback(x, configuration.AuditMode), requiredProperty); allResults = GetHazardousUsages(constructorMapper, propertyMappers, HazardousUsageEvaluators); ReportDiagnostics( RuleRequiredPasswordValidators, compilationAnalysisContext, allResults, configuration.AuditMode, requiredProperty); } allResults?.Free(compilationAnalysisContext.CancellationToken); allResults = null; (PropertyMapperCollection propertyMappers2, ConstructorMapper constructorMapper2) = BuildRequiredPropertiesMappers((x) => PropertyLenCallback(x, configuration.AuditMode, configuration.PasswordValidatorRequiredLength), "RequiredLength"); allResults = GetHazardousUsages(constructorMapper2, propertyMappers2, HazardousUsageEvaluators); ReportDiagnostics( RulePasswordLength, compilationAnalysisContext, allResults, configuration.AuditMode, configuration.PasswordValidatorRequiredLength); var hazardousUsageEvaluators = new HazardousUsageEvaluatorCollection( new HazardousUsageEvaluator( HazardousUsageEvaluatorKind.Return, (abstractValue) => PropertiesCountEvaluatorCallback( abstractValue, configuration.MinimumPasswordValidatorProperties, configuration.AuditMode)), new HazardousUsageEvaluator( HazardousUsageEvaluatorKind.Initialization, (abstractValue) => PropertiesCountEvaluatorCallback( abstractValue, configuration.MinimumPasswordValidatorProperties, configuration.AuditMode)), new HazardousUsageEvaluator( HazardousUsageEvaluatorKind.Argument, (abstractValue) => PropertiesCountEvaluatorCallback( abstractValue, configuration.MinimumPasswordValidatorProperties, configuration.AuditMode))); allResults?.Free(compilationAnalysisContext.CancellationToken); allResults = null; (PropertyMapperCollection propertyMappers3, ConstructorMapper constructorMapper3) = BuildRequiredPropertiesMappers((x) => PropertySetToTrueCallback(x, configuration.AuditMode), AllPropertyNames); allResults = GetHazardousUsages(constructorMapper3, propertyMappers3, hazardousUsageEvaluators); ReportDiagnostics( RulePasswordValidators, compilationAnalysisContext, allResults, configuration.AuditMode, configuration.MinimumPasswordValidatorProperties); } } finally { rootOperationsNeedingAnalysis.Free(compilationAnalysisContext.CancellationToken); allResults?.Free(compilationAnalysisContext.CancellationToken); } }); }); }