Beispiel #1
0
        public bool IsVulnerable(SemanticModel model, MethodDeclarationSyntax syntax)
        {
            //Quick check - public methods only
            if (!syntax.Modifiers.Any(i => i.Kind() == SyntaxKind.PublicKeyword))
            {
                return(false);
            }

            //Verify the return type is an expected value.
            if (syntax == null || !syntax.ContainsReturnType(model, _ACTION_RESULT_NAMESPACES))
            {
                return(false);
            }

            //Assuming a good design pattern where GET requests (no method decoration) actually
            //only retrieve data and do not make a data modifications. We all know this isn't always the case,
            //but this is to reduce false positives on methods that are not vulnerable
            if (syntax.AttributeLists.Count == 0)
            {
                return(false);
            }

            //Search for HttpPost, HttpPut, HttpPatch, and HttpDelete decorators on the action
            var dataModification         = false;
            var validateAntiForgeryToken = false;
            var anonymousMethod          = false;

            foreach (var attributeSyntax in syntax.AttributeLists)
            {
                foreach (var attribute in attributeSyntax.Attributes)
                {
                    //Check for action verb (post, put, delete, etc.)
                    if (!dataModification && _MODIFICATION_VERB_ATTRIBUTES.Split('|').Contains(attribute.Name?.ToString()))
                    {
                        dataModification = true;
                    }

                    //Check for anti forgery token method
                    if (!validateAntiForgeryToken && string.Compare(attribute.Name?.ToString(), _ANTI_FORGERY_TOKEN_ATTRIBUTE) == 0)
                    {
                        validateAntiForgeryToken = true;
                    }

                    //Check for anoynmous attribute (reduces fps)
                    if (!anonymousMethod && string.Compare(attribute.Name?.ToString(), _ANONYMOUS_ATTRIBUTE) == 0)
                    {
                        anonymousMethod = true;
                    }
                }
            }

            return(dataModification && !validateAntiForgeryToken && !anonymousMethod);
        }
Beispiel #2
0
        public List <SyntaxNode> IsVulnerable(SemanticModel model, ClassDeclarationSyntax syntax)
        {
            List <SyntaxNode> sources = new List <SyntaxNode>();

            //Check the class declaration
            if (!hasBaseClass(model, syntax))
            {
                return(sources);
            }

            //Pull the list of candidate methods
            var methodDeclarations = syntax.Members.Where(i => i.Kind() == SyntaxKind.MethodDeclaration).ToList();

            foreach (MemberDeclarationSyntax member in methodDeclarations)
            {
                MethodDeclarationSyntax methodSyntax = member as MethodDeclarationSyntax;
                if (methodSyntax == null)
                {
                    continue;
                }

                //Quick check - public methods only
                if (!methodSyntax.Modifiers.Any(i => i.Kind() == SyntaxKind.PublicKeyword))
                {
                    continue;
                }

                //If does not have the correct return type
                if (!methodSyntax.ContainsReturnType(model, _ACTION_RESULT_SYNTAXES))
                {
                    continue;
                }

                //Check method declaration for attributes
                if (isMissingAuthorizeAttribute(model, methodSyntax.AttributeLists))
                {
                    sources.Add(methodSyntax.ReturnType);
                }
            }

            return(sources);
        }