Beispiel #1
0
 private void AnalyzeNeverSetProperties(OperationAnalysisContext context, IPropertySymbol property, Location location)
 {
     if (property.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, SecurityMemberNames.InnerXml))
     {
         DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessing;
         context.ReportDiagnostic(
             Diagnostic.Create(
                 rule,
                 location,
                 SecurityDiagnosticHelpers.GetLocalizableResourceString(
                     nameof(DesktopAnalyzersResources.DoNotUseSetInnerXmlMessage)
                     )
                 )
             );
     }
     else if (property.MatchPropertyDerivedByName(_xmlTypes.DataViewManager, SecurityMemberNames.DataViewSettingCollectionString))
     {
         DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessing;
         context.ReportDiagnostic(
             Diagnostic.Create(
                 rule,
                 location,
                 SecurityDiagnosticHelpers.GetLocalizableResourceString(
                     nameof(DesktopAnalyzersResources.ReviewDtdProcessingPropertiesMessage)
                     )
                 )
             );
     }
 }
Beispiel #2
0
            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;
                }
            }
Beispiel #3
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            // TODO: Make analyzer thread-safe.
            //analysisContext.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics in generated code.
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            analysisContext.RegisterCompilationStartAction(
                (context) =>
            {
                Compilation compilation = context.Compilation;
                var xmlTypes            = new CompilationSecurityTypes(compilation);
                if (ReferencesAnyTargetType(xmlTypes))
                {
                    Version version = SecurityDiagnosticHelpers.GetDotNetFrameworkVersion(compilation);

                    // bail if we are not analyzing project targeting .NET Framework
                    // TODO: should we throw an exception to notify user?
                    if (version != null)
                    {
                        SymbolAndNodeAnalyzer analyzer = GetAnalyzer(context, xmlTypes, version);
                        context.RegisterSymbolAction(analyzer.AnalyzeSymbol, SymbolKind.NamedType);
                    }
                }
            });
        }
            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);
                    }
                }
            }
Beispiel #5
0
            private void AnalyzeObjectCreationInternal(OperationAnalysisContext context, ISymbol variable, IOperation value)
            {
                IObjectCreationExpression objCreation = value as IObjectCreationExpression;

                if (objCreation == null)
                {
                    return;
                }

                if (_objectCreationOperationsAnalyzed.Contains(objCreation))
                {
                    return;
                }
                else
                {
                    _objectCreationOperationsAnalyzed.Add(objCreation);
                }

                if (SecurityDiagnosticHelpers.IsXmlDocumentCtorDerived(objCreation.Constructor, _xmlTypes))
                {
                    AnalyzeObjectCreationForXmlDocument(context, variable, objCreation);
                }
                else if (SecurityDiagnosticHelpers.IsXmlTextReaderCtorDerived(objCreation.Constructor, _xmlTypes))
                {
                    AnalyzeObjectCreationForXmlTextReader(context, variable, objCreation);
                }
                else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsCtor(objCreation.Constructor, _xmlTypes))
                {
                    AnalyzeObjectCreationForXmlReaderSettings(variable, objCreation);
                }
                else
                {
                    AnalyzeMethodOverloads(context, objCreation.Constructor, objCreation);
                }
            }
Beispiel #6
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            // TODO: Make analyzer thread-safe
            //analysisContext.EnableConcurrentExecution();

            // Security analyzer - analyze and report diagnostics in generated code.
            analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

            analysisContext.RegisterCompilationStartAction(
                (context) =>
            {
                Compilation compilation = context.Compilation;
                var xmlTypes            = new CompilationSecurityTypes(compilation);

                if (ReferencesAnyTargetType(xmlTypes))
                {
                    Version version = SecurityDiagnosticHelpers.GetDotNetFrameworkVersion(compilation);

                    if (version != null)
                    {
                        context.RegisterOperationBlockStartAction(
                            (c) =>
                        {
                            RegisterAnalyzer(c, xmlTypes, version);
                        });
                    }
                }
            });
        }
Beispiel #7
0
            private void AnalyzeNodeForXmlDocumentDerivedTypeConstructorDecl(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node  = context.Node;
                SemanticModel model = context.SemanticModel;

                IMethodSymbol methodSymbol = SyntaxNodeHelper.GetDeclaredSymbol(node, model) as IMethodSymbol;

                if (methodSymbol == null ||
                    methodSymbol.MethodKind != MethodKind.Constructor ||
                    !((methodSymbol.ContainingType != _xmlTypes.XmlDocument) && methodSymbol.ContainingType.DerivesFrom(_xmlTypes.XmlDocument, baseTypesOnly: true)))
                {
                    return;
                }

                bool hasSetSecureXmlResolver = false;

                IEnumerable <SyntaxNode> assignments = _syntaxNodeHelper.GetDescendantAssignmentExpressionNodes(node);

                foreach (SyntaxNode a in assignments)
                {
                    bool isTargetProperty;
                    // this is intended to be an assignment, not a bug
                    if (hasSetSecureXmlResolver = IsAssigningIntendedValueToPropertyDerivedFromType(a,
                                                                                                    model,
                                                                                                    (s) =>
                    {
                        return(SecurityDiagnosticHelpers.IsXmlDocumentXmlResolverProperty(s, _xmlTypes));
                    },
                                                                                                    (n) =>
                    {
                        return(SyntaxNodeHelper.NodeHasConstantValueNull(n, model) ||
                               SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(n).Type, _xmlTypes));
                    },
                                                                                                    out isTargetProperty))
                    {
                        break;
                    }
                }

                if (!hasSetSecureXmlResolver)
                {
                    DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessingInApiDesign;
                    context.ReportDiagnostic(
                        CreateDiagnostic(
                            methodSymbol.Locations,
                            rule,
                            SecurityDiagnosticHelpers.GetLocalizableResourceString(
                                nameof(DesktopAnalyzersResources.XmlDocumentDerivedClassConstructorNoSecureXmlResolverMessage),
                                SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model)
                                )
                            )
                        );
                }
            }
