├── .gitignore ├── Dockerfile ├── README.md └── scripts ├── analyze.sh ├── compile-qs.sh └── run.py /.gitignore: -------------------------------------------------------------------------------- 1 | results/* -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 AS codeql_base 2 | LABEL maintainer="j3ssie" 3 | 4 | # tzdata install needs to be non-interactive 5 | ENV DEBIAN_FRONTEND=noninteractive 6 | 7 | # create user, install/update basics and python 8 | RUN apt-get update && \ 9 | apt-get upgrade -y && \ 10 | apt-get install -y --no-install-recommends \ 11 | software-properties-common \ 12 | nodejs \ 13 | vim \ 14 | curl \ 15 | wget \ 16 | git \ 17 | build-essential \ 18 | unzip \ 19 | apt-transport-https \ 20 | python3.10 \ 21 | python3-venv \ 22 | python3-pip \ 23 | python3-setuptools \ 24 | python3-dev \ 25 | python-is-python3 \ 26 | gnupg \ 27 | g++ \ 28 | make \ 29 | gcc \ 30 | apt-utils \ 31 | rsync \ 32 | file \ 33 | dos2unix \ 34 | gettext && \ 35 | apt-get clean && \ 36 | ln -sf /usr/bin/python3.8 /usr/bin/python && \ 37 | ln -sf /usr/bin/pip3 /usr/bin/pip 38 | 39 | # Install Golang 40 | RUN wget -q -O - https://raw.githubusercontent.com/canha/golang-tools-install-script/master/goinstall.sh | bash 41 | 42 | # Install latest codeQL 43 | ENV CODEQL_HOME /root/codeql-home 44 | 45 | # Get CodeQL verion 46 | RUN curl --silent "https://api.github.com/repos/github/codeql-cli-binaries/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/' > /tmp/codeql_version 47 | 48 | # record the latest version of the codeql-cli 49 | RUN mkdir -p ${CODEQL_HOME} \ 50 | ${CODEQL_HOME}/codeql-repo \ 51 | ${CODEQL_HOME}/codeql-go-repo \ 52 | /opt/codeql 53 | 54 | # get the latest codeql queries and record the HEAD 55 | RUN git clone --depth=1 https://github.com/github/codeql ${CODEQL_HOME}/codeql-repo && \ 56 | git --git-dir ${CODEQL_HOME}/codeql-repo/.git log --pretty=reference -1 > /opt/codeql/codeql-repo-last-commit 57 | 58 | RUN CODEQL_VERSION=$(cat /tmp/codeql_version) && \ 59 | wget -q https://github.com/github/codeql-cli-binaries/releases/download/${CODEQL_VERSION}/codeql-linux64.zip -O /tmp/codeql_linux.zip && \ 60 | unzip /tmp/codeql_linux.zip -d ${CODEQL_HOME} && \ 61 | rm /tmp/codeql_linux.zip 62 | 63 | ENV PATH="$PATH:${CODEQL_HOME}/codeql:/root/go/bin:/root/.go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 64 | COPY scripts /root/scripts 65 | 66 | # Pre-compile our queries to save time later 67 | RUN /root/scripts/compile-qs.sh 68 | 69 | WORKDIR /root/ 70 | ENTRYPOINT ["/root/scripts/analyze.sh"] 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker for CodeQL 2 | 3 | Based on [microsoft/codeql-container](https://github.com/microsoft/codeql-container) with Java, Golang installed and .NET removed. 4 | 5 | ## Build & Run 6 | 7 | ```shell 8 | docker build -t j3ssie/codeql-docker:latest . 9 | ``` 10 | 11 | or pull the latest from Docker hub 12 | 13 | ```shell 14 | docker pull j3ssie/codeql-docker:latest 15 | 16 | ``` 17 | *** 18 | 19 | ## Usage 20 | 21 | ### Run with helper scripts 22 | 23 | ```shell 24 | # usage 25 | ./scripts/run.py -l -s [--format=csv] [-o ouput] 26 | 27 | # simple usage 28 | ./scripts/run.py -l go -s /tmp/insecure-project 29 | # default output is JSON format so read them with this command 30 | cat results/issues.sarif-latest| jq '.runs[].results' 31 | 32 | # with custom format and output 33 | ./scripts/run.py -l javascript -s /tmp/cc/code-scanning-javascript-demo --format=csv -o sample 34 | # your output will be store at sample/issues.csv 35 | 36 | ``` 37 | 38 | ### Run with docker command 39 | 40 | With `/tmp/src` is your source code and `/tmp/results` is where result store. 41 | 42 | > NOTE: make sure /tmp/results folder exist otherwise it won't work 43 | 44 | ```shell 45 | # run in the current folder 46 | mkdir -p ${PWD}/codeql-result 47 | docker run --rm --name codeql-docker -v ${PWD}:/opt/src -v ${PWD}/codeql-result:/opt/results -e "LANGUAGE=javascript" -e "THREADS=5" j3ssie/codeql-docker:latest 48 | 49 | # simple usage 50 | docker run --rm --name codeql-docker -v "/tmp/src:/opt/src" -v "/tmp/local-results:/opt/results" -e "LANGUAGE=go" j3ssie/codeql-docker:latest 51 | 52 | # more options 53 | docker run --rm --name codeql-docker -v "/tmp/src:/opt/src" -v "/tmp/local-results:/opt/results" -e "LANGUAGE=javascript" -e "FORMAT=csv" -e "QS=javascript-security-and-quality.qls" j3ssie/codeql-docker:latest 54 | 55 | ``` 56 | 57 | ### Manual analyze 58 | 59 | ```shell 60 | # Directly access container with bash shell 61 | docker run -it --entrypoint=/bin/bash -t j3ssie/codeql-docker:latest 62 | 63 | # Copy your code to container 64 | docker cp :/opt/src 65 | 66 | # create DB in this folder /opt/src/db 67 | # This might take a while depend on your code 68 | codeql database create --language= /opt/src/db -s /opt/src 69 | 70 | # run analyze 71 | # normally query-suites will will be: -security-and-quality.qls 72 | codeql database analyze --format=sarif-latest --output=/opt/issues.sarif /opt/src/db 73 | 74 | # copy the result back to host machine 75 | docker cp :/opt/issues.sarif . 76 | ``` 77 | 78 | ### Other commands 79 | 80 | ```shell 81 | # List all query suites 82 | codeql resolve queries 83 | 84 | # Upgrade DB 85 | codeql database upgrade 86 | 87 | ``` 88 | -------------------------------------------------------------------------------- /scripts/analyze.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RED="\033[31m" 4 | YELLOW="\033[33m" 5 | GREEN="\033[32m" 6 | RESET="\033[0m" 7 | 8 | print_green() { 9 | echo -e "${GREEN}${1}${RESET}" 10 | } 11 | 12 | SRC=/opt/src 13 | if [ -z $FORMAT ] 14 | then 15 | FORMAT="sarif-latest" 16 | fi 17 | 18 | if [ -z $QS ] 19 | then 20 | QS="$LANGUAGE-security-and-quality.qls" 21 | fi 22 | 23 | if [ -z $THREADS ] 24 | then 25 | THREADS=5 26 | fi 27 | 28 | if [ -z $OUTPUT ] 29 | then 30 | OUTPUT="/opt/results" 31 | fi 32 | DB=$SRC/codeql-db 33 | 34 | echo "----------------" 35 | print_green " [+] Language: $LANGUAGE" 36 | print_green " [+] Query-suites: $QS" 37 | print_green " [+] Database: $DB" 38 | print_green " [+] Source: $SRC" 39 | print_green " [+] Output: $OUTPUT" 40 | print_green " [+] Format: $FORMAT" 41 | echo "----------------" 42 | 43 | echo -e "==> Creating DB: codeql database create --language=$LANGUAGE $DB -s $SRC" 44 | codeql database create --threads=$THREADS --language=$LANGUAGE $DB -s $SRC 45 | 46 | echo -e "==> Start Scanning: codeql database analyze --format=$FORMAT --output=$OUTPUT/issues.$FORMAT $DB $QS" 47 | codeql database analyze --threads=$THREADS --format=$FORMAT --output=$OUTPUT/issues.$FORMAT $DB $QS 48 | -------------------------------------------------------------------------------- /scripts/compile-qs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | RED="\033[31m" 4 | YELLOW="\033[33m" 5 | GREEN="\033[32m" 6 | RESET="\033[0m" 7 | 8 | print_green() { 9 | echo -e "${GREEN}${1}${RESET}" 10 | } 11 | 12 | print_green "[+] Start Compiling query suites" 13 | 14 | # get all query suites except Java 15 | ls /root/codeql-home/codeql-repo/*/ql/src/codeql-suites/*.qls | grep -v 'csharp' >> /tmp/list-querysuites 16 | 17 | while IFS="" read -r qs || [ -n "$qs" ] 18 | do 19 | print_green "[+] Compiling query suites: $qs" 20 | codeql query compile --threads=50 --ram=4096 $qs 21 | done < /tmp/list-querysuites 22 | 23 | print_green "[+] Done Compiling query suites ..." -------------------------------------------------------------------------------- /scripts/run.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import sys 5 | import argparse 6 | 7 | SRC = "" 8 | OUTPUT = "" 9 | DOCKER_CMD = "" 10 | LANG = "" 11 | FORMAT = "" 12 | QS = "" 13 | THREADS = "" 14 | ANALYZE_OUTPUT = "beautify-issues.txt" 15 | 16 | def update_docker(): 17 | PULL_CMD = "docker pull j3ssie/codeql-docker:latest" 18 | print(f"Update the latest docker: {PULL_CMD}") 19 | os.system(PULL_CMD) 20 | 21 | def start_analyze(): 22 | print(f"==> Start Analyze:: \033[1;32m{DOCKER_CMD}\033[0m") 23 | 24 | os.system(DOCKER_CMD) 25 | # proc = subprocess.Popen([DOCKER_CMD], shell=True, stdin=None, stdout=None, stderr=None, close_fds=True) 26 | # print("Start docker with process ID: {0}".format(proc.pid)) 27 | # return proc.pid 28 | 29 | def parse_input(args): 30 | global SRC, OUTPUT, DOCKER_CMD, LANG, FORMAT, QS, ANALYZE_OUTPUT, THREADS 31 | SRC = args.src 32 | if not os.path.isdir(SRC): 33 | print(f"[-] Source code folder not exist: {SRC}") 34 | os.exit(-1) 35 | 36 | LANG = args.lang 37 | FORMAT = args.format 38 | THREADS = args.threads 39 | 40 | OUTPUT = os.path.abspath(args.output) 41 | if not os.path.isdir(OUTPUT): 42 | print(f"[-] Output folder not exist, create new one: {OUTPUT}") 43 | os.makedirs(OUTPUT) 44 | 45 | if not args.query: 46 | QS = f"{LANG}-security-and-quality.qls" 47 | 48 | DOCKER_CMD = f'''docker run --rm --name codeql-docker -v "{SRC}:/opt/src" -v "{OUTPUT}:/opt/results" -e "LANGUAGE={LANG}" -e "FORMAT={FORMAT}" -e "QS={QS}" -e "THREADS={THREADS}" j3ssie/codeql-docker:latest''' 49 | 50 | 51 | def main(): 52 | parser = argparse.ArgumentParser(description="Script to start CodeQL Analyze") 53 | parser.add_argument('--format', nargs='?', type=str, default="sarif-latest", help='Format of output') 54 | parser.add_argument('-o', '--output', nargs='?', type=str, default="results", help='Output folder to store result') 55 | parser.add_argument('-s', '--src', nargs='?', type=str, required=True, help='Folder of source code to analyze') 56 | parser.add_argument('-l', '--lang', nargs='?', type=str, required=True, help='Language to run analyze') 57 | parser.add_argument('-q', '--query', nargs='?', type=str, help='Query Suite to run analyze') 58 | parser.add_argument('-j', '--threads', nargs='?', default=20, type=int, help='Number of threads to evaluate queries.') 59 | 60 | args = parser.parse_args() 61 | if len(sys.argv) == 1: 62 | sys.exit(0) 63 | 64 | parse_input(args) 65 | update_docker() 66 | start_analyze() 67 | print(f"[+] Detail Issue Store at: \033[1;32m{OUTPUT}/issues.{FORMAT}\033[0m") 68 | 69 | if __name__ == '__main__': 70 | main() --------------------------------------------------------------------------------