コード例 #1
0
            private static ImmutableHashSet <INamedTypeSymbol> GetIImmutableInterfaces(WellKnownTypeProvider wellKnownTypeProvider)
            {
                var builder = ImmutableHashSet.CreateBuilder <INamedTypeSymbol>();

                AddIfNotNull(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsImmutableIImmutableDictionary));
                AddIfNotNull(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsImmutableIImmutableList));
                AddIfNotNull(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsImmutableIImmutableQueue));
                AddIfNotNull(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsImmutableIImmutableSet));
                AddIfNotNull(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsImmutableIImmutableStack));
                return(builder.ToImmutable());

                // Local functions.
                void AddIfNotNull(INamedTypeSymbol?type)
                {
                    if (type != null)
                    {
                        builder.Add(type);
                    }
                }
            }
コード例 #2
0
        private static bool IsEventArgs(ITypeSymbol type, WellKnownTypeProvider wellKnownTypeProvider)
        {
            if (type.DerivesFrom(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemEventArgs)))
            {
                return(true);
            }

            if (type.IsValueType)
            {
                return(type.Name.EndsWith("EventArgs", StringComparison.Ordinal));
            }

            return(false);
        }
コード例 #3
0
 public KnownTypes(WellKnownTypeProvider wellKnownTypeProvider)
 {
     ICollectionType        = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsICollection);
     GenericICollectionType = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsGenericICollection1);
     ArrayType                    = wellKnownTypeProvider.Compilation.GetSpecialType(SpecialType.System_Array);
     DataMemberAttribute          = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeSerializationDataMemberAttribute);
     ImmutableInterfaces          = GetIImmutableInterfaces(wellKnownTypeProvider);
     ReadonlyCollection           = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsObjectModelReadOnlyCollection1);
     ReadonlyDictionary           = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsObjectModelReadOnlyDictionary2);
     ReadonlyObservableCollection = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsObjectModelReadOnlyObservableCollection1);
 }
コード例 #4
0
        private static bool IsSkippedMethod(IMethodSymbol methodSymbol, WellKnownTypeProvider wellKnownTypeProvider)
        {
            if (methodSymbol.IsConstructor() || methodSymbol.IsFinalizer())
            {
                return(true);
            }

            if (methodSymbol.ReturnsVoid &&
                methodSymbol.Parameters.IsEmpty &&
                (methodSymbol.Name == "Application_Start" || methodSymbol.Name == "Application_End") &&
                methodSymbol.ContainingType.Inherits(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebHttpApplication)))
            {
                return(true);
            }

            return(false);
        }
コード例 #5
0
        private static bool IsExplicitlyVisibleFromCom(IMethodSymbol methodSymbol, WellKnownTypeProvider wellKnownTypeProvider)
        {
            if (!methodSymbol.IsExternallyVisible() || methodSymbol.IsGenericMethod)
            {
                return(false);
            }

            var comVisibleAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeInteropServicesComVisibleAttribute);

            if (comVisibleAttribute == null)
            {
                return(false);
            }

            if (methodSymbol.GetAttributes().Any(attribute => attribute.AttributeClass.Equals(comVisibleAttribute)) ||
                methodSymbol.ContainingType.GetAttributes().Any(attribute => attribute.AttributeClass.Equals(comVisibleAttribute)))
            {
                return(true);
            }

            return(false);
        }
