SQL Injection in 2013: Lets Work Together to Remediate

January 4, 2013 by · Comments Off on SQL Injection in 2013: Lets Work Together to Remediate
Filed under: Development, Security 

We just started 2013 and SQL Injection has been a vulnerability plaguing us for over 10 years.  It is time to take action.  Not that we haven’t been taking action, but it is still prevalent in web applications.  We need to set attainable goals.  Does it seem attainable that we say we will eradicate all SQL Injection in 2013?  Probably not.  This is mostly due to legacy applications and the difficulty in modifying their code. There are some goals we can do to stop writing new code vulnerable to SQL Injection.  Fortunately, this is not a vulnerability that is not well understood.  Here are some thoughts for moving forward.

Don’t write SQL Injection Code

OK, this sounds like what everyone is saying, and it is.  Is it difficult to do? No.   Like anything, this is something we need to commit to and consciously make an effort to do.  Proper SQL Queries are not difficult.  Using parameterized queries is easy to do in most languages now.  Here is a quick example of a parameterized query in .Net:

using (SqlConnection cn = new SqlConnection())
{
    using (SqlCommand cmd = new SqlCommand())
    {
        string query = "SELECT fName,lName from Users WHERE fName = @fname";
        cmd.CommandText = query;
        cmd.CommandType = System.Data.CommandType.Text;
        cmd.Parameters.AddWithValue("@fname", untrustedInput);
        cmd.Connection = cn;
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
    }
}

What about stored procedures?  Stored procedures are good, but can be vulnerable to SQL Injection.  This is most common when you generate dynamic queries from within the stored procedure.  Yes, the parameters are passed to the procedure properly, but then used in an insecure way inside the procedure.  If you are unsure if your procedures are vulnerable, look for the use of EXEC or other SQL commands that run SQL code and make sure parameters are handled properly.

Often overlooked is how a Stored Procedure is called.  You are using a stored procedure but calling it like so:

string query = "EXEC spGetUser '" + untrustedinput + "'";

The above query can still be vulnerable to SQL Injection by chaining onto the EXEC statement.  So even though the stored procedure may be secure, an attacker may be able to run commands (just not see the output). 

The key to not writing vulnerable code is to not write it ever.  Whether it is a proof of concept, just some test code, or actual production code, take the time to use secure methods.  This secure way will be second nature and SQL injection reduction will be on its way.

Supportively Spread the Word

The key here is Supportively!!  Yes, we have been talking about SQL injection for years, but have we been doing it the right way, to the right people?  First, enough with the “Developers Suck”, “Your code sucks!” nonsense.  This is not productive and is probably much more destructive to the relationship between security and developers.  Second, security practitioners meet up at their cons and talk about this all year long.  This may sound crazy, but it is not the security practitioners that are writing the code.  We need to get the information into the developer’s hands and minds.  Just throwing the information on a blog (like this) or on a website like OWASP or SANS is not enough to get developers the information.  I don’t even want to guess at the number of developers that have never even heard of OWASP, but I would venture it is higher than you think.  Everyone needs to help spread the word.  Security is talking about it, developers need to be talking about it.  Major development conferences rarely have any content that is security related, that needs to change.  It needs to be thrown in everyone’s lap.   If you see someone writing something insecure, let them know so they can learn.  We can’t assume everyone knows everything.

Lets start including the secure way of writing SQL Queries in our tutorials, books, classes so all we see is the right way to do it.  I mentioned this a year or so ago and everyone cried that it would make the code samples in books and tutorials too long and impossible to follow.  First, I disagree that it would be that detrimental.  Second, where do developers get a lot of their code? From tutorials, samples, books, classes.  We don’t reinvent the wheel when we need to do something.  We look for someone that has done it, take the concept, make modifications to work in our situation and run with it.  All too often, this leads to a lot of vulnerabilities because we refuse to write secure code that is put out for anyone to use. We all need to get better at this.  And if you are the author, maybe it adds a few pages to your book ;).  

Take Responsibility

We can no longer blame others for the code we write.  Maybe the code was copied from an online resource.  As soon as it is in your paws, it is your code now.  It is not the fault of MSSQL or Oracle because they allow you to write dynamic  SQL queries.  This is the power of the system, and some people may just use it.  It is our responsibility to know how to use the systems we have. Many frameworks now try to help stop SQL Injection by default.  If you are relying on frameworks, know how they work, and keep them patched.  We just saw Ruby release a patch to fix a SQL Injection issue. 