Beispiel #8
0
 private static DiagnosticDescriptor CreateDiagnosticDescriptor(LocalizableResourceString messageFormat, LocalizableResourceString description, string helpLink = null)
 {
     return(new DiagnosticDescriptor(RuleId,
                                     SecurityDiagnosticHelpers.GetLocalizableResourceString(nameof(DesktopAnalyzersResources.InsecureXsltScriptProcessingMessage)),
                                     messageFormat,
                                     DiagnosticCategory.Security,
                                     DiagnosticSeverity.Warning,
                                     isEnabledByDefault: true,
                                     description: description,
                                     helpLinkUri: helpLink,
                                     customTags: WellKnownDiagnosticTags.Telemetry));
 }
Beispiel #9
0
            // Trying to find every "this.XmlResolver = [Insecure Resolve];" in methods of types derived from XmlDocment and generate a warning for each
            private void AnalyzeNodeForXmlDocumentDerivedTypeMethodDecl(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node  = context.Node;
                SemanticModel model = context.SemanticModel;

                IMethodSymbol methodSymbol = SyntaxNodeHelper.GetDeclaredSymbol(node, model) as IMethodSymbol;

                if (methodSymbol == null ||
                    // skip constructors since we report on the absence of secure assignment in AnalyzeNodeForXmlDocumentDerivedTypeConstructorDecl
                    methodSymbol.MethodKind == MethodKind.Constructor ||
                    !((methodSymbol.ContainingType != _xmlTypes.XmlDocument) && methodSymbol.ContainingType.DerivesFrom(_xmlTypes.XmlDocument, baseTypesOnly: true)))
                {
                    return;
                }

                var assignments = this._syntaxNodeHelper.GetDescendantAssignmentExpressionNodes(node);

                foreach (var assignment in assignments)
                {
                    bool isTargetProperty;
                    // this is intended to be an assignment, not a bug
                    if (IsAssigningIntendedValueToPropertyDerivedFromType(assignment,
                                                                          model,
                                                                          (s) =>
                    {
                        return(SecurityDiagnosticHelpers.IsXmlDocumentXmlResolverProperty(s, this._xmlTypes));
                    },
                                                                          (n) =>
                    {
                        return(!(SyntaxNodeHelper.NodeHasConstantValueNull(n, model) ||
                                 SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(n).Type, this._xmlTypes)));
                    },
                                                                          out isTargetProperty)
                        )
                    {
                        var rule = RuleDoNotUseInsecureDtdProcessingInApiDesign;
                        context.ReportDiagnostic(
                            CreateDiagnostic(
                                assignment.GetLocation(),
                                rule,
                                SecurityDiagnosticHelpers.GetLocalizableResourceString(
                                    nameof(DesktopAnalyzersResources.XmlDocumentDerivedClassSetInsecureXmlResolverInMethodMessage),
                                    methodSymbol.Name
                                    )
                                )
                            );
                    }
                }
            }