コード例 #6
0
            private bool ShouldSanitizeConversion(SpecialType type, IOperation operand)
            {
                if (type == SpecialType.System_Object || type == SpecialType.System_String)
                {
                    switch (operand.Type?.SpecialType)
                    {
                    case SpecialType.System_Enum:
                    case SpecialType.System_MulticastDelegate:
                    case SpecialType.System_Delegate:
                    case SpecialType.System_Boolean:
                    case SpecialType.System_SByte:
                    case SpecialType.System_Byte:
                    case SpecialType.System_Int16:
                    case SpecialType.System_Int32:
                    case SpecialType.System_Int64:
                    case SpecialType.System_UInt16:
                    case SpecialType.System_UInt32:
                    case SpecialType.System_UInt64:
                    case SpecialType.System_Decimal:
                    case SpecialType.System_Single:
                    case SpecialType.System_Double:
                    case SpecialType.System_IntPtr:
                    case SpecialType.System_UIntPtr:
                        return(true);

                    case SpecialType.None:
                    {
                        if (Equals(operand.Type, WellKnownTypeProvider.GetOrCreateTypeByMetadataName("System.Guid")))
                        {
                            return(true);
                        }
                    }
                    break;
                    }
                }

                return(false);
            }
        public sealed 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) =>
            {
                Compilation?compilation = compilationStartAnalysisContext.Compilation;
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

                if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataSet,
                        out INamedTypeSymbol? dataSetTypeSymbol) ||
                    !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataTable,
                        out INamedTypeSymbol? dataTableTypeSymbol))
                {
                    return;
                }

                INamedTypeSymbol?dataContractSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationDataContractSerializer);
                INamedTypeSymbol?dataContractJsonSerializerTypeSymbol =
                    wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemRuntimeSerializationJsonDataContractJsonSerializer);
                INamedTypeSymbol?javaScriptSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemWebScriptSerializationJavaScriptSerializer);
                INamedTypeSymbol?typeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemType);
                INamedTypeSymbol?xmlSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemXmlSerializationXmlSerializer);
                INamedTypeSymbol?jsonNetJsonSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.NewtonsoftJsonJsonSerializer);
                INamedTypeSymbol?jsonNetJsonConvertTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.NewtonsoftJsonJsonConvert);

                if (dataContractSerializerTypeSymbol == null &&
                    dataContractJsonSerializerTypeSymbol == null &&
                    javaScriptSerializerTypeSymbol == null &&
                    xmlSerializerTypeSymbol == null &&
                    jsonNetJsonSerializerTypeSymbol == null &&
                    jsonNetJsonConvertTypeSymbol == null)
                {
                    return;
                }

                InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IInvocationOperation invocationOperation =
                        (IInvocationOperation)operationAnalysisContext.Operation;
                    if (!IsDeserializationMethod(
                            invocationOperation,
                            out ObjectGraphOptions? optionsToUse,
                            out IEnumerable <(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>?deserializedTypes))
                    {
                        return;
                    }

                    RoslynDebug.Assert(optionsToUse != null);
                    RoslynDebug.Assert(deserializedTypes != null);

                    ReportDiagnosticsForInsecureTypes(operationAnalysisContext, optionsToUse, deserializedTypes);
                },
                    OperationKind.Invocation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IObjectCreationOperation objectCreationOperation =
                        (IObjectCreationOperation)operationAnalysisContext.Operation;
                    if (!IsDeserializationConstructor(
                            objectCreationOperation,
                            out ObjectGraphOptions? optionsToUse,
                            out IEnumerable <(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>?deserializedTypes))
                    {
                        return;
                    }

                    RoslynDebug.Assert(optionsToUse != null);
                    RoslynDebug.Assert(deserializedTypes != null);

                    ReportDiagnosticsForInsecureTypes(operationAnalysisContext, optionsToUse, deserializedTypes);
                },
                    OperationKind.ObjectCreation);

                return;

                // Local functions.

                // Determines if the invoked method is for deserialization, and what type of deserialization.
                bool IsDeserializationMethod(
                    IInvocationOperation invocationOperation,
                    out ObjectGraphOptions? optionsToUse,
                    out IEnumerable <(ITypeSymbol DeserializedTypeSymbol, IOperation OperationForLocation)>?deserializedTypes)
                {
                    optionsToUse      = null;
                    deserializedTypes = null;

                    IMethodSymbol targetMethod = invocationOperation.TargetMethod;
                    if (invocationOperation.Instance?.Type?.DerivesFrom(javaScriptSerializerTypeSymbol) == true)
                    {
                        if (targetMethod.MetadataName == "DeserializeObject" &&
                            invocationOperation.Parent?.Kind == OperationKind.Conversion &&
                            invocationOperation.Parent is IConversionOperation javaScriptConversionOperation)
                        {
                            optionsToUse      = ObjectGraphOptions.JavaScriptSerializerOptions;
                            deserializedTypes = new[]
                            {
                                (javaScriptConversionOperation.Type, (IOperation)javaScriptConversionOperation)
                            };
                        }
コード例 #8
0
        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) =>
            {
                Compilation?compilation = compilationStartAnalysisContext.Compilation;
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

                if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataSet,
                        out INamedTypeSymbol? dataSetTypeSymbol) ||
                    !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataTable,
                        out INamedTypeSymbol? dataTableTypeSymbol))
                {
                    return;
                }

                INamedTypeSymbol?serializableAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemSerializableAttribute);

                INamedTypeSymbol?generatedCodeAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemCodeDomCompilerGeneratedCodeAttribute);

                // For completeness, could also consider CollectionDataContractAttribute
                INamedTypeSymbol?dataContractAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationDataContractAttribute);
                INamedTypeSymbol?dataMemberAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationDataMemberAttribute);
                INamedTypeSymbol?ignoreDataMemberTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationIgnoreDataMemberAttribute);
                INamedTypeSymbol?knownTypeAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationKnownTypeAttribute);

                XmlSerializationAttributeTypes xmlSerializationAttributeTypes = new XmlSerializationAttributeTypes(
                    wellKnownTypeProvider);
                if (serializableAttributeTypeSymbol == null &&
                    (dataContractAttributeTypeSymbol == null || dataMemberAttributeTypeSymbol == null) &&
                    ignoreDataMemberTypeSymbol == null &&
                    knownTypeAttributeTypeSymbol == null &&
                    !xmlSerializationAttributeTypes.Any)
                {
                    return;
                }

                INamedTypeSymbol?designerCategoryAttributeTypeSymbol =
                    wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemComponentModelDesignerCategoryAttribute);
                INamedTypeSymbol?typedTableBaseTypeSymbol =
                    wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataTypedTableBase1);

                InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation);

                ConcurrentDictionary <INamedTypeSymbol, bool> visitedTypes =
                    new ConcurrentDictionary <INamedTypeSymbol, bool>();

                compilationStartAnalysisContext.RegisterSymbolAction(
                    (SymbolAnalysisContext symbolAnalysisContext) =>
                {
                    INamedTypeSymbol namedTypeSymbol = (INamedTypeSymbol)symbolAnalysisContext.Symbol;
                    bool hasSerializableAttribute    = namedTypeSymbol.HasAttribute(serializableAttributeTypeSymbol);

                    bool hasDataContractAttribute        = namedTypeSymbol.HasAttribute(dataContractAttributeTypeSymbol);
                    bool hasKnownTypeAttribute           = namedTypeSymbol.HasAttribute(knownTypeAttributeTypeSymbol);
                    bool hasAnyIgnoreDataMemberAttribute =
                        namedTypeSymbol.GetMembers().Any(m => m.HasAttribute(ignoreDataMemberTypeSymbol));
                    bool hasAnyXmlSerializationAttributes =
                        xmlSerializationAttributeTypes.HasAnyAttribute(namedTypeSymbol) ||
                        namedTypeSymbol.GetMembers().Any(m => xmlSerializationAttributeTypes.HasAnyAttribute(m));
                    if (!hasSerializableAttribute &&
                        !hasDataContractAttribute &&
                        !hasKnownTypeAttribute &&
                        !hasAnyIgnoreDataMemberAttribute &&
                        !hasAnyXmlSerializationAttributes)
                    {
                        // Don't have any attributes suggesting this class is serialized.
                        return;
                    }

                    bool isProbablyAutogeneratedForGuiApp =
                        namedTypeSymbol.HasAttribute(designerCategoryAttributeTypeSymbol) ||
                        (namedTypeSymbol.BaseType != null &&
                         namedTypeSymbol.BaseType.IsGenericType &&
                         namedTypeSymbol.BaseType.ConstructedFrom.Equals(typedTableBaseTypeSymbol));

                    ObjectGraphOptions options = new ObjectGraphOptions(
                        recurse: false,
                        binarySerialization: hasSerializableAttribute,
                        dataContractSerialization:
                        hasDataContractAttribute ||
                        hasAnyIgnoreDataMemberAttribute ||
                        hasKnownTypeAttribute,
                        xmlSerialization: hasAnyXmlSerializationAttributes);

                    if (decider.IsObjectGraphInsecure(
                            namedTypeSymbol,
                            options,
                            out ImmutableArray <InsecureObjectGraphResult> results))
                    {
                        DiagnosticDescriptor diagnosticToReport;
                        if (hasSerializableAttribute)
                        {
                            diagnosticToReport =
                                isProbablyAutogeneratedForGuiApp
                                            ? RceAutogeneratedSerializableContainsDangerousType
                                            : RceSerializableContainsDangerousType;
                        }
                        else
                        {
                            diagnosticToReport = SerializableContainsDangerousType;
                        }

                        foreach (InsecureObjectGraphResult result in results)
                        {
                            symbolAnalysisContext.ReportDiagnostic(
                                Diagnostic.Create(
                                    diagnosticToReport,
                                    result.GetLocation(),
                                    result.InsecureType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                    result.GetDisplayString()));
                        }
                    }
                },
                    SymbolKind.NamedType);
            });
        }
