Auditing the DNN CMS using DevAudit

In this article I’ll show how to do a security audit of the library dependencies, application configuration and code of a popular open-source ASP.NET web application: DNN CMS (née DotNetNuke) using DevAudit, an open-source cross-platform multi-purpose security auditing program.

Introduction

I’ve been following Harry Lee for a while and enjoying their articles describing how they use their PVS-Studio project to analyze the source code of different open-source projects. So with this as inspiration I decided to write a series of articles on a project that I work on which also performs analysis and auditing on many kinds of applications and servers to detect potential security issues. Here I will demonstrate some of the key features of the open-source DevAudit project and how you can use it to perform security audits on ASP.NET applications and projects you or your organization may depend on. Specifically I’ll cover:

Auditing the NuGet package dependencies for an ASP.NET application and how DevAudit handles package and vulnerability versions and ranges to minimize false positives. Auditing the Web.config application configuration for an ASP.NET application. Using a custom audit rule to detect a specific application vulnerability. Auditing a project directly on its GitHub project site using the DevAudit GitHub audit environment. Using static analysis on a .NET application’s binary to find potential security issues.

About DevAudit

Software developers today face a continuously evolving challenge of building secure distributed applications while dealing with increasingly complex development tool-chains and deployment scenarios and operating environments that are inherently hostile like the cloud. Security vulnerabilities can be present in every aspect of an application from library dependencies and frameworks to application code to application configuration to the server and operating environment configuration that the application must run in.

From the DevAudit README:

DevAudit is an open-source, cross-platform, multi-purpose security auditing tool targeted at developers and DevOps practitioners that detects security vulnerabilities at multiple levels of the solution stack. DevAudit provides a wide array of auditing capabilities that automate security practices and implementation of security auditing in the software development life-cycle. DevAudit can scan your operating system and application package dependencies, application and application server configurations, and application code, for potential vulnerabilities based on data aggregated by OSS Index from a wide array of sources and data feeds such as the National Vulnerability Database (NVD) CVE data feed, the Debian Security Advisories data feed, Drupal Security Advisories, and several others.

DevAudit is a “white-box” security scanner in contrast to black-box security scanners which attempt to detect vulnerabilities using externally visible application endpoints like web service URLs. DevAudit examines an application’s code and configuration files directly, resulting in more comprehensive and smarter auditing and vulnerability detection. With its remote audit capabilities over SSH and WinRM and inside Docker containers, DevAudit can have the same “reach” as black-box scanners in not requiring the application to reside on the same local computer as the security scanner. DevAudit ships with a CLI interface that can be easily integrated into your build scripts and CI pipelines.

Installing DevAudit

The easiest way to install DevAudit is to use the binary release files from the project releases page. If you want use the latest code from the DevAudit repository then you can follow the instructions for building and installing from the installation section of the documentation:

Make sure you have the pre-requisites installed: .NET Framework 4.6 on Windows or Mono 4.4+ on Linux. Clone the DevAudit repository: git clone https://github.com/OSSIndex/DevAudit Build the project by running build.cmd from a Visual Studio prompt on Windows or ./build.sh on Linux. You should be able to execute DevAudit from the project folder by typing devaudit from a Windows command prompt.

On Linux you can also pull the DevAudit Docker image from Docker Hub:

docker pull ossindex/devaudit:unstable

We’ll be auditing the latest release of the open-source DNN CMS. You can download the install archive from the DNN Software site and unpack it to a local directory. Note that you do not need to actually install DNN on your server; DevAudit will examine the DNN application files directly in the local directory and report any detected security issues before you decide to do an install.

Alternatively, using the 2.1.x builds of DevAudit you can audit the project directly on GitHub:

Auditing DNN directly on the GitHub project repository

You can specify a GitHub project owner, name, and branch to DevAudit using the -g command-line parameter to connect directly to the project’s GitHub repository. Support for other project hosting sites like BitBucket and GitLab is also planned.

To get started with the ASP.NET audit you should do:

devaudit aspnet -r D:\Apps\DNN_Platform_9.0.2_install -c @web.config

if you have unzipped the DNN install archive to D:\Apps\DNN_Platform_9.0.2_Install. The -r parameter tells DevAudit the root directory of the ASP.NET application and -c specifies the name of the ASP.NET configuration file to use. This will kick off an audit of the DNN application’s NuGet package dependencies and ASP.NET configuration. DevAudit runs the different audit tasks in parallel and as the tasks progress informational and other messages are echoed to the terminal.

_____ _______ __ __ __

| \ .-----..--.--.| _ |.--.--..--| ||__|| |_

| -- || -__|| | || || | || _ || || _|

|_____/ |_____| \___/ |___|___||_____||_____||__||____| v2.1.0.0

12:56:53<01> [AUDIT] [INFO] Using NuGet v2 package manager configuration file D:\Apps\DNN_Platform_9.0.2_Install\packages.config

12:56:53<01> [AUDIT] [INFO] Using ASP.NET configuration file D:\Apps\DNN_Platform_9.0.2_Install\web.config.

12:56:54<01> [AUDIT] [INFO] Got 16 referenced assemblies in 134 ms

12:56:54<01> [AUDIT] [SUCCESS] Got ASP.NET application version 9.0.2.5.

12:56:54<01> [AUDIT] [STATUS] Scanning NuGet packages.Scanning NuGet packages...

Scanning NuGet packages...

Scanning NuGet packages...

12:56:54<06> [AUDIT] [SUCCESS] Read configuration from web.config in 5 ms.

12:56:54<01> [AUDIT] [SUCCESS] Scanned 7 NuGet packages.

Searching OSS Index for vulnerabilities for 7 packages...

12:56:54<05> [AUDIT] [INFO] Loading default configuration rules for ASP.NET application.

Searching OSS Index for vulnerabilities for 7 packages...

12:56:54<05> [AUDIT] [INFO] Got 10 default configuration rule(s) for 1 module(s) from aspnet.yml in 83 ms.

You can also specify the -n option and redirect the terminal output to a file or other program to handle large amounts of text.

Auditing Library Dependencies

DevAudit supports auditing libraries and software installed by different application and operating system package managers like NuGet, Bower, Composer, dpkg and rpm/yum on Linux, and Chocolatey on Windows. For an ASP.NET application DevAudit will look at the NuGet packages.config file in the root directory and audit the names and versions of the application’s library dependencies against vulnerability data available from the OSS Index API.

Searching OSS Index for vulnerabilities for 7 packages...

12:56:55<07> [AUDIT] [SUCCESS] Found 1 vulnerabilities for 7 package(s) on OSS Index in 1086 ms.

Evaluating 10 configuration rule(s)...

12:56:55<06> [AUDIT] [SUCCESS] Evaluated 10 configuration rule(s) in 15 ms.

12:56:55<07> [AUDIT] [INFO] Evaluated 1 vulnerabilities with 0 matches to package version in 88 ms. Package Source Audit Results

============================

0 total vulnerabilities found in NuGet package source audit. Total time for audit: 1381 ms.

In this case there are only 7 library dependencies for DNN listed in the packages.config file. You can view the packages listed in the package manager configuration file using the --list-packages option.



_____ _______ __ __ __

| \ .-----..--.--.| _ |.--.--..--| ||__|| |_

| -- || -__|| | || || | || _ || || _|

|_____/ |_____| \___/ |___|___||_____||_____||__||____|





v2.1.0.0

21:26:16<01> [AUDIT] [INFO] Using NuGet v2 package manager configuration file D:\Apps\DNN_Platform_9.0.2_Install\packages.config

21:26:16<01> [AUDIT] [INFO] Using ASP.NET configuration file D:\Apps\DNN_Platform_9.0.2_Install\web.config.

21:26:16<01> [AUDIT] [WARNING] The .NET assembly application binary was not specified so application modules and version cannot be detected.