Beispiel #10
0
            private void AnalyzeObjectCreationForXmlReaderSettings(ISymbol variable, IObjectCreationExpression objCreation)
            {
                XmlReaderSettingsEnvironment xmlReaderSettingsEnv = new XmlReaderSettingsEnvironment(_isFrameworkSecure);

                if (variable != null)
                {
                    _xmlReaderSettingsEnvironments[variable] = xmlReaderSettingsEnv;
                }

                xmlReaderSettingsEnv.XmlReaderSettingsDefinition = objCreation.Syntax;
                foreach (ISymbolInitializer init in objCreation.MemberInitializers)
                {
                    var prop = init as IPropertyInitializer;

                    if (prop != null)
                    {
                        if (SecurityDiagnosticHelpers.IsXmlReaderSettingsXmlResolverProperty(
                                prop.InitializedProperty,
                                _xmlTypes)
                            )
                        {
                            IConversionExpression operation = prop.Value as IConversionExpression;

                            if (operation == null)
                            {
                                return;
                            }

                            if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(operation.Operand.Type, _xmlTypes))
                            {
                                xmlReaderSettingsEnv.IsSecureResolver = true;
                            }
                            else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(operation.Operand))
                            {
                                xmlReaderSettingsEnv.IsSecureResolver = true;
                            }
                        }
                        else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsDtdProcessingProperty(prop.InitializedProperty, _xmlTypes))
                        {
                            xmlReaderSettingsEnv.IsDtdProcessingDisabled = !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(prop.Value);
                        }
                        else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsMaxCharactersFromEntitiesProperty(prop.InitializedProperty, _xmlTypes))
                        {
                            xmlReaderSettingsEnv.IsMaxCharactersFromEntitiesLimited = !SecurityDiagnosticHelpers.IsExpressionEqualsIntZero(prop.Value);
                        }
                    }
                }
            }
            private void AnalyzeNodeForDtdProcessingProperties(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node          = context.Node;
                SemanticModel semanticModel = context.SemanticModel;

                SyntaxNode lhs = _syntaxNodeHelper.GetAssignmentLeftNode(node);

                if (lhs == null)
                {
                    return;
                }

                IPropertySymbol property = SyntaxNodeHelper.GetCalleePropertySymbol(lhs, semanticModel);

                if (property == null)
                {
                    return;
                }

                if (property.MatchPropertyDerivedByName(_xmlTypes.XmlDocument, SecurityMemberNames.InnerXml))                                       //FxCop CA3058
                {
                    DiagnosticDescriptor rule = RuleDoNotUseInsecureDTDProcessing;
                    context.ReportDiagnostic(
                        Diagnostic.Create(
                            rule,
                            node.GetLocation(),
                            SecurityDiagnosticHelpers.GetLocalizableResourceString(
                                nameof(DesktopAnalyzersResources.DoNotUseSetInnerXmlMessage),
                                SecurityDiagnosticHelpers.GetNonEmptyParentName(node, semanticModel)
                                )
                            )
                        );
                }
                else if (property.MatchPropertyDerivedByName(_xmlTypes.DataViewManager, SecurityMemberNames.DataViewSettingCollectionString))   //FxCop CA3065
                {
                    DiagnosticDescriptor rule = RuleDoNotUseInsecureDTDProcessing;
                    context.ReportDiagnostic(
                        Diagnostic.Create(
                            rule,
                            node.GetLocation(),
                            SecurityDiagnosticHelpers.GetLocalizableResourceString(
                                nameof(DesktopAnalyzersResources.ReviewDtdProcessingPropertiesMessage),
                                SecurityDiagnosticHelpers.GetNonEmptyParentName(node, semanticModel)
                                )
                            )
                        );
                }
            }
Beispiel #12
0
            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);
                        }
                    }
                }
Beispiel #14
0
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.RegisterCompilationStartAction(
                (context) =>
            {
                Compilation compilation = context.Compilation;
                var xmlTypes            = new CompilationSecurityTypes(compilation);
                if (ReferencesAnyTargetType(xmlTypes))
                {
                    Version version = SecurityDiagnosticHelpers.GetDotNetFrameworkVersion(compilation);

                    // bail if we are not analyzing project targeting .NET Framework
                    // TODO: should we throw an exception to notify user?
                    if (version != null)
                    {
                        SymbolAndNodeAnalyzer analyzer = GetAnalyzer(context, xmlTypes, version);
                        context.RegisterSymbolAction(analyzer.AnalyzeSymbol, SymbolKind.NamedType);
                    }
                }
            });
        }
Beispiel #15
0
            // report warning if no explicit definition of contrsuctor in XmlTextReader derived types
            private void AnalyzeSymbolForXmlTextReaderDerivedType(SymbolAnalysisContext context)
            {
                ISymbol symbol = context.Symbol;

                if (symbol.Kind != SymbolKind.NamedType)
                {
                    return;
                }
                var typeSymbol = (INamedTypeSymbol)symbol;
                INamedTypeSymbol xmlTextReaderSym = _xmlTypes.XmlTextReader;

                if ((typeSymbol != xmlTextReaderSym) && typeSymbol.DerivesFrom(xmlTextReaderSym, baseTypesOnly: true))
                {
                    bool explicitlyDeclared = true;

                    if (typeSymbol.Constructors.Length == 1)
                    {
                        IMethodSymbol constructor = typeSymbol.Constructors[0];
                        explicitlyDeclared = !constructor.IsImplicitlyDeclared;

                        if (!explicitlyDeclared && !_isFrameworkSecure)
                        {
                            DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessingInApiDesign;
                            context.ReportDiagnostic(
                                CreateDiagnostic(
                                    typeSymbol.Locations,
                                    rule,
                                    SecurityDiagnosticHelpers.GetLocalizableResourceString(
                                        nameof(DesktopAnalyzersResources.XmlTextReaderDerivedClassNoConstructorMessage),
                                        symbol.Name
                                        )
                                    )
                                );
                        }
                    }

                    _xmlTextReaderDerivedTypes.AddOrUpdate(typeSymbol, explicitlyDeclared, (k, v) => explicitlyDeclared);
                }
            }
 public override void Initialize(AnalysisContext analysisContext)
 {
     analysisContext.RegisterCompilationStartAction(
         (context) =>
     {
         Compilation compilation = context.Compilation;
         var xmlTypes            = new CompilationSecurityTypes(compilation);
         if (ReferencesAnyTargetType(xmlTypes))
         {
             Version version = SecurityDiagnosticHelpers.GetDotNetFrameworkVersion(compilation);
             // bail if we are not analyzing project targeting .NET Framework
             // TODO: should we throw an exception to notify user?
             if (version != null)
             {
                 context.RegisterCodeBlockStartAction <TLanguageKindEnum>(
                     (c) =>
                 {
                     RegisterAnalyzer(c, xmlTypes, version);
                 });
             }
         }
     });
 }
        public override void Initialize(AnalysisContext analysisContext)
        {
            analysisContext.RegisterCompilationStartAction(
                (context) =>
            {
                Compilation compilation = context.Compilation;
                var xmlTypes            = new CompilationSecurityTypes(compilation);

                if (ReferencesAnyTargetType(xmlTypes))
                {
                    Version version = SecurityDiagnosticHelpers.GetDotNetFrameworkVersion(compilation);

                    if (version != null)
                    {
                        context.RegisterOperationBlockStartAction(
                            (c) =>
                        {
                            RegisterAnalyzer(c, xmlTypes, version);
                        });
                    }
                }
            });
        }