コード例 #9
0
 public DisposableFieldAnalyzer(WellKnownTypeProvider wellKnownTypeProvider)
 {
     _disposableTypeSymbol      = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable);
     _asyncDisposableTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIAsyncDisposable);
 }
コード例 #10
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.EnableConcurrentExecution();
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            analysisContext.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartContext) =>
            {
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilationStartContext.Compilation);
                INamedTypeSymbol?mvcControllerSymbol        = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcController);
                INamedTypeSymbol?mvcControllerBaseSymbol    = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcControllerBase);
                INamedTypeSymbol?actionResultSymbol         = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcActionResult);

                if ((mvcControllerSymbol == null && mvcControllerBaseSymbol == null) || actionResultSymbol == null)
                {
                    // No MVC controllers that return an ActionResult here.
                    return;
                }

                MvcAttributeSymbols mvcAttributeSymbols = new MvcAttributeSymbols(compilationStartContext.Compilation);

                compilationStartContext.RegisterSymbolAction(
                    (SymbolAnalysisContext symbolContext) =>
                {
                    // TODO enhancements: Consider looking at IAsyncResult-based action methods.
                    if (!(symbolContext.Symbol is IMethodSymbol methodSymbol) ||
                        methodSymbol.MethodKind != MethodKind.Ordinary ||
                        methodSymbol.IsStatic ||
                        !methodSymbol.IsPublic() ||
                        !(methodSymbol.ReturnType.Inherits(actionResultSymbol) ||          // FxCop implementation only looked at ActionResult-derived return types.
                          wellKnownTypeProvider.IsTaskOfType(
                              methodSymbol.ReturnType,
                              (ITypeSymbol typeArgument) => typeArgument.Inherits(actionResultSymbol))) ||
                        (!methodSymbol.ContainingType.Inherits(mvcControllerSymbol) &&
                         !methodSymbol.ContainingType.Inherits(mvcControllerBaseSymbol)))
                    {
                        return;
                    }

                    ImmutableArray <AttributeData> methodAttributes = methodSymbol.GetAttributes();
                    mvcAttributeSymbols.ComputeAttributeInfo(methodAttributes, out var verbs, out var isAntiforgeryTokenDefined, out var isAction);

                    if (!isAction)
                    {
                        return;
                    }

                    if (verbs == MvcHttpVerbs.None)
                    {
                        // no verbs specified
                        if (isAntiforgeryTokenDefined)
                        {
                            // antiforgery token attribute is set, but verbs are not specified
                            symbolContext.ReportDiagnostic(Diagnostic.Create(NoVerbsRule, methodSymbol.Locations[0], methodSymbol.MetadataName));
                        }
                        else
                        {
                            // no verbs, no antiforgery token attribute
                            symbolContext.ReportDiagnostic(Diagnostic.Create(NoVerbsNoTokenRule, methodSymbol.Locations[0], methodSymbol.MetadataName));
                        }
                    }
                    else
                    {
                        // verbs are defined
                        if (isAntiforgeryTokenDefined)
                        {
                            if (verbs.HasFlag(MvcHttpVerbs.Get))
                            {
                                symbolContext.ReportDiagnostic(Diagnostic.Create(GetAndTokenRule, methodSymbol.Locations[0], methodSymbol.MetadataName));

                                if ((verbs & (MvcHttpVerbs.Post | MvcHttpVerbs.Put | MvcHttpVerbs.Delete | MvcHttpVerbs.Patch)) != MvcHttpVerbs.None)
                                {
                                    // both verbs, antiforgery token attribute
                                    symbolContext.ReportDiagnostic(Diagnostic.Create(GetAndOtherAndTokenRule, methodSymbol.Locations[0], methodSymbol.MetadataName));
                                }
                            }
                        }
                        else
                        {
                            if ((verbs & (MvcHttpVerbs.Post | MvcHttpVerbs.Put | MvcHttpVerbs.Delete | MvcHttpVerbs.Patch)) != MvcHttpVerbs.None)
                            {
                                // HttpPost, no antiforgery token attribute
                                symbolContext.ReportDiagnostic(Diagnostic.Create(VerbsAndNoTokenRule, methodSymbol.Locations[0], methodSymbol.MetadataName));
                            }
                        }
                    }
                },
                    SymbolKind.Method);
            }
                );
        }
