Merge branch 'master' into no-ql-pack
This commit is contained in:
commit
9fa2bfe135
12 changed files with 155 additions and 56 deletions
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
|
|
@ -1,7 +1,7 @@
|
||||||
### Merge / deployment checklist
|
### Merge / deployment checklist
|
||||||
|
|
||||||
- Run test builds as necessary. Can be on this repository or elsewhere as needed in order to test the change - please include links to tests in otehr repos!
|
- Run test builds as necessary. Can be on this repository or elsewhere as needed in order to test the change - please include links to tests in other repos!
|
||||||
- [ ] CodeQL using init/finish actions
|
- [ ] CodeQL using init/finish actions
|
||||||
- [ ] 3rd party tool using upload action
|
- [ ] 3rd party tool using upload action
|
||||||
- [ ] Confirm this change is backwards compatible with existing workflows.
|
- [ ] Confirm this change is backwards compatible with existing workflows.
|
||||||
- [ ] Confirm the [readme](https://github.com/github/codeql-action/blob/master/README.md) has been updated if necessary.
|
- [ ] Confirm the [readme](https://github.com/github/codeql-action/blob/master/README.md) has been updated if necessary.
|
||||||
|
|
|
||||||
98
README.md
98
README.md
|
|
@ -1,9 +1,8 @@
|
||||||
# CodeQL Action
|
# CodeQL Action
|
||||||
This action runs GitHub's industry-leading static analysis engine, CodeQL, against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/semmle/ql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
|
|
||||||
|
This action runs GitHub's industry-leading static analysis engine, CodeQL, against a repository's source code to find security vulnerabilities. It then automatically uploads the results to GitHub so they can be displayed in the repository's security tab. CodeQL runs an extensible set of [queries](https://github.com/semmle/ql), which have been developed by the community and the [GitHub Security Lab](https://securitylab.github.com/) to find common vulnerabilities in your code.
|
||||||
[Sign up for the Advanced Security beta](https://github.com/features/security/advanced-security/signup)
|
|
||||||
|
## Usage
|
||||||
## Usage
|
|
||||||
|
|
||||||
To get code scanning results from CodeQL analysis on your repo you can use the following workflow as a template:
|
To get code scanning results from CodeQL analysis on your repo you can use the following workflow as a template:
|
||||||
|
|
||||||
|
|
@ -22,39 +21,38 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
|
|
||||||
|
|
||||||
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
|
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@v1
|
||||||
# Override language selection by uncommenting this and choosing your languages
|
# Override language selection by uncommenting this and choosing your languages
|
||||||
# with:
|
# with:
|
||||||
# languages: go, javascript, csharp, python, cpp, java
|
# languages: go, javascript, csharp, python, cpp, java
|
||||||
|
|
||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below).
|
# If this step fails, then you should remove it and run the build manually (see below).
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v1
|
uses: github/codeql-action/autobuild@v1
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
|
|
||||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
# ✏️ If the Autobuild fails above, remove it and uncomment the following
|
||||||
# and modify them (or add more) to build your code if your project
|
# three lines and modify them (or add more) to build your code if your
|
||||||
# uses a compiled language
|
# project uses a compiled language
|
||||||
|
|
||||||
#- run: |
|
#- run: |
|
||||||
# make bootstrap
|
# make bootstrap
|
||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v1
|
||||||
```
|
```
|
||||||
|
|
||||||
If you prefer to integrate this within an existing CI workflow, it should end up looking something like this:
|
If you prefer to integrate this within an existing CI workflow, it should end up looking something like this:
|
||||||
|
|
@ -73,19 +71,23 @@ If you prefer to integrate this within an existing CI workflow, it should end up
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v1
|
||||||
```
|
```
|
||||||
### Actions triggers
|
|
||||||
The CodeQL action should be run on `push` events, and on a `schedule`. `Push` events allow us to do detailed analysis of the delta in a pull request, while the `schedule` event ensures that GitHub regularly scans the repository for the latest vulnerabilities, even if the repository becomes inactive. This action does not support the `pull_request` event.
|
|
||||||
|
|
||||||
### Configuration
|
### Actions triggers
|
||||||
|
|
||||||
|
The CodeQL action should be run on `push` events, and on a `schedule`. `Push` events allow us to do a detailed analysis of the delta in a pull request, while the `schedule` event ensures that GitHub regularly scans the repository for the latest vulnerabilities, even if the repository becomes inactive. This action does not support the `pull_request` event.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
You may optionally specify additional queries for CodeQL to execute by using a config file. The queries must belong to a [QL pack](https://help.semmle.com/codeql/codeql-cli/reference/qlpack-overview.html) and can be in your repository or any public repository. You can choose a single .ql file, a folder containing multiple .ql files, a .qls [query suite](https://help.semmle.com/codeql/codeql-cli/procedures/query-suites.html) file, or any combination of the above. To use queries from other repositories use the same syntax as when [using an action](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses).
|
You may optionally specify additional queries for CodeQL to execute by using a config file. The queries must belong to a [QL pack](https://help.semmle.com/codeql/codeql-cli/reference/qlpack-overview.html) and can be in your repository or any public repository. You can choose a single .ql file, a folder containing multiple .ql files, a .qls [query suite](https://help.semmle.com/codeql/codeql-cli/procedures/query-suites.html) file, or any combination of the above. To use queries from other repositories use the same syntax as when [using an action](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses).
|
||||||
|
|
||||||
You can choose to ignore some files or folders from the analysis, or include additional files/folders for analysis. This *only* works for Javascript and Python analysis.
|
You can choose to ignore some files or folders from the analysis, or include additional files/folders for analysis. This *only* works for Javascript and Python analysis.
|
||||||
Identifying potential files for extraction:
|
Identifying potential files for extraction:
|
||||||
- Scans each folder that's defined as `paths` in turn, traversing subfolders and looking for relevant files.
|
|
||||||
|
- Scans each folder that's defined as `paths` in turn, traversing subfolders, and looking for relevant files.
|
||||||
- If it finds a subfolder that's defined as `paths-ignore`, stop traversing.
|
- If it finds a subfolder that's defined as `paths-ignore`, stop traversing.
|
||||||
- If a file or folder is both in `paths` and `paths-ignore`, the `paths-ignore` is ignored.
|
- If a file or folder is both in `paths` and `paths-ignore`, the `paths-ignore` is ignored.
|
||||||
|
|
||||||
Use the config-file parameter of the init action to enable the configuration file. For example:
|
Use the `config-file` parameter of the init action to enable the configuration file. For example:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- uses: github/codeql-action/init@v1
|
- uses: github/codeql-action/init@v1
|
||||||
|
|
@ -103,8 +105,8 @@ queries:
|
||||||
uses: ./my-queries
|
uses: ./my-queries
|
||||||
- name: External Javascript QL pack (Runs a QL pack located in an external repo)
|
- name: External Javascript QL pack (Runs a QL pack located in an external repo)
|
||||||
uses: /Semmle/ql/javascript/ql/src/Electron@master
|
uses: /Semmle/ql/javascript/ql/src/Electron@master
|
||||||
- name: External query (Runs a single query located in an external QL pack)
|
- name: External query (Runs a single query located in an external QL pack)
|
||||||
uses: Semmle/ql/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql@master
|
uses: Semmle/ql/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql@master
|
||||||
- name: Select query suite (Runs a query suites)
|
- name: Select query suite (Runs a query suites)
|
||||||
uses: ./codeql-querypacks/complex-python-querypack/rootAndBar.qls
|
uses: ./codeql-querypacks/complex-python-querypack/rootAndBar.qls
|
||||||
|
|
||||||
|
|
@ -112,8 +114,8 @@ paths:
|
||||||
- src/util.ts
|
- src/util.ts
|
||||||
|
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- src
|
- src
|
||||||
- lib
|
- lib
|
||||||
```
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
@ -128,6 +130,7 @@ Try passing
|
||||||
env:
|
env:
|
||||||
GOFLAGS: "-mod=vendor"
|
GOFLAGS: "-mod=vendor"
|
||||||
```
|
```
|
||||||
|
|
||||||
to `github/codeql-action/analyze`.
|
to `github/codeql-action/analyze`.
|
||||||
|
|
||||||
### If you do not use a vendor directory
|
### If you do not use a vendor directory
|
||||||
|
|
@ -136,21 +139,24 @@ Dependencies on public repositories should just work. If you have dependencies o
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
steps:
|
steps:
|
||||||
- name: Configure git private repo access
|
- name: Configure git private repo access
|
||||||
env:
|
env:
|
||||||
TOKEN: ${{ secrets.GITHUB_PAT }}
|
TOKEN: ${{ secrets.GITHUB_PAT }}
|
||||||
run: |
|
run: |
|
||||||
git config --global url."https://${TOKEN}@github.com/foo/bar".insteadOf "https://github.com/foo/bar"
|
git config --global url."https://${TOKEN}@github.com/foo/bar".insteadOf "https://github.com/foo/bar"
|
||||||
git config --global url."https://${TOKEN}@github.com/foo/baz".insteadOf "https://github.com/foo/baz"
|
git config --global url."https://${TOKEN}@github.com/foo/baz".insteadOf "https://github.com/foo/baz"
|
||||||
```
|
```
|
||||||
before any codeql actions. A similar thing can also be done with a SSH key or deploy key.
|
|
||||||
|
before any codeql actions. A similar thing can also be done with an SSH key or deploy key.
|
||||||
|
|
||||||
### C# using dotnet version 2 on linux
|
### C# using dotnet version 2 on linux
|
||||||
|
|
||||||
This currently requires invoking `dotnet` with the `/p:UseSharedCompilation=false` flag. For example:
|
This currently requires invoking `dotnet` with the `/p:UseSharedCompilation=false` flag. For example:
|
||||||
```
|
|
||||||
|
```shell
|
||||||
dotnet build /p:UseSharedCompilation=false
|
dotnet build /p:UseSharedCompilation=false
|
||||||
```
|
```
|
||||||
|
|
||||||
Version 3 does not require the additional flag.
|
Version 3 does not require the additional flag.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
|
||||||
2
lib/config-utils.js
generated
2
lib/config-utils.js
generated
|
|
@ -84,7 +84,7 @@ function initConfig() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const pathsIgnore = parsedYAML['paths-ignore'];
|
const pathsIgnore = parsedYAML['paths-ignore'];
|
||||||
if (pathsIgnore && queries instanceof Array) {
|
if (pathsIgnore && pathsIgnore instanceof Array) {
|
||||||
pathsIgnore.forEach(path => {
|
pathsIgnore.forEach(path => {
|
||||||
if (typeof path === "string") {
|
if (typeof path === "string") {
|
||||||
config.pathsIgnore.push(path);
|
config.pathsIgnore.push(path);
|
||||||
|
|
|
||||||
4
lib/upload-lib.js
generated
4
lib/upload-lib.js
generated
|
|
@ -100,6 +100,7 @@ async function uploadFiles(sarifFiles) {
|
||||||
if (matrix === "null" || matrix === "") {
|
if (matrix === "null" || matrix === "") {
|
||||||
matrix = undefined;
|
matrix = undefined;
|
||||||
}
|
}
|
||||||
|
const toolNames = util.getToolNames(sarifPayload);
|
||||||
const payload = JSON.stringify({
|
const payload = JSON.stringify({
|
||||||
"commit_oid": commitOid,
|
"commit_oid": commitOid,
|
||||||
"ref": ref,
|
"ref": ref,
|
||||||
|
|
@ -108,7 +109,8 @@ async function uploadFiles(sarifFiles) {
|
||||||
"workflow_run_id": workflowRunID,
|
"workflow_run_id": workflowRunID,
|
||||||
"checkout_uri": checkoutURI,
|
"checkout_uri": checkoutURI,
|
||||||
"environment": matrix,
|
"environment": matrix,
|
||||||
"started_at": startedAt
|
"started_at": startedAt,
|
||||||
|
"tool_names": toolNames,
|
||||||
});
|
});
|
||||||
core.info('Uploading results');
|
core.info('Uploading results');
|
||||||
const githubToken = core.getInput('token');
|
const githubToken = core.getInput('token');
|
||||||
|
|
|
||||||
18
lib/util.js
generated
18
lib/util.js
generated
|
|
@ -262,3 +262,21 @@ async function reportActionSucceeded(action) {
|
||||||
await sendStatusReport(await createStatusReport(action, 'success'));
|
await sendStatusReport(await createStatusReport(action, 'success'));
|
||||||
}
|
}
|
||||||
exports.reportActionSucceeded = reportActionSucceeded;
|
exports.reportActionSucceeded = reportActionSucceeded;
|
||||||
|
/**
|
||||||
|
* Get the array of all the tool names contained in the given sarif contents.
|
||||||
|
*
|
||||||
|
* Returns an array of unique string tool names.
|
||||||
|
*/
|
||||||
|
function getToolNames(sarifContents) {
|
||||||
|
const sarif = JSON.parse(sarifContents);
|
||||||
|
const toolNames = {};
|
||||||
|
for (const run of sarif.runs || []) {
|
||||||
|
const tool = run.tool || {};
|
||||||
|
const driver = tool.driver || {};
|
||||||
|
if (typeof driver.name === "string" && driver.name.length > 0) {
|
||||||
|
toolNames[driver.name] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Object.keys(toolNames);
|
||||||
|
}
|
||||||
|
exports.getToolNames = getToolNames;
|
||||||
|
|
|
||||||
6
package-lock.json
generated
6
package-lock.json
generated
|
|
@ -15,9 +15,9 @@
|
||||||
"integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ=="
|
"integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ=="
|
||||||
},
|
},
|
||||||
"@actions/http-client": {
|
"@actions/http-client": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz",
|
||||||
"integrity": "sha512-6EzXhqapKKtYr21ZnFQVBYwfrYPKPCivuSkUN/66/BDakkH2EPjUZH8tZ3MgHdI+gQIdcsY0ybbxw9ZEOmJB6g==",
|
"integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tunnel": "0.0.6"
|
"tunnel": "0.0.6"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/core": "^1.0.0",
|
"@actions/core": "^1.0.0",
|
||||||
"@actions/exec": "^1.0.1",
|
"@actions/exec": "^1.0.1",
|
||||||
"@actions/http-client": "^1.0.4",
|
"@actions/http-client": "^1.0.8",
|
||||||
"@actions/io": "^1.0.1",
|
"@actions/io": "^1.0.1",
|
||||||
"@actions/tool-cache": "^1.1.2",
|
"@actions/tool-cache": "^1.1.2",
|
||||||
"@octokit/rest": "^17.1.0",
|
"@octokit/rest": "^17.1.0",
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ function initConfig(): Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
const pathsIgnore = parsedYAML['paths-ignore'];
|
const pathsIgnore = parsedYAML['paths-ignore'];
|
||||||
if (pathsIgnore && queries instanceof Array) {
|
if (pathsIgnore && pathsIgnore instanceof Array) {
|
||||||
pathsIgnore.forEach(path => {
|
pathsIgnore.forEach(path => {
|
||||||
if (typeof path === "string") {
|
if (typeof path === "string") {
|
||||||
config.pathsIgnore.push(path);
|
config.pathsIgnore.push(path);
|
||||||
|
|
|
||||||
41
src/testdata/tool-names.sarif
vendored
Normal file
41
src/testdata/tool-names.sarif
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
||||||
|
"version": "2.1.0",
|
||||||
|
"runs": [
|
||||||
|
{
|
||||||
|
"tool": {
|
||||||
|
"driver": {
|
||||||
|
"name": "CodeQL command-line toolchain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool": {
|
||||||
|
"driver": {
|
||||||
|
"name": "CodeQL command-line toolchain"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool": {
|
||||||
|
"driver": {
|
||||||
|
"name": "ESLint"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool": {
|
||||||
|
"driver": {
|
||||||
|
"name": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tool": {
|
||||||
|
"driver": {
|
||||||
|
"name": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -98,6 +98,8 @@ async function uploadFiles(sarifFiles: string[]) {
|
||||||
matrix = undefined;
|
matrix = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const toolNames = util.getToolNames(sarifPayload);
|
||||||
|
|
||||||
const payload = JSON.stringify({
|
const payload = JSON.stringify({
|
||||||
"commit_oid": commitOid,
|
"commit_oid": commitOid,
|
||||||
"ref": ref,
|
"ref": ref,
|
||||||
|
|
@ -106,7 +108,8 @@ async function uploadFiles(sarifFiles: string[]) {
|
||||||
"workflow_run_id": workflowRunID,
|
"workflow_run_id": workflowRunID,
|
||||||
"checkout_uri": checkoutURI,
|
"checkout_uri": checkoutURI,
|
||||||
"environment": matrix,
|
"environment": matrix,
|
||||||
"started_at": startedAt
|
"started_at": startedAt,
|
||||||
|
"tool_names": toolNames,
|
||||||
});
|
});
|
||||||
|
|
||||||
core.info('Uploading results');
|
core.info('Uploading results');
|
||||||
|
|
|
||||||
9
src/util.test.ts
Normal file
9
src/util.test.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
import * as util from './util';
|
||||||
|
|
||||||
|
test('getToolNames', () => {
|
||||||
|
const input = fs.readFileSync(__dirname + '/testdata/tool-names.sarif', 'utf8')
|
||||||
|
const toolNames = util.getToolNames(input);
|
||||||
|
expect(toolNames).toStrictEqual(["CodeQL command-line toolchain", "ESLint"])
|
||||||
|
})
|
||||||
20
src/util.ts
20
src/util.ts
|
|
@ -293,3 +293,23 @@ export async function reportActionFailed(action: string, cause?: string, excepti
|
||||||
export async function reportActionSucceeded(action: string) {
|
export async function reportActionSucceeded(action: string) {
|
||||||
await sendStatusReport(await createStatusReport(action, 'success'));
|
await sendStatusReport(await createStatusReport(action, 'success'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the array of all the tool names contained in the given sarif contents.
|
||||||
|
*
|
||||||
|
* Returns an array of unique string tool names.
|
||||||
|
*/
|
||||||
|
export function getToolNames(sarifContents: string): string[] {
|
||||||
|
const sarif = JSON.parse(sarifContents);
|
||||||
|
const toolNames = {};
|
||||||
|
|
||||||
|
for (const run of sarif.runs || []) {
|
||||||
|
const tool = run.tool || {};
|
||||||
|
const driver = tool.driver || {};
|
||||||
|
if (typeof driver.name === "string" && driver.name.length > 0) {
|
||||||
|
toolNames[driver.name] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Object.keys(toolNames);
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue