private void AnalyzeMethodOverloads(OperationAnalysisContext context, IMethodSymbol method, IHasArgumentsExpression expression) { if (method.MatchMethodDerivedByName(_xmlTypes.XmlDocument, SecurityMemberNames.Load) || //FxCop CA3056 method.MatchMethodDerivedByName(_xmlTypes.XmlDocument, SecurityMemberNames.LoadXml) || //FxCop CA3057 method.MatchMethodDerivedByName(_xmlTypes.XPathDocument, WellKnownMemberNames.InstanceConstructorName) || //FxCop CA3059 method.MatchMethodDerivedByName(_xmlTypes.XmlSchema, SecurityMemberNames.Read) || //FxCop CA3060 method.MatchMethodDerivedByName(_xmlTypes.DataSet, SecurityMemberNames.ReadXml) || //FxCop CA3063 method.MatchMethodDerivedByName(_xmlTypes.DataSet, SecurityMemberNames.ReadXmlSchema) || //FxCop CA3064 method.MatchMethodDerivedByName(_xmlTypes.XmlSerializer, SecurityMemberNames.Deserialize) || //FxCop CA3070 method.MatchMethodDerivedByName(_xmlTypes.DataTable, SecurityMemberNames.ReadXml) || //FxCop CA3071 method.MatchMethodDerivedByName(_xmlTypes.DataTable, SecurityMemberNames.ReadXmlSchema)) //FxCop CA3072 { if (SecurityDiagnosticHelpers.HasXmlReaderParameter(method, _xmlTypes) < 0) { DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessing; context.ReportDiagnostic( Diagnostic.Create( rule, expression.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.DoNotUseDtdProcessingOverloadsMessage), method.Name ) ) ); } } else if (method.MatchMethodDerivedByName(_xmlTypes.XmlReader, SecurityMemberNames.Create)) { int xmlReaderSettingsIndex = SecurityDiagnosticHelpers.GetXmlReaderSettingsParameterIndex(method, _xmlTypes); if (xmlReaderSettingsIndex < 0) { DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessing; Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, expression.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateWrongOverloadMessage) ) ); context.ReportDiagnostic(diag); } else { SemanticModel model = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree); IArgument arg = expression.ArgumentsInParameterOrder[xmlReaderSettingsIndex]; ISymbol settingsSymbol = arg.Value.Syntax.GetDeclaredOrReferencedSymbol(model); if (settingsSymbol == null) { return; } XmlReaderSettingsEnvironment env; if (!_xmlReaderSettingsEnvironments.TryGetValue(settingsSymbol, out env)) { // symbol for settings is not found => passed in without any change => assume insecure Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, expression.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateInsecureInputMessage) ) ); context.ReportDiagnostic(diag); } else if (!env.IsDtdProcessingDisabled && !(env.IsSecureResolver && env.IsMaxCharactersFromEntitiesLimited)) { Diagnostic diag; if (env.IsConstructedInCodeBlock) { diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, expression.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateInsecureConstructedMessage) ) ); } else { diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, expression.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateInsecureInputMessage) ) ); } context.ReportDiagnostic(diag); } } } }
private void AnalyzeNodeForDtdProcessingOverloads(SyntaxNodeAnalysisContext context) { SyntaxNode node = context.Node; SemanticModel model = context.SemanticModel; IMethodSymbol method = _syntaxNodeHelper.GetCalleeMethodSymbol(node, model); if (method == null) { return; } CompilationSecurityTypes xmlTypes = _xmlTypes; if (method.MatchMethodDerivedByName(xmlTypes.XmlDocument, SecurityMemberNames.Load) || //FxCop CA3056 method.MatchMethodDerivedByName(xmlTypes.XmlDocument, SecurityMemberNames.LoadXml) || //FxCop CA3057 method.MatchMethodDerivedByName(xmlTypes.XPathDocument, WellKnownMemberNames.InstanceConstructorName) || //FxCop CA3059 method.MatchMethodDerivedByName(xmlTypes.XmlSchema, SecurityMemberNames.Read) || //FxCop CA3060 method.MatchMethodDerivedByName(xmlTypes.DataSet, SecurityMemberNames.ReadXml) || //FxCop CA3063 method.MatchMethodDerivedByName(xmlTypes.DataSet, SecurityMemberNames.ReadXmlSchema) || //FxCop CA3064 method.MatchMethodDerivedByName(xmlTypes.XmlSerializer, SecurityMemberNames.Deserialize) || //FxCop CA3070 method.MatchMethodDerivedByName(xmlTypes.DataTable, SecurityMemberNames.ReadXml) || //FxCop CA3071 method.MatchMethodDerivedByName(xmlTypes.DataTable, SecurityMemberNames.ReadXmlSchema)) //FxCop CA3072 { if (SecurityDiagnosticHelpers.HasXmlReaderParameter(method, xmlTypes) < 0) { DiagnosticDescriptor rule = RuleDoNotUseInsecureDTDProcessing; context.ReportDiagnostic( Diagnostic.Create( rule, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.DoNotUseDtdProcessingOverloadsMessage), SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model), method.Name) ) ); } } // We assume the design of derived type are secure, per Rule CA9003 else if (method.MatchMethodByName(xmlTypes.XmlDocument, WellKnownMemberNames.InstanceConstructorName)) { if (IsObjectConstructionForTemporaryObject(node)) // REVIEW: may be hard to check { bool isXmlDocumentSecureResolver = false; foreach (SyntaxNode arg in _syntaxNodeHelper.GetObjectInitializerExpressionNodes(node)) { SyntaxNode argLhs = _syntaxNodeHelper.GetAssignmentLeftNode(arg); SyntaxNode argRhs = _syntaxNodeHelper.GetAssignmentRightNode(arg); if (SecurityDiagnosticHelpers.IsXmlDocumentXmlResolverProperty(SyntaxNodeHelper.GetSymbol(argLhs, model), xmlTypes)) { if (!(SyntaxNodeHelper.NodeHasConstantValueNull(argRhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(argRhs).Type, xmlTypes))) { // if XmlResolver property is explicitly set to an insecure value in initializer list, // a warning would be generated when handling assignment of XmlDocument.XmlResolver // AnalyzeNodeForXmlDocument method, so we ignore it here. return; } else { isXmlDocumentSecureResolver = true; } } } if (!isXmlDocumentSecureResolver) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlDocumentWithNoSecureResolverMessage), _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model).Name) ); context.ReportDiagnostic(diag); } } } // We assume the design of derived type are secure, per Rule CA9003 else if (method.MatchMethodByName(xmlTypes.XmlTextReader, WellKnownMemberNames.InstanceConstructorName)) { if (IsObjectConstructionForTemporaryObject(node)) // REVIEW: may be hard to check { bool isXmlTextReaderSecureResolver, isXmlTextReaderDtdProcessingDisabled; isXmlTextReaderSecureResolver = isXmlTextReaderDtdProcessingDisabled = false; foreach (SyntaxNode arg in _syntaxNodeHelper.GetObjectInitializerExpressionNodes(node)) { SyntaxNode argLhs = _syntaxNodeHelper.GetAssignmentLeftNode(arg); SyntaxNode argRhs = _syntaxNodeHelper.GetAssignmentRightNode(arg); ISymbol symArgLhs = SyntaxNodeHelper.GetSymbol(argLhs, model); if (SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverProperty(symArgLhs, xmlTypes)) { if (!(SyntaxNodeHelper.NodeHasConstantValueNull(argRhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(argRhs).Type, xmlTypes))) { // Generate a warning whenever the XmlTextReader.XmlResolver property is set to an insecure value Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderSetInsecureResolutionMessage), _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model).Name ) ); context.ReportDiagnostic(diag); return; } else { isXmlTextReaderSecureResolver = true; } } else if (SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingProperty(symArgLhs, xmlTypes)) { if (SyntaxNodeHelper.GetSymbol(argRhs, model).MatchFieldByName(xmlTypes.DtdProcessing, SecurityMemberNames.Parse)) { // Generate a warning whenever the XmlTextReader.DtdProcessing property is set to DtdProcessing.Parse Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderSetInsecureResolutionMessage), _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model).Name ) ); context.ReportDiagnostic(diag); return; } else { isXmlTextReaderDtdProcessingDisabled = true; } } } if (!isXmlTextReaderSecureResolver || !isXmlTextReaderDtdProcessingDisabled) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderConstructedWithNoSecureResolutionMessage), SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model) ) ); context.ReportDiagnostic(diag); } } } else if (method.MatchMethodDerivedByName(xmlTypes.XmlReader, SecurityMemberNames.Create)) { int xmlReaderSettingsIndex = SecurityDiagnosticHelpers.HasXmlReaderSettingsParameter(method, xmlTypes); if (xmlReaderSettingsIndex < 0) //FxCop CA3053:XmlReaderCreateWrongOverload { DiagnosticDescriptor rule = RuleDoNotUseInsecureDTDProcessing; context.ReportDiagnostic( Diagnostic.Create( rule, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateWrongOverloadMessage), SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model) ) ) ); } else { SyntaxNode settingsNode = _syntaxNodeHelper.GetInvocationArgumentExpressionNodes(node).ElementAt(xmlReaderSettingsIndex); ISymbol settingsSymbol = SyntaxNodeHelper.GetSymbol(settingsNode, model); XmlReaderSettingsEnvironment env = null; if (!_xmlReaderSettingsEnvironments.TryGetValue(settingsSymbol, out env)) { // symbol for settings is not found => passed in without any change => assume insecure Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateInsecureInputMessage), SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model) ) ); context.ReportDiagnostic(diag); } else if (!env.IsDtdProcessingDisabled && !(env.IsSecureResolver & env.IsMaxCharactersFromEntitiesLimited)) { Diagnostic diag; if (env.IsConstructedInCodeBlock) { diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateInsecureConstructedMessage) ) ); } else { diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlReaderCreateInsecureInputMessage) ) ); } context.ReportDiagnostic(diag); } } } }