コード例 #11
0
        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) =>
            {
                Compilation?compilation = compilationStartAnalysisContext.Compilation;
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

                if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataSet,
                        out INamedTypeSymbol? dataSetTypeSymbol) ||
                    !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataTable,
                        out INamedTypeSymbol? dataTableTypeSymbol))
                {
                    return;
                }

                INamedTypeSymbol?webMethodAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemWebServicesWebMethodAttribute);
                INamedTypeSymbol?operationContractAttributeTypeSymbol =
                    wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemServiceModelOperationContractAttribute);

                if (webMethodAttributeTypeSymbol == null && operationContractAttributeTypeSymbol == null)
                {
                    return;
                }

                InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation);

                // Symbol actions for SymbolKind.Method don't seem to trigger on interface methods, so we'll do register
                // for SymbolKind.NamedTypeSymbol instead.
                compilationStartAnalysisContext.RegisterSymbolAction(
                    (SymbolAnalysisContext symbolAnalysisContext) =>
                {
                    INamedTypeSymbol namedTypeSymbol = (INamedTypeSymbol)symbolAnalysisContext.Symbol;
                    if (namedTypeSymbol.TypeKind != TypeKind.Interface &&
                        namedTypeSymbol.TypeKind != TypeKind.Class)
                    {
                        return;
                    }

                    foreach (ISymbol?memberSymbol in namedTypeSymbol.GetMembers())
                    {
                        if (!(memberSymbol is IMethodSymbol methodSymbol))
                        {
                            continue;
                        }

                        ObjectGraphOptions optionsToUse;
                        if (methodSymbol.HasAttribute(webMethodAttributeTypeSymbol))
                        {
                            optionsToUse = ObjectGraphOptions.XmlSerializerOptions;
                        }
                        else if (methodSymbol.HasAttribute(operationContractAttributeTypeSymbol))
                        {
                            optionsToUse = ObjectGraphOptions.DataContractOptions;
                        }
                        else
                        {
                            continue;
                        }

                        foreach (IParameterSymbol parameterSymbol in methodSymbol.Parameters)
                        {
                            if (decider.IsObjectGraphInsecure(
                                    parameterSymbol.Type,
                                    optionsToUse,
                                    out ImmutableArray <InsecureObjectGraphResult> results))
                            {
                                foreach (InsecureObjectGraphResult result in results)
                                {
                                    symbolAnalysisContext.ReportDiagnostic(
                                        Diagnostic.Create(
                                            ObjectGraphContainsDangerousTypeDescriptor,
                                            parameterSymbol.DeclaringSyntaxReferences.First().GetSyntax().GetLocation(),
                                            result.InsecureType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                            result.GetDisplayString()));
                                }
                            }
                        }
                    }
                },
                    SymbolKind.NamedType);
            });
        }
        public sealed 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) =>
            {
                Compilation?compilation = compilationStartAnalysisContext.Compilation;
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

                if (!wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataSet,
                        out INamedTypeSymbol? dataSetTypeSymbol) ||
                    !wellKnownTypeProvider.TryGetOrCreateTypeByMetadataName(
                        WellKnownTypeNames.SystemDataDataTable,
                        out INamedTypeSymbol? dataTableTypeSymbol))
                {
                    return;
                }

                INamedTypeSymbol?serializableAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemSerializableAttribute);
                INamedTypeSymbol?nonSerializedAttributeTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemSerializableAttribute);
                INamedTypeSymbol?binaryFormatterTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationFormattersBinaryBinaryFormatter);
                INamedTypeSymbol?netDataContractSerializerTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationNetDataContractSerializer);
                INamedTypeSymbol?objectStateFormatterTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemWebUIObjectStateFormatter);
                INamedTypeSymbol?soapFormatterTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                    WellKnownTypeNames.SystemRuntimeSerializationFormattersSoapSoapFormatter);

                if (serializableAttributeTypeSymbol == null ||
                    (binaryFormatterTypeSymbol == null &&
                     netDataContractSerializerTypeSymbol == null &&
                     objectStateFormatterTypeSymbol == null &&
                     soapFormatterTypeSymbol == null))
                {
                    return;
                }

                InsecureDeserializationTypeDecider decider = InsecureDeserializationTypeDecider.GetOrCreate(compilation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IInvocationOperation invocationOperation =
                        (IInvocationOperation)operationAnalysisContext.Operation;
                    string methodName = invocationOperation.TargetMethod.MetadataName;
                    if (!(((invocationOperation.Instance?.Type?.DerivesFrom(binaryFormatterTypeSymbol) == true &&
                            SecurityHelpers.BinaryFormatterDeserializationMethods.Contains(methodName)) ||
                           (invocationOperation.Instance?.Type?.DerivesFrom(netDataContractSerializerTypeSymbol) == true &&
                            SecurityHelpers.NetDataContractSerializerDeserializationMethods.Contains(methodName)) ||
                           (invocationOperation.Instance?.Type?.DerivesFrom(objectStateFormatterTypeSymbol) == true &&
                            SecurityHelpers.ObjectStateFormatterDeserializationMethods.Contains(methodName)) ||
                           (invocationOperation.Instance?.Type?.DerivesFrom(soapFormatterTypeSymbol) == true &&
                            SecurityHelpers.SoapFormatterDeserializationMethods.Contains(methodName))) &&
                          invocationOperation.Parent?.Kind == OperationKind.Conversion &&
                          invocationOperation.Parent is IConversionOperation conversionOperation))
                    {
                        return;
                    }

                    ITypeSymbol deserializedType = conversionOperation.Type;

                    ObjectGraphOptions options;
                    if (invocationOperation.Instance?.Type?.DerivesFrom(netDataContractSerializerTypeSymbol) == true)
                    {
                        options = ObjectGraphOptions.DataContractOptions;
                    }
                    else
                    {
                        options = ObjectGraphOptions.BinarySerializationOptions;
                    }

                    if (decider.IsObjectGraphInsecure(
                            deserializedType,
                            options,
                            out ImmutableArray <InsecureObjectGraphResult> results))
                    {
                        foreach (InsecureObjectGraphResult result in results)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                Diagnostic.Create(
                                    ObjectGraphContainsDangerousTypeDescriptor,
                                    invocationOperation.Parent.Syntax.GetLocation(),
                                    result.InsecureType.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat),
                                    result.GetDisplayString(typedConstant => ToString(typedConstant))));
                        }
                    }
                },
                    OperationKind.Invocation);
            });
        }