21:26:16<01> [AUDIT] [STATUS] Scanning NuGet packages.

Scanning NuGet packages...

Scanning NuGet packages...

Scanning NuGet packages...

21:26:16<01> [AUDIT] [SUCCESS] Scanned 7 NuGet packages.

[1/7] Microsoft.AspNet.Mvc 5.1.1

[2/7] Microsoft.AspNet.Razor 3.1.1

[3/7] Microsoft.AspNet.WebApi.Client 5.2.3

[4/7] Microsoft.AspNet.WebApi.Core 5.2.3

[5/7] Microsoft.AspNet.WebPages 3.1.1

[6/7] Microsoft.Web.Infrastructure 1.0.0.0

[7/7] Newtonsoft.Json 7.0.1 > devaudit aspnet -r D:\Apps\DNN_Platform_9.0.2_Install -c @web .config --list-packages_____ _______ __ __ __| \ .-----..--.--.| _ |.--.--..--| ||__|| |_| -- || -__|| | || || | || _ || || _||_____/ |_____| \___/ |___|___||_____||_____||__||____|v2.1.0.021:26:16<01> [AUDIT] [INFO] Using NuGet v2 package manager configuration file D:\Apps\DNN_Platform_9.0.2_Install\packages.config21:26:16<01> [AUDIT] [INFO] Using ASP.NET configuration file D:\Apps\DNN_Platform_9.0.2_Install\web.config.21:26:16<01> [AUDIT] [WARNING] The .NET assembly application binary was not specified so application modules and version cannot be detected.21:26:16<01> [AUDIT] [STATUS] Scanning NuGet packages.Scanning NuGet packages...Scanning NuGet packages...Scanning NuGet packages...21:26:16<01> [AUDIT] [SUCCESS] Scanned 7 NuGet packages.[1/7] Microsoft.AspNet.Mvc 5.1.1[2/7] Microsoft.AspNet.Razor 3.1.1[3/7] Microsoft.AspNet.WebApi.Client 5.2.3[4/7] Microsoft.AspNet.WebApi.Core 5.2.3[5/7] Microsoft.AspNet.WebPages 3.1.1[6/7] Microsoft.Web.Infrastructure 1.0.0.0[7/7] Newtonsoft.Json 7.0.1

Currently (and fortunately) there aren’t any vulnerabilities indexed by OSS Index for the above package versions. Hypothetically if DNN depended on an older vulnerable version of a package then this would be flagged in the Package Source Audit Results. So for instance if I edit the packages.config file and specify version 5.1 of the Microsoft.AspNet.Mvc package instead of the more recent 5.1.1:

<package id=”Microsoft.AspNet.Mvc” version=”5.1" targetFramework=”net45" allowedVersions=”[5.1]” />

This leads to a vulnerability being detected by DevAudit:

Simulated NuGet package dependency vulnerability

The vulnerability detected in this simulation is an XSS vuln affecting versions up to 5.1 of the System.Web.Mvc library. However the actual version that the application uses is a patch release to 5.1 (5.1.1) which DevAudit correctly detects as being a higher version than 5.1. The version detection in DevAudit can handle the semantics of NuGet versioning and other package manager versioning schemes thanks to the Versatile library.

Handling Package Versions in DevAudit

Minimizing false positives and false negatives is an important secondary goal of vulnerability detection and security auditing. Vulnerabilities are reported as being present in particular versions or version ranges of software packages and libraries e.g < 1.3.0 . One major source of false positives is the incorrect handling of package versions and version ranges in determining if a particular package version satisfies a version range for a vulnerability. When comparing software versions, the ordering of versions does not necessarily correspond to the lexical ordering of the version components which complicates trying to determine whether a range expression like

>1.3.0-beta.1 and <1.3.0-beta.11

is satisfied by a version like 1.3.0-beta.2, since in terms of lexical ordering the 1.3.0-beta.2 version would be ‘greater’ than 1.3.0-beta.11. This situation is further complicated by differint version schemes that use different range syntax. e.g NuGet versions use a range syntax like