Beispiel #18
0
            private void AnalyzeNodeForXmlTextReaderDerivedTypeMethodDecl(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node  = context.Node;
                SemanticModel model = context.SemanticModel;

                IMethodSymbol methodSymbol = SyntaxNodeHelper.GetDeclaredSymbol(node, model) as IMethodSymbol;

                if (methodSymbol == null ||
                    !((methodSymbol.ContainingType != _xmlTypes.XmlTextReader) && methodSymbol.ContainingType.DerivesFrom(_xmlTypes.XmlTextReader, baseTypesOnly: true)))
                {
                    return;
                }

                // If the default value are not secure, the AnalyzeNodeForXmlTextReaderDerivedTypeConstructorDecl would be skipped,
                // therefoer we need to check constructor for any insecure settings.
                // Otherwise, we skip checking constructors
                if (_isFrameworkSecure && methodSymbol.MethodKind == MethodKind.Constructor)
                {
                    return;
                }

                bool hasSetXmlResolver         = false;
                bool hasSetInsecureXmlResolver = true;
                bool isDtdProcessingSet        = false;
                bool isDtdProcessingEnabled    = true;

                List <Location> locs = null;
                Location        insecureXmlResolverAssignLoc = null;
                Location        issecureDtdProcessingLoc     = null;

                IEnumerable <SyntaxNode> assignments = _syntaxNodeHelper.GetDescendantAssignmentExpressionNodes(node);

                foreach (SyntaxNode assignment in assignments)
                {
                    bool ret;
                    bool isTargetProperty;

                    ret = IsAssigningIntendedValueToPropertyDerivedFromType(assignment,
                                                                            model,
                                                                            (s) =>
                    {
                        return(SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverProperty(s, _xmlTypes));
                    },
                                                                            (n) =>
                    {
                        return(!(SyntaxNodeHelper.NodeHasConstantValueNull(n, model) ||
                                 SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(n).Type, _xmlTypes)));
                    },
                                                                            out isTargetProperty
                                                                            );

                    if (isTargetProperty)
                    {
                        hasSetXmlResolver          = true;
                        hasSetInsecureXmlResolver &= ret; // use 'AND' to avoid false positives (but imcrease false negative rate)
                        if (ret)
                        {
                            if (locs == null)
                            {
                                locs = new List <Location>();
                            }
                            locs.Add(assignment.GetLocation());
                        }
                        continue;
                    }

                    ret = IsAssigningIntendedValueToPropertyDerivedFromType(assignment,
                                                                            model,
                                                                            (s) =>
                    {
                        return(SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingProperty(s, _xmlTypes));
                    },
                                                                            (n) =>
                    {
                        return(SyntaxNodeHelper.GetSymbol(n, model).MatchFieldByName(_xmlTypes.DtdProcessing, SecurityMemberNames.Parse));
                    },
                                                                            out isTargetProperty);

                    if (isTargetProperty)
                    {
                        isDtdProcessingSet      = true;
                        isDtdProcessingEnabled &= ret; // use 'AND' to avoid false positives (but imcrease false negative rate)
                        if (ret)
                        {
                            if (locs == null)
                            {
                                locs = new List <Location>();
                            }
                            locs.Add(assignment.GetLocation());
                        }
                    }
                }

                // neither XmlResolver nor DtdProcessing is explicitly set
                if (!(hasSetXmlResolver || isDtdProcessingSet))
                {
                    return;
                }
                // explicitly set XmlResolver and/or DtdProcessing to secure value
                else if (!hasSetInsecureXmlResolver || !isDtdProcessingEnabled)
                {
                    return;
                }
                // didn't explicitly set either one of XmlResolver and DtdProcessing to secure value
                // but explicitly set XmlResolver and/or DtdProcessing to insecure value
                else
                {
                    if (insecureXmlResolverAssignLoc != null)
                    {
                        locs.Add(insecureXmlResolverAssignLoc);
                    }
                    if (issecureDtdProcessingLoc != null)
                    {
                        locs.Add(issecureDtdProcessingLoc);
                    }
                    DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessingInApiDesign;
                    // TODO: Only first location is shown in error, maybe we want to report on method instead?
                    //       Or on each insecure assignment?
                    context.ReportDiagnostic(
                        CreateDiagnostic(
                            locs,
                            rule,
                            SecurityDiagnosticHelpers.GetLocalizableResourceString(
                                nameof(DesktopAnalyzersResources.XmlTextReaderDerivedClassSetInsecureSettingsInMethodMessage),
                                methodSymbol.Name
                                )
                            )
                        );
                }
            }
            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);
                        }
                    }
                }
            }