コード例 #13
0
        private void VisitClass(
            ITypeSymbol classSymbol,
            NamedGroup group,
            Dictionary <Location, Diagnostic> diagnostics,
            ConcurrentDictionary <INamedTypeSymbol, bool> classCache)
        {
            if (!(classSymbol is INamedTypeSymbol typeSymbol))
            {
                return;
            }

            if (RequiredAttributeExists((c) => typeSymbol.TryGetDerivedAttribute(c), group.IncludedRequiredAttributes, group.ExcludedRequiredAttributes))
            {
                return;
            }

            if (group.Class != null)
            {
                if (!classCache.TryGetValue(typeSymbol, out bool isTheClass))
                {
                    isTheClass = false;

                    bool IsTheClassBySuffix()
                    {
                        if (typeSymbol.Name.EndsWith(group.Class.Suffix.Text, StringComparison.Ordinal))
                        {
                            return(true);
                        }
                        else if (group.Class.Suffix.IncludeParent &&
                                 typeSymbol.GetBaseTypes().Any(x => x.Name.EndsWith(group.Class.Suffix.Text, StringComparison.Ordinal)))
                        {
                            return(true);
                        }
                        else
                        {
                            return(false);
                        }
                    }

                    if (group.Class.Accessibility != null &&
                        group.Class.Accessibility.All(a => a != typeSymbol.DeclaredAccessibility))
                    {
                        isTheClass = false;
                    }
                    else
                    {
                        if (group.Class.Suffix != null &&
                            group.Class.Parent == null)
                        {
                            isTheClass = IsTheClassBySuffix();
                        }
                        else if (group.Class.Parent != null &&
                                 typeSymbol.GetBaseTypesAndThis().Any(x => x == WellKnownTypeProvider.GetOrCreateTypeByMetadataName(group.Class.Parent)))
                        {
                            isTheClass = group.Class.Suffix != null?IsTheClassBySuffix() : true;
                        }

                        if (group.Class?.Exclude != null &&
                            RequiredAttributeExists((c) => typeSymbol.TryGetDerivedAttribute(c), group.Class.Exclude))
                        {
                            isTheClass = false;
                        }
                        else if (group.Class?.Include != null &&
                                 RequiredAttributeExists((c) => typeSymbol.TryGetDerivedAttribute(c), group.Class.Include))
                        {
                            isTheClass = true;
                        }
                    }

                    classCache.TryAdd(typeSymbol, isTheClass);
                }

                if (!isTheClass)
                {
                    return;
                }
            }

            foreach (var member in classSymbol.GetMembers())
            {
                if (!(member is IMethodSymbol methodSymbol) || methodSymbol.IsPropertyAccessor())
                {
                    continue;
                }

                var location = methodSymbol.Locations[0];
                if (diagnostics.ContainsKey(location)) // first NamedGroup in a sequence wins
                {
                    continue;
                }

                if (group.Method != null)
                {
                    if (group.Method.Static.HasValue && group.Method.Static != methodSymbol.IsStatic)
                    {
                        continue;
                    }

                    if (group.Method.IncludeConstructor.HasValue && group.Method.IncludeConstructor != methodSymbol.IsConstructor())
                    {
                        continue;
                    }

                    if (group.Method?.Accessibility?.All(a => a != methodSymbol.DeclaredAccessibility) == true)
                    {
                        continue;
                    }

                    if (group.Method?.Exclude != null &&
                        RequiredAttributeExists((c) => methodSymbol.TryGetDerivedAttribute(c), group.Method.Exclude))
                    {
                        continue;
                    }
                    else if (group.Method?.Include?.Any() == true &&
                             !RequiredAttributeExists((c) => methodSymbol.TryGetDerivedAttribute(c), group.Method.Include))
                    {
                        continue;
                    }
                }

                if (RequiredAttributeExists((c) => methodSymbol.TryGetDerivedAttribute(c), group.IncludedRequiredAttributes, group.ExcludedRequiredAttributes))
                {
                    continue;
                }

                if (group.Parameter != null && AreParametersExcluded(methodSymbol, group))
                {
                    continue;
                }

                diagnostics.Add(location, Diagnostic.Create(group.Message != null ? group.Message : Rule, location));
            }
        }