[3.5, 3.9)

to represent the range 3.5 ≤ version < 3.9, but this range syntax is not valid for Semver versioning.

DevAudit uses the Versatile library for parsing and comparing package versions and version ranges and determining if a specified package version or version range satisfies or intersects a version or range specified for a vulnerability. Versatile does full syntactic parsing and modelling of the semantics of software versions and versions ranges. This means that for instance when given a version string like “1.3.0-beta.11” and the particular version class (NuGet, Composer or SemVer etc.) that the string represents, Versatile parses this string into components according to the version class syntax: in this case a major, minor, patch and special version. Versatile will use the semantics of the version class like NuGet for version comparison so that in our example the version 1.3.0-beta.11 is a later version than 1.3.0-beta.1 but an earlier version than 1.3.0, since the beta special version component indicates this is a pre-release version.

Most of the code we’ve seen that tackles this problem uses complex regular expressions to try to tackle the problem of working with different software version formats. We believe our approach which attempts to model the full syntax and semantics of software versions and ranges will produce more accurate results and significantly reduce the rate of false positives and negatives when comparing installed package versions against version ranges that are reported for vulnerabilities. This is even more important when working with operating system packages on distributions like Debian and Ubuntu which often have a complex set of rules for package versions e.g. “7.3p1–1”, “1.13~alpha1+dfsg” and so on.

Auditing Application Configuration

DevAudit also analyzes an ASP.NET application’s Web.config configuration file looking for known weaknesses and vulnerabilities. In the case of DNN we have some findings in the stock Web.config file that ships with the installer:



=======================================

2 total vulnerabilities found in ASP.NET application configuration audit. Total time for audit: 1521 ms.



[1/1] Module: aspnet. 10 rule(s). 2 rule(s) succeeded. [VULNERABLE]

--[1/10] Rule: ASP.NET does not require SSL for authentication cookies. Result: True.

--Summary:

--ASP.NET uses the SSL protocol to encrypt sensitive data like form authentication cookies that must be transmitted on a public network.

--SSL should always be required for form authentication otherwise user sessions and identities in appliction are vulnerable to hijacking by attackers.

--Tags:

--CWE/614/Sensitive Cookie in HTTPS Session Without 'Secure' Attribute

--CWE/311/Missing Encryption of Sensitive Data

--CWE/784/Reliance on Cookies without Validation and Integrity Checking in a Security Decision

--OWASP-Top10-2013/A5/Security Misconfiguration

--OWASP-Top10-2013/A6/Sensitive Data Disclosure

--Severity: 3

--Resolution:

--Set the requireSSL attribute to true in the forms element of the system.web element in the Web.config file.

--Note that additional steps are required to configure the IIS web server to use SSL, e.g

--

--Urls:

--



--[2/10] Rule: ASP.NET cookieless forms authentication is enabled. Result: False.

--[3/10] Rule: ASP.NET request validation is disabled globally. Result: False.

--[4/10] Rule: ASP.NET hashing algorithm for form view-state validation is insecure. Result: True.

--Summary:

--ASP.NET uses hashing algorithms to help secure and make tamper-proof data such as form view state.

--By default, ASP.NET after version 4 uses the HMACSHA256 algorithm for hash operations for validating form view-state.

--Older hashing algorithms like MD5 are today considered cryptographically insecure.

--Compliance with standards like FIPS requires more secure hash algorithms like HMACSHA256 to be used.

--Tags:

--OWASP-Top10-2013/A5/Security Misconfiguration

--CWE/327/Use of a Broken or Risky Cryptographic Algorithm

--Severity: 2

--Resolution:

--Set the validation attribute on the machineKey element of system.web in the Web.config file to HMACSHA256 or another cryptographically secure hash algorithm.

--Urls:

--



--[5/10] Rule: ASP.NET cookies are accessible through client-side script. Result: False.

--[6/10] Rule: ASP.NET version headers are enabled. Result: False.

--[7/10] Rule: ASP.NET custom errors mode is not enabled. Result: False.