Beispiel #20
0
            private void AnalyzeNodeForXmlTextReaderDerivedTypeConstructorDecl(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node  = context.Node;
                SemanticModel model = context.SemanticModel;

                IMethodSymbol methodSymbol = SyntaxNodeHelper.GetDeclaredSymbol(node, model) as IMethodSymbol;

                if (methodSymbol == null ||
                    methodSymbol.MethodKind != MethodKind.Constructor ||
                    !((methodSymbol.ContainingType != _xmlTypes.XmlTextReader) && methodSymbol.ContainingType.DerivesFrom(_xmlTypes.XmlTextReader, baseTypesOnly: true)))
                {
                    return;
                }

                bool hasSetSecureXmlResolver = false;
                bool isDtdProcessingDisabled = false;

                IEnumerable <SyntaxNode> assignments = _syntaxNodeHelper.GetDescendantAssignmentExpressionNodes(node);

                foreach (SyntaxNode assignment in assignments)
                {
                    bool isTargetProperty = false;

                    hasSetSecureXmlResolver = hasSetSecureXmlResolver || IsAssigningIntendedValueToPropertyDerivedFromType(assignment,
                                                                                                                           model,
                                                                                                                           (s) =>
                    {
                        return(SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverProperty(s, _xmlTypes));
                    },
                                                                                                                           (n) =>
                    {
                        return(SyntaxNodeHelper.NodeHasConstantValueNull(n, model) ||
                               SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(n).Type, _xmlTypes));
                    },
                                                                                                                           out isTargetProperty);

                    if (isTargetProperty)
                    {
                        continue;
                    }

                    isDtdProcessingDisabled = isDtdProcessingDisabled || IsAssigningIntendedValueToPropertyDerivedFromType(assignment,
                                                                                                                           model,
                                                                                                                           (s) =>
                    {
                        return(SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingProperty(s, _xmlTypes));
                    },
                                                                                                                           (n) =>
                    {
                        return(!SyntaxNodeHelper.GetSymbol(n, model).MatchFieldByName(_xmlTypes.DtdProcessing, SecurityMemberNames.Parse));
                    },
                                                                                                                           out isTargetProperty);

                    if (hasSetSecureXmlResolver && isDtdProcessingDisabled)
                    {
                        return;
                    }
                }

                DiagnosticDescriptor rule = RuleDoNotUseInsecureDtdProcessingInApiDesign;

                context.ReportDiagnostic(
                    CreateDiagnostic(
                        methodSymbol.Locations,
                        rule,
                        SecurityDiagnosticHelpers.GetLocalizableResourceString(
                            nameof(DesktopAnalyzersResources.XmlTextReaderDerivedClassConstructorNoSecureSettingsMessage),
                            SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model)
                            )
                        )
                    );
            }
Beispiel #21
0
            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 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);
                    }
                }
            }
            //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);
                        }
                    }
                }
            }
Beispiel #24
0
            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);
                }
            }
            //Note: False negative if integer is used to set DtdProcessing instead of enumeration
            private void AnalyzeNodeForXmlReaderSettings(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node  = context.Node;
                SemanticModel model = context.SemanticModel;

                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.IsXmlReaderSettingsCtor(rhsMethodSymbol, xmlTypes))
                {
                    XmlReaderSettingsEnvironment env = new XmlReaderSettingsEnvironment(_isFrameworkSecure);
                    _xmlReaderSettingsEnvironments[lhsSymbol] = env;

                    env.XmlReaderSettingsDefinition = node;
                    env.EnclosingConstructSymbol    = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model);

                    foreach (SyntaxNode arg in _syntaxNodeHelper.GetObjectInitializerExpressionNodes(rhs))
                    {
                        SyntaxNode argLhs = _syntaxNodeHelper.GetAssignmentLeftNode(arg);
                        SyntaxNode argRhs = _syntaxNodeHelper.GetAssignmentRightNode(arg);

                        ISymbol argLhsSymbol = SyntaxNodeHelper.GetSymbol(argLhs, model);

                        if (SecurityDiagnosticHelpers.IsXmlReaderSettingsXmlResolverProperty(argLhsSymbol, xmlTypes))
                        {
                            env.IsSecureResolver = SyntaxNodeHelper.NodeHasConstantValueNull(argRhs, model) ||
                                                   SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(argRhs).Type, xmlTypes);
                        }
                        else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsDtdProcessingProperty(argLhsSymbol, xmlTypes))
                        {
                            // since the default is always Prohibit, we only need update if it is set to Parse
                            if (SyntaxNodeHelper.GetSymbol(argRhs, model).MatchFieldByName(xmlTypes.DtdProcessing, SecurityMemberNames.Parse))
                            {
                                env.IsDtdProcessingDisabled = false;
                            }
                        }
                        else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsMaxCharactersFromEntitiesProperty(argLhsSymbol, xmlTypes))
                        {
                            env.IsMaxCharactersFromEntitiesLimited = !SyntaxNodeHelper.NodeHasConstantValueIntZero(argRhs, model);
                        }
                    }
                }
                else if (lhsSymbol.Kind == SymbolKind.Property)
                {
                    bool isXmlReaderSettingsXmlResolverProperty   = SecurityDiagnosticHelpers.IsXmlReaderSettingsXmlResolverProperty(lhsSymbol, xmlTypes);
                    bool isXmlReaderSettingsDtdProcessingProperty = !isXmlReaderSettingsXmlResolverProperty &&
                                                                    SecurityDiagnosticHelpers.IsXmlReaderSettingsDtdProcessingProperty(lhsSymbol, xmlTypes);
                    bool isXmlReaderSettingsMaxCharactersFromEntitiesProperty =
                        !(isXmlReaderSettingsXmlResolverProperty | isXmlReaderSettingsDtdProcessingProperty) &&
                        SecurityDiagnosticHelpers.IsXmlReaderSettingsMaxCharactersFromEntitiesProperty(lhsSymbol, xmlTypes);

                    if (isXmlReaderSettingsXmlResolverProperty |
                        isXmlReaderSettingsDtdProcessingProperty |
                        isXmlReaderSettingsMaxCharactersFromEntitiesProperty)
                    {
                        SyntaxNode lhsExpressionNode = _syntaxNodeHelper.GetMemberAccessExpressionNode(lhs);
                        if (lhsExpressionNode == null)
                        {
                            return;
                        }

                        ISymbol lhsExpressionSymbol = SyntaxNodeHelper.GetSymbol(lhsExpressionNode, model);
                        if (lhsExpressionSymbol == null)
                        {
                            return;
                        }

                        XmlReaderSettingsEnvironment env = null;
                        if (!_xmlReaderSettingsEnvironments.TryGetValue(lhsExpressionSymbol, out env))
                        {
                            // env.IsConstructedInCodeBlock is false
                            env = new XmlReaderSettingsEnvironment();
                            _xmlReaderSettingsEnvironments[lhsExpressionSymbol] = env;
                        }

                        ITypeSymbol rhsType = model.GetTypeInfo(rhs).Type;

                        if (isXmlReaderSettingsXmlResolverProperty)
                        {
                            env.IsSecureResolver = SyntaxNodeHelper.NodeHasConstantValueNull(rhs, model) ||
                                                   SecurityDiagnosticHelpers.IsXmlSecureResolverType(rhsType, xmlTypes);
                        }
                        else if (isXmlReaderSettingsDtdProcessingProperty)
                        {
                            env.IsDtdProcessingDisabled = !SyntaxNodeHelper.GetSymbol(rhs, model).MatchFieldByName(xmlTypes.DtdProcessing, SecurityMemberNames.Parse);
                        }
                        else
                        {
                            env.IsMaxCharactersFromEntitiesLimited = !SyntaxNodeHelper.NodeHasConstantValueIntZero(rhs, model);
                        }
                    }
                }
            }
