private void AnalyzeXmlResolverPropertyAssignmentForXmlDocument(OperationAnalysisContext context, ISymbol assignedSymbol, IAssignmentExpression expression) { bool isSecureResolver = false; IConversionExpression conv = expression.Value as IConversionExpression; if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(conv.Operand.Type, _xmlTypes)) { isSecureResolver = true; } else if (conv != null && SecurityDiagnosticHelpers.IsExpressionEqualsNull(conv.Operand)) { isSecureResolver = true; } else // Assigning XmlDocument's XmlResolver to an insecure value { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, context.Operation.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlDocumentWithNoSecureResolverMessage) ) ); context.ReportDiagnostic(diag); } if (_xmlDocumentEnvironments.ContainsKey(assignedSymbol)) { XmlDocumentEnvironment xmlDocumentEnv = _xmlDocumentEnvironments[assignedSymbol]; xmlDocumentEnv.IsXmlResolverSet = true; xmlDocumentEnv.IsSecureResolver = isSecureResolver; } }
private XmlDocumentEnvironment AnalyzeObjectCreationForXmlDocument(ISymbol symbol, SyntaxNode node, SemanticModel model) { var env = new XmlDocumentEnvironment(AreDefaultsSecure, symbol.ContainingType, node); if (!ReferenceEquals(symbol.ContainingType, XmlTypes.XmlDocument) && !ReferenceEquals(symbol.ContainingType, XmlTypes.XmlDataDocument) && !ReferenceEquals(symbol.ContainingType, XmlTypes.ConfigXmlDocument) && !ReferenceEquals(symbol.ContainingType, XmlTypes.XmlFileInfoDocument) && !ReferenceEquals(symbol.ContainingType, XmlTypes.XmlTransformableDocument)) { // We assume the design of derived type is secure env.IsSecureResolver = true; } foreach (SyntaxNode arg in SyntaxNodeHelper.GetObjectInitializerExpressionNodes(node)) { SyntaxNode argLhs = SyntaxNodeHelper.GetAssignmentLeftNode(arg); SyntaxNode argRhs = SyntaxNodeHelper.GetAssignmentRightNode(arg); if (!SecurityDiagnosticHelpers.IsXmlDocumentXmlResolverPropertyDerived(SyntaxNodeHelper.GetSymbol(argLhs, model), XmlTypes)) { continue; } env.IsSecureResolver = SyntaxNodeHelper.NodeHasConstantValueNull(argRhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(argRhs).Type, XmlTypes); break; } return(env); }
public void AnalyzeCodeBlockEnd(CodeBlockAnalysisContext context) { foreach (KeyValuePair <ISymbol, XmlDocumentEnvironment> p in _xmlDocumentEnvironments) { XmlDocumentEnvironment env = p.Value; if (!(env.IsXmlResolverSet | env.IsSecureResolver)) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, env.XmlDocumentDefinition.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlDocumentWithNoSecureResolverMessage), env.EnclosingConstructSymbol.Name)); context.ReportDiagnostic(diag); } } foreach (KeyValuePair <ISymbol, XmlTextReaderEnvironment> p in _xmlTextReaderEnvironments) { XmlTextReaderEnvironment env = p.Value; if (!(env.IsXmlResolverSet | env.IsSecureResolver) || !(env.IsDtdProcessingSet | env.IsDtdProcessingDisabled)) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, env.XmlTextReaderDefinition.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderConstructedWithNoSecureResolutionMessage), env.EnclosingConstructSymbol.Name)); context.ReportDiagnostic(diag); } } }
public void AnalyzeOperationBlock(OperationBlockAnalysisContext context) { foreach (KeyValuePair <ISymbol, XmlDocumentEnvironment> p in _xmlDocumentEnvironments) { XmlDocumentEnvironment env = p.Value; if (!(env.IsXmlResolverSet | env.IsSecureResolver)) { context.ReportDiagnostic(env.XmlDocumentDefinition.CreateDiagnostic(RuleXmlDocumentWithNoSecureResolver)); } } foreach (KeyValuePair <ISymbol, XmlTextReaderEnvironment> p in _xmlTextReaderEnvironments) { XmlTextReaderEnvironment env = p.Value; if (!(env.IsXmlResolverSet | env.IsSecureResolver) || !(env.IsDtdProcessingSet | env.IsDtdProcessingDisabled)) { context.ReportDiagnostic(env.XmlTextReaderDefinition.CreateDiagnostic(RuleXmlTextReaderConstructedWithNoSecureResolution)); } } }
private void AnalyzeObjectCreationForXmlDocument(OperationAnalysisContext context, ISymbol variable, IObjectCreationOperation objCreation) { XmlDocumentEnvironment xmlDocumentEnvironment; if (variable == null || !_xmlDocumentEnvironments.TryGetValue(variable, out xmlDocumentEnvironment)) { xmlDocumentEnvironment = new XmlDocumentEnvironment { IsSecureResolver = false, IsXmlResolverSet = false }; } xmlDocumentEnvironment.XmlDocumentDefinition = objCreation.Syntax; SyntaxNode node = objCreation.Syntax; bool isXmlDocumentSecureResolver = false; if (objCreation.Constructor.ContainingType != _xmlTypes.XmlDocument) { isXmlDocumentSecureResolver = true; } // propertyInitlizer is not returned any more // and no way to get propertysymbol if (objCreation.Initializer != null) { foreach (IOperation init in objCreation.Initializer.Initializers) { if (init is IAssignmentOperation assign) { var propValue = assign.Value; IPropertySymbol prop = context.Compilation.GetSemanticModel(context.Operation.Syntax.SyntaxTree)?.GetSymbolInfo(assign.Target.Syntax).Symbol as IPropertySymbol; if (prop == null) { continue; } if (prop.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, "XmlResolver")) { IConversionOperation operation = propValue as IConversionOperation; if (operation == null) { return; } if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes)) { isXmlDocumentSecureResolver = true; } else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand)) { isXmlDocumentSecureResolver = true; } else // Non secure resolvers { return; } } } } } xmlDocumentEnvironment.IsSecureResolver = isXmlDocumentSecureResolver; if (variable != null) { _xmlDocumentEnvironments[variable] = xmlDocumentEnvironment; } else if (!xmlDocumentEnvironment.IsSecureResolver) // Insecure temp object { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(MicrosoftNetFrameworkAnalyzersResources.XmlDocumentWithNoSecureResolverMessage) ) ); context.ReportDiagnostic(diag); } }
private void AnalyzeObjectCreationForXmlDocument(OperationAnalysisContext context, ISymbol variable, IObjectCreationOperation objCreation) { if (variable == null || !_xmlDocumentEnvironments.TryGetValue(variable, out var xmlDocumentEnvironment)) { xmlDocumentEnvironment = new XmlDocumentEnvironment { IsSecureResolver = false, IsXmlResolverSet = false }; } xmlDocumentEnvironment.XmlDocumentDefinition = objCreation.Syntax; SyntaxNode node = objCreation.Syntax; bool isXmlDocumentSecureResolver = false; if (!Equals(objCreation.Constructor.ContainingType, _xmlTypes.XmlDocument)) { isXmlDocumentSecureResolver = true; } // propertyInitlizer is not returned any more // and no way to get propertysymbol if (objCreation.Initializer != null) { foreach (IOperation init in objCreation.Initializer.Initializers) { if (init is IAssignmentOperation assign) { var propValue = assign.Value; if (!(assign.Target is IPropertyReferenceOperation propertyReference)) { continue; } var prop = propertyReference.Property; if (prop.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, "XmlResolver")) { if (!(propValue is IConversionOperation operation)) { return; } if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes)) { isXmlDocumentSecureResolver = true; } else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand)) { isXmlDocumentSecureResolver = true; } else // Non secure resolvers { context.ReportDiagnostic(assign.Syntax.CreateDiagnostic(RuleXmlDocumentWithNoSecureResolver)); return; } } else { AnalyzeNeverSetProperties(context, prop, assign.Syntax.GetLocation()); } } } } xmlDocumentEnvironment.IsSecureResolver = isXmlDocumentSecureResolver; if (variable != null) { _xmlDocumentEnvironments[variable] = xmlDocumentEnvironment; } else if (!xmlDocumentEnvironment.IsSecureResolver) // Insecure temp object { context.ReportDiagnostic(node.CreateDiagnostic(RuleXmlDocumentWithNoSecureResolver)); } return; }
private void AnalyzeObjectCreationForXmlDocument(OperationAnalysisContext context, ISymbol variable, IObjectCreationExpression objCreation) { XmlDocumentEnvironment xmlDocumentEnvironment; if (variable == null || !_xmlDocumentEnvironments.ContainsKey(variable)) { xmlDocumentEnvironment = new XmlDocumentEnvironment { IsSecureResolver = false, IsXmlResolverSet = false }; } else { xmlDocumentEnvironment = _xmlDocumentEnvironments[variable]; } xmlDocumentEnvironment.XmlDocumentDefinition = objCreation.Syntax; SyntaxNode node = objCreation.Syntax; bool isXmlDocumentSecureResolver = false; if (objCreation.Constructor.ContainingType != _xmlTypes.XmlDocument) { isXmlDocumentSecureResolver = true; } foreach (ISymbolInitializer init in objCreation.MemberInitializers) { var prop = init as IPropertyInitializer; if (prop != null) { if (prop.InitializedProperty.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, "XmlResolver")) { IConversionExpression operation = prop.Value as IConversionExpression; if (operation == null) { return; } if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes)) { isXmlDocumentSecureResolver = true; } else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand)) { isXmlDocumentSecureResolver = true; } else // Non secure resolvers { IObjectCreationExpression xmlResolverObjCreated = operation.Operand as IObjectCreationExpression; if (xmlResolverObjCreated != null) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, prop.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlDocumentWithNoSecureResolverMessage) ) ); context.ReportDiagnostic(diag); } return; } } else { AnalyzeNeverSetProperties(context, prop.InitializedProperty, prop.Syntax.GetLocation()); } } } xmlDocumentEnvironment.IsSecureResolver = isXmlDocumentSecureResolver; if (variable != null) { _xmlDocumentEnvironments[variable] = xmlDocumentEnvironment; } else if (!xmlDocumentEnvironment.IsSecureResolver) // Insecure temp object { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlDocumentWithNoSecureResolverMessage) ) ); context.ReportDiagnostic(diag); } }
private void AnalyzeNodeForXmlDocument(SyntaxNodeAnalysisContext context) { SyntaxNode node = context.Node; SemanticModel model = context.SemanticModel; node = _syntaxNodeHelper.GetVariableDeclaratorOfAFieldDeclarationNode(node) ?? node; SyntaxNode lhs = _syntaxNodeHelper.GetAssignmentLeftNode(node); SyntaxNode rhs = _syntaxNodeHelper.GetAssignmentRightNode(node); if (lhs == null || rhs == null) { return; } ISymbol lhsSymbol = SyntaxNodeHelper.GetSymbol(lhs, model); if (lhsSymbol == null) { return; } CompilationSecurityTypes xmlTypes = _xmlTypes; IMethodSymbol rhsMethodSymbol = _syntaxNodeHelper.GetCalleeMethodSymbol(rhs, model); if (SecurityDiagnosticHelpers.IsXmlDocumentCtorDerived(rhsMethodSymbol, xmlTypes)) { XmlDocumentEnvironment env = new XmlDocumentEnvironment(); if (rhsMethodSymbol.ContainingType != xmlTypes.XmlDocument) { env.IsSecureResolver = true; } foreach (SyntaxNode arg in _syntaxNodeHelper.GetObjectInitializerExpressionNodes(rhs)) { SyntaxNode argLhs = _syntaxNodeHelper.GetAssignmentLeftNode(arg); SyntaxNode argRhs = _syntaxNodeHelper.GetAssignmentRightNode(arg); if (SecurityDiagnosticHelpers.IsXmlDocumentXmlResolverPropertyDerived(SyntaxNodeHelper.GetSymbol(argLhs, model), xmlTypes)) { env.IsXmlResolverSet = true; if (SyntaxNodeHelper.NodeHasConstantValueNull(argRhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(argRhs).Type, xmlTypes)) { env.IsSecureResolver = true; } break; } } // if XmlResolver property is explicitly set to an insecure value in initializer list, // a warning would be generated when handling assignment of XmlDocument.XmlResolver in the // else-if clause below, so we ignore it here. // Only keep track of XmlDocument constructed here when if is not explicitly set to insecure value. if (!env.IsXmlResolverSet | env.IsSecureResolver) { env.XmlDocumentDefinition = node; env.EnclosingConstructSymbol = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model); _xmlDocumentEnvironments[lhsSymbol] = env; } } else if (SecurityDiagnosticHelpers.IsXmlDocumentXmlResolverPropertyDerived(lhsSymbol, xmlTypes)) { SyntaxNode lhsExpressionNode = _syntaxNodeHelper.GetMemberAccessExpressionNode(lhs) ?? lhs; if (lhsExpressionNode == null) { return; } ISymbol lhsExpressionSymbol = SyntaxNodeHelper.GetSymbol(lhsExpressionNode, model); if (lhsExpressionSymbol == null) { return; } XmlDocumentEnvironment env = null; _xmlDocumentEnvironments.TryGetValue(lhsExpressionSymbol, out env); ITypeSymbol rhsType = model.GetTypeInfo(rhs).Type; // if XmlDocument was constructed in the same code block with default values. if (env != null) { env.IsXmlResolverSet = true; } if (SyntaxNodeHelper.NodeHasConstantValueNull(rhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(rhsType, xmlTypes)) { if (env != null) { env.IsSecureResolver = true; } } else { // Generate a warning whenever the XmlResolver property is set to an insecure value Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlDocumentWithNoSecureResolverMessage), _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model).Name ) ); context.ReportDiagnostic(diag); } } }
private void AnalyzeObjectCreationForXmlDocument(OperationAnalysisContext context, ISymbol variable, IObjectCreationOperation objCreation) { // create new environment representation if does not already exist if (variable == null || !_xmlDocumentEnvironments.TryGetValue(variable, out var xmlDocumentEnvironment)) { xmlDocumentEnvironment = new XmlDocumentEnvironment(_isFrameworkSecure); } xmlDocumentEnvironment.XmlDocumentDefinition = objCreation.Syntax; SyntaxNode node = objCreation.Syntax; // initial XmlResolver secure value dependent on whether framework version secure // < .NET 4.5.2 insecure - XmlDocument would set XmlResolver as XmlUrlResolver // >= .NET 4.5.2 secure - XmlDocument would set XmlResolver as null bool isXmlDocumentSecureResolver = _isFrameworkSecure; if (!Equals(objCreation.Constructor.ContainingType, _xmlTypes.XmlDocument)) { isXmlDocumentSecureResolver = true; } // propertyInitlizer is not returned any more // and no way to get propertysymbol if (objCreation.Initializer != null) { foreach (IOperation init in objCreation.Initializer.Initializers) { if (init is IAssignmentOperation assign) { var propValue = assign.Value; if (assign.Target is not IPropertyReferenceOperation propertyReference) { continue; } var prop = propertyReference.Property; if (prop.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, "XmlResolver")) { if (propValue is not IConversionOperation operation) { return; } // if XmlResolver declared as XmlSecureResolver by initializer if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes)) { isXmlDocumentSecureResolver = true; } // if XmlResolver declared as null by initializer else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand)) { isXmlDocumentSecureResolver = true; } // otherwise insecure resolver else { context.ReportDiagnostic(assign.Syntax.CreateDiagnostic(RuleXmlDocumentWithNoSecureResolver)); return; } } else { AnalyzeNeverSetProperties(context, prop, assign.Syntax.GetLocation()); } } } } xmlDocumentEnvironment.IsSecureResolver = isXmlDocumentSecureResolver; // if XmlDocument object not temporary, add environment to dictionary if (variable != null) { _xmlDocumentEnvironments[variable] = xmlDocumentEnvironment; } // else is temporary (variable null) and XmlResolver insecure, then report now else if (!xmlDocumentEnvironment.IsSecureResolver) { context.ReportDiagnostic(node.CreateDiagnostic(RuleXmlDocumentWithNoSecureResolver)); } return; }