--[8/10] Rule: ASP.NET cookieless sessions are enabled. Result: False.

--[9/10] Rule: ASP.NET compilation is set to debug mode. Result: False.

--[10/10] Rule: ASP.NET tracing is enabled. Result: False. Application Configuration Audit Results=======================================2 total vulnerabilities found in ASP.NET application configuration audit. Total time for audit: 1521 ms.[1/1] Module: aspnet. 10 rule(s). 2 rule(s) succeeded. [VULNERABLE]--[1/10] Rule: ASP.NET does not require SSL for authentication cookies. Result: True.--Summary:--ASP.NET uses the SSL protocol to encrypt sensitive data like form authentication cookies that must be transmitted on a public network.--SSL should always be required for form authentication otherwise user sessions and identities in appliction are vulnerable to hijacking by attackers.--Tags:--CWE/614/Sensitive Cookie in HTTPS Session Without 'Secure' Attribute--CWE/311/Missing Encryption of Sensitive Data--CWE/784/Reliance on Cookies without Validation and Integrity Checking in a Security Decision--OWASP-Top10-2013/A5/Security Misconfiguration--OWASP-Top10-2013/A6/Sensitive Data Disclosure--Severity: 3--Resolution:--Set the requireSSL attribute to true in the forms element of the system.web element in the Web.config file.--Note that additional steps are required to configure the IIS web server to use SSL, e.g-- https://www.iis.net/learn/manage/configuring-security/how-to-set-up-ssl-on-iis --Urls:-- http://www.developerfusion.com/article/6745/top-10-application-security-vulnerabilities-in-webconfig-files-part-two/3/ --[2/10] Rule: ASP.NET cookieless forms authentication is enabled. Result: False.--[3/10] Rule: ASP.NET request validation is disabled globally. Result: False.--[4/10] Rule: ASP.NET hashing algorithm for form view-state validation is insecure. Result: True.--Summary:--ASP.NET uses hashing algorithms to help secure and make tamper-proof data such as form view state.--By default, ASP.NET after version 4 uses the HMACSHA256 algorithm for hash operations for validating form view-state.--Older hashing algorithms like MD5 are today considered cryptographically insecure.--Compliance with standards like FIPS requires more secure hash algorithms like HMACSHA256 to be used.--Tags:--OWASP-Top10-2013/A5/Security Misconfiguration--CWE/327/Use of a Broken or Risky Cryptographic Algorithm--Severity: 2--Resolution:--Set the validation attribute on the machineKey element of system.web in the Web.config file to HMACSHA256 or another cryptographically secure hash algorithm.--Urls:-- https://msdn.microsoft.com/library/w8h3skw9(v=vs.100).aspx --[5/10] Rule: ASP.NET cookies are accessible through client-side script. Result: False.--[6/10] Rule: ASP.NET version headers are enabled. Result: False.--[7/10] Rule: ASP.NET custom errors mode is not enabled. Result: False.--[8/10] Rule: ASP.NET cookieless sessions are enabled. Result: False.--[9/10] Rule: ASP.NET compilation is set to debug mode. Result: False.--[10/10] Rule: ASP.NET tracing is enabled. Result: False.

DevAudit was able to detect 2 vulnerabilities in the stock configuration file the DNN website installer ships with. In the first case the application is configured to not require SSL for authentication cookies, meaning that users can send their login credentials over insecure HTTP connections. This is to be expected as SSL is not enabled by default for DNN and the application’s user manual details the steps needed to enable SSL for your DNN site on IIS. However it is still very important for administrators to be aware of the potential vulnerabilities the stock configuration of an ASP.NET application contains. Leaving applications in the default configuration state without doing additional configuration and securing is a major source of vulnerabilities in web applications.

The 2nd finding relates to the hashing algorithm ASP.NET uses to validate view state data. Older versions of ASP.NET used the HMACSHA1 hash algorithm by default whereas more recent versions of ASP.NET have defaulted to using the HMACSHA256 algorithm which is more secure and FIPS-certified. But applications like DNN may still need use the older hash algorithms for backward compatibility with previous versions of the software.