Conclusion

So maybe this was a lot of rambling, or maybe it will mean something and get a few people thinking about defending against SQL Injection.  I apologize for some small tangents, those are part of another post that will be coming soon.  The purpose of this post is to start setting some goals that we can achieve in 2013.   Not everyone can eat an entire apple in one bite, so lets take some small bites and really chew on them for the year.  Lets focus on what we can do and do it well.

Authorization: Bad Implementation

January 3, 2013 by · Comments Off on Authorization: Bad Implementation
Filed under: Development, Security, Testing 

A few years ago, I joined a development team and got a chance to poke around a little bit for security issues.  For a team that didn’t think much about security, it didn’t take long to identify some serious vulnerabilities.  One of those issues that I saw related to authorization for privileged areas of the application. Authorization is a critical control when it comes to protecting your applications because you don’t want unauthorized users performing actions they should not be able to perform. 

The application was designed using security by obscurity: that’s right, if we only display the administrator navigation panel to administrators, no one will ever find the pages.   There was no authorization check performed on the page itself.  If you were an administrator, the page displayed the links that you could click.  If you were not an administrator, no links.

In the security community, we all know (or should know), that this is not acceptable.  Unfortunately, we are still working to get all of our security knowledge into the developers’ hands.  When this vulnerability was identified, the usual first argument was raised: "No hacker is going to guess the page names and paths."   This is pretty common and usually because we don’t think of internal malicious users, or authorized individuals inadvertently sharing this information on forums.  Lets not forget DirBuster or other file brute force tools that are available.  Remember, just because you think the naming convention is clever, it very well can be found.

The group understood the issue and a developer was tasked to resolve the issue.  Great.. We are getting this fixed, and it was a high priority.   The problem….  There was no consultation with the application security guy (me at the time) as to the proposed solution.  I don’t have all the answers, and anyone that says they do are foolish.  However, it is a good idea to discuss with an application security expert when it comes to a large scale remediation to such a vulnerability and here is why.

The developer decided that adding a check to the Page_Init method to check the current user’s role was a good idea.  At this point, that is a great idea.  Looking deeper at the code, the developer only checked the authorization on the initial page request.  In .Net, that would look something like this:

protected void Page_Init(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        //Check the user authorization on initial load
        if (!Context.User.IsInRole("Admin"))
        {
            Response.Redirect("Default.aspx", true);
        }
    }
}

What happens if the user tricks the page into thinking it is a postback on the initial request?  Depending on the system configuration, this can be pretty simple.  By default, a little more difficult due to EventValidation being enabled.  Unfortunately, this application didn’t use EventValidation. 

There are two ways to tell the request that it is a postback:

  1. Include the __EVENTTARGET parameter.
  2. Include the __VIEWSTATE parameter.

So lets say we have an admin page that looks like the above code snippet, checking for admins and redirecting if not found.  By accessing this page like so would bypass the check for admin and display the page:

http://localhost:49607/Admin.aspx?__EVENTTARGET=

This is an easy oversight to make, because it requires a thorough understanding of how the .Net framework determines postback requests.  It gives us a false sense of security because it only takes one user to know these details to then determine how to bypass the check. 

Lets be clear here, Although this is possible, there are a lot of factors that tie into if this may or may not work.  For example, I have seen many pages that it was possible to do this, but all of the data was loaded on INITIAL page load.  For example, the code may have looked like this:

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        LoadDropDownLists();
        LoadDefaultData();
    }
}

In this situation, you may be able to get to the page, but not do anything because the initial data needed hasn’t been loaded.  In addition, EventValidation may cause a problem.  This can happen because if you attempt a blank ViewState value it could catch that and throw an exception.  In .Net 4.0+, even if EventValidation is disabled, ViewStateUserKey use can also block this attempt. 

As a developer, it is important to understand how this feature works so we don’t make this simple mistake.  It is not much more difficult to change that logic to test the users authorization on every request, rather than just on initial page load.

As a penetration tester, we should be testing this during the assessment to verify that a simple mistake like this has not been implemented and overlooked.

