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); } } }
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); }
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); }
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); }
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); }
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) }; }
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); }); }
public DisposableFieldAnalyzer(WellKnownTypeProvider wellKnownTypeProvider) { _disposableTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable); _asyncDisposableTypeSymbol = wellKnownTypeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIAsyncDisposable); }
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); } ); }
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); }); }
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)); } }
/// <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; }
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); }); }
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); }