ASP.NET Security Consultant

I'm an author, speaker, and generally a the-way-we've-always-done-it-sucks security guy who specializes in web technologies and ASP.NET.

I'm a bit of a health nut too, having lost 50 pounds in 2019 and 2020. Check out my blog for weight loss tips!

Free/Open Source SAST Scanner Comparison (ASP.NET Core) - November 2019

Published on: 2019-11-18

Image by Arek Socha from Pixabay

Introduction

I recently did a comparison of the free and/or open source scanners because of a lack of quality comparisons between available options. I thought we'd do a similar comparison for a .NET Core scanner comparison because I couldn't find any available. So, I've decided to do a comparison of the results of the source code scanners using a slightly modified version of the website I used in the DAST comparison.

Methodology

Running scans using the more stereotypical SAST scanners (SonarQube and VisualCodeGrepper) was straightforward — I followed the instructions of the software vendors to scan my site. Three of the five "scanners" we used (FxCop/Roslyn Analyzers, Puma Scan, and Security Code Scan) aren't SAST scanners in the traditional sense — they're intended to give you feedback directly in Visual Studio instead. To make it easier for me to pull results and make comparisons, I pulled the results into a database much like I would if I were running these as a traditional scanner.

In all cases, after running the scans, I filtered out the results that weren't relevant to security, then compared the remaining findings to the list of vulnerabilities I expected (or hoped) the scanners would find. I noted any anomalies, and in one case, added a vulnerability to my list.

Vulnerabilities

The website has a wide variety of vulnerabilities, each marked with a difficulty of Very Low to Very High. A complete list is available at the end of the report. Here's a breakdown of what I mean by each difficulty:

  • Very Low: This is a simple, straightforward problem that a scanner should easily find.
  • Low: Most scanners should find most of these.
  • Medium: A good scanner probably should be able to find this, but there is some twist to the vulnerability that makes it harder to find.
  • High: I believe that it is possible for a scanner to find this, but I'll be surprised if they do.
  • Very High: This is difficult or impossible for an automated scanner to exploit this. I will include it in our test in case I'm wrong.

