protected void AnalyzeInvocation(SyntaxNode node, SemanticModel model, Action <Diagnostic> reportDiagnostic) { IMethodSymbol method = SyntaxNodeHelper.GetCalleeMethodSymbol(node, model); if (method == null) { return; } if (method.MatchMethodByName(XmlTypes.XmlSchema, "Read")) { if (!AreDefaultsSecure && SecurityDiagnosticHelpers.GetSpecifiedParameterIndex(method, XmlTypes, SecurityDiagnosticHelpers.IsXmlReaderType) < 0) { var diag = Diagnostic.Create(XxeDiagnosticAnalyzer.Rule, node.GetLocation()); reportDiagnostic(diag); } } else if (method.MatchMethodDerivedByName(XmlTypes.XmlReader, "Create")) { int xmlReaderSettingsIndex = SecurityDiagnosticHelpers.GetXmlReaderSettingsParameterIndex(method, XmlTypes); if (xmlReaderSettingsIndex < 0) { return; } SyntaxNode settingsNode = SyntaxNodeHelper.GetInvocationArgumentExpressionNodes(node).ElementAt(xmlReaderSettingsIndex); XmlReaderSettingsEnvironment env; if (SyntaxNodeHelper.IsObjectConstructionForTemporaryObject(settingsNode)) { OjectCreationOperationsAnalyzed.Add(settingsNode); env = AnalyzeObjectCreationForXmlReaderSettings(settingsNode, model); TempXmlReaderSettingsEnvironments[settingsNode] = env; } else { ISymbol settingsSymbol = SyntaxNodeHelper.GetSymbol(settingsNode, model); XmlReaderSettingsEnvironments.TryGetValue(settingsSymbol, out env); } if (env == null) { // symbol for settings is not found => passed in without any change => assume insecure reportDiagnostic(Diagnostic.Create(XxeDiagnosticAnalyzer.Rule, node.GetLocation())); } } else if (ReferenceEquals(method.ContainingType, XmlTypes.ConfigXmlDocument)) { var variableNode = SyntaxNodeHelper.GetMemberAccessExpressionNode(SyntaxNodeHelper.GetInvocationExpressionNode(node)); if (variableNode == null) { throw new ArgumentException(nameof(variableNode)); } var variableSymbol = SyntaxNodeHelper.GetSymbol(variableNode, model); if (variableSymbol == null) { return; } XmlDocumentEnvironment env; if (SyntaxNodeHelper.IsObjectConstructionForTemporaryObject(variableNode)) { OjectCreationOperationsAnalyzed.Add(variableNode); env = AnalyzeObjectCreationForXmlDocument(variableSymbol, variableNode, model); TempXmlDocumentEnvironments[variableNode] = env; } else { XmlDocumentEnvironments.TryGetValue(variableSymbol, out env); } if (method.MatchMethodDerivedByName(XmlTypes.ConfigXmlDocument, "Load")) { if (env != null) { env.WasSafeFunctionCalled = true; } } else { if (env == null) { // symbol not found => passed in without any change => assume insecure reportDiagnostic(Diagnostic.Create(XxeDiagnosticAnalyzer.Rule, node.GetLocation())); } else { env.WasSomethingElseCalled = true; } } } else if (ReferenceEquals(method.ContainingType, XmlTypes.XmlDocument)) { var variableNode = SyntaxNodeHelper.GetMemberAccessExpressionNode(SyntaxNodeHelper.GetInvocationExpressionNode(node)); if (variableNode == null) { throw new ArgumentException(nameof(variableNode)); } var variableSymbol = SyntaxNodeHelper.GetSymbol(variableNode, model); if (variableSymbol == null) { return; } XmlDocumentEnvironment env; if (SyntaxNodeHelper.IsObjectConstructionForTemporaryObject(variableNode)) { OjectCreationOperationsAnalyzed.Add(variableNode); env = AnalyzeObjectCreationForXmlDocument(variableSymbol, variableNode, model); TempXmlDocumentEnvironments[variableNode] = env; } else { XmlDocumentEnvironments.TryGetValue(variableSymbol, out env); } // Special case XmlDataDocument.LoadXml throws NotSupportedException if (env == null || !ReferenceEquals(env.Type, XmlTypes.XmlDataDocument)) { return; } // LoadXml is not overridden in XmlDataDocument, thus XmlTypes.XmlDocument if (method.MatchMethodDerivedByName(XmlTypes.XmlDocument, "LoadXml")) { env.WasSafeFunctionCalled = true; } else { env.WasSomethingElseCalled = true; } } }
protected void AnalyzeObjectCreation(ISymbol variableSymbol, SyntaxNode objectCreationNode, SemanticModel model, Action <Diagnostic> reportDiagnostic) { if (!(SyntaxNodeHelper.GetSymbol(objectCreationNode, model) is IMethodSymbol symbol)) { return; } if (OjectCreationOperationsAnalyzed.Contains(objectCreationNode)) { return; } OjectCreationOperationsAnalyzed.Add(objectCreationNode); if (SecurityDiagnosticHelpers.IsXmlDocumentCtorDerived(symbol, XmlTypes)) { var env = AnalyzeObjectCreationForXmlDocument(symbol, objectCreationNode, model); if (variableSymbol != null) { XmlDocumentEnvironments[variableSymbol] = env; } else { TempXmlDocumentEnvironments[objectCreationNode] = env; } } else if (SecurityDiagnosticHelpers.IsXmlTextReaderCtorDerived(symbol, XmlTypes)) { var env = AnalyzeObjectCreationForXmlTextReader(symbol, objectCreationNode, model); if (variableSymbol != null) { XmlTextReaderEnvironments[variableSymbol] = env; } else { TempXmlTextReaderEnvironments[objectCreationNode] = env; } } else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsCtor(symbol, XmlTypes)) { var env = AnalyzeObjectCreationForXmlReaderSettings(objectCreationNode, model); if (variableSymbol != null) { XmlReaderSettingsEnvironments[variableSymbol] = env; } else { TempXmlReaderSettingsEnvironments[objectCreationNode] = env; } } else if (symbol.MatchMethodByName(XmlTypes.XPathDocument, WellKnownMemberNames.InstanceConstructorName)) { if (AreDefaultsSecure) { return; } if (SecurityDiagnosticHelpers.GetSpecifiedParameterIndex(symbol, XmlTypes, SecurityDiagnosticHelpers.IsXmlReaderType) == 0) { return; } var diag = Diagnostic.Create(XxeDiagnosticAnalyzer.Rule, objectCreationNode.GetLocation()); reportDiagnostic(diag); } }