public IEnumerable <VulnerabilityDetail> FindVulnerabilties(SyntaxNode syntaxNode, string filePath, SemanticModel model = null, Solution solution = null)
        {
            List <VulnerabilityDetail> vulnerabilities   = new List <VulnerabilityDetail>();
            IEnumerable <SyntaxNode>   classDeclarations = syntaxNode.DescendantNodesAndSelf().OfType <ClassDeclarationSyntax>();

            classDeclarations = classDeclarations.Union(syntaxNode.DescendantNodesAndSelf().OfType <StructDeclarationSyntax>());

            foreach (var declaration in classDeclarations)
            {
                var symbol = (INamedTypeSymbol)model.GetDeclaredSymbol(declaration);
                if (symbol == null)
                {
                    continue;
                }

                var fields = symbol.GetMembers().Where(m => m.Kind == SymbolKind.Field).OfType <IFieldSymbol>();
                if (!fields.Any())
                {
                    continue;
                }

                var properties = GetExplictlyDeclaredProperties(symbol);
                if (!properties.Any())
                {
                    continue;
                }

                var propertyToField = new PropertyToField(fields);
                var allPropertyData = CollectPropertyData(properties, model.Compilation);

                // Check that if there is a single matching field name it is used by the property
                foreach (var data in allPropertyData)
                {
                    var expectedField = propertyToField.GetMatchingField(data.PropertySymbol);
                    if (expectedField != null)
                    {
                        SyntaxNodeOrToken unsafeNodeOrToken = null;
                        if (!data.IgnoreGetter)
                        {
                            unsafeNodeOrToken = CheckExpectedFieldIsUsed(data.PropertySymbol.GetMethod, expectedField, data.ReadFields);
                            if (unsafeNodeOrToken != null)
                            {
                                vulnerabilities.Add(VulnerabilityDetail.Create(filePath, unsafeNodeOrToken, Enums.ScannerType.PropertyAccessor,
                                                                               string.Format(message, "getter", unsafeNodeOrToken)));
                            }
                        }
                        if (!data.IgnoreSetter)
                        {
                            unsafeNodeOrToken = CheckExpectedFieldIsUsed(data.PropertySymbol.SetMethod, expectedField, data.UpdatedFields);
                            if (unsafeNodeOrToken != null)
                            {
                                vulnerabilities.Add(VulnerabilityDetail.Create(filePath, unsafeNodeOrToken, Enums.ScannerType.PropertyAccessor,
                                                                               string.Format(message, "setter", unsafeNodeOrToken)));
                            }
                        }
                    }
                }
            }
            return(vulnerabilities);
        }
        protected bool MatchPropertyToField(MemberInfo subject)
        {
            PropertyInfo property = subject as PropertyInfo;

            if (property == null)
            {
                return(false);
            }

            FieldInfo fieldInfo = PropertyToField.GetBackFieldInfo(property);

            return(fieldInfo != null);
        }
        protected bool MatchReadOnlyProperty(MemberInfo subject)
        {
            PropertyInfo property = subject as PropertyInfo;

            if (property == null)
            {
                return(false);
            }

            if (CanReadCantWriteInsideType(property) || CanReadCantWriteInBaseType(property))
            {
                return(PropertyToField.GetBackFieldInfo(property) == null);
            }

            return(false);
        }
Пример #4
0
        private static bool IsSetFieldType(MemberInfo mi, bool declared)
        {
            var propertyTypeIsSet = mi.GetPropertyOrFieldType()
                                    .GetGenericIntercafesTypeDefinitions()
                                    .Contains(typeof(ISet <>));

            if (propertyTypeIsSet)
            {
                return(true);
            }

            var backFieldInfo = PropertyToField.GetBackFieldInfo((PropertyInfo)mi);

            return(backFieldInfo != null &&
                   backFieldInfo
                   .FieldType.GetGenericIntercafesTypeDefinitions().Contains(typeof(ISet <>)));
        }
        protected bool MatchNoSetterProperty(MemberInfo subject)
        {
            PropertyInfo property = subject as PropertyInfo;

            if (property == null || property.CanWrite || !property.CanRead)
            {
                return(false);
            }

            FieldInfo fieldInfo = PropertyToField.GetBackFieldInfo(property);

            if (fieldInfo != null)
            {
                return(fieldInfo.FieldType == property.PropertyType);
            }

            return(false);
        }