I excluded several vulnerabilities that existed in the website because I thought that there was no possibility that the scanners would find them (and wasn't pleasantly surprised). I also listed the vulnerabilities in the place I thought were most likely the scanners would find them, not necessarily in the place that the vulnerability would need to be fixed. This became important with the SQL injection attacks in particular, where the SQL was parsed unsafely in one class but the database call occurred in another. This separation confused all but one of the scanners.

Overall Findings

As with the DAST comparison, the overall performance for each scanner was disappointing. A full 41% of the findings were missed by each scanner, and no scanner found more than 34% (39/116), and even that number was inflated by the high number of CSRF tokens my site was missing. So, it is important to keep that in mind when reading these results for two reasons:

  1. Results will be low for each scanner, but that may still mean that it did well in comparison to the others in the group
  2. If you're going to stick with free scanners, you should very strongly consider running multiple code scanners in addition to DAST/Active scans and manual penetration tests

FxCop/Roslyn Analyzers

FxCop or Roslyn Analyzers is an analyzer that is intended to work directly within Visual Studio to help you find code issues, including (but not limited to) security problems. It is not intended to be run as a separate scanner, but can be if you know how to pull the individual rules directly from the source and apply them to your code.

Overall Results

FxCop generally did well finding the SQL injection issues — finding all obvious vulnerabilities, and also was the only one of these scanners that flagged the vulnerable indirect database calls as a possible issue. (Though it did so in such a way that leads me to believe that it would have a large number of SQL injection-related false positives as well.) It also flagged all of my questionable or bad choices of encryption and hashing algorithms, though it missed all other cryptography issues.

The scanner missed all other issues, including each of the web-specific issues.

Overall, FxCop found 12 out of the 116 items, making it below average of these scanners.

Puma Scan

Puma Scan has several versions available on their website, including a free "community" version. You can also download the source code and run your own scans. The Puma source is based on the same Roslyn source as FxCop, so if you write a wrapper to run FxCop scans, you can run Puma scans with next to no additional effort.

Overall Results

Puma Scan did a good job in flagging all of my POSTs that didn't have anti-CSRF attributes applied, found all of the obvious and verifiable SQL injection vulnerabilities, flagged all of my obviously bad choices of cryptography algorithms, and flagged my use of ECB as my cipher mode.

Puma Scan missed my use of RC2 encryption (which is generally safe with a long enough key, but I didn't have that), all logic errors, and all XSS issues. There were no issues that only Puma Scan found.

Though I didn't track this because of my use of custom authentication, Puma Scan also flagged all of my methods as missing Authorization checks. This may be good or bad for you, depending on whether you want a large number of false positives in order to more easily find a true positive.

Overall, Puma Scan found 36 of the 116 issues, making it above average of these scanners.

Security Code Scan

Like FxCop and Puma Scan, Security Code Scan is a Roslyn-based Visual Studio extension that looks for vulnerabilities right in Visual Studio. Because it is a Roslyn-based scanner, if you choose to run scans outside of Visual Studio, you can reuse code that calls FxCop or Puma Scan to run Security Code Scan.

Overall Results

Like Puma Scan, Security Code Scan found all of the missing CSRF attributes and misconfigured Cipher Modes. Like FxCop, Security Code Scan flagged the RC2 encryption. Unlike either, though, Security Code Scan found the unsafe file names and flagged my lack of SSL and header-only protections on the cookies I created.

Unfortunately, Security Code Scan missed all remaining issues, including most of the SQL injection vulnerabilities, XSS vulnerabilities, and faulty business logic.

Overall, Security Code Scan found 39 of 116 issues, making it above average of these scanners.

SonarQube

Like Puma Scan, SonarQube has both a commercial version and a free "community" version that is open source. SonarQube is not a Roslyn-based scanner, so I chose to run it via the UI. Unlike the other scanners so far, though, it does offer support for languages outside of the .NET stack. I have only evaluated its ability to scan the ASP.NET Core site here.

Overall Results

SonarQube found three links on the home page that did not include an attribute called rel='noopener noreferrer', which helps prevent pages opened in a new tab from controlling the opening page. Not only was this not caught by any of the other scanners in this comparison, it was not caught by any of the DAST scanners.

SonarQube also recommended that I not use either DES or RC2, which most other scanners also recommended.

Unfortunately, SonarQube missed everything else. It is worth noting that SonarQube supports running a Roslyn-based scanner and including those findings in a SonarQube report, which would significantly increase the number of security findings in a report. If you do use SonarQube, I very strongly recommend that you do so.

Overall, SonarQube found only 7 of 116 issues, making it below average compared to the other scanners.

VisualCodeGrepper

VisualCodeGrepper is a scanner that supports multiple languages (though not as many as SonarQube), and is available as a download from SourceForge or source code on Github. For my evaluation, we chose to use the version on SourceForge for ease of use and installation.

Overall Results

VisualCodeGrepper was the only scanner that found any XSS issues at all, albeit found them in the cshtml.g.cs versions of the views created in the obj folder (so you need to compile code to get all results — you can't just pull source code and scan) and the scan found many XSS false positives. VisualCodeGrepper was also the only scanner to find the hard-coded password found on the home page and highlighted my XML usage as a possible XXE risk (it is).

Oddly, this scanner flagged my use of the ECB cipher mode, but ignored the fact that I'm using DES. My opinion is that using ECB is a much lesser security risk than using DES, so this was an unexpected finding.

Unfortunately, VisualCodeGrepper didn't find anything else. Most notably, it didn't find any of the SQL injection vulnerabilities.

Overall, VisualCodeGrepper found 24 of 116 issues, putting it about average compared to other scanners.

Summary

It's tough to call these results anything other than "disappointing". There was not a single finding that was discovered by all 5 scanners, and there were several obvious items, such as hard-coding the Key and IV for encryption or having an unvalidated redirect after logging in, should have been found and flagged by at least one of the scanners, but they weren't.

It is my experience that commercial scanners are much more effective at finding items, and I'm planning to show this next year. However, these scanners are quite expensive. If you're looking to do SAST scanning on a budget, as mentioned earlier, you should very strongly consider running multiple code scanners in addition to DAST/Active scans and manual penetration tests.

Appendix: All Results

Page Vulnerability Difficulty FxCop Puma Scan Security Code Scan Sonar Qube Visual Code Grepper
/Areas/Identity/Pages/Account/Login.cshtmlPassword field has autocomplete turned onMedium     
/Areas/Identity/Pages/Account/Login.cshtml.csInformation leakage - incorrect username has different message than incorrect passwordVery High     
/Areas/Identity/Pages/Account/Login.cshtml.csPage has IgnoreAntiForgeryToken in placeLow     
/Areas/Identity/Pages/Account/Login.cshtml.csUnvalidated redirect after user logs inVery Low     
/Areas/Identity/Pages/Account/Register.cshtmlConfirm Password field has autocomplete turned onMedium     
/Areas/Identity/Pages/Account/Register.cshtmlPassword field has autocomplete turned onMedium     
/Authentication/AuthManager/DecryptDecryption service uses DES, which is not safe to useVery LowY (2)YYY 
/Authentication/AuthManager/DecryptDecryption service uses ECB mode, which is not safe to useVery Low YY Y
/Authentication/AuthManager/DecryptMethod uses an decryption service with a hard-coded IVLow     
/Authentication/AuthManager/DecryptMethod uses an decryption service with a hard-coded KeyLow     
/Authentication/AuthManager/EncryptEncryption service uses DES, which is not safe to useVery LowY (2)YYY 
/Authentication/AuthManager/EncryptEncryption service uses ECB mode, which is not safe to useVery Low YY Y
/Authentication/AuthManager/EncryptMethod uses an encryption service with a hard-coded IVLow     
/Authentication/AuthManager/EncryptMethod uses an encryption service with a hard-coded KeyLow     
/Authentication/AuthManager/GetLoggedInUser"Method calls FromSql and includes user input unsafely, making the method vulnerable to SQL injection attacks"Low YY  
/Authentication/AuthManager/SignInMethod adds a misconfigured cookie to the responseVery Low  Y  
/Controllers/AdminControllerAn "admin" section should be protected via authenticationHigh     
/Controllers/AdminControllerPages do not check user role before showing informationVery High     
/Controllers/AuthOnlyController/ConfirmController method lacks anti-CSRF tokenVery Low YY  
/Controllers/AuthOnlyController/ConfirmPage uses user-supplied data in unprotected redirectionsMedium  Y  
/Controllers/AuthOnlyController/CreateUnsafeGenericModelMethod is vulnerable to SQL Injection attacksLow     
/Controllers/AuthOnlyController/EncryptEncryption service uses ECB mode, which is not safe to useVery Low YY Y
/Controllers/AuthOnlyController/EncryptIV is hard-coded and is not randomizedVery Low     
/Controllers/AuthOnlyController/EncryptKey is hard-coded and is not randomizedVery Low     
/Controllers/AuthOnlyController/EncryptRC2 method uses a ridiculously short key, which is not safe to useMediumY YY 
/Controllers/AuthOnlyController/GetUploadedFilesMethod enumerates all files within a particular folder and shows them on various pagesHigh     
/Controllers/AuthOnlyController/ShopController method lacks anti-CSRF tokenVery Low YY  
/Controllers/AuthOnlyController/ShopPage calculates price based on values passed in hidden fields that can be changed by hackersVery High     
/Controllers/AuthOnlyController/UnsafeFileUploadController method lacks anti-CSRF tokenVery Low YY  
/Controllers/AuthOnlyController/UnsafeFileUploadFile save method uses the original file name without checking for invalid charactersVery Low  Y  
/Controllers/AuthOnlyController/UnsafeFileUploadPage saves files from file upload without checking contents/format, etc.High     
/Controllers/AuthOnlyController/UnsafeFileUploadPage uploads are stored within the file rootMedium     
/Controllers/HomeControllerPage creates a new user with a hard-coded passwordMedium    Y
/Controllers/MiscellaneousController/CSSInjectionController method lacks anti-CSRF tokenVery Low YY  
/Controllers/MiscellaneousController/FileInclusionController method lacks anti-CSRF tokenVery Low YY  
/Controllers/MiscellaneousController/FileInclusionMethod unsafely uses user input to create a filepath and write contents to the screenLow  Y  
/Controllers/MiscellaneousController/MD5Page adds misconfigured cookie to the pageLow     
/Controllers/MiscellaneousController/MD5Page creates a hash with the unsafe MD5 algorithmVery LowY Y  
/Controllers/MiscellaneousController/SearchByNameController method lacks anti-CSRF tokenVery Low YY  
/Controllers/MiscellaneousController/ValueShadowingPage is vulnerable to value shadowingHigh     
/Controllers/MiscellaneousController/XxeController method lacks anti-CSRF tokenVery Low YY  
/Controllers/MiscellaneousController/XxeThe default XmlUrlResolver is used, which makes the method vulnerable to XXE attacksVery Low    ?
/Controllers/SqlController/AllIntInFormController method lacks anti-CSRF tokenVery Low YY  
/Controllers/SqlController/AllStringInFormController method lacks anti-CSRF tokenVery Low YY  
/Controllers/SqlController/AllStringLineBreakController method lacks anti-CSRF tokenVery Low YY  
/Controllers/SqlController/FalsePostive_CalcPage runs a calculation on the query string valueHigh     
/Controllers/SqlController/IntInCookieA misconfigured cookie is added to the responseMedium  Y  
/Controllers/SqlController/StringInCookieA misconfigured cookie is added to the responseMedium  Y  
/Controllers/SqlController/StringInCookieController method lacks anti-CSRF tokenVery Low YY  
/Controllers/SqlController/UnsafeModel_ConcatMethod unsafely concatenates a string that is used in a SQL queryVery LowYY   
/Controllers/SqlController/UnsafeModel_Concat_QueryMethod unsafely concatenates a string that is indirectly used in a SQL queryVery LowYY   
/Controllers/SqlController/UnsafeModel_FormatMethod unsafely uses user input in an unsafe SQL query via a string.FormatLowYY   
/Controllers/SqlController/UnsafeModel_Format_QueryMethod unsafely uses user input indirectly in an unsafe SQL query via a string.FormatLowYY   
/Controllers/SqlController/UnsafeModel_InterpolationMethod unsafely adds user input in an interpolated string that is used in a SQL queryLowYY   
/Controllers/SqlController/UnsafeModel_Interpolation_QueryMethod unsafely adds user input in an interpolated string that is indirectly used in a SQL queryLowYY   
/Controllers/XSSController/AllowBodyController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/AllowIFrameController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/AllowImgController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/AllowMarqueeController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/AllowMixedCaseController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/AllowObjectController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/AllowUpperCaseController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/AllowVideoController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/GetFoodNameFromValueShadowingMethod looks in several places for a value, making it vulnerable to value shadowingVery High     
/Controllers/XSSController/InputEncodedUser input is partially encoded and is unsafely added to an input attributeHigh     
/Controllers/XSSController/InputNoEncodingUser input is unsafely added to an input attributeHigh     
/Controllers/XSSController/MetaTagController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/RecursiveEndBracketController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/RecursiveNoEndBracketController method lacks anti-CSRF tokenVery Low YY  
/Controllers/XSSController/UrlDecodeController method lacks anti-CSRF tokenVery Low YY  
/Data/ApplicationDbContext_Partial.cs/ExecSQLExecSQL does not clean queries before executing them against the databaseHighY    
/Models/AdminOrderItemViewModel.csDecryption service uses ECB mode, which is not safe to useVery Low YY Y
/Models/AdminOrderItemViewModel.csIV is hard-coded and is not randomizedVery Low     
/Models/AdminOrderItemViewModel.csKey is hard-coded and is not randomizedVery Low     
/Models/AdminOrderItemViewModel.csRC2 method uses a ridiculously short key, which is not safe to useMediumY YY 
/Models/SearchItemViewModel.csHTML creation is not actually a problem here, but we'd like a good SAST scanner to flag itHigh     
/Views/Admin/AllUsers.cshtmlPage shows username and passwords for all users in the systemMedium     
/Views/Admin/ViewAllOrdersPage shows credit card numbers in plain textMedium     
/Views/AuthOnly/ConfirmAll values on the page are editable via hidden fields by hackersHigh     
/Views/AuthOnly/ConfirmPage shows sensitive information (credit card number)Medium     
/Views/AuthOnly/PayPage sends sensitive information via query string to the next pageLow     
/Views/AuthOnly/StoredXSSPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/AuthOnly/XSSPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/Home/Index.cshtmlPage includes link to beefproject.com and is missing noopener and noreferrer "rel" itemsLow   Y 
/Views/Home/Index.cshtmlPage includes link to docs.google.com and is missing noopener and noreferrer "rel" itemsLow   Y 
/Views/Home/Index.cshtmlPage includes link to norbergconsultinggroup.com and is missing noopener and noreferrer "rel" itemsLow   Y 
/Views/Miscellaneous/AngularJSPage includes text within an AngularJS controllerVery High     
/Views/Miscellaneous/ConnectionStringA connection string (with password) is included in the comments behind the pageLow     
/Views/Miscellaneous/CSSInjectionPage unsafely includes form data within CSS on the pageVery High     
/Views/Miscellaneous/JSInjectionPage unsafely includes query string text within script on the pageHigh    Y
/Views/Shared/_Layout.cshtmlCross-Domain Script IncludeLow     
/Views/Shared/_Layout.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/Shared/_Layout.cshtmlSite uses a vulnerable version of bootstrapLow     
/Views/Shared/_Layout.cshtmlSite uses a vulnerable version of jqueryLow     
/Views/XSS/AllowAudio.cshtmlPage uses Html.Span(), which is a custom method that's vulnerable to XSS attacksVery High     
/Views/XSS/AllowBody.cshtmlPage uses Html.Italic(), which is a custom method that's vulnerable to XSS attacksVery High     
/Views/XSS/AllowIFrame.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/AllowImg.cshtmlPage uses Html.Bold(), which is a custom method that's vulnerable to XSS attacksVery High     
/Views/XSS/AllowMarquee.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/AllowMixedCase.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/AllowObject.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/AllowSlash.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/AllowSvg.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/AllowUpperCase.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/AllowVideo.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/DoubleQuotesEncoded.cshtmlPage uses Html.EncodeDoubleQuotes(), which is a custom method that's vulnerable to XSS attacksVery High     
/Views/XSS/InputEncoded.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/InputNoEncoding.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/JQuery.cshtmlPage adds text as HTML to an element via JQuery, which is vulnerable to XSS attacksHigh     
/Views/XSS/RecursiveEndBracket.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/RecursiveNoEndBracket.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/ReflectedFromQS.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/Views/XSS/SingleQuotesEncoded.cshtmlPage uses Html.EncodeSingleQuotes(), which is a custom method that's vulnerable to XSS attacksVery High     
/Views/XSS/UrlDecode.cshtmlPage uses Html.Raw(), which is vulnerable to XSS attacks if not handled properlyMedium    Y
/wwwroot/js/angular.min.jsSite uses a vulnerable version of AngularJSMedium     
Startup.csError page is used for both development and productionLow