The stock configuration of DNN 9.0.2 still uses HMACSHA1 as the hashing algorithm for view state validation. This is flagged by DevAudit as a vulnerability. To customize this behavior, you can change or add to the way DevAudit detects configuration vulnerabilities in applications by using custom audit rules.

Using a custom audit rule

DevAudit ships with a defaultset of audit rules stored in the Rules directory of your DevAudit release (If you have built directly from source then this folder will be in DevAudit.CommandLine\bin\Debug ). You can customize the audit rules for ASP.NET applications by editing the aspnet.yml YAML file. Here we will add the following rule to detect a particular vulnerability in DNN:

- id: 11

title: DNN machine key is set to a known default value

tags:

- CWE/1004/Sensitive

- OWASP-Top10-2013/A5/Security Misconfiguration

severity: 2

xpathtest: >

boolean(/configuration/system.web/machineKey[@validationKey='F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902']) or

boolean(/configuration/system.web/machineKey[@decryptionKey='F9D1A2D3E1D3E2F7B3D9F90FF3965ABDAC304902F8D923AC'])

summary: |

DNN ships with well-known default values for the validation and decryption keys used to validate and encrypt form view state and authentication cookies.

These keys are normally changed during the installation process but a bad installation or copy-pasting of configuration can leave the default keys active.

If a DNN site still uses these keys then authentication cookies can be easily forged and used

to impersonate users and compromise a site's security.

resolution: |

DNN may not have been properly installed or is misconfigured. You should disable your DNN site until it can be properly installed and configured.

urls:

- https://blog.gdssecurity.com/labs/2008/3/21/dotnetnuke-default-machine-key-advisory.html

Which detects a vulnerability related to a bad DNN installation. With this rule appended to our aspnet.yml rules file, a 2nd audit run produces a 3rd finding:

Detecting a potential DNN vulnerability using a custom audit rule

As development progresses we will add specialized rule-sets for ASP.NET applications like DNN that check compliance with published security and hardening guidelines for the application configuration.

Auditing via static analysis

In addition to auditing package dependencies and application configuration, DevAudit can also audit a .NET application’s code via static analysis. If your application has been already compiled then you can specify the path to the application’s binary using the -b command-line parameter

Static analysis of DNN application code

Here we’re using the Mono project’s Gendarme static analyzer for .NET CIL code in addition to a preliminary version of a custom analyzer from the DevAudit project that detects potential use of weak cryptography in an application. In this case the custom analyzer detected use of the SHA1CryptoServiceProvider class and a call to the ComputeHash method which indicates a SHA1 hashing operation is requested. In this case this is being done in the SignHMAC method of the FacebookRequestController class of DNN, indicating the app is making a remote request to an API using SHA1 to create a keyed-hash message authentication code. This is not necessarily a vulnerability but it is still important to know what cryptographic methods and algorithms are being used by application. Attacks against SHA1 have recently been shown to be feasible and in the future SHA1 may be deprecated as a hashing algorithm. Custom analyzers are stored in the Analyzers folder in your DevAudit project folder and can be removed as required.

Currently you can use any rule-set defined by Gendarme in an application code audit using the Gendarme analyzer. For instance we can use the Gendarme.Rules.Correctness rule-set by setting the GendarmeRules command-line parameter to Gendarme.Rules.Correctness:



08:12:43<01> [AUDIT] [INFO] Using .NET Framework 4 configuration file D:\Apps\DNN_Platform_9.0.2_Install\web.config.

08:12:43<01> [AUDIT] [INFO] Got 16 referenced assemblies in 19 ms

08:12:43<01> [AUDIT] [SUCCESS] Got .NET Framework 4 application version 9.0.2.5.

08:12:43<03> [AUDIT] [SUCCESS] Read configuration from web.config in 4 ms.

08:12:43<04> [AUDIT] [INFO] Loading default configuration rules for .NET Framework 4 application.

