Exemplo n.º 1
0
        private void AnalyzeAssignment(OperationAnalysisContext context)
        {
            var assignmentOperation = (ISimpleAssignmentOperation)context.Operation;

            // Check if there are more then one assignment in a statement
            if (assignmentOperation.Target is not IMemberReferenceOperation operationTarget)
            {
                return;
            }

            // This analyzer makes sense only for reference type objects
            if (operationTarget.Instance?.Type?.IsReferenceType != true)
            {
                return;
            }

            bool isViolationFound = operationTarget.Instance switch
            {
                ILocalReferenceOperation localInstance =>
                AnalyzeAssignmentToMember(assignmentOperation, localInstance, (a, b) => a.Local.Equals(b.Local)),
                IMemberReferenceOperation memberInstance =>
                AnalyzeAssignmentToMember(assignmentOperation, memberInstance, (a, b) => a.Member.Equals(b.Member) && a.Instance?.Syntax.ToString() == b.Instance?.Syntax.ToString()),
                IParameterReferenceOperation parameterInstance =>
                AnalyzeAssignmentToMember(assignmentOperation, parameterInstance, (a, b) => a.Parameter.Equals(b.Parameter)),
                _ => false,
            };

            if (isViolationFound)
            {
                var diagnostic = operationTarget.CreateDiagnostic(Rule, operationTarget.Instance.Syntax, operationTarget.Member.Name);
                context.ReportDiagnostic(diagnostic);
            }
        }