Beispiel #26
0
            private void AnalyzeNodeForXsltSettings(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node  = context.Node;
                SemanticModel model = context.SemanticModel;

                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;
                }

                IMethodSymbol   rhsMethodSymbol   = _syntaxNodeHelper.GetCalleeMethodSymbol(rhs, model);
                IPropertySymbol rhsPropertySymbol = SyntaxNodeHelper.GetCalleePropertySymbol(rhs, model);

                if (SecurityDiagnosticHelpers.IsXsltSettingsCtor(rhsMethodSymbol, _xmlTypes))
                {
                    XsltSettingsEnvironment env = new XsltSettingsEnvironment();
                    _xsltSettingsEnvironments[lhsSymbol] = env;

                    env.XsltSettingsSymbol           = lhsSymbol;
                    env.XsltSettingsDefinitionSymbol = rhsMethodSymbol;
                    env.XsltSettingsDefinition       = node;
                    env.EnclosingConstructSymbol     = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model);
                    //default both properties are disbled
                    env.IsDocumentFunctionDisabled = true;
                    env.IsScriptDisabled           = true;

                    // XsltSettings Constructor (Boolean, Boolean)
                    if (rhsMethodSymbol.Parameters.Any())
                    {
                        IEnumerable <SyntaxNode> argumentExpressionNodes = _syntaxNodeHelper.GetObjectCreationArgumentExpressionNodes(rhs);
                        env.IsDocumentFunctionDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argumentExpressionNodes.ElementAt(0), model);
                        env.IsScriptDisabled           = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argumentExpressionNodes.ElementAt(1), model);
                    }

                    foreach (SyntaxNode arg in _syntaxNodeHelper.GetObjectInitializerExpressionNodes(rhs))
                    {
                        SyntaxNode argLhs = _syntaxNodeHelper.GetAssignmentLeftNode(arg);
                        SyntaxNode argRhs = _syntaxNodeHelper.GetAssignmentRightNode(arg);

                        ISymbol argLhsSymbol = SyntaxNodeHelper.GetSymbol(argLhs, model);

                        // anything other than a constant false is treated as true
                        if (SecurityDiagnosticHelpers.IsXsltSettingsEnableDocumentFunctionProperty(argLhsSymbol as IPropertySymbol, _xmlTypes))
                        {
                            env.IsDocumentFunctionDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argRhs, model);
                        }
                        else if (SecurityDiagnosticHelpers.IsXsltSettingsEnableScriptProperty(argLhsSymbol as IPropertySymbol, _xmlTypes))
                        {
                            env.IsScriptDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(argRhs, model);
                        }
                    }
                }
                else if (SecurityDiagnosticHelpers.IsXsltSettingsDefaultProperty(rhsPropertySymbol, _xmlTypes))
                {
                    XsltSettingsEnvironment env = new XsltSettingsEnvironment();
                    _xsltSettingsEnvironments[lhsSymbol] = env;

                    env.XsltSettingsSymbol           = lhsSymbol;
                    env.XsltSettingsDefinitionSymbol = rhsPropertySymbol;
                    env.XsltSettingsDefinition       = node;
                    env.EnclosingConstructSymbol     = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model);
                    env.IsDocumentFunctionDisabled   = true;
                    env.IsScriptDisabled             = true;
                }
                else if (SecurityDiagnosticHelpers.IsXsltSettingsTrustedXsltProperty(rhsPropertySymbol, _xmlTypes))
                {
                    XsltSettingsEnvironment env = new XsltSettingsEnvironment();
                    _xsltSettingsEnvironments[lhsSymbol] = env;

                    env.XsltSettingsSymbol           = lhsSymbol;
                    env.XsltSettingsDefinitionSymbol = rhsPropertySymbol;
                    env.XsltSettingsDefinition       = node;
                    env.EnclosingConstructSymbol     = _syntaxNodeHelper.GetEnclosingConstructSymbol(node, model);
                }
                else
                {
                    bool isXlstSettingsEnableDocumentFunctionProperty = SecurityDiagnosticHelpers.IsXsltSettingsEnableDocumentFunctionProperty(lhsSymbol as IPropertySymbol, _xmlTypes);
                    bool isXlstSettingsEnableScriptProperty           = SecurityDiagnosticHelpers.IsXsltSettingsEnableScriptProperty(lhsSymbol as IPropertySymbol, _xmlTypes);


                    if (isXlstSettingsEnableDocumentFunctionProperty ||
                        isXlstSettingsEnableScriptProperty)
                    {
                        SyntaxNode lhsExpressionNode = _syntaxNodeHelper.GetMemberAccessExpressionNode(lhs);
                        if (lhsExpressionNode == null)
                        {
                            return;
                        }

                        ISymbol lhsExpressionSymbol = SyntaxNodeHelper.GetSymbol(lhsExpressionNode, model);
                        if (lhsExpressionSymbol == null)
                        {
                            return;
                        }

                        XsltSettingsEnvironment env;
                        if (!_xsltSettingsEnvironments.TryGetValue(lhsExpressionSymbol, out env))
                        {
                            env = new XsltSettingsEnvironment
                            {
                                XsltSettingsSymbol = lhsExpressionSymbol
                            };
                            _xsltSettingsEnvironments[lhsExpressionSymbol] = env;
                        }

                        ITypeSymbol rhsType = model.GetTypeInfo(rhs).Type;

                        if (isXlstSettingsEnableDocumentFunctionProperty)
                        {
                            env.IsDocumentFunctionDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(rhs, model);
                        }
                        else if (isXlstSettingsEnableScriptProperty)
                        {
                            env.IsScriptDisabled = SyntaxNodeHelper.NodeHasConstantValueBoolFalse(rhs, model);
                        }
                    }
                }
            }
