15 Audit tools

This chapter covers

  • Finding security vulnerabilities in a web application
  • Using OWASP ZAP to automatically scan for vulnerabilities
  • Using Security Code Scan and other static code analyzers
  • Learning how GitHub Advanced Security helps find security issues

In September 2019, GitHub acquired Semmle, a company providing a code analysis platform for securing software. About a year later, they had integrated and improved the code analysis service and published the results of a 5-month beta phase: 12,000 repositories were scanned, and over 20,000 security issues were identified (see http://mng.bz/woA2).

Not all security issues are visible when just looking at the code, especially for websites. As we have discussed previously in this book—for instance, in chapter 3 (cookie attributes) and chapter 9 (HTTP headers)—even the absence of certain security settings can count as a vulnerability. Therefore, testing an actual, running web application is an important approach as well. The “nine out of ten web applications have security vulnerabilities” study result from chapter 1 (here’s the link again: http://mng.bz/qYAJ) was retrieved by doing exactly that: scanning (running) websites for issues.

Wouldn’t it be nice to have such a feature available—at the push of a button, any security risks in our application would be found? In theory, that’s exactly how those tools work. In practice, however, things are not as easy as they seem. Not everything a tool reports is really a security issue. There might be false positives—vulnerabilities that really aren’t vulnerabilities. Also, tools will never be able to reliably find everything security-related in an app. When used correctly, though, code scanners and other software can help in finding (and fixing!) potential issues.

In this chapter, we will look at a few common tools for finding security vulnerabilities and give you a brief introduction to them. We will also discuss gotchas and how to handle the results those tools report. But first, we need to discuss the different approaches to finding security issues in a web application.

15.1 Finding vulnerabilities

When a security audit is conducted, there are usually several processes that help the auditor compile a list of issues and vulnerabilities that are then covered in the report. Tooling can help to a certain degree, and there are two approaches that complement each other well:

  • Dynamic analysis is the process that tries to analyze or scan a running application.

  • Static analysis analyzes the code itself.

Let’s start with dynamic analysis. When talking about web application security, the application that will be scanned is a website. A scanner usually starts by enumerating all the different pages, resources, and APIs that make up the web application. Similar to how search engines like Google index a site, the dynamic scanner tries to determine the structure and components of the target site. Then, each of the pages and endpoints found is scanned. The scanner has a library of potential attack vectors; for instance, sending JavaScript code in different forms, or typical SQL injection payloads. The result from those HTTP requests is scanned to find out whether, for example, the script code sent is now really part of the HTTP response or whether there are any errors on the page once the malicious payload is sent. The scanner also analyzes the HTTP headers that appear in the response to verify the presence of security-related HTTP headers and cookie settings.

Tip The Open Web Application Security Project (OWASP) has compiled a list of dynamic analysis software for web applications, containing both commercial and free tools. You can find it at http://mng.bz/7yRe.

Static code analysis, on the other hand, looks for typical patterns to identify insecure code. In ASP.NET Core web applications, these patterns might include string concatenation for SQL commands or uses of @Html.Raw() that potentially allow cross-site scripting. Having access to the source code also allows more complex analysis scenarios, such as determining the source of any data used by the application to verify whether it is (or has originally been) user input or not.

Tip OWASP also curates and maintains a list of static code analysis tools, available at http://mng.bz/mOA4.

Both types of analysis can also be conducted manually, without the aid of specialized software. In practice, both approaches are combined: a tool automatically looks for any incidents. A human then wades through the complete list, throws away the false positives, and manually rechecks the application to find items that are missing. Here, experience and in-depth knowledge can really pay off. For instance, when analyzing a web application based on ASP.NET Framework, there are a few things I am always specifically looking for. For example, is the site using an old version of ASP.NET (prior to 4.5.2, actually), and is the ViewState not secured with a message authentication code? In that case, cross-site scripting is likely. This may be tested in the browser and by looking at the HTML markup sent from the server. However, access to the source code would show us the middlewares being used and the configuration options set, which might also unveil potential issues.

The more information you have about a web application, the more likely you are to uncover security vulnerabilities. There are often situations where the source code will not be made available to the auditor; in those cases, dynamic analysis is the only—but still very powerful—option.

The previous chapters gave you many starting points to look for suspicious application behavior and typical code patterns. With regard to tools, it’s hard to recommend just one specific piece of software. Requirements are different, features are different, and the pricing may be very different. In the remaining chapter, we will cover a select number of software products and services that are free to use (and therefore very accessible). Since anything in those tools is subject to change, we limit ourselves to a rather brief introduction to get you started and then point you to further resources. We’ll look at a dynamic analysis tool first.

15.2 OWASP ZAP

The Open Web Application Security Project, or OWASP, has been mentioned before in this book, including in this chapter. The next chapter will reveal a little bit more about that organization and one of its publications. Now, however, we will focus on one specific software project that OWASP provides for free: the Zed Attack Proxy (ZAP). This is an open source security scanner that conducts a dynamic analysis of web applications. The OWASP website has a section on ZAP, https://owasp.org/www-project-zap/, but due to the popularity of the project, there is also a dedicated website at www.zaproxy.org/.

On that site, you will find in-depth documentation and much more information on ZAP, as well as a download section. At www.zaproxy.org/download/, you can retrieve ZAP for Windows, Linux, and macOS. Even if your operating system is not in the preceding list, if you have Java 11 on your system, the cross-platform package on the download page will enable you to run ZAP.

But before you start using ZAP, you need to find a target to scan. A few important words of caution: don’t use an arbitrary web application. ZAP (and other scanning tools) will send many, many HTTP requests to that site. Some applications will consider this a denial-of-service (DoS) attack and temporarily block your IP address, or—even worse—start to malfunction under load. In some jurisdictions, it might even be illegal to do that without the previous consent of the company or person responsible for that site.

There are some publicly available web applications with built-in security holes that purely exist to test scanning tools (and personal hacking skills).

One such web application comes from the team behind the Netsparker application security testing suite. The site at http://aspnet.testsparker.com/, shown in figure 15.1, looks fishy—and it is.

CH15_F01_Wenz

Figure 15.1 An insecure ASP.NET-based web application

As the URL already suggests, this application is implemented using ASP.NET, not ASP.NET Core, but as we have seen so far, the vast majority of attacks work independently of the technology being used. This web application has some well-hidden and some not-so-well-hidden security vulnerabilities, and ZAP might be able to assist in finding them.

Consider using one of those intentionally insecure sites, or even better, your application. Since ZAP runs on your computer, you can also scan web applications in your internal network, not just public ones.

When you launch ZAP, you are greeted with a modal window asking whether you want to persist the session (figure 15.2).

CH15_F02_Wenz

Figure 15.2 Persisting a ZAP session

Keeping a session makes it easier to resume later; either ZAP uses the current timestamp for the session name, or you can specify a specific one (and the location at which to store it). For one-off experiments, there is obviously no need to persist anything, and that option exists as well.

Next up, the actual ZAP application UI appears, including a welcome screen. Click Automated Scan to open a window like the one in figure 15.3, where you can initiate an automated scan (or, as ZAP calls it, launch an “attack”).

CH15_F03_Wenz

Figure 15.3 The ZAP main screen while a scan is running

You can provide a URL to attack and to use one or two spiders that are responsible for discovering all URLs that the application is using:

  • Traditional spider—Basically, the application parses the HTML markup on the URL you provide, pulls out all links, and recursively retrieves and parses those.

  • Ajax spider—JavaScript-based SPAs do not use many regular links, if any. The Ajax (asynchronous JavaScript + XML; an approach used for SPAs in the 2000s) spider launches an invisible browser, loads the application there, and checks which APIs and additional sources are being loaded when simulating user interactions such as mouse clicks.

Afterward, all resources found are now attacked with malicious requests. If you revisit figure 15.3, you will note that in the lower part of the UI, ZAP is running at full steam, having sent almost 9,000 requests, and has found several noteworthy issues (the flags in the lower left corner).

For the Netsparker sample ASP .NET application, figure 15.4 shows the findings after going through the application.

CH15_F04_Wenz

Figure 15.4 Findings in the insecure app

Fifteen alerts don’t sound like much, but note that that’s just the number of types of issues found. For instance, SQL injection was found twice, and something called cross-domain JavaScript source file inclusion was found a whopping 471 times.

That was easy—the actual challenge is to find out which of those items are really worth fixing. For example, including cross-domain JavaScript source files is not an issue per se. The application might intentionally load JavaScript code from a CDN, for instance. It’s good that ZAP reports those, since they might also be the result of an XSS attack, but that’s also the reason why this issue is marked with a yellow flag.

ZAP provides four categories of issues, or, as they are called in the application, alerts. Here they are in descending order of severity, with one example each:

  • Red—High (SQL injection)

  • Orange—Medium (X-FRAME-OPTIONS HTTP header missing)

  • Yellow—Low (HTTP headers revealing server software)

  • Blue—Informational (comments found in the HTML markup)

For a complete list of all supported alerts, see www.zaproxy.org/docs/alerts/. Let’s look at one of the red-flagged entries. SQL injection certainly deserves a closer look. Figure 15.5 shows the detailed alert information for one of the two SQL injections ZAP supposedly found.

CH15_F05_Wenz

Figure 15.5 Details about a potential SQL injection attack

As you can see from the URL, the pid query string parameter is set to 5-2. If you can’t see it due to ZAP’s tiny font size, here is the full URL: http://aspnet.testsparker.com/Products.aspx?pid=5-2.

Product IDs in the application are numeric, so this value is certainly invalid. But how does the application react? It turns out that the data returned from the server when requesting that URL is practically identical to that for this URL: http://aspnet.testsparker.com/Products.aspx?pid=3.

It’s pretty safe to say that the application interprets 5-2 as 3, and it is highly likely that this happens because the SQL string contains 5-2 (and is then evaluated as 3 by the database). ZAP has successfully detected SQL injection.

OWASP has its own intentionally insecure web application called Juice Shop. Three URLs come in handy here:

  • The project home page on the OWASP site is https://owasp.org/www-project-juice-shop/.

  • The source code of the app is contained at https://github.com/juice-shop/juice-shop (mostly in TypeScript). Don’t copy any of it to one of your own applications, because you copy the security vulnerabilities, too. The code allows you to run the application locally and conveniently do dynamic and static code analysis.

  • You can find a running, public instance of the application at https://juice-shop.herokuapp.com/ (figure 15.6). This is the easiest and fastest way to look at the app.

CH15_F06_Wenz

Figure 15.6 The very insecure OWASP Juice Shop

Whether you run ZAP against a local or an online instance of Juice Shop, some (but not all) vulnerabilities will be found. For instance, one of the issues reported is cross-site scripting when calling one of Juice Shop’s APIs like this:

https://juice-shop.herokuapp.com/api/Challenges/?sort=<script>alert(1);</script>

Indeed, calling that API in a browser returns content with the <script> element intact, as figure 15.7 shows.

CH15_F07_Wenz

Figure 15.7 Looks like cross-site scripting, but isn’t

However, as you can also see in the same figure, the Content-Type of the resulting page seems to be along the lines of application/json, because the browser renders the content as JSON, not as HTML (and therefore does not execute the JavaScript code). This is not a security vulnerability. In the JSON context, a special character that might allow certain injection scenarios would be the double quotes, since they delimit the user-supplied data. Turns out that the Juice Shop implementation does escape double quotes properly (at least within that specific endpoint). To make a long story short, you have to verify and validate each item reported by ZAP and weed out what looks suspicious but in reality, isn’t. And that’s why an audit is never a fully automated process. Scanning tools are useful but still need human oversight.

This was, of course, just a glimpse of ZAP. The advice given also applies to similar tools: let them run against a web application, and then scrutinize all results, and use additional measures to add more findings to the list.

Authentication for ZAP

ZAP actually missed many of the vulnerabilities in both applications. One of the reasons is that there were issues only visible when the user is logged in, yet we did not provide ZAP with any credentials or with instructions on how and where to use them. There are several approaches to fix that. You might try to log into the application locally and then note the cookies that are created. Most likely, these cookies are used by the application to authenticate the user. If ZAP sends those cookies, it is also logged into the application. It would be even better to specifically tell ZAP how logging into the application works and which username/password combination to use. The ZAP documentation has a dedicated page for this topic at http://mng.bz/5QRa.

You can find much more information on using ZAP in the online documentation at www.zaproxy.org/docs/. A good starting point is the aptly named “Getting Started” section (www.zaproxy.org/docs/desktop/start/), which covers all the basics and dives into many advanced features.

ZAP also supports an add-on system, where you can find those add-ons that are shipped with ZAP by default and can install additional ones using ZAP’s own marketplace. There is a tiny Manage Add-ons button in the title navigation bar of the ZAP UI, which opens a dialog to install and update add-ons (figure 15.8).

CH15_F08_Wenz

Figure 15.8 Installing ZAP add-ons

To be honest, the default distribution of ZAP already contains virtually everything you need, but it’s still good to know that you might add more features to the application.

ZAP works well independent of which framework is used to create the web application. When doing a static code analysis, it’s obviously necessary to have a specialized tool that knows the development stack being used in order to detect insecure code.

15.3 Security Code Scan

The open source project Security Code Scan is a static code analyzer for .NET code. It already existed in the .NET Framework days and has been updated to work with .NET and ASP.NET Core as well. The project home page, https://security-code-scan.github.io/, contains installation instructions, a release history, and a pretty thorough documentation. This section will show you how to get started easily.

The first decision to be made is how Security Code Scan should be used, since the project provides three different options:

  • A tool integrated in Visual Studio, working globally for all projects

  • A NuGet package, working for individual projects

  • A standalone command-line application

Let’s start with the first option, which can be enabled using the Extensions > Manage Extensions menu entry. Searching for “Security Code Scan” should lead to a result similar to figure 15.9.

CH15_F09_Wenz

Figure 15.9 Installing Security Code Scan as a Visual Studio extension

If you are seeing an extension just called Security Code Scan, resist installing it, since it’s an outdated version. There are additional packages specifically for Visual Studio versions 2017 and 2019 (the latter one is also currently the correct one for 2022). After installing the matching extension for your IDE version and restarting Visual Studio, Security Code Scan is activated.

The code is now checked while you are typing it and when compiling. Figure 15.10 shows a typical output listing potential issues.

CH15_F10_Wenz

Figure 15.10 The Visual Studio extension found issues in the current project.

Typical findings are MVC controller methods with disabled CSRF protection (as shown in the figure), or potential XSS vulnerabilities or missing configuration options.

Alternatively, you can go the NuGet route, adding Security Code Scan solution-wide, or per project. Once again, don’t be tempted to install the package called SecurityCodeScan (the first option in figure 15.11). Use the version-specific one instead.

CH15_F11_Wenz

Figure 15.11 Installing Security Code Scan as a NuGet package

Once the package is installed and active, you might see warning messages in the output window of Visual Studio (figure 15.12). As you can easily see, the messages are the same as the one from the Visual Studio extension.

CH15_F12_Wenz

Figure 15.12 The NuGet package found issues in the current project.

The third option for using Security Code Scanner is a command-line tool, which can be installed globally using the dotnet tool command. Here is the complete call required to get it onto your system:

dotnet tool install --global security-scan

Afterward, you will have the security-scan command at your disposal. The easiest way to run it is to provide the .sln file of the Visual Studio solution to scan as an argument:

security-scan MyProject.sln

Figure 15.13 shows both the installation and the output of running the tool against the same application that was previously used for the NuGet and Visual Studio extension versions.

CH15_F13_Wenz

Figure 15.13 Security Code Scan as a standalone application

The warnings created are the same, but this time, you have more options at your disposal due to the command-line arguments supported (security-scan -? gives you a complete list, including options to exclude certain projects and to run scans in parallel). The standalone tool also allows you to explicitly execute the scan, whereas the options integrated in Visual Studio basically scan the application all the time.

As usual, the quality of the results depends on the quality of the rules included in the code scanner. Security Code Scanner comes with more than 30 rules (https://security-code-scan.github.io/#Rules provides a complete list). It cannot detect everything, but it is still helpful. Remember: defense in-depth is key in security.

More often than not, an application’s source code is checked into a repository. If GitHub is being used, we have an additional scanning opportunity at our disposal.

15.4 GitHub Advanced Security

Remember GitHub’s 2019 purchase of the Semmle company we mentioned at the beginning of this chapter? The technology GitHub was probably most interested in was CodeQL, a code-analysis engine. In the meantime, it is now an integral part of the distributed code-hosting service. GitHub calls this GitHub Advanced Security. For public repositories, you can currently activate scanning at no cost. For private repositories and enterprise accounts, a license is required.

The service is very easy to use: just configure a workflow that essentially triggers CodeQL. The engine currently supports the following languages:

  • C++

  • C#

  • Go

  • Java

  • JavaScript

  • Python

  • Ruby

  • TypeScript

C# and JavaScript, possibly the two languages the audience of this book primarily uses, are included, so we should be ready to go. First, we need to create a YAML file that configures CodeQL and sets up a workflow. Go to the settings page of any of your applicable (i.e., public, unless you have a license) repositories, and select the Security & Analysis tab. The result may look similar to figure 15.14.

CH15_F14_Wenz

Figure 15.14 GitHub’s security and analysis features

You are provided with several choices, including the option to use Dependabot (see chapter 14), and, as the final item, setting up code-scanning services. Click the appropriate Set Up button to load a URL with this pattern: https://github.com/<GitHub user name>/<repository name>/security/code-scanning.

The resulting page provides a list of all available code-scanning services, as shown in figure 15.15.

CH15_F15_Wenz

Figure 15.15 GitHub’s code-scanning services

At the time of this writing, the first entry is GitHub’s CodeQL Analysis service, but there’s also a marketplace with three dozen third-party alternatives. When selecting CodeQL, you are prompted to create a file called codeql-analysis.yml in the .github/workflows folder of your repository. GitHub uses the contents in this folder to find, configure, and execute workflows.

GitHub already suggests content for the new YAML file, including configuring it for the languages supposedly used in your code. Some projects already come with such a file (in that case, you may skip creating the new file). The contents of the file, of course, depend on the mechanism and structure of your repository and code, but the following listing shows a good starting point with reasonable settings for most projects.

Listing 15.1 Configuring a CodeQL workflow

name: "CodeQL"
 
on:
  push:
    branches: [ main ]                               
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ main ]                               
  schedule:
    - cron: '44 5 * * 1'
 
jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
 
    strategy:
      fail-fast: false
      matrix:
        language: [ 'javascript', 'csharp' ]         
 
    steps:
    - name: Checkout repository                      
      uses: actions/checkout@v2                      
 
    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL                        
      uses: github/codeql-action/init@v1             
      with:                                          
        languages: ${{ matrix.language }}            
 
    - name: Autobuild                                
      uses: github/codeql-action/autobuild@v1        
 
    - name: Perform CodeQL Analysis                  
      uses: github/codeql-action/analyze@v1          

Starts analysis when a push happens to these branch(es)

Starts analysis when a pull request for this/these branch(es) is created

Shows languages used in the code to be scanned

Does checkout prior to scanning

Initializes CodeQL for the language(s) selected

Automatically builds the application prior to analysis

Performs the analysis

Basically, you define when to run code analysis (e.g., after pushing code or receiving a pull request), which languages to scan, and what to do prior to the analysis (checking out the repository, building the solution, and so on).

Once that file has been added to your repository, it won’t take long for GitHub to pick it up and process it. If you go to the Actions page of your repository (https://github.com/<user name>/<repository name>/actions), you will see your workflow. It could still be in the queue, waiting for a slot to run, or already in progress (figure 15.16 shows the latter).

Any issues the code-scanning process finds are reported in the Security tab of the repository, under Code Scanning Alerts. Figure 15.17 shows the results when running such an analysis over a forked version of the Juice Shop source code.

CH15_F16_Wenz

Figure 15.16 The code-analysis workflow is running.

CH15_F17_Wenz

Figure 15.17 The issues found by the CodeQL code-scanning service

Fifty-one alerts—that’s quite a lot. All potential finds have been converted into issues ready to be verified and resolved by the development team. The same caveat applies as for the other automated tools: not everything they find is necessarily a security vulnerability, and they also won’t find 100% of the issues all of the time. But with minimal configuration, applications have yet another extra safeguard against insecure code.

Summary

Let’s review what you have learned so far:

  • Static code analysis looks at the source code, searching for patterns known to be insecure.

  • Dynamic code analysis tries to attack a running (web) application, finding exploitable vulnerabilities.

  • During a security audit of a web application, static and dynamic code analysis are routinely used, utilizing tools and manual analysis.

  • OWASP ZAP is an open source dynamic code-analysis tool that can help find security issues in a web application.

  • Security Code Scan is a static code-analysis tool, available as a Visual Studio extension, a NuGet package, and a standalone command-line tool.

  • GitHub Advanced Security provides free static code scanning to public GitHub repositories, using the CodeQL technology acquired in 2019.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.208.117