Exemplo n.º 2
0
            // Local functions
            static bool IsArgumentValueEqual(IOperation targetArg, IOperation valueArg)
            {
                // Check if arguments are identical constant/local/parameter reference operations.
                //   1. Not identical: 'this[i] = this[j]'
                //   2. Identical: 'this[i] = this[i]', 'this[0] = this[0]'
                if (targetArg.Kind != valueArg.Kind)
                {
                    return(false);
                }

                if (targetArg.ConstantValue.HasValue != valueArg.ConstantValue.HasValue)
                {
                    return(false);
                }

                if (targetArg.ConstantValue.HasValue)
                {
                    return(Equals(targetArg.ConstantValue.Value, valueArg.ConstantValue.Value));
                }

#pragma warning disable IDE0055 // Fix formatting - Does not seem to be handling switch expressions.
                return(targetArg switch
                {
                    ILocalReferenceOperation targetLocalReference =>
                    Equals(targetLocalReference.Local, ((ILocalReferenceOperation)valueArg).Local),
                    IParameterReferenceOperation targetParameterReference =>
                    Equals(targetParameterReference.Parameter, ((IParameterReferenceOperation)valueArg).Parameter),
                    _ => false,
                });
Exemplo n.º 3
0
 internal static ISymbol?GetUnderlyingSymbol(IOperation?operation)
 {
     return(operation switch
     {
         IParameterReferenceOperation paramRef => paramRef.Parameter,
         ILocalReferenceOperation localRef => localRef.Local,
         IMemberReferenceOperation memberRef => memberRef.Member,
         _ => null,
     });
            public override IdentifierInfo VisitParameterReference([NotNull] IParameterReferenceOperation operation,
                                                                   [CanBeNull] object argument)
            {
                var name = new IdentifierName(operation.Parameter.Name,
                                              /* CSharpShortErrorMessageFormat returns 'int', ie. without parameter name */
                                              operation.Parameter.Name);

                return(new IdentifierInfo(name, operation.Parameter.Type));
            }
Exemplo n.º 5
0
        private static AbstractExpression ReadParameterReference(IParameterReferenceOperation op)
        {
            var context = CodeReaderContext.GetContextOrThrow();

            return(new ParameterExpression()
            {
                // TODO: implement properly
            });
        }
    public override void VisitParameterReference(IParameterReferenceOperation operation)
    {
        var visitor = new NullableParameterVisitor();

        visitor.Visit(operation.Parameter);
        if (visitor.IsNullableParameter)
        {
            MatchedNullableParameter = operation.Parameter;
        }
    }
            protected override ITypeSymbol GetSymbolType(
                SemanticModel semanticModel,
                ISymbol symbol
                )
            {
                var selectionOperation = semanticModel.GetOperation(
                    SelectionResult.GetContainingScope()
                    );

                switch (symbol)
                {
                case ILocalSymbol localSymbol
                    when localSymbol.NullableAnnotation == NullableAnnotation.Annotated:
                case IParameterSymbol parameterSymbol
                    when parameterSymbol.NullableAnnotation == NullableAnnotation.Annotated:

                    // For local symbols and parameters, we can check what the flow state
                    // for refences to the symbols are and determine if we can change
                    // the nullability to a less permissive state.
                    var references = selectionOperation
                                     .DescendantsAndSelf()
                                     .Where(IsSymbolReferencedByOperation);

                    if (AreAllReferencesNotNull(references))
                    {
                        return(base.GetSymbolType(semanticModel, symbol)
                               .WithNullableAnnotation(NullableAnnotation.NotAnnotated));
                    }

                    return(base.GetSymbolType(semanticModel, symbol));

                default:
                    return(base.GetSymbolType(semanticModel, symbol));
                }

                bool AreAllReferencesNotNull(IEnumerable <IOperation> references) =>
                references.All(
                    r =>
                    semanticModel.GetTypeInfo(r.Syntax).Nullability.FlowState
                    == NullableFlowState.NotNull
                    );

                bool IsSymbolReferencedByOperation(IOperation operation) =>
                operation switch
                {
                    ILocalReferenceOperation localReference
                    => localReference.Local.Equals(symbol),
                    IParameterReferenceOperation parameterReference
                    => parameterReference.Parameter.Equals(symbol),
                    IAssignmentOperation assignment
                    => IsSymbolReferencedByOperation(assignment.Target),
                    _ => false
                };
            }
        }
            public override IdentifierInfo VisitParameterReference([NotNull] IParameterReferenceOperation operation,
                                                                   [CanBeNull] object argument)
            {
                var name = new IdentifierName(operation.Parameter.Name,
#pragma warning disable AV2310 // Code blocks should not contain inline comments
                               /* CSharpShortErrorMessageFormat returns 'int', ie. without parameter name */
#pragma warning restore AV2310 // Code blocks should not contain inline comments
                                              operation.Parameter.Name);

                return(new IdentifierInfo(name, operation.Parameter.Type, operation.Parameter.Kind.ToString()));
            }
            private Task VisitReferenceAsync(IOperation operation, CancellationToken cancellationToken)
            {
                Debug.Assert(operation is
                             ILocalReferenceOperation or
                             IParameterReferenceOperation or
                             IFieldReferenceOperation or
                             IPropertyReferenceOperation);

                if (IsContainedIn <IArgumentOperation>(operation, out var argumentOperation) && argumentOperation.Parameter is not null)
                {
                    if (argumentOperation.Parameter.IsRefOrOut())
                    {
                        // Always add ref or out parameters to track as assignments since the values count as
                        // assignments across method calls for the purposes of value tracking.
                        return(AddOperationAsync(operation, argumentOperation.Parameter, cancellationToken));
                    }

                    // If the parameter is not a ref or out param, track the reference assignments that count
                    // as input to the argument being passed to the method.
                    return(AddReference(operation, cancellationToken));
                }

                if (IsContainedIn <IReturnOperation>(operation) || IsContainedIn <IAssignmentOperation>(operation))
                {
                    // If the reference is part of a return operation or assignment operation we want to track where the values come from
                    // since they contribute to the "output" of the method/assignment and are relavent for value tracking.
                    return(AddReference(operation, cancellationToken));
                }

                return(Task.CompletedTask);

                Task AddReference(IOperation operation, CancellationToken cancellationToken)
                => operation switch
                {
                    IParameterReferenceOperation parameterReference => AddOperationAsync(operation, parameterReference.Parameter, cancellationToken),
                    IFieldReferenceOperation fieldReferenceOperation => AddOperationAsync(operation, fieldReferenceOperation.Member, cancellationToken),
                    IPropertyReferenceOperation propertyReferenceOperation => AddOperationAsync(operation, propertyReferenceOperation.Member, cancellationToken),
                    ILocalReferenceOperation localReferenceOperation => AddOperationAsync(operation, localReferenceOperation.Local, cancellationToken),
                    _ => Task.CompletedTask
                };
            }
Exemplo n.º 10
0
            public override PointsToAbstractValue VisitParameterReference(IParameterReferenceOperation operation, object argument)
            {
                // Create a dummy PointsTo value for each reference type parameter.
                if (!operation.Type.HasValueCopySemantics())
                {
                    var result = AnalysisEntityFactory.TryCreateForSymbolDeclaration(operation.Parameter, out AnalysisEntity analysisEntity);
                    Debug.Assert(result);
                    if (!HasAbstractValue(analysisEntity))
                    {
                        var value = new PointsToAbstractValue(AbstractLocation.CreateAllocationLocation(operation, operation.Parameter.Type));
                        SetAbstractValue(analysisEntity, value);
                        return(value);
                    }

                    return(GetAbstractValue(analysisEntity));
                }
                else
                {
                    return(PointsToAbstractValue.NoLocation);
                }
            }
Exemplo n.º 11
0
 public override MultiValue VisitParameterReference(IParameterReferenceOperation paramRef, StateValue state)
 {
     return(paramRef.Parameter.Type.IsTypeInterestingForDataflow() ? new MethodParameterValue(paramRef.Parameter) : TopValue);
 }
Exemplo n.º 12
0
 public override IOperation VisitParameterReference(IParameterReferenceOperation operation, object argument)
 {
     return(new ParameterReferenceExpression(operation.Parameter, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit));
 }
Exemplo n.º 13
0
 public override Scope VisitParameterReference(IParameterReferenceOperation operation, Scope currentScope) =>
 currentScope;
Exemplo n.º 14
0
 public override void VisitParameterReference(IParameterReferenceOperation operation)
 {
     Assert.Equal(OperationKind.ParameterReference, operation.Kind);
     Assert.NotNull(operation.Parameter);
     Assert.Empty(operation.Children);
 }
Exemplo n.º 15
0
            public override GlobalFlowStateDictionaryAnalysisValue VisitParameterReference(IParameterReferenceOperation operation, object?argument)
            {
                var value = base.VisitParameterReference(operation, argument);

                return(VisitLocalOrParameter(operation.Parameter.Type?.OriginalDefinition, operation, value));
            }
Exemplo n.º 16
0
        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 compilationContext) =>
            {
                var config = Configuration.GetOrCreate(compilationContext);

                if (config.AuditMode)
                {
                    TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = config.TaintConfiguration.GetSinkSymbolMap(this.SinkKind);
                    if (sinkInfoSymbolMap.IsEmpty)
                    {
                        return;
                    }

                    Compilation compilation = compilationContext.Compilation;
                    compilationContext.RegisterOperationBlockStartAction(
                        operationBlockStartContext =>
                    {
                        ISymbol owningSymbol                = operationBlockStartContext.OwningSymbol;
                        AnalyzerOptions options             = operationBlockStartContext.Options;
                        CancellationToken cancellationToken = operationBlockStartContext.CancellationToken;
                        if (options.IsConfiguredToSkipAnalysis(TaintedDataEnteringSinkDescriptor, owningSymbol, compilation, cancellationToken))
                        {
                            return;
                        }

                        WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

                        void CreateWarning(OperationAnalysisContext operationAnalysisContext, Location location, ISymbol paramSymbol, ISymbol symbol)
                        {
                            // Something like:
                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                            Diagnostic diagnostic = Diagnostic.Create(
                                this.TaintedDataEnteringSinkDescriptor,
                                location,
                                additionalLocations: new Location[] { location },
                                messageArgs: new object[] {
                                paramSymbol.Name,
                                symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                            });
                            operationAnalysisContext.ReportDiagnostic(diagnostic);
                        }

                        bool IsConstant(IOperation operation, IOperation value, OperationAnalysisContext operationAnalysisContext)
                        {
                            if (value.ConstantValue.HasValue || value is ITypeOfOperation)
                            {
                                return(true);
                            }

                            if (!operation.TryGetEnclosingControlFlowGraph(out var cfg))
                            {
                                return(false);
                            }

                            var valueContentResult = ValueContentAnalysis.TryGetOrComputeResult(cfg, owningSymbol, wellKnownTypeProvider,
                                                                                                operationAnalysisContext.Options, TaintedDataEnteringSinkDescriptor, PointsToAnalysisKind.Complete, operationAnalysisContext.CancellationToken);
                            if (valueContentResult == null)
                            {
                                return(false);
                            }

                            ValueContentAbstractValue abstractValue = valueContentResult[value.Kind, value.Syntax];
                            return(abstractValue.NonLiteralState == ValueContainsNonLiteralState.No);
                        }

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IAssignmentOperation operation = (IAssignmentOperation)operationAnalysisContext.Operation;
                            if (!(operation.Target is IPropertyReferenceOperation propertyReferenceOperation))
                            {
                                return;
                            }

                            IEnumerable <SinkInfo>?infosForType = sinkInfoSymbolMap.GetInfosForType(propertyReferenceOperation.Member.ContainingType);
                            if (infosForType != null &&
                                infosForType.Any(x => x.SinkProperties.Contains(propertyReferenceOperation.Member.MetadataName)) &&
                                !IsConstant(operation, operation.Value, operationAnalysisContext))
                            {
                                CreateWarning(
                                    operationAnalysisContext,
                                    propertyReferenceOperation.Syntax.GetLocation(),
                                    operation.Value.Type,
                                    propertyReferenceOperation.Member);
                            }
                        },
                            OperationKind.SimpleAssignment);

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                            IEnumerable <SinkInfo>?infosForType      = sinkInfoSymbolMap.GetInfosForType(invocationOperation.TargetMethod.ContainingType);
                            if (infosForType == null)
                            {
                                return;
                            }

                            foreach (SinkInfo sinkInfo in infosForType)
                            {
                                foreach (IArgumentOperation taintedArgument in invocationOperation.Arguments.Where(x => !IsConstant(x, x.Value, operationAnalysisContext)))
                                {
                                    if (sinkInfo.SinkMethodParameters.TryGetValue(invocationOperation.TargetMethod.MetadataName, out ImmutableHashSet <string> sinkParameters) &&
                                        sinkParameters.Contains(taintedArgument.Parameter.MetadataName))
                                    {
                                        CreateWarning(operationAnalysisContext, invocationOperation.Syntax.GetLocation(), taintedArgument.Parameter, invocationOperation.TargetMethod);
                                        return;
                                    }
                                }
                            }
                        },
                            OperationKind.Invocation);

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IObjectCreationOperation invocationOperation = (IObjectCreationOperation)operationAnalysisContext.Operation;
                            IEnumerable <SinkInfo>?infosForType          = sinkInfoSymbolMap.GetInfosForType(invocationOperation.Constructor.ContainingType);
                            if (infosForType == null)
                            {
                                return;
                            }

                            foreach (SinkInfo sinkInfo in infosForType)
                            {
                                foreach (IArgumentOperation taintedArgument in invocationOperation.Arguments.Where(x => !IsConstant(x, x.Value, operationAnalysisContext)))
                                {
                                    if (sinkInfo.IsAnyStringParameterInConstructorASink &&
                                        taintedArgument.Parameter.Type.SpecialType == SpecialType.System_String)
                                    {
                                        CreateWarning(operationAnalysisContext, invocationOperation.Syntax.GetLocation(), taintedArgument.Parameter, invocationOperation.Constructor);
                                        return;
                                    }
                                    else if (sinkInfo.SinkMethodParameters.TryGetValue(invocationOperation.Constructor.MetadataName, out ImmutableHashSet <string> sinkParameters) &&
                                             sinkParameters.Contains(taintedArgument.Parameter.MetadataName))
                                    {
                                        CreateWarning(operationAnalysisContext, invocationOperation.Syntax.GetLocation(), taintedArgument.Parameter, invocationOperation.Constructor);
                                        return;
                                    }
                                }
                            }
                        },
                            OperationKind.ObjectCreation);
                    });
                }
                else
                {
                    TaintedDataSymbolMap <SourceInfo> sourceInfoSymbolMap = config.TaintConfiguration.GetSourceSymbolMap(this.SinkKind);
                    if (sourceInfoSymbolMap.IsEmpty)
                    {
                        return;
                    }

                    TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = config.TaintConfiguration.GetSinkSymbolMap(this.SinkKind);
                    if (sinkInfoSymbolMap.IsEmpty)
                    {
                        return;
                    }

                    Compilation compilation = compilationContext.Compilation;
                    compilationContext.RegisterOperationBlockStartAction(
                        operationBlockStartContext =>
                    {
                        ISymbol owningSymbol                = operationBlockStartContext.OwningSymbol;
                        AnalyzerOptions options             = operationBlockStartContext.Options;
                        CancellationToken cancellationToken = operationBlockStartContext.CancellationToken;
                        if (options.IsConfiguredToSkipAnalysis(TaintedDataEnteringSinkDescriptor, owningSymbol, compilation, cancellationToken))
                        {
                            return;
                        }

                        WellKnownTypeProvider wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(compilation);
                        Lazy <ControlFlowGraph?> controlFlowGraphFactory = new Lazy <ControlFlowGraph?>(
                            () => operationBlockStartContext.OperationBlocks.GetControlFlowGraph());
                        Lazy <PointsToAnalysisResult?> pointsToFactory = new Lazy <PointsToAnalysisResult?>(
                            () =>
                        {
                            if (controlFlowGraphFactory.Value == null)
                            {
                                return(null);
                            }

                            InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                                options,
                                SupportedDiagnostics,
                                controlFlowGraphFactory.Value,
                                operationBlockStartContext.Compilation,
                                defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                cancellationToken: cancellationToken,
                                defaultMaxInterproceduralMethodCallChain: config.MaxInterproceduralMethodCallChain,
                                defaultMaxInterproceduralLambdaOrLocalFunctionCallChain: config.MaxInterproceduralLambdaOrLocalFunctionCallChain);
                            return(PointsToAnalysis.TryGetOrComputeResult(
                                       controlFlowGraphFactory.Value,
                                       owningSymbol,
                                       options,
                                       wellKnownTypeProvider,
                                       PointsToAnalysisKind.Complete,
                                       interproceduralAnalysisConfiguration,
                                       interproceduralAnalysisPredicate: null));
                        });
                        Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)> valueContentFactory = new Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)>(
                            () =>
                        {
                            if (controlFlowGraphFactory.Value == null)
                            {
                                return(null, null);
                            }

                            InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                                options,
                                SupportedDiagnostics,
                                controlFlowGraphFactory.Value,
                                operationBlockStartContext.Compilation,
                                defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive,
                                cancellationToken: cancellationToken,
                                defaultMaxInterproceduralMethodCallChain: config.MaxInterproceduralMethodCallChain,
                                defaultMaxInterproceduralLambdaOrLocalFunctionCallChain: config.MaxInterproceduralLambdaOrLocalFunctionCallChain);
                            ValueContentAnalysisResult?valuecontentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                                controlFlowGraphFactory.Value,
                                owningSymbol,
                                options,
                                wellKnownTypeProvider,
                                PointsToAnalysisKind.Complete,
                                interproceduralAnalysisConfiguration,
                                out _,
                                out PointsToAnalysisResult? p);

                            return(p, valuecontentAnalysisResult);
                        });

                        var rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IPropertyReferenceOperation propertyReferenceOperation = (IPropertyReferenceOperation)operationAnalysisContext.Operation;
                            if (sourceInfoSymbolMap.IsSourceProperty(propertyReferenceOperation.Property))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(propertyReferenceOperation.GetRoot());
                                }
                            }
                        },
                            OperationKind.PropertyReference);

                        if (sourceInfoSymbolMap.RequiresFieldReferenceAnalysis)
                        {
                            operationBlockStartContext.RegisterOperationAction(
                                operationAnalysisContext =>
                            {
                                IFieldReferenceOperation fieldReferenceOperation = (IFieldReferenceOperation)operationAnalysisContext.Operation;
                                if (sourceInfoSymbolMap.IsSourceField(fieldReferenceOperation.Field))
                                {
                                    lock (rootOperationsNeedingAnalysis)
                                    {
                                        rootOperationsNeedingAnalysis.Add(fieldReferenceOperation.GetRoot());
                                    }
                                }
                            },
                                OperationKind.FieldReference);
                        }

                        if (sourceInfoSymbolMap.RequiresParameterReferenceAnalysis)
                        {
                            operationBlockStartContext.RegisterOperationAction(
                                operationAnalysisContext =>
                            {
                                IParameterReferenceOperation parameterReferenceOperation = (IParameterReferenceOperation)operationAnalysisContext.Operation;
                                if (sourceInfoSymbolMap.IsSourceParameter(parameterReferenceOperation.Parameter, wellKnownTypeProvider))
                                {
                                    lock (rootOperationsNeedingAnalysis)
                                    {
                                        rootOperationsNeedingAnalysis.Add(parameterReferenceOperation.GetRoot());
                                    }
                                }
                            },
                                OperationKind.ParameterReference);
                        }

                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                            if (sourceInfoSymbolMap.IsSourceMethod(
                                    invocationOperation.TargetMethod,
                                    invocationOperation.Arguments,
                                    pointsToFactory,
                                    valueContentFactory,
                                    out _))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(invocationOperation.GetRoot());
                                }
                            }
                        },
                            OperationKind.Invocation);

                        if (config.TaintConfiguration.HasTaintArraySource(SinkKind, config))
                        {
                            operationBlockStartContext.RegisterOperationAction(
                                operationAnalysisContext =>
                            {
                                IArrayInitializerOperation arrayInitializerOperation = (IArrayInitializerOperation)operationAnalysisContext.Operation;
                                if (arrayInitializerOperation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation)?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                                    sourceInfoSymbolMap.IsSourceConstantArrayOfType(arrayTypeSymbol, arrayInitializerOperation))
                                {
                                    lock (rootOperationsNeedingAnalysis)
                                    {
                                        rootOperationsNeedingAnalysis.Add(operationAnalysisContext.Operation.GetRoot());
                                    }
                                }
                            },
                                OperationKind.ArrayInitializer);
                        }

                        operationBlockStartContext.RegisterOperationBlockEndAction(
                            operationBlockAnalysisContext =>
                        {
                            try
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    if (!rootOperationsNeedingAnalysis.Any())
                                    {
                                        return;
                                    }

                                    if (controlFlowGraphFactory.Value == null)
                                    {
                                        return;
                                    }

                                    foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                    {
                                        TaintedDataAnalysisResult?taintedDataAnalysisResult = TaintedDataAnalysis.TryGetOrComputeResult(
                                            controlFlowGraphFactory.Value,
                                            operationBlockAnalysisContext.Compilation,
                                            operationBlockAnalysisContext.OwningSymbol,
                                            operationBlockAnalysisContext.Options,
                                            TaintedDataEnteringSinkDescriptor,
                                            sourceInfoSymbolMap,
                                            config.TaintConfiguration.GetSanitizerSymbolMap(this.SinkKind),
                                            sinkInfoSymbolMap,
                                            operationBlockAnalysisContext.CancellationToken,
                                            config.MaxInterproceduralMethodCallChain,
                                            config.MaxInterproceduralLambdaOrLocalFunctionCallChain);
                                        if (taintedDataAnalysisResult == null)
                                        {
                                            return;
                                        }

                                        foreach (TaintedDataSourceSink sourceSink in taintedDataAnalysisResult.TaintedDataSourceSinks)
                                        {
                                            if (!sourceSink.SinkKinds.Contains(this.SinkKind))
                                            {
                                                continue;
                                            }

                                            foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                            {
                                                // Something like:
                                                // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                                Diagnostic diagnostic = Diagnostic.Create(
                                                    this.TaintedDataEnteringSinkDescriptor,
                                                    sourceSink.Sink.Location,
                                                    additionalLocations: new Location[] { sourceOrigin.Location },
                                                    messageArgs: new object[] {
                                                    sourceSink.Sink.Symbol.Name,
                                                    sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                    sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                    sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                                });
                                                operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                            }
                                        }
                                    }
                                }
                            }
                            finally
                            {
                                rootOperationsNeedingAnalysis.Free(compilationContext.CancellationToken);
                            }
                        });
                    });
                }
            });
        }
