Compare commits

...

23 Commits

Author SHA1 Message Date
Arthur Baars
60d35a8ead Make an all-in-one action
A more easy to use action that runs the 'init' step as
a 'pre' script and the 'analyze' step as the 'main' script.
2020-04-30 17:11:27 +02:00
David Verdeguer
1cdde3eb41 Merge pull request #7 from github/disable-default-queries
Disable default queries
2020-04-30 14:54:55 +02:00
David Verdeguer
d2a505de4c Merge branch 'master' into disable-default-queries 2020-04-30 13:12:00 +02:00
Robert
292747618d Merge pull request #8 from github/pr_template_typos
Fix typos / errors in PR template
2020-04-30 10:31:23 +01:00
Robert
1bb13e0ffa Merge branch 'master' into pr_template_typos 2020-04-30 10:24:49 +01:00
David Verdeguer
f16b356044 Merge pull request #4 from github/no-ql-pack
Error on queries with missing/multiple languages
2020-04-30 11:20:20 +02:00
David Verdeguer
9e35ea1ac8 Merge branch 'master' into disable-default-queries 2020-04-30 11:12:28 +02:00
David Verdeguer
9fa2bfe135 Merge branch 'master' into no-ql-pack 2020-04-30 11:08:06 +02:00
David Verdeguer
d60a8550ed Merge pull request #9 from github/dependabot/npm_and_yarn/actions/http-client-1.0.8
Bump @actions/http-client from 1.0.4 to 1.0.8
2020-04-30 10:02:03 +02:00
Justin Hutchings
34db3b0291 Update README.md 2020-04-29 14:09:20 -07:00
Kevin Sawicki
bbc0dc88fb Merge pull request #2 from github/send-tool-names
Send tool names to upload endpoint
2020-04-29 12:22:18 -07:00
dependabot[bot]
0cf8450c24 Bump @actions/http-client from 1.0.4 to 1.0.8
Bumps [@actions/http-client](https://github.com/actions/http-client) from 1.0.4 to 1.0.8.
- [Release notes](https://github.com/actions/http-client/releases)
- [Changelog](https://github.com/actions/http-client/blob/master/RELEASES.md)
- [Commits](https://github.com/actions/http-client/commits)

Signed-off-by: dependabot[bot] <support@github.com>
2020-04-29 18:03:56 +00:00
Robert
20a0628ed7 Fix typos / errors in PR template 2020-04-29 16:45:47 +01:00
Kevin Sawicki
62f756fc9d Fix other typo 2020-04-29 08:10:28 -07:00
Kevin Sawicki
0916a68508 Merge branch 'master' into send-tool-names 2020-04-29 08:10:14 -07:00
Kevin Sawicki
6f11b5d213 Add initial util test 2020-04-29 08:04:46 -07:00
Robert
606ff659a8 Merge pull request #3 from XhmikosR/patch-1
Update README.md
2020-04-29 13:39:02 +01:00
Robert
ac6822fc14 Merge branch 'master' into patch-1 2020-04-29 13:36:23 +01:00
Arthur Baars
72f1ed0be5 Merge pull request #5 from github/aibaars-patch-1
Fix parsing of path-ignore field
2020-04-29 13:30:56 +02:00
Arthur Baars
e7afa7cb98 Fix parsing of path-ignore field 2020-04-29 13:23:32 +02:00
XhmikosR
a983d385c7 Update README.md
* indentation fixes
* fix `JavaScript` capitalization
* minor grammar tweaks
2020-04-29 13:09:42 +03:00
David Verdeguer
b419ff6d7b Error on queries with missing/multiple languages 2020-04-29 11:43:39 +02:00
Kevin Sawicki
2789712b42 Send tool names as parameter to upload endpoint 2020-04-28 11:29:10 -07:00
15 changed files with 192 additions and 61 deletions

View File

@@ -1,7 +1,7 @@
### 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!
- [ ] CodeQL using init/finish actions
- 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/analyze actions
- [ ] 3rd party tool using upload action
- [ ] 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.

View File

@@ -1,9 +1,8 @@
# 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.
[Sign up for the Advanced Security beta](https://github.com/features/security/advanced-security/signup)
## Usage
# 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.
## Usage
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:
fail-fast: false
# CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, 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).
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# 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).
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
# ✏️ If the Autobuild fails above, remove it and uncomment the following
# three lines and modify them (or add more) to build your code if your
# project uses a compiled language
#- run: |
# make bootstrap
# make release
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
- name: Perform CodeQL Analysis
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:
@@ -73,21 +71,25 @@ If you prefer to integrate this within an existing CI workflow, it should end up
- name: Perform CodeQL Analysis
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 can disable the default queries using `disable-default-queries: true`.
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:
- 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 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
- uses: github/codeql-action/init@v1
@@ -107,8 +109,8 @@ queries:
uses: ./my-queries
- name: External Javascript QL pack (Runs a QL pack located in an external repo)
uses: /Semmle/ql/javascript/ql/src/Electron@master
- name: External query (Runs a single query located in an external QL pack)
uses: Semmle/ql/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql@master
- name: External query (Runs a single query located in an external QL pack)
uses: Semmle/ql/javascript/ql/src/AngularJS/DeadAngularJSEventListener.ql@master
- name: Select query suite (Runs a query suites)
uses: ./codeql-querypacks/complex-python-querypack/rootAndBar.qls
@@ -116,8 +118,8 @@ paths:
- src/util.ts
paths-ignore:
- src
- lib
- src
- lib
```
## Troubleshooting
@@ -132,6 +134,7 @@ Try passing
env:
GOFLAGS: "-mod=vendor"
```
to `github/codeql-action/analyze`.
### If you do not use a vendor directory
@@ -140,21 +143,24 @@ Dependencies on public repositories should just work. If you have dependencies o
```yaml
steps:
- name: Configure git private repo access
env:
TOKEN: ${{ secrets.GITHUB_PAT }}
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/baz".insteadOf "https://github.com/foo/baz"
- name: Configure git private repo access
env:
TOKEN: ${{ secrets.GITHUB_PAT }}
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/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
This currently requires invoking `dotnet` with the `/p:UseSharedCompilation=false` flag. For example:
```
```shell
dotnet build /p:UseSharedCompilation=false
```
Version 3 does not require the additional flag.
## License

32
action.yml Normal file
View File

@@ -0,0 +1,32 @@
name: 'CodeQL'
description: 'CodeQL analysis'
author: 'GitHub'
inputs:
tools:
description: URL of CodeQL tools
required: false
default: https://github.com/github/codeql-action/releases/download/codeql-bundle-20200427/codeql-bundle.tar.gz
languages:
description: The languages to be analysed
required: false
token:
default: ${{ github.token }}
config-file:
description: Path of the config file to use
required: false
check_name:
description: The name of the check run to add text to.
output:
description: The path of the directory in which to save the SARIF results
required: false
default: '../results'
upload:
description: Upload the SARIF file
required: false
default: true
matrix:
default: ${{ toJson(matrix) }}
runs:
using: 'node12'
pre: './lib/setup-tracer.js'
main: './lib/finalize-db.js'

2
lib/config-utils.js generated
View File

@@ -88,7 +88,7 @@ function initConfig() {
});
}
const pathsIgnore = parsedYAML['paths-ignore'];
if (pathsIgnore && queries instanceof Array) {
if (pathsIgnore && pathsIgnore instanceof Array) {
pathsIgnore.forEach(path => {
if (typeof path === "string") {
config.pathsIgnore.push(path);

4
lib/finalize-db.js generated
View File

@@ -73,12 +73,12 @@ async function resolveQueryLanguages(codeqlCmd, config) {
const noDeclaredLanguage = resolveQueriesOutputObject.noDeclaredLanguage;
const noDeclaredLanguageQueries = Object.keys(noDeclaredLanguage);
if (noDeclaredLanguageQueries.length !== 0) {
core.warning('Some queries do not declare a language:\n' + noDeclaredLanguageQueries.join('\n'));
throw new Error('Some queries do not declare a language, their qlpack.yml file is missing or is invalid');
}
const multipleDeclaredLanguages = resolveQueriesOutputObject.multipleDeclaredLanguages;
const multipleDeclaredLanguagesQueries = Object.keys(multipleDeclaredLanguages);
if (multipleDeclaredLanguagesQueries.length !== 0) {
core.warning('Some queries declare multiple languages:\n' + multipleDeclaredLanguagesQueries.join('\n'));
throw new Error('Some queries declare multiple languages, their qlpack.yml file is missing or is invalid');
}
}
return res;

4
lib/upload-lib.js generated
View File

@@ -100,6 +100,7 @@ async function uploadFiles(sarifFiles) {
if (matrix === "null" || matrix === "") {
matrix = undefined;
}
const toolNames = util.getToolNames(sarifPayload);
const payload = JSON.stringify({
"commit_oid": commitOid,
"ref": ref,
@@ -108,7 +109,8 @@ async function uploadFiles(sarifFiles) {
"workflow_run_id": workflowRunID,
"checkout_uri": checkoutURI,
"environment": matrix,
"started_at": startedAt
"started_at": startedAt,
"tool_names": toolNames,
});
core.info('Uploading results');
const githubToken = core.getInput('token');

18
lib/util.js generated
View File

@@ -262,3 +262,21 @@ async function reportActionSucceeded(action) {
await sendStatusReport(await createStatusReport(action, 'success'));
}
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
View File

@@ -15,9 +15,9 @@
"integrity": "sha512-nvFkxwiicvpzNiCBF4wFBDfnBvi7xp/as7LE1hBxBxKG2L29+gkIPBiLKMVORL+Hg3JNf07AKRfl0V5djoypjQ=="
},
"@actions/http-client": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.4.tgz",
"integrity": "sha512-6EzXhqapKKtYr21ZnFQVBYwfrYPKPCivuSkUN/66/BDakkH2EPjUZH8tZ3MgHdI+gQIdcsY0ybbxw9ZEOmJB6g==",
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz",
"integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==",
"requires": {
"tunnel": "0.0.6"
},

View File

@@ -12,7 +12,7 @@
"dependencies": {
"@actions/core": "^1.0.0",
"@actions/exec": "^1.0.1",
"@actions/http-client": "^1.0.4",
"@actions/http-client": "^1.0.8",
"@actions/io": "^1.0.1",
"@actions/tool-cache": "^1.1.2",
"@octokit/rest": "^17.1.0",

View File

@@ -96,7 +96,7 @@ function initConfig(): Config {
}
const pathsIgnore = parsedYAML['paths-ignore'];
if (pathsIgnore && queries instanceof Array) {
if (pathsIgnore && pathsIgnore instanceof Array) {
pathsIgnore.forEach(path => {
if (typeof path === "string") {
config.pathsIgnore.push(path);

View File

@@ -82,13 +82,13 @@ async function resolveQueryLanguages(codeqlCmd: string, config: configUtils.Conf
const noDeclaredLanguage = resolveQueriesOutputObject.noDeclaredLanguage;
const noDeclaredLanguageQueries = Object.keys(noDeclaredLanguage);
if (noDeclaredLanguageQueries.length !== 0) {
core.warning('Some queries do not declare a language:\n' + noDeclaredLanguageQueries.join('\n'));
throw new Error('Some queries do not declare a language, their qlpack.yml file is missing or is invalid');
}
const multipleDeclaredLanguages = resolveQueriesOutputObject.multipleDeclaredLanguages;
const multipleDeclaredLanguagesQueries = Object.keys(multipleDeclaredLanguages);
if (multipleDeclaredLanguagesQueries.length !== 0) {
core.warning('Some queries declare multiple languages:\n' + multipleDeclaredLanguagesQueries.join('\n'));
throw new Error('Some queries declare multiple languages, their qlpack.yml file is missing or is invalid');
}
}

41
src/testdata/tool-names.sarif vendored Normal file
View 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
}
}
}
]
}

View File

@@ -98,6 +98,8 @@ async function uploadFiles(sarifFiles: string[]) {
matrix = undefined;
}
const toolNames = util.getToolNames(sarifPayload);
const payload = JSON.stringify({
"commit_oid": commitOid,
"ref": ref,
@@ -106,7 +108,8 @@ async function uploadFiles(sarifFiles: string[]) {
"workflow_run_id": workflowRunID,
"checkout_uri": checkoutURI,
"environment": matrix,
"started_at": startedAt
"started_at": startedAt,
"tool_names": toolNames,
});
core.info('Uploading results');

9
src/util.test.ts Normal file
View 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"])
})

View File

@@ -293,3 +293,23 @@ export async function reportActionFailed(action: string, cause?: string, excepti
export async function reportActionSucceeded(action: string) {
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);
}