コード例 #14
0
        /// <summary>
        /// Constructs.
        /// </summary>
        /// <param name="wellKnownTypeProvider">The compilation's <see cref="WellKnownTypeProvider"/>.</param>
        public XmlSerializationAttributeTypes(WellKnownTypeProvider wellKnownTypeProvider)
        {
            this.XmlAnyAttributeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlAnyAttributeAttribute);
            this.XmlAnyElementAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlAnyElementAttribute);
            this.XmlArrayAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlArrayAttribute);
            this.XmlArrayItemAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlArrayItemAttribute);
            this.XmlAttributeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlAttributeAttribute);
            this.XmlChoiceIdentifierAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlChoiceIdentifierAttribute);
            this.XmlElementAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlElementAttribute);
            this.XmlEnumAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlEnumAttribute);
            this.XmlIgnoreAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlIgnoreAttribute);
            this.XmlIncludeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlIncludeAttribute);
            this.XmlRootAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlRootAttribute);
            this.XmlTextAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlTextAttribute);
            this.XmlTypeAttribute = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(
                WellKnownTypeNames.SystemXmlSerializationXmlTypeAttribute);

            this.Any =
                this.XmlAnyAttributeAttribute != null ||
                this.XmlAnyElementAttribute != null ||
                this.XmlArrayAttribute != null ||
                this.XmlArrayItemAttribute != null ||
                this.XmlAttributeAttribute != null ||
                this.XmlChoiceIdentifierAttribute != null ||
                this.XmlElementAttribute != null ||
                this.XmlEnumAttribute != null ||
                this.XmlIgnoreAttribute != null ||
                this.XmlIncludeAttribute != null ||
                this.XmlRootAttribute != null ||
                this.XmlTextAttribute != null ||
                this.XmlTypeAttribute != null;
        }
