Share
## https://sploitus.com/exploit?id=68E8191D-21C4-5FEC-A0AA-02ECF37B7768
# CodeQL workshop for Java: Finding a SQL injection

In this workshop we will use syntactical and semantic reasoning to find a SQL injection in the XWiki platform's rating component documented by CVE-2021-21380

## Contents

- [CodeQL workshop for Java: Finding a SQL injection](#codeql-workshop-for-java-finding-a-sql-injection)
  - [Contents](#contents)
  - [Prerequisites and setup instructions](#prerequisites-and-setup-instructions)
    - [On your local machine ](#on-your-local-machine-)
      - [Installation](#installation)
      - [Setup steps](#setup-steps)
  - [Workshop](#workshop)
    - [Learnings](#learnings)
    - [Problem statement](#problem-statement)
    - [Exercises](#exercises)
      - [Exercise 1](#exercise-1)
      - [Intermezzo 1](#intermezzo-1)
      - [Exercise 2](#exercise-2)
      - [Exercise 3](#exercise-3)
      - [Intermezzo 2](#intermezzo-2)
      - [Exercise 4](#exercise-4)
      - [Exercise 5](#exercise-5)
      - [Intermezzo 3](#intermezzo-3)
      - [Exercise 6](#exercise-6)
      - [Exercise 7](#exercise-7)
      - [Exercise 8](#exercise-8)
  - [What's next?](#whats-next)


## Prerequisites and setup instructions

### On your local machine <a id="setup"></a>

Please complete this section before the workshop, if possible.

#### Installation

- Install [Visual Studio Code](https://code.visualstudio.com/).
- Install the [CodeQL extension for Visual Studio Code](https://codeql.github.com/docs/codeql-for-visual-studio-code/setting-up-codeql-in-visual-studio-code/).
- You do _not_ need to install the CodeQL CLI: the extension will handle this for you.
- Clone this repository:
  
  ```bash
  git clone https://github.com/advanced-security/codeql-workshop-cve-2021-21380.git
  ```

#### Setup steps

- Import the [CodeQL database](https://github.com/advanced-security/codeql-workshop-cve-2021-21380/raw/main/xwiki-platform-CVE-2021-21380.zip) to be used in the workshop:
  - Right-click on the `xwiki-platform-CVE-2021-21380.zip` file in the Explorer view and select the command `CodeQL: Set Current Database`.
  - The database will show up in the CodeQL databases view reachable from the QL icon on the Activity Bar.
- Install the dependencies for analyzing Java code and to run the tests for the exercises and solutions.
  - From the Command Palette (`Cmd/Ctrl+Shift+P`), search for and run the command `CodeQL: Install Pack Dependencies`.
  - At the top of your VS Code window, type `github` in the box to filter the list.
  - Check the box next to `cve-2021-21380-exercises`, `cve-2021-21380-exercises-tests`, `cve-2021-21380-solutions`, and `cve-2021-21380-solutions-tests`.
  - Click **OK**/**Enter**.
- Validate everything works as expected by running the tests for the solutions.
  - Open the view testing and press run tests (play icon is shown when hovering solutions) next to the solutions item in the tree.

## Workshop

### Learnings

The workshop is split into several exercises introducing the QL language support for Java and ends with a final query to find the known SQL injection.
In these exercises you will learn:

- How to reason about syntactic information.
- How to reason about semantic information.
- Explore the QL language support for Java to express patterns.
- Explore how to reuse and extend existing modelling.
- Use multiple building blocks to compose the final query.

### Problem statement

In this workshop we will look for known _SQL injection vulnerabilities_ in the [XWiki Platform](https://xwiki.org)'s ratings API component. Such vulnerabilities can occur in applications when information that is controlled by an external user makes its way to application code that insecurely construct a SQL query and executes it.

The known SQL injection discussed in this workshop is reviewed in [GHSA-79rg-7mv3-jrr5](https://github.com/advisories/GHSA-79rg-7mv3-jrr5) in [GitHub Advisory Database](https://github.com/advisories). To find the SQL injection, and possible variants, we are going to the following sub-problems:

- Identify the source of intrusted information and model it in QL.
- Identify the sink, the method executing SQL queries, and model it in QL.
- Combine the above solutions to determine if there is a flow of information between the source and the sink using taint tracking.

### Exercises

In the first few exercises we will reason about syntactic information, using the Abstract Syntax Tree (AST), to identify:

- the method described in the security advisory to build understanding of the vulnerability 
- parameters that contain untrusted data, our **sources**
- method calls that accept SQL statements, our **sinks**

#### Exercise 1

Find all methods with the name `getAverageRating` and its declaring type in the program by completing the query [exercise1.ql](exercises/exercise1.ql)

<details>
<summary>Hints</summary>

- The `java` module provides a class `Method` to reason about methods in a program.
- The class `Method` provides the member predicates `getName` and `hasName` to reason about the name of a method.
- The class `Method` provides the member `getDeclaringType` to reason about the type that declares the method.

</details>

A solution can be found in the query [exercise1.ql](solutions/exercise1.ql)

#### Intermezzo 1

A solution to [exercise 1](#exercise-1) returns a list of methods. Some of which are defined in an interface called `RatingsManager` and some which are defined in the classes `AbstractRatingsManager` and `RatingsScriptService`.

From the information returned by the query and [XWiki component documentation](https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/Tutorials/WritingComponents/) we can deduce that:

- XWiki uses a component oriented design to allow for extensions and customizations.
- The vulnerable method is part of a component.
- A component consist of an interface, annotated with `Role`, and an implementation annotated with `Component`.
- A component that extends `ScriptService` are made accessible to wiki pages through scripting.

#### Exercise 2

Find all the classes annotated with the annotation `Component` by completing the query [exercise2.ql](exercises/exercise2.ql).
Note that the fully qualified name of the annotation's type is `org.xwiki.component.annotation.Component`.

<details>
<summary>Hints</summary>

- The /class domain type/, the intersection of its super types, can be accessed using the keyword `this` in the /characteristic predicate/.
- The `Class` class provides a method `getAnAnnotation` to get associated annotations.
- The `Annotation` class provides the `getType` member predicate to reason about its type.
- The `Type` class provides the member predicates `getName` and `hasName` to reason about the name of a type.
- The `RefType` class, representing classes and interfaces, provides the member predicates `getQualifiedName` and `hasQualifiedName` to reason about the fully qualified name of the reftype.

</details>

A solution can be found in the query [exercise2.ql](solutions/exercise2.ql)

#### Exercise 3

Find all the components that implement the `ScriptService` interface by completing the query [excercise3.ql](exercises/exercise3.ql)

<details>
<summary>Hints</summary>

- The `Class` type provides the member predicate `getASuperType` to reason about a class its super types, that is types it `extends` or `implements`.

</details>

A solution can be found in the query [exercise3.ql](solutions/exercise3.ql)

#### Intermezzo 2

At this point we have syntactically identified the methods that can be called by a user and whose parameters we will consider sources of untrusted data further on in the workshop.

In the next exercise we are going to investigate and identify possible sinks. From the results of [exercise 1](#exercise-1) we can deduce that one of the implementations calls the method `getAverageRatingFromQuery`. Using a similar query we can find the declaring types of `getAverageRatingFromQuery` which allows us to establish that the implementation in the class `AbstractRatingsManager` constructs a SQL statement that is passed to the `search` method.

The `search` method is implemented in a dependency and thus its implementation is not available. In the next exercises we are going to use the available type information to identify this `search` method call and its declaring type.

#### Exercise 4

Find all methods calls to the method `search` and identify its declaring type by completing the query  [exercise4.ql](exercises/exercise4.ql)

<details>
<summary>Hints</summary>

- The `MethodAccess` type provide us with the means to reason about method calls.
- The `MethodAcccess` type provides the member predicate `getMethod` to reason about the target of a method call.

</details>

A solution can be found in the query [exercise4.ql](solutions/exercise4.ql)

#### Exercise 5

Find all the method calls to methods declared by the interface `XWikiStorageInterface` (with the qualified name `com.xpn.xwiki.store.XWikiStoreInterface`) by completing the query [exercise5.ql](exercises/exercise5.ql)

<details>
<summary>Hints</summary>

- The `instanceof` keyword can be used to state that a value belongs to the set of values represented by a type. 
  For example, to identify all the calls to interface methods:
  
  ```ql
  import java

  from MethodAccess ma
  where ma.getMethod.getDeclaringType() instanceof Interface
  select ma
  ```

</details>

A solution can be found in the query [exercise5.ql](solutions/exercise5.ql)

#### Intermezzo 3

At this point we have syntactically described possible sources and sink using QL. To determine if information flows between these points in the program we are going to semantically analyze the program using taint tracking.
The standard libraries of the languages we support provide two data flow mechanism:

1. The module `DataFlow` supports value preserving flow of information.
2. The module `TaintTracking` supports flow of information even if values are modified.

The latter is of interest, because in injection vulnerability such as SQL injection it is common for untrusted data to become part of a larger statement that is acted upon.

In this workshop we are going to reuse an existing SQL injection taint tracking configuration and extend it with our modelled sources and sinks to find the SQL injection. To understand how we can extend the configuration we start with looking at the definition of the configuration below.

```ql
class QueryInjectionFlowConfig extends TaintTracking::Configuration {
  QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" }

  override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }

  override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }

  override predicate isSanitizer(DataFlow::Node node) {
    node.getType() instanceof PrimitiveType or
    node.getType() instanceof BoxedType or
    node.getType() instanceof NumberType
  }

  override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
    any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
  }
}
```

Both the `isSource` and `isSink` predicate used by the configuration to identify those program location use the `instanceof` keyword that we have seen before. Both the `RemoteFlowSource` and `QueryInjectionSink` classes are `abstract` classes.
This is a common pattern that you will encounter in the standard libraries and this pattern allow us to extend the set of values represented by the `RemoteFlowSource` and `QueryInjectionSink` classes.

A QL `class` extending an `abstract class` does not refine the set of value represented by the super class, but adds the values represented by the subclass to the superclass.
In the next exercises we are going to implement these subclasses and construct our final query.

#### Exercise 6

Extend the `RemoteFlowSource`'s value set with the parameters of the public methods of the component classes identified in [exercise 3](#exercise-3) by completing the query [exercise6.ql](exercises/exercise6.ql).

<details>
<summary>Hints</summary>

- The `instanceof` keyword can be used to state that a value belongs to the set of values represented by a type. 
  For example, to identify all the calls to interface methods:
  
  ```ql
  import java

  from MethodAccess ma
  where ma.getMethod.getDeclaringType() instanceof Interface
  select ma
  ```

</details>

A solution can be found in the query [exercise6.ql](solutions/exercise6.ql)

#### Exercise 7

Extend the `QueryInjectionSink`'s value set with the arguments of calls to the methods of the storage interface identified in [exercise 5](#exercise-5) by completing the query [exercise7.ql](exercises/exercise7.ql)

<details>
<summary>Hints</summary>

- The [`exists`](https://codeql.github.com/docs/ql-language-reference/formulas/#exists) formula allows for the introduction of temporary variable that can be reasoned about in the scope of the `exists`.

    The following example uses the `exists` expression to reduce the set of methods to methods that are called.

    ```ql
    from Method m
    where m.hasName("foo") and exists(MethodAccess ma | ma.getMethod() = m)
    select m
    ```

- The `MethodAccess` class provides the member predicate `getQualifer` to reason about the qualifier of the method access.

</details>

A solution can be found in the query [exercise7.ql](solutions/exercise7.ql)

#### Exercise 8

Combine your solutions from the previous exercise into a final solution by completing by completing the query [exercise8.ql](exercises/exercise8.ql).

A solution can be found in the query [exercise8.ql](solutions/exercise8.ql)

## What's next?

- The query includes a module to model parts of the XWiki framework. Refactor this into its own module file and use it in your query.
- We limited our source of untrusted data to script service components. Look at how to expand this with other sources.
- For the sink we limited ourselves to direct usage of the `XWikiStoreInterface`. Expand the sink to include direct uses of implementation of the interface. The `Class` class provides the member predicate [extendsOrImplements](https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Type.qll/predicate.Type$RefType$extendsOrImplements.1.html) and the `Method` class provides the member predicate [overridesOrInstantiates](https://codeql.github.com/codeql-standard-libraries/java/semmle/code/java/Member.qll/predicate.Member$Method$overridesOrInstantiates.1.html) that may be of help.
- Use the definition of sources to find interesting uses of untrusted data with the query '[Untrusted data passed to external API](https://github.com/github/codeql/blob/main/java/ql/src/Security/CWE/CWE-020/UntrustedDataToExternalAPI.ql)
'