08:12:43<04> [AUDIT] [INFO] Got 0 default configuration rule(s) for 0 module(s) from netfx4.yml in 60 ms.

08:12:44<03> [HOST] [INFO] Loaded SA-NETFX-0001-GendarmeRules analyzer from c:\Projects\DevAudit\DevAudit.CommandLine\bin\Debug\Analyzers\NetFx\GendarmeRules.cs.

08:12:44<03> [HOST] [INFO] Loaded SA-NETFX-0002-WeakCrypto analyzer from c:\Projects\DevAudit\DevAudit.CommandLine\bin\Debug\Analyzers\NetFx\WeakCrypto.cs.

08:12:44<03> [HOST] [SUCCESS] Loaded 2 out of 2 analyzer(s) in 1169 ms.

08:12:44<08> [HOST] [STATUS] SA-NETFX-0001-GendarmeRules analyzing.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule TypesWithNativeFieldsShouldBeDisposableRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule DoNotRecurseInEqualityRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AttributeStringLiteralsShouldParseCorrectlyRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AvoidConstructorsInStaticTypesRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule TypesWithDisposableFieldsShouldBeDisposableRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewSelfAssignmentRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ProvideCorrectArgumentsToFormattingMethodsRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AvoidCodeWithSideEffectsInConditionalCodeRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AvoidFloatingPointEqualityRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewDoubleAssignmentRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule EnsureLocalDisposalRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule UseNoInliningWithGetCallingAssemblyRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewUselessControlFlowRule.

08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewUseOfInt64BitsToDoubleRule.

... > devaudit netfx -r D:\Apps\DNN_Platform_9.0.2_Install -c @web .config -b @bin \DotNeTNUKE.DLL --skip-packages-audit -o GendarmeRules=Gendarme.Rules.Correctness -n | more08:12:43<01> [AUDIT] [INFO] Using .NET Framework 4 configuration file D:\Apps\DNN_Platform_9.0.2_Install\web.config.08:12:43<01> [AUDIT] [INFO] Got 16 referenced assemblies in 19 ms08:12:43<01> [AUDIT] [SUCCESS] Got .NET Framework 4 application version 9.0.2.5.08:12:43<03> [AUDIT] [SUCCESS] Read configuration from web.config in 4 ms.08:12:43<04> [AUDIT] [INFO] Loading default configuration rules for .NET Framework 4 application.08:12:43<04> [AUDIT] [INFO] Got 0 default configuration rule(s) for 0 module(s) from netfx4.yml in 60 ms.08:12:44<03> [HOST] [INFO] Loaded SA-NETFX-0001-GendarmeRules analyzer from c:\Projects\DevAudit\DevAudit.CommandLine\bin\Debug\Analyzers\NetFx\GendarmeRules.cs.08:12:44<03> [HOST] [INFO] Loaded SA-NETFX-0002-WeakCrypto analyzer from c:\Projects\DevAudit\DevAudit.CommandLine\bin\Debug\Analyzers\NetFx\WeakCrypto.cs.08:12:44<03> [HOST] [SUCCESS] Loaded 2 out of 2 analyzer(s) in 1169 ms.08:12:44<08> [HOST] [STATUS] SA-NETFX-0001-GendarmeRules analyzing.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule TypesWithNativeFieldsShouldBeDisposableRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule DoNotRecurseInEqualityRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AttributeStringLiteralsShouldParseCorrectlyRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AvoidConstructorsInStaticTypesRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule TypesWithDisposableFieldsShouldBeDisposableRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewSelfAssignmentRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ProvideCorrectArgumentsToFormattingMethodsRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AvoidCodeWithSideEffectsInConditionalCodeRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule AvoidFloatingPointEqualityRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewDoubleAssignmentRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule EnsureLocalDisposalRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule UseNoInliningWithGetCallingAssemblyRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewUselessControlFlowRule.08:12:44<08> [SCRIPT] [INFO] Using Gendarme rule ReviewUseOfInt64BitsToDoubleRule....