This is another post that shows the importance of a good security configuration for .Net and a solid understanding of how the framework actually works.  In .Net 2.0+ EventValidation and ViewStateMac are enabled by default.  In Visual Studio 2012, the default Web Form application template also adds an implementation of the ViewStateUserKey.  Code Safe everyone.

2012 in Review

December 31, 2012 by · Comments Off on 2012 in Review
Filed under: Development, Security, Testing 

Well here it is, 2012 is coming to an end and I thought I would wish everyone happy holidays, as well as mention some of the topics covered this year on my blog.

The year started out with a few issues in the ASP.Net framework. We saw a Forms Authentication Bypass that was patched at the very end of 2011 and an ASP.Net Insecure Redirect issue. Both of these issues show exactly why it is important to keep your frameworks patched.

Next, I did a lot of discussions about ViewStateMAC and EventValidation. This was some new stuff mixed in with some old. We learned that ViewStateMAC also protects the EventValidation field from being tampered with. I couldn’t find any MSDN documentation that states this fact. In addition, I showed how it is possible to manipulate the EventValidation field (when ViewStateMAC is not enabled) to tamper with the application. Here are some links to those posts:

I also created the ASP.Net Webforms CSRF Workflow, which is a small diagram to determine possible CSRF vulnerabilities with an ASP.Net web form application.

The release of .Net 4.5 was fairly big and some of the enhancements are really great. One of those, was the change in how Request Validation works. Adding the ability for lazy validation increases the ability to limit what doesn’t get validated. In addition, ModSecurity was released for IIS.

The release of the Web.Config Security Analyzer happened early on in the year. It is a simple tool that can be used to scan a web.config file for common security misconfigurations.

Some other topics covered included .Net Validators (lets not forget the check for Page.IsValid), Forms Authentication Remember Me functionality, how the Request Method can matter, and a Request Validation Bypass technique.

I discussed how XSS can be performed by tampering with the ViewState and the circumstances needed for it to be possible. This is commonly overlooked by both developers and testers.

In addition, I have created a YouTube channel for creating videos of some of these demonstrations. There are currently two videos available, but look forward to more coming in 2013.

There is a lot to look forward to in 2013 and I can’t wait to get started. Look for more changes and content coming out of Jardine Software and its resources.

I hope everyone had a great year in 2012 and that 2013 brings better things to come.

Another Request Validation Bypass?

August 29, 2012 by · Comments Off on Another Request Validation Bypass?
Filed under: Development, Security 

