Giter Club home page Giter Club logo

codeql-codifying-security-knowledge's Introduction

Codifying security knowledge

Going from security advisory to CodeQL query

@theztefan, @lcartey, @rvermeulen

Prerequisites โ€ข Resources โ€ข Learning Objectives

  • Who is this for: Security Engineers, Security Researchers, Developers.
  • What you'll learn: Learn how to use CodeQL for code exploration and for finding security issues.
  • What you'll build: Build a CodeQL query based on a security advisory to find a SQL injection.

Learning Objectives

In this workshop will cover the following learning objectives:

  • Understand how to use CodeQL in exploration and identification of security vulnerabilities.
  • Be able to codify a security vulnerability as a CodeQL query.
  • Be able to refine queries to find variants and increase precision.
  • Understand how refined queries can be integrated into the developer workflow to prevent future vulnerabilities.

๐Ÿ“ฃ Prerequisites

Before joining the workshop, there are a few items that you will need to install or bring with you.

  • Install Visual Studio Code.

  • Install the CodeQL extension.

    Walkthrough

    Screenrecording demonstrating how to install the CodeQL extension

  • Install the required CodeQL pack dependencies by running the command CodeQL: Install pack dependencies to install the dependencies for the pack githubuniverseworkshop/sql-injection-queries.

    Walkthrough

    Screenrecording demonstrating how to install CodeQL pack dependencies

  • Install git LFS to download the prepared databases or build the databases locally using the provide Make file. The Makefile requires the presence of Docker.

  • Test your setup perform the steps:

    1. Right-click on the file xwiki-platform-ratings-api-12.8-db.zip and run the command CodeQL: Set Current Database.
    2. Right-click on the file SqlInjection.ql and run the command CodeQL: Run Queries in Selected Files.
    3. See the result Hello GitHub Universe! in the CodeQL Query Results pane.

    If you run into issues with your setup feel free to ask for support at the start of the workshop.

    Walkthrough

    Screencast demonstrating how to test your setup

After finishing the technical prerequisites consider the following tutorials/guides for basic understanding of QL and Java query writing:

๐Ÿ“š Resources

Workshop

Welcome to the workshop Codifying security knowledge - Going from security advisory to CodeQL query! In this workshop we will apply CodeQL to gain a better understanding of a security issues reported in a security advisory, codify this new security knowledge, and run it to find a SQL injection issue and other variants.

Before we get started it is important that all of the prerequisites are met so you can participate in the workshop.

The workshop is divided into multiple sections and each section consists of exercises that build up to the final query. For each section we provide hints that help you finish the exercise by providing you with references to QL classes and member predicates that you can use.

Overview

In this workshop we will look for a known SQL injection vulnerabilities in the XWiki Platform's ratings API component. Such vulnerabilities can occur in applications when information that is controlled by a user makes its way to application code that insecurely construct a SQL query and executes it. SQL queries insecurely constructed from user input can be rewritten to perform unintended actions such as the disclosure of sensitive information.

The SQL injection discussed in this workshop is reviewed in GHSA-79rg-7mv3-jrr5 in GitHub Advisory Database.

To find the SQL injection we are going to:

  • Identify the vulnerable method discussed in the advisory and determine how it is used.
  • Model the vulnerable method as a SQL sink so the SQL injection query is aware of this method.
  • Identify how the vulnerable method can be used by finding new XWiki specific entrypoints.
  • Model the new entrypoints as a source of untrusted data that can be used by CodeQL queries.

Once we have completed the above steps, we can see whether the models, our codified security knowledge, can uncover variants or possible other security issues.

Let's start with finding more about the SQL injection.

1. Finding the insecure method

In the security advisory GHSA-79rg-7mv3-jrr5 in GitHub Advisory Database we learn of a Jira issue that discusses SQL injection in more detail.

From the Jira issue we learn that:

  1. There exists a method getAverageRating in the Rating Script Service.
  2. The two parameters of getAverageRating are used in the class AbstractRatingManager to insecurely construct a SQL statement.

We will use CodeQL to find the method and use the results to better understand how the SQL injection can manifest.

Select the database [xwiki-platform-ratings-api-12.8-db.zip] as the current database by right-clicking on it in the Explorer and executing the command CodeQL: Set current database.

The following steps can be implemented in the exercise file SqlInjection.ql

  1. Find all the methods with the name getAverageRating

    Hints
    • 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.
  2. Refine the set of results by limiting it to methods named getAverageRating, that acceptes two parameters where the first parameter is named fromsql.

    Hints
    • The class Method provides the member predicates getParameter that expects an index to retrieve the corresponding parameter, if any, and getNumberOfParameters that returns the number of formal paramerters.
    • The class Parameter provides the member predicates getName and hasName to reason about the name of a parameter.
    • getFile() returns a File associated with an element which has a member predicate getAbsolutePath useful for debugging.
  3. Find all the methods with the name getAverageRatingFromQuery.

    Hints
    • 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.
  4. Reduce the number of results by filtering uninteresting results.

    Hints
    • The class Method provides the member predicates getBody to reason about the statements that constitute a method.
    • You can use the quantifier exists like not exists(foo()) to determine if a predicate has no results.
  5. Find all the calls to a method named search.

    Hints
    • Calls to methods are method accesses. The class MethodAccess allows you to reason about method accesses.
    • The class MethodAccess provides a member predicate getMethod allows you to reason about the method being accessed.
    • The class MethodAccess provides the member predicates getName and hasName to reason about the name of a method.
  6. Find all the method accesses in the method getAverageRatingFromQuery.

    Hints
  7. Select the qualified name of the method search.

    Hints
  8. Use the qualified name of the method search to uniquely identify it.

    Hints

