This action will run CodeQL rules on files in $GITHUB_WORKSPACE
and checks for security issues. A markdown report is generated with the results and available in $CODEQL_MD
Here is an action that will run on every pull request, scan all the files and post the result in a comment:
name: CodeQL Security Scan
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
env:
LANGUAGE: javascript
steps:
- uses: actions/checkout@v2
- name: Run CodeQL scan
uses: themenu/codeql-security-report@master
- name: Comment PR
uses: thollander/actions-comment-pull-request@master
with:
message: |
${{ env.CODEQL_MD }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Here is an action that will run on every pull request, scan only the files edited in the PR and post the result in a comment:
name: CodeQL Security Scan
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
env:
LANGUAGE: javascript
steps:
- uses: actions/checkout@v2
- name: Get changed files
id: changed-files
uses: tj-actions/[email protected]
- name: Delete unedited files
id: delete
continue-on-error: true
run: |
for file in ${{ steps.changed-files.outputs.all_changed_and_modified_files }}; do
edited="$edited ! -name ${file##*/}"
done
edited="${edited:1}"
find $GITHUB_WORKSPACE $edited -type f -exec rm -f {} +
ls -R $GITHUB_WORKSPACE
if [[ "$edited" == *".js"* ]]; then
exit 0
fi
exit 1
- name: Run CodeQL scan
if: steps.delete.outcome == 'success'
uses: vedza/codeql-security-report@master
- name: Comment PR
if: steps.delete.outcome == 'success'
uses: thollander/actions-comment-pull-request@main
with:
message: |
${{ env.CODEQL_MD }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
The docker image of this action is based on mcr.microsoft.com/cstsectools/codeql-container. But because of some issue, I had to build my own image vedza/codeql-github-action, which use the same Dockerfile as mcr.microsoft.com/cstsectools/codeql-container.
So when the base image is updated, we will need to update the docker image to use the latest microsoft image.
Our image run our script that scan and generate the markdown report only if no $CODEQL_CLI_ARGS
is passed in env.
So you can still use this image the same way as mcr.microsoft.com/cstsectools/codeql-container to run CodeQL queries if you want.
If you want to skip test on some files or vulnerabilities, you can add path and/or vulnerability id
in a .sastignore
file in the root of your project.
The security report is available in $CODEQL_MD
as markdown.
It contains security issues split by priority, and issues in each priority level are sorted by score.
You can click on the file URL to see the exact piece of code causing the security issue.
Here is an example of what the markdown report look like for NodeGoat:
NodeGoat
Uncontrolled data used in network request
Score: 9.1
Definition: Sending network requests with user-controlled data allows for request forgery attacks.
ID: js/request-forgery
Title | File | Precision |
---|---|---|
The URL of this request depends on a user-provided value | example/NodeGoat/app/routes/research.js | Medium |
Log injection
Score: 7.8
Definition: Building log entries from user-controlled sources is vulnerable to insertion of forged log entries by a malicious user.
ID: js/log-injection
Title | File | Precision |
---|---|---|
User-provided value flows to log entry | example/NodeGoat/app/routes/session.js | Medium |
Inefficient regular expression
Score: 7.5
Definition: A regular expression that requires exponential time to match certain inputs can be a performance bottleneck, and may be vulnerable to denial-of-service attacks.
ID: js/redos
Title | File | Precision |
---|---|---|
This part of the regular expression may cause exponential backtracking on strings containing many repetitions of '0' | example/NodeGoat/app/routes/profile.js | High |
Polynomial regular expression used on uncontrolled data
Score: 7.5
Definition: A regular expression that can require polynomial time to match may be vulnerable to denial-of-service attacks.
ID: js/polynomial-redos
Title | File | Precision |
---|---|---|
This regular expression that depends on a user-provided value may run slow on strings with many repetitions of '0' | example/NodeGoat/app/routes/profile.js | High |
Uncontrolled data used in path expression
Score: 7.5
Definition: Accessing paths influenced by users can allow an attacker to access unexpected resources.
ID: js/path-injection
Title | File | Precision |
---|---|---|
This path depends on a user-provided value | example/NodeGoat/app/routes/index.js | High |
Code injection
Score: 6.1
Definition: Interpreting unsanitized user input as code allows a malicious user arbitrary code execution.
ID: js/code-injection
Title | File | Precision |
---|---|---|
User-provided value flows to here and is interpreted as code | example/NodeGoat/app/data/allocations-dao.js | High |
User-provided value flows to here and is interpreted as code | example/NodeGoat/app/routes/contributions.js | High |
User-provided value flows to here and is interpreted as code | example/NodeGoat/app/routes/contributions.js | High |
User-provided value flows to here and is interpreted as code | example/NodeGoat/app/routes/contributions.js | High |
Server-side URL redirect
Score: 6.1
Definition: Server-side URL redirection based on unvalidated user input may cause redirection to malicious web sites.
ID: js/server-side-unvalidated-url-redirection
Title | File | Precision |
---|---|---|
Untrusted URL redirection due to user-provided value | example/NodeGoat/app/routes/index.js | High |
DOM text reinterpreted as HTML
Score: 6.1
Definition: Reinterpreting text from the DOM as HTML can lead to a cross-site scripting vulnerability.
ID: js/xss-through-dom
Title | File | Precision |
---|---|---|
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
DOM text is reinterpreted as HTML without escaping meta-characters | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
Unsafe jQuery plugin
Score: 6.1
Definition: A jQuery plugin that unintentionally constructs HTML from some of its options may be unsafe to use for clients.
ID: js/unsafe-jquery-plugin
Title | File | Precision |
---|---|---|
Potential XSS vulnerability in the '$fntooltip' plugin | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
Potential XSS vulnerability in the '$fncollapse' plugin | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
Potential XSS vulnerability in the '$fnscrollspy' plugin | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |
Potential XSS vulnerability in the '$fnscrollspy' plugin | example/NodeGoat/app/assets/vendor/bootstrap/bootstrap.js | High |