Beispiel #27
0
            private void AnalyzeAssignment(OperationAnalysisContext context)
            {
                IAssignmentExpression expression = context.Operation as IAssignmentExpression;

                if (expression.Target == null)
                {
                    return;
                }

                SemanticModel model   = context.Compilation.GetSemanticModel(expression.Syntax.SyntaxTree);
                var           propRef = expression.Target as IPropertyReferenceExpression;

                if (propRef == null) // A variable/field assignment
                {
                    ISymbol symbolAssignedTo = expression.Target.Syntax.GetDeclaredOrReferencedSymbol(model);

                    if (symbolAssignedTo != null)
                    {
                        AnalyzeObjectCreationInternal(context, symbolAssignedTo, expression.Value);
                    }
                }
                else // A property assignment
                {
                    ISymbol assignedSymbol = propRef.Instance.Syntax.GetDeclaredOrReferencedSymbol(model);

                    if (propRef.Property.MatchPropertyByName(_xmlTypes.XmlDocument, "XmlResolver"))
                    {
                        AnalyzeXmlResolverPropertyAssignmentForXmlDocument(context, assignedSymbol, expression);
                    }
                    else
                    {
                        bool isXmlTextReaderXmlResolverProperty   = SecurityDiagnosticHelpers.IsXmlTextReaderXmlResolverPropertyDerived(propRef.Property, _xmlTypes);
                        bool isXmlTextReaderDtdProcessingProperty = !isXmlTextReaderXmlResolverProperty &&
                                                                    SecurityDiagnosticHelpers.IsXmlTextReaderDtdProcessingPropertyDerived(propRef.Property, _xmlTypes);
                        if (isXmlTextReaderXmlResolverProperty || isXmlTextReaderDtdProcessingProperty)
                        {
                            AnalyzeXmlTextReaderProperties(context, assignedSymbol, expression, isXmlTextReaderXmlResolverProperty, isXmlTextReaderDtdProcessingProperty);
                        }
                        else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsType(propRef.Instance.Type, _xmlTypes))
                        {
                            XmlReaderSettingsEnvironment env;

                            if (!_xmlReaderSettingsEnvironments.TryGetValue(assignedSymbol, out env))
                            {
                                env = new XmlReaderSettingsEnvironment(_isFrameworkSecure);
                                _xmlReaderSettingsEnvironments[assignedSymbol] = env;
                            }

                            IConversionExpression conv = expression.Value as IConversionExpression;

                            if (conv != null && SecurityDiagnosticHelpers.IsXmlReaderSettingsXmlResolverProperty(
                                    propRef.Property,
                                    _xmlTypes)
                                )
                            {
                                if (SecurityDiagnosticHelpers.IsXmlSecureResolverType(conv.Operand.Type, _xmlTypes))
                                {
                                    env.IsSecureResolver = true;
                                }
                                else if (SecurityDiagnosticHelpers.IsExpressionEqualsNull(conv.Operand))
                                {
                                    env.IsSecureResolver = true;
                                }
                            }
                            else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsDtdProcessingProperty(propRef.Property, _xmlTypes))
                            {
                                env.IsDtdProcessingDisabled = !SecurityDiagnosticHelpers.IsExpressionEqualsDtdProcessingParse(expression.Value);
                            }
                            else if (SecurityDiagnosticHelpers.IsXmlReaderSettingsMaxCharactersFromEntitiesProperty(propRef.Property, _xmlTypes))
                            {
                                env.IsMaxCharactersFromEntitiesLimited = !SecurityDiagnosticHelpers.IsExpressionEqualsIntZero(expression.Value);
                            }
                        }
                        else
                        {
                            AnalyzeNeverSetProperties(context, propRef.Property, expression.Syntax.GetLocation());
                        }
                    }
                }
            }