Here we are using the -n parameter to indicate we want non-interactive program output and piping the output through the more Windows command so we can easily view the long pages of output (you can accomplish the same thing on Linux using the less command.) Many of the findings appear to be benign, being related to the way ASP.NET controls are used on a page. However there also appear to be some points of concern:

--[882/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: DotNetNuke.Services.Cache.DNNCacheDependency DotNetNuke.Services.Cache.DNNCacheDependency::_cacheDependency

--[883/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: Lucene.Net.Index.IndexWriter DotNetNuke.Services.Search.Internals.LuceneControllerImpl::_writer

--[884/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: Lucene.Net.Index.IndexReader DotNetNuke.Services.Search.Internals.LuceneControllerImpl::_idxReader

--[885/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: DotNetNuke.Services.Search.Internals.LuceneControllerImpl/CachedReader DotNetNuke.Services.Search.Internals.LuceneControllerImpl::_reader

--[886/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: System.Collections.Generic.IEnumerator`1<T> DotNetNuke.Collections.Internal.NaiveLockingList`1/NaiveLockingEnumerator::_enumerator

--[887/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: DotNetNuke.Collections.Internal.ISharedCollectionLock DotNetNuke.Collections.Internal.NaiveLockingList`1/NaiveLockingEnumerator::_readLock

--[888/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: DotNetNuke.Collections.Internal.ExclusiveLockStrategy DotNetNuke.Collections.Internal.MonitorLock::_lockStrategy

--[889/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: System.Threading.ReaderWriterLockSlim DotNetNuke.Collections.Internal.ReaderWriterSlimLock::_lock

--[890/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: DotNetNuke.Collections.Internal.ILockStrategy DotNetNuke.Collections.Internal.SharedDictionary`2::_lockController

--[891/2084] Name: DisposableFieldsShouldBeDisposedRule Severity: High

--Problem: This type contains disposable field(s) which aren't disposed.

--Location: DotNetNuke.Collections.Internal.ILockStrategy DotNetNuke.Collections.Internal.SharedList`1::_lockStrategy

--[892/2084] Name: EnsureLocalDisposalRule Severity: High

--Problem: This disposable local is not guaranteed to be disposed of before the method returns.

--Location: System.Drawing.Bitmap DotNetNuke.UI.WebControls.CaptchaControl::CreateImage(System.Int32,System.Int32)

...

It appears that some class fields implementing IDisposable aren’t being disposed of in the class’ Dispose implementations, and some method variables implementing IDisposable are not guaranteed to be disposed of before the method returns. These all indicate potential problems in the correctness of an application. Problems like these could potentially lead to memory leaks during run-time. Information like this can be very valuable to the administrators of a ASP.NET web application seeking to gain insight into potential trouble spots in a application or troubleshooting a web server problem after deployment.

As development progresses we will be adding significantly to the static analysis rule sets and analyzers available for ASP.NET applications. We plan to add things like the ability to analyze the data-flow of variables in ASP.NET page and controller methods to detect potential XSS vulnerabilities. Importantly this analysis only requires access to the application binaries (i.e the DLL assembly files) and not the source code, meaning you will have the ability to audit applications you have already deployed to a server, or off-the-shelf commercial applications, or legacy applications or any scenario where you do not have access to the source code of a .NET application.

Conclusion

DevAudit provides a range of auditing functions that can automate security auditing .NET applications for potential vulnerabilities and problems at multiple levels. I did not cover several cool DevAudit features for ASP.NET auditing here, like remoting auditing over SSH and WinRM and auditing Docker containers, but look for future articles describing more of the project’s key features. The DevAudit wiki is the first stop for information on the project.

We are building out the capabilities of the project to audit an ever increasing number of servers and applications (like Drupal) and languages like PHP. Our ultimate goal is to provide a complete platform for automating all aspects of security auditing for developers and teams adopting DevOps and DevSecOps.