Exemplo n.º 17
0
 public virtual void VisitParameterReference(IParameterReferenceOperation operation)
 {
     DefaultVisit(operation);
 }
Exemplo n.º 18
0
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="operation">IOperationインスタンス</param>
        /// <param name="container">イベントコンテナ</param>
        public ParameterReference(IParameterReferenceOperation operation, EventContainer container) : base(container)
        {
            var symbol = operation.Parameter;

            Expressions.Add(new Expression(symbol.Name, Expression.GetSymbolTypeName(symbol)));
        }
Exemplo n.º 19
0
 public override void VisitParameterReference([NotNull] IParameterReferenceOperation operation)
 {
     base.VisitParameterReference(operation);
 }
 public override TAbstractAnalysisValue VisitParameterReference(IParameterReferenceOperation operation, object argument)
 {
     return(GetAbstractValue(operation.Parameter));
 }
Exemplo n.º 21
0
 public override bool VisitParameterReference([NotNull] IParameterReferenceOperation operation1,
                                              [CanBeNull] IOperation argument)
 {
     return(argument is IParameterReferenceOperation operation2 && AreBaseOperationsEqual(operation1, operation2) &&
            AreSymbolsEqual(operation1.Parameter, operation2.Parameter));
 }
Exemplo n.º 22
0
        public override void VisitParameterReference(IParameterReferenceOperation operation)
        {
            var parameter = operation.Parameter;

            base.VisitParameterReference(operation);
        }