コード例 #15
0
        public sealed override void Initialize(AnalysisContext context)
        {
            ImmutableHashSet <string> cachedDeserializationMethodNames = this.DeserializationMethodNames;

            Debug.Assert(!cachedDeserializationMethodNames.IsEmpty);

            context.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics on generated code.
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            context.RegisterCompilationStartAction(
                (CompilationStartAnalysisContext compilationStartAnalysisContext) =>
            {
                WellKnownTypeProvider wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(
                    compilationStartAnalysisContext.Compilation);
                INamedTypeSymbol?deserializerTypeSymbol =
                    wellKnownTypeProvider.GetOrCreateTypeByMetadataName(this.DeserializerTypeMetadataName);
                if (deserializerTypeSymbol == null)
                {
                    return;
                }

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IInvocationOperation invocationOperation =
                        (IInvocationOperation)operationAnalysisContext.Operation;
                    if (invocationOperation.Instance?.Type?.DerivesFrom(deserializerTypeSymbol) == true &&
                        cachedDeserializationMethodNames.Contains(invocationOperation.TargetMethod.MetadataName))
                    {
                        DiagnosticDescriptor?chosenDiagnostic =
                            this.ChooseDiagnosticDescriptor(operationAnalysisContext, wellKnownTypeProvider);
                        if (chosenDiagnostic != null)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                invocationOperation.CreateDiagnostic(
                                    chosenDiagnostic,
                                    invocationOperation.TargetMethod.ToDisplayString(
                                        SymbolDisplayFormat.MinimallyQualifiedFormat)));
                        }
                    }
                },
                    OperationKind.Invocation);

                compilationStartAnalysisContext.RegisterOperationAction(
                    (OperationAnalysisContext operationAnalysisContext) =>
                {
                    IMethodReferenceOperation methodReferenceOperation =
                        (IMethodReferenceOperation)operationAnalysisContext.Operation;
                    if (methodReferenceOperation.Instance?.Type?.DerivesFrom(deserializerTypeSymbol) == true &&
                        cachedDeserializationMethodNames.Contains(methodReferenceOperation.Method.MetadataName))
                    {
                        DiagnosticDescriptor?chosenDiagnostic =
                            this.ChooseDiagnosticDescriptor(operationAnalysisContext, wellKnownTypeProvider);
                        if (chosenDiagnostic != null)
                        {
                            operationAnalysisContext.ReportDiagnostic(
                                methodReferenceOperation.CreateDiagnostic(
                                    chosenDiagnostic,
                                    methodReferenceOperation.Method.ToDisplayString(
                                        SymbolDisplayFormat.MinimallyQualifiedFormat)));
                        }
                    }
                },
                    OperationKind.MethodReference);
            });
        }