2. Modelling a SQL sink

The following steps can be implemented in the exercise file SqlInjection.ql You can use CheckPoint1.ql as a starting point if you were unable to complete the previous section.

  1. Find the first argument of all the method calls to search method.

    Hints

To inform the data flow analysis of our new sink we must extend the class QueryInjectionSink with the logic of our select clause

Replace your select clause with the following query:

// Import the SQL injection data flow configuration and extensions points.
import semmle.code.java.security.SqlInjectionQuery

class XWikiSearchSqlInjectionSink extends QueryInjectionSink {
    XWikiSearchSqlInjectionSink() {
      exists(Method searchMethod, MethodAccess searchMethodInvocation, Expr firstArg |
        searchMethod.hasQualifiedName("com.xpn.xwiki.store", "XWikiStoreInterface", "search") and
        searchMethod = searchMethodInvocation.getMethod() and
        searchMethodInvocation.getArgument(0) = firstArg
      |
        firstArg = this.asExpr()
      )
    }
}

from QueryInjectionSink sink
select sink

3 Attack surface and sources

The following steps can be implemented in the exercise file SqlInjection.ql You can use CheckPoint2.ql as a starting point if you were unable to complete the previous section.

  1. Write a query that finds classes annotated with org.xwiki.component.annotation.Component.

    Hints
    • The class Class provides the member predicate hasAnnotation to determine if the class is annotated.
  2. Extend the query to include only classes that implement the interface org.xwiki.script.service.ScriptService.

    Hints
  3. Extends the query to find all the parameters of the just found public methods.

    Hints
    • The class Class provides the member predicate getAMethod to reason about method declared by a class.
    • The class Method provides the member predicate isPublic to determine if a method is publicly accessible.
    • The class Method provides the member predicates getParameter and getAParameter to reason about a method's parameters.

To inform the data flow analysis of our new source we must extend the class RemoteFlowSource with the logic of our select clause

  1. Replace your select clause with the following query:

    class XWikiScriptableComponentSource extends RemoteFlowSource {
       XWikiScriptableComponentSource() {
          exists(Class component, Interface scriptService, Method publicMethod, Parameter parameter |
             component.hasAnnotation("org.xwiki.component.annotation", "Component") and
             scriptService.hasQualifiedName("org.xwiki.script.service", "ScriptService") and
             component.extendsOrImplements(scriptService) and
             component.getAMethod() = publicMethod and
             publicMethod.isPublic() and
             publicMethod.getAParameter() = parameter
             |
             this.asParameter() = parameter
          )
       }
    
       override string getSourceType() { result = "XWiki scriptable component" }
    }
    
    import QueryInjectionFlow::PathGraph
    
    from QueryInjectionFlow::PathNode source, QueryInjectionFlow::PathNode sink
    where QueryInjectionFlow::flowPath(source, sink)
    select sink, source, sink, "Found SQL injection from $@", source, "source"
  2. Add the following meta data to the top of your query (above the import java) to inform the CodeQL Result Viewer to display paths.

    /**
    * @kind path-problem
    */
  3. Run you query.

With the final query we can commence with variant analysis. You can use CheckPoint3.ql as a starting point if you were unable to complete this section.

codeql-codifying-security-knowledge's People

Contributors

rvermeulen avatar theztefan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

codeql-codifying-security-knowledge's Issues

Hello Universe 2023 Workshopers!

We are so excited to see you all soon! ๐Ÿคฉ

For Codifying security knowledge on November 8th we'll need a bit of prep work so we can dive into the content during the actual workshop.

Please follow the Prerequisites steps in the README of the repository. Here is the checklist:

  • I have a working GitHub Account
  • Visual Studio Code is installed on my laptop
  • The CodeQL extension is added to my Visual Studio Code
  • I've installed the required CodeQL pack dependencies
  • Git client and git LFS is setup on my laptop
  • I've cloned this repository locally
  • All set! ๐Ÿš€

@matpadley , @InfernapeXavier , @chriswblake , @mcrepssdi , @AndrewEverywhere , @dkian214 , @jimseiwert , @itsBrock , @LawanIdriss , @anshitmishra , @lautapercuspain , @cpcloud , @darshankhunt , @elviskahoro , @marietheresa , @JLLeitschuh , @voongc , @shaneakr , @brianbeck , @ahmad-luqman , @tim-white-esri , @samyukthagopalsamy , @mmaraya , @victkarangwa , @dot-derek , @kjaymiller , @sutharzan-ch , @fabasoad , @andreaso , @amaltson , @jhdub23 , @ansckasell , @dsanchezcr , @vshashkov , @mstokes , @SP-DBAG , @dina-heidar , @bushjak , @LuisDavidRodriguez , @TE-YasuhiroOsaki , @ooples , @mb388a , @tkbr0wn , @bspain , @nettiquet , @jimkohl , @kevin-bednar , @aco732 , @aberfeldy , @mrhein

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.