Exemplo n.º 23
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationContext) =>
            {
                Compilation compilation             = compilationContext.Compilation;
                TaintedDataConfig taintedDataConfig = TaintedDataConfig.GetOrCreate(compilation);
                TaintedDataSymbolMap <SourceInfo> sourceInfoSymbolMap = taintedDataConfig.GetSourceSymbolMap(this.SinkKind);
                if (sourceInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                TaintedDataSymbolMap <SinkInfo> sinkInfoSymbolMap = taintedDataConfig.GetSinkSymbolMap(this.SinkKind);
                if (sinkInfoSymbolMap.IsEmpty)
                {
                    return;
                }

                compilationContext.RegisterOperationBlockStartAction(
                    operationBlockStartContext =>
                {
                    ISymbol owningSymbol                = operationBlockStartContext.OwningSymbol;
                    AnalyzerOptions options             = operationBlockStartContext.Options;
                    CancellationToken cancellationToken = operationBlockStartContext.CancellationToken;
                    if (options.IsConfiguredToSkipAnalysis(TaintedDataEnteringSinkDescriptor, owningSymbol, compilation))
                    {
                        return;
                    }

                    WellKnownTypeProvider wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(compilation);
                    Lazy <ControlFlowGraph?> controlFlowGraphFactory = new Lazy <ControlFlowGraph?>(
                        () => operationBlockStartContext.OperationBlocks.GetControlFlowGraph());
                    Lazy <PointsToAnalysisResult?> pointsToFactory = new Lazy <PointsToAnalysisResult?>(
                        () =>
                    {
                        if (controlFlowGraphFactory.Value == null)
                        {
                            return(null);
                        }

                        InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                            options,
                            SupportedDiagnostics,
                            controlFlowGraphFactory.Value,
                            operationBlockStartContext.Compilation,
                            defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive);
                        return(PointsToAnalysis.TryGetOrComputeResult(
                                   controlFlowGraphFactory.Value,
                                   owningSymbol,
                                   options,
                                   wellKnownTypeProvider,
                                   PointsToAnalysisKind.Complete,
                                   interproceduralAnalysisConfiguration,
                                   interproceduralAnalysisPredicate: null));
                    });
                    Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)> valueContentFactory = new Lazy <(PointsToAnalysisResult?, ValueContentAnalysisResult?)>(
                        () =>
                    {
                        if (controlFlowGraphFactory.Value == null)
                        {
                            return(null, null);
                        }

                        InterproceduralAnalysisConfiguration interproceduralAnalysisConfiguration = InterproceduralAnalysisConfiguration.Create(
                            options,
                            SupportedDiagnostics,
                            controlFlowGraphFactory.Value,
                            operationBlockStartContext.Compilation,
                            defaultInterproceduralAnalysisKind: InterproceduralAnalysisKind.ContextSensitive);
                        ValueContentAnalysisResult?valuecontentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                            controlFlowGraphFactory.Value,
                            owningSymbol,
                            options,
                            wellKnownTypeProvider,
                            PointsToAnalysisKind.Complete,
                            interproceduralAnalysisConfiguration,
                            out _,
                            out PointsToAnalysisResult? p);

                        return(p, valuecontentAnalysisResult);
                    });

                    PooledHashSet <IOperation> rootOperationsNeedingAnalysis = PooledHashSet <IOperation> .GetInstance();

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IPropertyReferenceOperation propertyReferenceOperation = (IPropertyReferenceOperation)operationAnalysisContext.Operation;
                        if (sourceInfoSymbolMap.IsSourceProperty(propertyReferenceOperation.Property))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(propertyReferenceOperation.GetRoot());
                            }
                        }
                    },
                        OperationKind.PropertyReference);

                    if (sourceInfoSymbolMap.RequiresParameterReferenceAnalysis)
                    {
                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IParameterReferenceOperation parameterReferenceOperation = (IParameterReferenceOperation)operationAnalysisContext.Operation;
                            if (sourceInfoSymbolMap.IsSourceParameter(parameterReferenceOperation.Parameter, wellKnownTypeProvider))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(parameterReferenceOperation.GetRoot());
                                }
                            }
                        },
                            OperationKind.ParameterReference);
                    }

                    operationBlockStartContext.RegisterOperationAction(
                        operationAnalysisContext =>
                    {
                        IInvocationOperation invocationOperation = (IInvocationOperation)operationAnalysisContext.Operation;
                        if (sourceInfoSymbolMap.IsSourceMethod(
                                invocationOperation.TargetMethod,
                                invocationOperation.Arguments,
                                pointsToFactory,
                                valueContentFactory,
                                out _))
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                rootOperationsNeedingAnalysis.Add(invocationOperation.GetRoot());
                            }
                        }
                    },
                        OperationKind.Invocation);

                    if (TaintedDataConfig.HasTaintArraySource(SinkKind))
                    {
                        operationBlockStartContext.RegisterOperationAction(
                            operationAnalysisContext =>
                        {
                            IArrayInitializerOperation arrayInitializerOperation = (IArrayInitializerOperation)operationAnalysisContext.Operation;
                            if (arrayInitializerOperation.GetAncestor <IArrayCreationOperation>(OperationKind.ArrayCreation)?.Type is IArrayTypeSymbol arrayTypeSymbol &&
                                sourceInfoSymbolMap.IsSourceConstantArrayOfType(arrayTypeSymbol, arrayInitializerOperation))
                            {
                                lock (rootOperationsNeedingAnalysis)
                                {
                                    rootOperationsNeedingAnalysis.Add(operationAnalysisContext.Operation.GetRoot());
                                }
                            }
                        },
                            OperationKind.ArrayInitializer);
                    }

                    operationBlockStartContext.RegisterOperationBlockEndAction(
                        operationBlockAnalysisContext =>
                    {
                        try
                        {
                            lock (rootOperationsNeedingAnalysis)
                            {
                                if (!rootOperationsNeedingAnalysis.Any())
                                {
                                    return;
                                }

                                if (controlFlowGraphFactory.Value == null)
                                {
                                    return;
                                }

                                foreach (IOperation rootOperation in rootOperationsNeedingAnalysis)
                                {
                                    TaintedDataAnalysisResult?taintedDataAnalysisResult = TaintedDataAnalysis.TryGetOrComputeResult(
                                        controlFlowGraphFactory.Value,
                                        operationBlockAnalysisContext.Compilation,
                                        operationBlockAnalysisContext.OwningSymbol,
                                        operationBlockAnalysisContext.Options,
                                        TaintedDataEnteringSinkDescriptor,
                                        sourceInfoSymbolMap,
                                        taintedDataConfig.GetSanitizerSymbolMap(this.SinkKind),
                                        sinkInfoSymbolMap);
                                    if (taintedDataAnalysisResult == null)
                                    {
                                        return;
                                    }

                                    foreach (TaintedDataSourceSink sourceSink in taintedDataAnalysisResult.TaintedDataSourceSinks)
                                    {
                                        if (!sourceSink.SinkKinds.Contains(this.SinkKind))
                                        {
                                            continue;
                                        }

                                        foreach (SymbolAccess sourceOrigin in sourceSink.SourceOrigins)
                                        {
                                            // Something like:
                                            // CA3001: Potential SQL injection vulnerability was found where '{0}' in method '{1}' may be tainted by user-controlled data from '{2}' in method '{3}'.
                                            Diagnostic diagnostic = Diagnostic.Create(
                                                this.TaintedDataEnteringSinkDescriptor,
                                                sourceSink.Sink.Location,
                                                additionalLocations: new Location[] { sourceOrigin.Location },
                                                messageArgs: new object[] {
                                                sourceSink.Sink.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceSink.Sink.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.Symbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                                sourceOrigin.AccessingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat)
                                            });
                                            operationBlockAnalysisContext.ReportDiagnostic(diagnostic);
                                        }
                                    }
                                }
                            }
                        }
                        finally
                        {
                            rootOperationsNeedingAnalysis.Free(compilationContext.CancellationToken);
                        }
                    });
                });
            });
        }
        public override TAbstractAnalysisValue VisitParameterReference(IParameterReferenceOperation operation, object argument)
        {
            var value = base.VisitParameterReference(operation, argument);

            return(ComputeAnalysisValueForReferenceOperation(operation, value));
        }
Exemplo n.º 25
0
 public override Scope VisitParameterReference(IParameterReferenceOperation operation, Scope currentScope) =>
 currentScope.Union(
     new ParameterValue(operation.Parameter)
     );