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); } } }
private XmlTextReaderEnvironment AnalyzeObjectCreationForXmlTextReader(IMethodSymbol symbol, SyntaxNode node, SemanticModel model) { var env = new XmlTextReaderEnvironment(AreDefaultsSecure, symbol, node); if (!ReferenceEquals(symbol.ContainingType, XmlTypes.XmlTextReader)) { // We assume the design of derived type is secure env.IsDtdProcessingDisabled = true; env.IsSecureResolver = true; } foreach (SyntaxNode arg in SyntaxNodeHelper.GetObjectInitializerExpressionNodes(node)) { SyntaxNode argLhs = SyntaxNodeHelper.GetAssignmentLeftNode(arg); SyntaxNode argRhs = SyntaxNodeHelper.GetAssignmentRightNode(arg); ISymbol argLhsSymbol = SyntaxNodeHelper.GetSymbol(argLhs, model); if (SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(argLhsSymbol, XmlTypes)) { env.IsSecureResolver = SyntaxNodeHelper.NodeHasConstantValueNull(argRhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(argRhs).Type, XmlTypes); } else if (SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(argLhsSymbol, XmlTypes)) { env.IsDtdProcessingDisabled = !SyntaxNodeHelper.NodeHasConstantValue(argRhs, model, 2 /*DtdProcessing.Parse*/); } else if (SecurityDiagnosticHelpers.IsXmlTextReaderProhibitDtdPropertyDerived(argLhsSymbol, XmlTypes)) { env.IsDtdProcessingDisabled = !SyntaxNodeHelper.NodeHasConstantValue(argRhs, model, false); } } return(env); }
private void AnalyzeObjectCreationForXmlTextReader(OperationAnalysisContext context, ISymbol variable, IObjectCreationOperation objCreation) { if (variable == null || !_xmlTextReaderEnvironments.TryGetValue(variable, out XmlTextReaderEnvironment env)) { env = new XmlTextReaderEnvironment(_isFrameworkSecure) { XmlTextReaderDefinition = objCreation.Syntax }; } if (objCreation.Constructor.ContainingType != _xmlTypes.XmlTextReader) { env.IsDtdProcessingDisabled = true; env.IsSecureResolver = true; } 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 (propValue is IConversionOperation operation && SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(prop, _xmlTypes)) { env.IsXmlResolverSet = true; if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes)) { env.IsSecureResolver = true; } else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand)) { env.IsSecureResolver = true; } else { env.IsSecureResolver = false; } } else if (SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(prop, _xmlTypes)) { env.IsDtdProcessingSet = true; env.IsDtdProcessingDisabled = !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(propValue); } } } }
private void AnalyzeXmlTextReaderProperties(OperationAnalysisContext context, ISymbol assignedSymbol, IAssignmentExpression expression, bool isXmlTextReaderXmlResolverProperty, bool isXmlTextReaderDtdProcessingProperty) { XmlTextReaderEnvironment env; if (!_xmlTextReaderEnvironments.TryGetValue(assignedSymbol, out env)) { env = new XmlTextReaderEnvironment(_isFrameworkSecure); } if (isXmlTextReaderXmlResolverProperty) { env.IsXmlResolverSet = true; } else { env.IsDtdProcessingSet = true; } IConversionExpression conv = expression.Value as IConversionExpression; if (isXmlTextReaderXmlResolverProperty && conv != null && SecurityDiagnosticHelpers.IsXmlSecureResolverType(conv.Operand.Type, _xmlTypes)) { env.IsSecureResolver = true; } else if (isXmlTextReaderXmlResolverProperty && conv != null && SecurityDiagnosticHelpers.IsExpressionEqualsNull(conv.Operand)) { env.IsSecureResolver = true; } else if (isXmlTextReaderDtdProcessingProperty && conv == null && !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(expression.Value)) { env.IsDtdProcessingDisabled = !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(expression.Value); } else { // Generate a warning whenever the XmlResolver or DtdProcessing property is set to an insecure value Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, expression.Syntax.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderSetInsecureResolutionMessage) ) ); context.ReportDiagnostic(diag); } }
private void AnalyzeObjectCreationForXmlTextReader(OperationAnalysisContext context, ISymbol variable, IObjectCreationExpression objCreation) { if (variable == null || !_xmlTextReaderEnvironments.TryGetValue(variable, out XmlTextReaderEnvironment env)) { env = new XmlTextReaderEnvironment(_isFrameworkSecure) { XmlTextReaderDefinition = objCreation.Syntax }; } if (objCreation.Constructor.ContainingType != _xmlTypes.XmlTextReader) { env.IsDtdProcessingDisabled = true; env.IsSecureResolver = true; } foreach (ISymbolInitializer init in objCreation.MemberInitializers) { if (init is IPropertyInitializer prop) { if (prop.Value is IConversionExpression operation && SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(prop.InitializedProperty, _xmlTypes)) { env.IsXmlResolverSet = true; if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes)) { env.IsSecureResolver = true; } else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand)) { env.IsSecureResolver = true; } else { env.IsSecureResolver = false; } } else if (SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(prop.InitializedProperty, _xmlTypes)) { env.IsDtdProcessingSet = true; env.IsDtdProcessingDisabled = !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(prop.Value); } } }
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 AnalyzeObjectCreationForXmlTextReader(OperationAnalysisContext context, ISymbol variable, IObjectCreationExpression objCreation) { XmlTextReaderEnvironment env; if (variable == null || !_xmlTextReaderEnvironments.TryGetValue(variable, out env)) { env = new XmlTextReaderEnvironment(_isFrameworkSecure) { XmlTextReaderDefinition = objCreation.Syntax }; } if (objCreation.Constructor.ContainingType != _xmlTypes.XmlTextReader) { env.IsDtdProcessingDisabled = true; env.IsSecureResolver = true; } foreach (ISymbolInitializer init in objCreation.MemberInitializers) { var prop = init as IPropertyInitializer; if (prop != null) { IConversionExpression operation = prop.Value as IConversionExpression; if (operation != null && SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(prop.InitializedProperty, _xmlTypes)) { env.IsXmlResolverSet = true; if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes)) { env.IsSecureResolver = true; } else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand)) { env.IsSecureResolver = true; } else { env.IsSecureResolver = false; } } else if (SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(prop.InitializedProperty, _xmlTypes)) { env.IsDtdProcessingSet = true; env.IsDtdProcessingDisabled = !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(prop.Value); } } } // if the XmlResolver or Dtdprocessing property is explicitly set when created, and is to an insecure value, generate a warning if ((env.IsXmlResolverSet && !env.IsSecureResolver) || (env.IsDtdProcessingSet && !env.IsDtdProcessingDisabled)) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, env.XmlTextReaderDefinition.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderSetInsecureResolutionMessage) ) ); context.ReportDiagnostic(diag); } // if the XmlResolver or Dtdprocessing property is not explicitly set when constructed for a non-temp XmlTextReader object, add env to the dictionary. else if (variable != null && !(env.IsDtdProcessingSet && env.IsXmlResolverSet)) { _xmlTextReaderEnvironments[variable] = env; } // if the is not set or set to Parse for a temporary object, report right now. else if (variable == null && !(env.IsDtdProcessingSet && env.IsXmlResolverSet && env.IsDtdProcessingDisabled && env.IsSecureResolver)) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDtdProcessing, env.XmlTextReaderDefinition.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderConstructedWithNoSecureResolutionMessage) ) ); context.ReportDiagnostic(diag); } }
//Note: False negative if integer is used to set DtdProcessing instead of enumeration private void AnalyzeNodeForXmlTextReader(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.IsXmlTextReaderCtorDerived(rhsMethodSymbol, xmlTypes)) { XmlTextReaderEnvironment env = null; if (!_xmlTextReaderEnvironments.TryGetValue(lhsSymbol, out env)) { env = new XmlTextReaderEnvironment(_isFrameworkSecure); } if (rhsMethodSymbol.ContainingType != xmlTypes.XmlTextReader) { env.IsDtdProcessingDisabled = true; env.IsSecureResolver = true; } foreach (SyntaxNode arg in _syntaxNodeHelper.GetObjectInitializerExpressionNodes(rhs)) { SyntaxNode argLhs = _syntaxNodeHelper.GetAssignmentLeftNode(arg); SyntaxNode argRhs = _syntaxNodeHelper.GetAssignmentRightNode(arg); if (SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(SyntaxNodeHelper.GetSymbol(argLhs, model), xmlTypes)) { env.IsXmlResolverSet = true; env.IsSecureResolver = SyntaxNodeHelper.NodeHasConstantValueNull(argRhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(argRhs).Type, xmlTypes); } else if (SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(SyntaxNodeHelper.GetSymbol(argLhs, model), xmlTypes)) { env.IsDtdProcessingSet = true; env.IsDtdProcessingDisabled = !SyntaxNodeHelper.GetSymbol(argRhs, model).MatchFieldByName(xmlTypes.DtdProcessing, SecurityMemberNames.Parse); } } // if the XmlResolver or Dtdprocessing property is explicitly set when created, and is to an insecure value, generate a warning if ((env.IsXmlResolverSet & !env.IsSecureResolver) || (env.IsDtdProcessingSet & !env.IsDtdProcessingDisabled)) { Diagnostic diag = Diagnostic.Create( RuleDoNotUseInsecureDTDProcessing, node.GetLocation(), SecurityDiagnosticHelpers.GetLocalizableResourceString( nameof(DesktopAnalyzersResources.XmlTextReaderSetInsecureResolutionMessage), _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model).Name ) ); context.ReportDiagnostic(diag); } // if the XmlResolver or Dtdprocessing property is not explicitly set when constructed for XmlTextReader type, add env to the dictionary. else if (!(env.IsDtdProcessingSet & env.IsXmlResolverSet) && (rhsMethodSymbol.ContainingType == xmlTypes.XmlTextReader)) { env.XmlTextReaderDefinition = node; env.EnclosingConstructSymbol = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model); _xmlTextReaderEnvironments[lhsSymbol] = env; } } else if (lhsSymbol.Kind == SymbolKind.Property) { bool isXmlTextReaderXmlResolverProperty = SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(lhsSymbol, xmlTypes); bool isXmlTextReaderDtdProcessingProperty = !isXmlTextReaderXmlResolverProperty && SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(lhsSymbol, xmlTypes); if (isXmlTextReaderXmlResolverProperty | isXmlTextReaderDtdProcessingProperty) { // unlike XmlDocument, we already generate a warning for this scenario: // var doc = new XmlTextReader(path){XmlResolver = new XmlUrlResolver()}; // therefore we only need to check property setting in the form of: // xmlTextReaderObject.XmlResolver = new XmlUrlResolver(); SyntaxNode lhsExpressionNode = _syntaxNodeHelper.GetMemberAccessExpressionNode(lhs); if (lhsExpressionNode == null) { return; } ISymbol lhsExpressionSymbol = SyntaxNodeHelper.GetSymbol(lhsExpressionNode, model); if (lhsExpressionSymbol == null) { return; } XmlTextReaderEnvironment env = null; _xmlTextReaderEnvironments.TryGetValue(lhsExpressionSymbol, out env); ITypeSymbol rhsType = model.GetTypeInfo(rhs).Type; // if the XmlTextReader object was constructed with default values if (env != null) { if (isXmlTextReaderXmlResolverProperty) { env.IsXmlResolverSet = true; } else { env.IsDtdProcessingSet = true; } } if (isXmlTextReaderXmlResolverProperty && (SyntaxNodeHelper.NodeHasConstantValueNull(rhs, model) || SecurityDiagnosticHelpers.IsXmlSecureResolverType(rhsType, xmlTypes))) { if (env != null) { env.IsSecureResolver = true; } } else if (isXmlTextReaderDtdProcessingProperty && !SyntaxNodeHelper.GetSymbol(rhs, model).MatchFieldByName(xmlTypes.DtdProcessing, SecurityMemberNames.Parse)) { if (env != null) { env.IsDtdProcessingDisabled = true; } } else { // Generate a warning whenever the XmlResolver or DtdProcessing 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); } } } }