コード例 #16
0
        private static ImmutableArray <INamedTypeSymbol> GetSkippedAttributes(WellKnownTypeProvider wellKnownTypeProvider)
        {
            ImmutableArray <INamedTypeSymbol> .Builder?builder = null;

            void Add(INamedTypeSymbol?symbol)
            {
                if (symbol != null)
                {
                    builder ??= ImmutableArray.CreateBuilder <INamedTypeSymbol>();
                    builder.Add(symbol);
                }
            }

            // Web attributes
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebServicesWebMethodAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcHttpGetAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcHttpPostAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcHttpPutAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcHttpDeleteAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcHttpPatchAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcHttpHeadAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebMvcHttpOptionsAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemWebHttpRouteAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcHttpDeleteAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcHttpGetAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcHttpPostAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcHttpPutAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcHttpHeadAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcHttpPatchAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcHttpOptionsAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftAspNetCoreMvcRouteAttribute));


            // MSTest attributes
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestInitializeAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestMethodAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingDataTestMethodAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestCleanupAttribute));

            // XUnit attributes
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.XunitFactAttribute));

            // NUnit Attributes
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkSetUpAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkOneTimeSetUpAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkOneTimeTearDownAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkTestAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkTestCaseAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkTestCaseSourceAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkTheoryAttribute));
            Add(wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.NUnitFrameworkTearDownAttribute));

            return(builder?.ToImmutable() ?? ImmutableArray <INamedTypeSymbol> .Empty);
        }