kibana/scripts/codeql/quick_check.sh
Kibana Machine 9a7dafcf38
[8.x] [CodeQL] Local run script (#194272) (#197989)
# Backport

This will backport the following commits from `main` to `8.x`:
- [[CodeQL] Local run script
(#194272)](https://github.com/elastic/kibana/pull/194272)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Elena
Shostak","email":"165678770+elena-shostak@users.noreply.github.com"},"sourceCommit":{"committedDate":"2024-10-28T12:40:27Z","message":"[CodeQL]
Local run script (#194272)\n\n## Summary\r\n\r\nThis PR introduces a
script that allows developers to run CodeQL\r\nanalysis locally. It uses
a Docker container with prebuilt CodeQL\r\nqueries to facilitate easy
setup and execution.\r\nThe script has the following key steps:\r\n-
Creating a CodeQL database from the source code. The database
is\r\nessentially a representation of the codebase that CodeQL uses to
analyze\r\nfor potential issues.\r\n- Running the analysis on the
created database,\r\n`javascript-security-and-quality` suit is
used.\r\n\r\n### Usage\r\n```\r\nbash scripts/codeql/quick_check.sh -s
path/to/your-source-dir\r\n```\r\nFor example\r\n```\r\nbash
scripts/codeql/quick_check.sh -s
./x-pack/plugins/security_solution/public/common/components/ml/conditional_links\r\n```\r\n\r\nThe
`-s` option allows you to specify the path to the source
code\r\ndirectory that you wish to analyze.\r\n\r\n### Why custom Docker
file?\r\nChecked the ability to use MSFT image for local
run\r\nhttps://github.com/microsoft/codeql-container. Turned out it has
several\r\nproblems:\r\n1. The published one has an error with
[execute\r\npermissions](https://github.com/microsoft/codeql-container/issues/53).\r\n2.
Container has outdated nodejs version, so it didn't parse our
syntax\r\n(like `??`) and failed.\r\n3. The technique used in the
repository to download the CodeQL binaries\r\nand precompile the queries
is outdated in the sense that GitHub now\r\noffers pre-compiled queries
you can just download. Follow
this\r\n[comment](https://github.com/microsoft/codeql-container/issues/53#issuecomment-1875879512).\r\n\r\nTaking
this into consideration I have created a lightweight docker
image\r\nwithout extraneous dependencies for go/.net/java.\r\n\r\n##
Context and interdependencies issues\r\nThere are issues sometimes when
analyze run returns no results,\r\nparticularly when analyzing a single
folder.\r\nIt might be due to the missing context for the data flow
graph CodeQL\r\ngenerates or context for interdependencies. This is
actually a trade off\r\nof running it locally for a subset of source
directories. We need to\r\nexplicitly state that in the documentation
and advise to expand the\r\nscope of source code directories involved
for local scan.\r\n\r\nDocumentation for triaging issues will be updated
separately.\r\n\r\n__Closes:
https://github.com/elastic/kibana/issues/195740__","sha":"9dd4205639ed16f9086a7c5d70e077b6db21d73b","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["Team:Security","enhancement","release_note:skip","v9.0.0","backport:prev-minor"],"title":"[CodeQL]
Local run
script","number":194272,"url":"https://github.com/elastic/kibana/pull/194272","mergeCommit":{"message":"[CodeQL]
Local run script (#194272)\n\n## Summary\r\n\r\nThis PR introduces a
script that allows developers to run CodeQL\r\nanalysis locally. It uses
a Docker container with prebuilt CodeQL\r\nqueries to facilitate easy
setup and execution.\r\nThe script has the following key steps:\r\n-
Creating a CodeQL database from the source code. The database
is\r\nessentially a representation of the codebase that CodeQL uses to
analyze\r\nfor potential issues.\r\n- Running the analysis on the
created database,\r\n`javascript-security-and-quality` suit is
used.\r\n\r\n### Usage\r\n```\r\nbash scripts/codeql/quick_check.sh -s
path/to/your-source-dir\r\n```\r\nFor example\r\n```\r\nbash
scripts/codeql/quick_check.sh -s
./x-pack/plugins/security_solution/public/common/components/ml/conditional_links\r\n```\r\n\r\nThe
`-s` option allows you to specify the path to the source
code\r\ndirectory that you wish to analyze.\r\n\r\n### Why custom Docker
file?\r\nChecked the ability to use MSFT image for local
run\r\nhttps://github.com/microsoft/codeql-container. Turned out it has
several\r\nproblems:\r\n1. The published one has an error with
[execute\r\npermissions](https://github.com/microsoft/codeql-container/issues/53).\r\n2.
Container has outdated nodejs version, so it didn't parse our
syntax\r\n(like `??`) and failed.\r\n3. The technique used in the
repository to download the CodeQL binaries\r\nand precompile the queries
is outdated in the sense that GitHub now\r\noffers pre-compiled queries
you can just download. Follow
this\r\n[comment](https://github.com/microsoft/codeql-container/issues/53#issuecomment-1875879512).\r\n\r\nTaking
this into consideration I have created a lightweight docker
image\r\nwithout extraneous dependencies for go/.net/java.\r\n\r\n##
Context and interdependencies issues\r\nThere are issues sometimes when
analyze run returns no results,\r\nparticularly when analyzing a single
folder.\r\nIt might be due to the missing context for the data flow
graph CodeQL\r\ngenerates or context for interdependencies. This is
actually a trade off\r\nof running it locally for a subset of source
directories. We need to\r\nexplicitly state that in the documentation
and advise to expand the\r\nscope of source code directories involved
for local scan.\r\n\r\nDocumentation for triaging issues will be updated
separately.\r\n\r\n__Closes:
https://github.com/elastic/kibana/issues/195740__","sha":"9dd4205639ed16f9086a7c5d70e077b6db21d73b"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/194272","number":194272,"mergeCommit":{"message":"[CodeQL]
Local run script (#194272)\n\n## Summary\r\n\r\nThis PR introduces a
script that allows developers to run CodeQL\r\nanalysis locally. It uses
a Docker container with prebuilt CodeQL\r\nqueries to facilitate easy
setup and execution.\r\nThe script has the following key steps:\r\n-
Creating a CodeQL database from the source code. The database
is\r\nessentially a representation of the codebase that CodeQL uses to
analyze\r\nfor potential issues.\r\n- Running the analysis on the
created database,\r\n`javascript-security-and-quality` suit is
used.\r\n\r\n### Usage\r\n```\r\nbash scripts/codeql/quick_check.sh -s
path/to/your-source-dir\r\n```\r\nFor example\r\n```\r\nbash
scripts/codeql/quick_check.sh -s
./x-pack/plugins/security_solution/public/common/components/ml/conditional_links\r\n```\r\n\r\nThe
`-s` option allows you to specify the path to the source
code\r\ndirectory that you wish to analyze.\r\n\r\n### Why custom Docker
file?\r\nChecked the ability to use MSFT image for local
run\r\nhttps://github.com/microsoft/codeql-container. Turned out it has
several\r\nproblems:\r\n1. The published one has an error with
[execute\r\npermissions](https://github.com/microsoft/codeql-container/issues/53).\r\n2.
Container has outdated nodejs version, so it didn't parse our
syntax\r\n(like `??`) and failed.\r\n3. The technique used in the
repository to download the CodeQL binaries\r\nand precompile the queries
is outdated in the sense that GitHub now\r\noffers pre-compiled queries
you can just download. Follow
this\r\n[comment](https://github.com/microsoft/codeql-container/issues/53#issuecomment-1875879512).\r\n\r\nTaking
this into consideration I have created a lightweight docker
image\r\nwithout extraneous dependencies for go/.net/java.\r\n\r\n##
Context and interdependencies issues\r\nThere are issues sometimes when
analyze run returns no results,\r\nparticularly when analyzing a single
folder.\r\nIt might be due to the missing context for the data flow
graph CodeQL\r\ngenerates or context for interdependencies. This is
actually a trade off\r\nof running it locally for a subset of source
directories. We need to\r\nexplicitly state that in the documentation
and advise to expand the\r\nscope of source code directories involved
for local scan.\r\n\r\nDocumentation for triaging issues will be updated
separately.\r\n\r\n__Closes:
https://github.com/elastic/kibana/issues/195740__","sha":"9dd4205639ed16f9086a7c5d70e077b6db21d73b"}}]}]
BACKPORT-->

Co-authored-by: Elena Shostak <165678770+elena-shostak@users.noreply.github.com>
2024-10-28 09:23:36 -05:00

126 lines
4.3 KiB
Bash

#!/bin/bash
LANGUAGE="javascript"
CODEQL_DIR=".codeql"
DATABASE_PATH="$CODEQL_DIR/database"
QUERY_OUTPUT="$DATABASE_PATH/results.sarif"
OUTPUT_FORMAT="sarif-latest"
DOCKER_IMAGE="codeql-env"
BASE_DIR="$(cd "$(dirname "$0")"; pwd)"
# Colors
bold=$(tput bold)
reset=$(tput sgr0)
red=$(tput setaf 1)
green=$(tput setaf 2)
blue=$(tput setaf 4)
yellow=$(tput setaf 3)
while getopts ":s:r:" opt; do
case $opt in
s) SRC_DIR="$OPTARG" ;;
r) CODEQL_DIR="$OPTARG"; DATABASE_PATH="$CODEQL_DIR/database"; QUERY_OUTPUT="$DATABASE_PATH/results.sarif" ;;
\?) echo "Invalid option -$OPTARG" >&2; exit 1 ;;
:) echo "Option -$OPTARG requires an argument." >&2; exit 1 ;;
esac
done
if [ -z "$SRC_DIR" ]; then
echo "Usage: $0 -s <source_dir> [-r <results_dir>]"
exit 1
fi
mkdir -p "$CODEQL_DIR"
# Check the architecture
ARCH=$(uname -m)
PLATFORM_FLAG=""
# CodeQL CLI binary does not support arm64 architecture, setting the platform to linux/amd64
if [[ "$ARCH" == "arm64" ]]; then
PLATFORM_FLAG="--platform linux/amd64"
fi
if [[ "$(docker images -q $DOCKER_IMAGE 2> /dev/null)" == "" ]]; then
echo "Docker image $DOCKER_IMAGE not found. Building locally..."
docker build $PLATFORM_FLAG -t "$DOCKER_IMAGE" -f "$BASE_DIR/codeql.dockerfile" "$BASE_DIR"
if [ $? -ne 0 ]; then
echo "${red}Docker image build failed.${reset}"
exit 1
fi
fi
cleanup_database() {
echo "Deleting contents of $CODEQL_DIR."
rm -rf "$CODEQL_DIR"/*
}
SRC_DIR="$(cd "$(dirname "$SRC_DIR")"; pwd)/$(basename "$SRC_DIR")"
CODEQL_DIR="$(cd "$(dirname "$CODEQL_DIR")"; pwd)/$(basename "$CODEQL_DIR")"
DATABASE_PATH="$(cd "$(dirname "$DATABASE_PATH")"; pwd)/$(basename "$DATABASE_PATH")"
# Step 1: Run the Docker container to create a CodeQL database from the source code.
echo "Creating a CodeQL database from the source code: $SRC_DIR"
docker run $PLATFORM_FLAG --rm -v "$SRC_DIR":/workspace/source-code \
-v "${DATABASE_PATH}":/workspace/shared $DOCKER_IMAGE \
"codeql database create /workspace/shared/codeql-db --language=javascript --source-root=/workspace/source-code --overwrite"
if [ $? -ne 0 ]; then
echo "CodeQL database creation failed."
cleanup_database
exit 1
fi
echo "Analyzing a CodeQL database: $DATABASE_PATH"
# Step 2: Run the Docker container to analyze the CodeQL database.
docker run $PLATFORM_FLAG --rm -v "${DATABASE_PATH}":/workspace/shared $DOCKER_IMAGE \
"codeql database analyze --format=${OUTPUT_FORMAT} --output=/workspace/shared/results.sarif /workspace/shared/codeql-db javascript-security-and-quality.qls"
if [ $? -ne 0 ]; then
echo "CodeQL database analysis failed."
cleanup_database
exit 1
fi
# Step 3: Print summary of SARIF results
echo "Analysis complete. Results saved to $QUERY_OUTPUT"
if command -v jq &> /dev/null; then
vulnerabilities=$(jq -r '.runs[] | select(.results | length > 0)' "$QUERY_OUTPUT")
if [[ -z "$vulnerabilities" ]]; then
echo "${blue}${bold}No vulnerabilities found in the SARIF results.${reset}"
else
echo "${yellow}${bold}Summary of SARIF results:${reset}"
jq -r '
.runs[] |
.results[] as $result |
.tool.driver.rules[] as $rule |
select($rule.id == $result.ruleId) |
"Rule: \($result.ruleId)\nMessage: \($result.message.text)\nFile: \($result.locations[].physicalLocation.artifactLocation.uri)\nLine: \($result.locations[].physicalLocation.region.startLine)\nSecurity Severity: \($rule.properties."security-severity" // "N/A")\n"' "$QUERY_OUTPUT" |
while IFS= read -r line; do
case "$line" in
Rule:*)
echo "${red}${bold}$line${reset}"
;;
Message:*)
echo "${green}$line${reset}"
;;
File:*)
echo "${blue}$line${reset}"
;;
Line:*)
echo "${yellow}$line${reset}"
;;
Security\ Severity:*)
echo "${yellow}$line${reset}"
;;
*)
echo "$line"
;;
esac
done
fi
else
echo "${red}${bold}Please install jq to display a summary of the SARIF results.${reset}"
echo "${bold}You can view the full results in the SARIF file using a SARIF viewer.${reset}"
fi