Beispiel #28
0
            private void AnalyzeNodeForXslCompiledTransformLoad(SyntaxNodeAnalysisContext context)
            {
                SyntaxNode    node         = context.Node;
                SemanticModel model        = context.SemanticModel;
                IMethodSymbol methodSymbol = _syntaxNodeHelper.GetCalleeMethodSymbol(node, model);

                if (SecurityDiagnosticHelpers.IsXslCompiledTransformLoad(methodSymbol, _xmlTypes))
                {
                    bool isSecureResolver;
                    bool isSecureSettings;
                    bool isSetInBlock;

                    int xmlResolverIndex  = SecurityDiagnosticHelpers.GetXmlResolverParameterIndex(methodSymbol, _xmlTypes);
                    int xsltSettingsIndex = SecurityDiagnosticHelpers.GetXsltSettingsParameterIndex(methodSymbol, _xmlTypes);

                    // Overloads with no XmlResolver and XstlSettings specified are secure since they all have folowing behavior:
                    //  1. An XmlUrlResolver with no user credentials is used to process any xsl:import or xsl:include elements.
                    //  2. The document() function is disabled.
                    //  3. Embedded scripts are not supported.
                    if (xmlResolverIndex >= 0 &&
                        xsltSettingsIndex >= 0)
                    {
                        IEnumerable <SyntaxNode> argumentExpressionNodes = _syntaxNodeHelper.GetInvocationArgumentExpressionNodes(node);
                        SyntaxNode resolverNode = argumentExpressionNodes.ElementAt(xmlResolverIndex);

                        isSecureResolver = SyntaxNodeHelper.NodeHasConstantValueNull(resolverNode, model) ||
                                           SecurityDiagnosticHelpers.IsXmlSecureResolverType(model.GetTypeInfo(resolverNode).Type, _xmlTypes);


                        SyntaxNode settingsNode   = argumentExpressionNodes.ElementAt(xsltSettingsIndex);
                        ISymbol    settingsSymbol = SyntaxNodeHelper.GetSymbol(settingsNode, model);
                        XsltSettingsEnvironment env;

                        // 1. pass null or XsltSettings.Default as XsltSetting : secure
                        if (settingsSymbol == null || SecurityDiagnosticHelpers.IsXsltSettingsDefaultProperty(settingsSymbol as IPropertySymbol, _xmlTypes))
                        {
                            isSetInBlock     = true;
                            isSecureSettings = true;
                        }
                        // 2. XsltSettings.TrustedXslt : insecure
                        else if (SecurityDiagnosticHelpers.IsXsltSettingsTrustedXsltProperty(settingsSymbol as IPropertySymbol, _xmlTypes))
                        {
                            isSetInBlock     = true;
                            isSecureSettings = false;
                        }
                        // 3. check xsltSettingsEnvironments, if IsScriptDisabled && IsDocumentFunctionDisabled then secure, else insecure
                        else if (_xsltSettingsEnvironments.TryGetValue(settingsSymbol, out env))
                        {
                            isSetInBlock     = false;
                            isSecureSettings = env.IsDocumentFunctionDisabled && env.IsScriptDisabled;
                        }
                        //4. symbol for settings is not found => passed in without any change => assume insecure
                        else
                        {
                            isSetInBlock     = true;
                            isSecureSettings = false;
                        }

                        if (!isSecureSettings && !isSecureResolver)
                        {
                            LocalizableResourceString message = SecurityDiagnosticHelpers.GetLocalizableResourceString(
                                isSetInBlock ? nameof(DesktopAnalyzersResources.XslCompiledTransformLoadInsecureConstructedMessage) :
                                nameof(DesktopAnalyzersResources.XslCompiledTransformLoadInsecureInputMessage),
                                SecurityDiagnosticHelpers.GetNonEmptyParentName(node, model)
                                );

                            context.ReportDiagnostic(
                                Diagnostic.Create(
                                    RuleDoNotUseInsecureXSLTScriptExecution,
                                    node.GetLocation(),
                                    message
                                    )
                                );
                        }
                    }
                }
            }
Beispiel #29
0
            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);
                }
            }