I stumbled across this BugTraq(http://www.securityfocus.com/archive/1/524043) on Security Focus today that indicates another way to bypass ASP.Net’s built in Request Validation feature. It was reported by Zamir Paltiel from Seeker Research Center showing us how using a % symbol in the tag name (ex. <%tag>) makes it possible to bypass Request Validation and apparently some versions of Internet Explorer will actually parse that as a valid tag. Unfortunately, I do not have the specifics of which versions of IE will parse this. My feeble attempts in IE8 and IE9 did not succeed (and yes, I turned off the XSS filter). I did a previous post back in July of 2011 (which you can read here: https://jardinesoftware.net/2011/07/17/bypassing-validaterequest/) which discussed using Unicode-wide characters to bypass request validation. 

I am not going to go into all the details of the BugTraq, please read the provided link as Zamir has done a great write up for it.  Instead, I would like to talk about the proper way of dealing with this issue.  Sure, .Net provides some great built in features, Event Validation, Request Validation, ViewStateMac, etc., but they are just helpers to our overall security cause.  If finding out that there is a new way to bypass Request validation opens your application up to Cross-Site Scripting…  YOU ARE DOING THINGS WRONG!!!  Request Validation is so limited in its own nature that, although it is a nice-to-have, it is not going to stop XSS in your site.  We have talked about this time and time again.  Input Validation, Output Encoding.    Say it with me:  Input Validation, Output Encoding.  Lets briefly discuss what we mean here (especially you.. the dev whose website is now vulnerable to XSS because you relied solely on Request Validation).

Input Validation

There are many things we can do with input validation, but lets not get too crazy here.  Here are some common things we need to think about when doing input validation:

  • What TYPE of data are we receiving.  If you expect an Integer, then make sure that the value casts to an Integer.  If you expect a date-time, then make sure it casts to a date time. 
  • How long should the data be.  If you only want to allow 2 characters (state abbreviation?) then only allow 2 characters.
  • Validate the data is in a specific range.  If you have a numeric field, say an age, then validate that it is greater than 0 and less than 150, or whatever your business logic requires.
  • Define a whitelist of characters allowed.  This is big, especially for free-form text.   If you only allow letters and numbers then only allow letters and numbers.  This can be difficult to define depending on your business requirements.  The more you add the better off you will be.

Output Encoding

I know a lot of people will disagree with me on this, but I personally believe that this is where XSS is getting resolved.  Sure, we can do strict input validation on the front end.  But what if data gets in our application some other way, say a rogue DBA or script running directly against the server.   I will not get into all my feelings toward this, but know that I am all for implementing Input Validation.  Now, on to Output Encoding.  The purpose is to let the client or browser be able to distinguish commands from data.  This is done by encoding command characters that the parser understands.  For Example, for HTML the < character gets replaced with &lt;.  This tells the parser to display the less than character rather than interpret it as the start of a tag definition. 

Even with all the input validation in the world, we must be encoding our output to protect against cross site scripting.  It is pretty simple to do, although you do have to know what needs encoding and what does not.  .Net itself makes this somewhat difficult since some controls auto encode data and others do not.

Can We Fix It?

With little hope that this will get resolved within the .Net framework itself, there are ways that we can update Request Validation ourselves, if you are using 4.0 or higher.  Request Validation is Extensible, so it is possible to create your own class to add this check into Request Validation.  I have included a simple PROOF OF CONCEPT!!! of attempting to detect this.  THIS CODE IS NOT PRODUCTION READY and is ONLY FOR DEMONSTRATION PURPOSES..  USE AT YOUR OWN RISK!.  ok enough of that.  Below is code that will crudely look for the presence of the combination of <% in the request parameter.  There are better ways of doing this, I just wanted to show that this can be done.  Keep in mind, that if your application allows the submission of this combination of characters, this would probably not be a good solution.   Alright..  the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Util;

namespace WebTester
{
    public class NewRequestValidation : RequestValidator
    {
        public NewRequestValidation() { }

        protected override bool IsValidRequestString(
            HttpContext context, 
            string value, 
            RequestValidationSource requestValidationSource, 
            string collectionKey, 
            out int validationFailureIndex)
        {
            validationFailureIndex = -1;

            // This check is not meant to be production code...
            // This is just an example of how to set up 
            // a Request Validator override.  
            // Please pick a better way of searching for this.
            if (value.Contains("<%")) // Look for <%...  
            {
                return false;
            }
            else // Let the default Request Validtion take a look.
            {
                return base.IsValidRequestString(
                    context, 
                    value, 
                    requestValidationSource, 
                    collectionKey, 
                    out validationFailureIndex);
            }
        }
    }
}

In order to get a custom request validation override to work in your application, you must tell the application to use it in the web.config.  Below is my sample web.config file updated for this:

  <system.web>
    <httpRuntime requestValidationType="WebTester.NewRequestValidation"/>
  </system.web>

 

Conclusion

We, as developers, must stop relying on built in items and frameworks to protect us against security vulnerabilities.  We must take charge and start practicing secure coding principles so that when a bug like this one is discovered, we can shrug it off and say that we are not worried because we are properly protecting our site. 

Hopefully this will not affect many people, but I can assure you that you will start seeing this being tested during authorized penetration tests and criminals.  The good news, if you are protected, is that it is going to waste a little bit of the attacker’s time by trying this out.  The bad news, and you know who I am talking about, is that your site may now be vulnerable to XSS.  BTW, if you were relying solely on Request Validation to protect your site against XSS, you are probably already vulnerable. 

ASP.Net 4: Change the Default Encoder

July 9, 2011 by · Comments Off on ASP.Net 4: Change the Default Encoder
Filed under: Development, Security 

In ASP.Net 4.0, Microsoft added the ability to override the default encoder.  This is specifically focused on the HTMLEncode, HTMLAttributeEncode, and URLEncode functionality.  These functions are used, in the eyes of security, to help mitigate cross-site scripting (XSS).  The problem with the built in .Net routines is that they are built on a black-list methodology, rather than a white-list methodology.  The built in routines use a very small list of characters that get encoded.  For example, the .Net version of HTMLEncode encodes the following characters: <,>,”,&.   The Microsoft Web Protection Library (previously known as the Anti-XSS Library) instead determines all characters that don’t need encoding, a-z0-9 for example, and then encodes all the rest.  This is a much safer approach to encoding. 

In this post, I will show you how to use the Web Protection Library as the default encoder for an ASP.Net 4.0 application.  The first step is to download the Web Protection Library.  In this example, I use version 4.0 which can be found at: http://wpl.codeplex.com/

Next, you will need to have an application to implement this.  You can use an existing application, or create a new one.  Add a reference to the AntiXSSLibrary.dll found in” Program Files\Microsoft Information Security\AntiXSS Library v4.0”.

To use the library, it is time to create a new class.  You can see the code in my class in Figure 1.  I named the class “MyEncoder” and this is just a sample. (THIS IS NOT PRODUCTION CODE)  There are two important factors to this class:

1.  The class must inherit from System.Web.Util.HttpEncoder.

2.  You must override each Encode Method you want to change.

If you only wanted to update the HTMLEncode and leave the other methods alone, just leave them out of the class.

Figure 1

using System;
using System.Web;

public class MyEncoder : System.Web.Util.HttpEncoder
{
  public MyEncoder(){}

    protected override void HtmlEncode(string value, System.IO.TextWriter output)
    {
        if (null == value)
            return;

        output.Write(Microsoft.Security.Application.Encoder.HtmlEncode(value));
    }
    protected override void HtmlAttributeEncode(string value, System.IO.TextWriter output)
    {
        if (null == value)
            return;

        output.Write(Microsoft.Security.Application.Encoder.HtmlAttributeEncode(value));
    }
}

The final step to implementing this custom encoding is to update the web.config file. To do this, modify your httpRuntime element to have the “encoderType” attribute set, as seen in Figure 2.  Change “MyEncoder” to the name of the class you created.  If you do not have the httpRuntime element, just add it in.

Figure 2

  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
    <httpRuntime encoderType="MyEncoder"/>
    .....

Although it would be really nice if the .Net Framework would just start using the Web Protection Library, they are just not ready for that yet.  It is important that plenty of testing is always done when working with output encoding.  Different encoders produce different outputs and may cause display defects.  It is also important to note that this only effects items that get auto-encoded by the framework.  For example, a text property of a textbox.

This is just a small example of modifying the default encoding type of your application.  There is much more that you could potentially do with this.  This is just a sample and this code is NOT FOR PRODUCTION USE. 

SQL Injection: Common Mistake

September 1, 2010 by · Comments Off on SQL Injection: Common Mistake
Filed under: Security 

One of the most common suggestions for remediating SQL Injection vulnerabilities is to use stored procedures.  Using stored procedures can help decrease the risk of SQL Injection, but if implemented incorrectly, it can create a false sense of security.  For example, look at the created stored procedure below:

CREATE PROCEDURE dbo.usp_IsValidUser
(
  @UserName varchar(50),
  @Password varchar(50)
)
AS
    SET NOCOUNT ON
    SELECT  MemberId
    FROM    Member
    WHERE   UserName = @UserName
    AND     Password = @Password
    RETURN

This looks like a pretty secure stored procedure.  It does not use any dynamic SQL, or the dreaded EXEC command.   It is still recommended that you validate your inputs, but the parameters should not execute as SQL code, but instead just as strings. 

Lets take a look at the wrong way to call a stored procedure below:

_command.CommandType = CommandType.Text;
_command.CommandText = "EXEC usp_IsValidUser '" +
                       UserName + "', '" +
                       Password + "'";

 

In this example, although calling a stored procedure, is still vulnerable to SQL Injection (if proper input validation is not performed).  The stored procedure may be safe, but the developer has just created an inline query to call the stored procedure.   A malicious user could append SQL queries to the end of this query to run their own queries.

For example, if the user passes in a Password value that contains the single quote (‘), then they can dump out of the password parameter and append on their own queries.  It is beyond this post to show detailed examples of exploiting this type of statement.

It is important for developers to keep this scenario in mind when developing and doing peer code reviews.  Any time the code is appending data to send to the data store you should investigate further.  Always validate the input received from un-trusted sources.  Use Parameterized queries instead of string building to create database queries.

Frame Busting

July 19, 2010 by · Comments Off on Frame Busting
Filed under: Security 

An often overlooked security feature for a web application is to not allow the application (especially the login screen) to be embedded in a frame.  This is often referred to “frame busting”.  In some browsers, it is possible to capture the keystrokes in one frame, from the parent window.  This would be a problem with an embedded login form where the malicious attacker embeds a login screen in a different domain and tricks a user to attempting to login.  The attacker could then capture the user name and password for that user to log in at a later time. 

Pages that can be captured in any frame set may also be susceptible to click jacking.  Click jacking is beyond the scope of this post, but more information can be found at http://www.owasp.org/index.php/Clickjacking.

There are a few possibilities to a layered approach to protecting against both of these attacks.  Internet Explorer 8 supports the X-FRAME-OPTIONS response header.   Unfortunately, this is not supported by all browsers.   Mozilla is working on their own directives to do the same thing, with a more robust approach.  Both of these approaches are limited because they are targeted at specific browsers.

Another approach is to add JavaScript to the pages that checks the content against the parent location.  If they are not the same, it breaks out of the frame and loads the content in the main window.  There is a great document discussing research about this topic at Http://seclab.Stanford.edu/websec/framebusting/framebust.pdf

It is important for application developers to assess their designs to make sure frame busting and click jacking are addressed. 

Microsoft Introduces Quick Security References

January 19, 2010 by · Comments Off on Microsoft Introduces Quick Security References
Filed under: Security 

Yesterday, Microsoft released two new Quick Security References (QSR’s) to help application development teams understand Security issues.  These new guides are the first part of a continuing series to help multiple roles within the team understand common vulnerabilities.  Not only do they provide great detail on the security issues, but they also help teams move toward SDL adoption. 

The first two QSR’s focus on Cross Site Scripting and SQL Injection.  I think it is good that they started with these two vulnerabilities because they are the two most common types of attacks.  These two vulnerabilities take turns in the first and second position on the OWASP Top 10.  I encourage anyone and everyone involved with applications, from the business personnel to the technical teams, to read over these guides.   They are about 20 pages in length, but provide a really good description of the attacks.

The QSR’s can be downloaded from Microsoft here: http://www.microsoft.com/downloads/details.aspx?FamilyID=79042476-951f-48d0-8ebb-89f26cf8979d&displayLang=en

CAT.NET Microsoft’s Code Analysis Tool

January 5, 2010 by · Comments Off on CAT.NET Microsoft’s Code Analysis Tool
Filed under: Security 

Microsoft has introduced a new  code analysis tool called CAT.NET to help analyze source code for security flaws within managed applications.  This is a visual studio add-in that works directly within Visual Studio, so there is no need for separate programs.  The tool will trace through all statements, methods, and assemblies referenced within the application.  It is currently on Version One in CTP.  Its rules look to identify the following flaws:

  • Cross Site Scripting (XSS)
  • SQL Injection
  • Process Command Injection
  • File Canonicalization
  • Exception Information (a form of Information Leakage)
  • LDAP Injection
  • XPATH Injection
  • Redirection to User Controlled Site

I executed the tool against a web application with the following code snippet:

The results of the scan are provided below:

As you can see from the above samples, the tool does a good job of distinguishing between threats.  By default, asp:textbox will encode its text value, whereas the label control will not.  The information provided by the tool is very helpful as well.  It shows what file and what line of code is the offender.  It also recommends a resolution to help protect against this.  For developers new to focusing on security, it would be nice if the tool gave the link to the Anti-XSS library or a sample code snippet to show how to implement the fix.  That information is pretty easy to find and for a free tool it provides some good general protection for your code. 

The tool can be downloaded at http://www.microsoft.com/downloads/details.aspx?FamilyId=0178e2ef-9da8-445e-9348-c93f24cc9f9d&displaylang=en.

I have tried this tool on a few different projects and it has worked pretty well.  I have found that on very large solutions I ran into out of memory exceptions.  This is a limitation for all add-ins because Visual Studio is limited to 2GB of space.  The larger projects use up more of that so the tool doesn’t have space to function properly.   This can be managed by selecting specific projects to analyze. 

« Previous Page