mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
Merge branch 'main' into redsun82/rust-cli-flags
This commit is contained in:
1
.github/pull_request_template.md
vendored
1
.github/pull_request_template.md
vendored
@@ -11,3 +11,4 @@
|
|||||||
|
|
||||||
- [ ] Autofixes generated based on these changes are valid, only needed if this PR makes significant changes to `.ql`, `.qll`, or `.qhelp` files. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required).
|
- [ ] Autofixes generated based on these changes are valid, only needed if this PR makes significant changes to `.ql`, `.qll`, or `.qhelp` files. See [the documentation](https://github.com/github/codeql-team/blob/main/docs/best-practices/validating-autofix-for-query-changes.md) (internal access required).
|
||||||
- [ ] Changes are validated [at scale](https://github.com/github/codeql-dca/) (internal access required).
|
- [ ] Changes are validated [at scale](https://github.com/github/codeql-dca/) (internal access required).
|
||||||
|
- [ ] Adding a new query? Consider also [adding the query to autofix](https://github.com/github/codeml-autofix/blob/main/docs/updating-query-support.md#adding-a-new-query-to-the-query-suite).
|
||||||
|
|||||||
@@ -59,14 +59,16 @@ extended.rel: reorder input.rel (int id, string name, int parent) id name parent
|
|||||||
// QLL library, and will run in the context of the *old* dbscheme.
|
// QLL library, and will run in the context of the *old* dbscheme.
|
||||||
relationname.rel: run relationname.qlo
|
relationname.rel: run relationname.qlo
|
||||||
|
|
||||||
// Create relationname.rel by running the query predicate 'predicatename' in
|
// Create relation1.rel by running the query predicate 'predicate1' in upgrade.qlo
|
||||||
// relationname.qlo and writing the query results as a .rel file. This command
|
// and writing the query results as a .rel file, and running 'predicate2' in
|
||||||
|
// upgrade.qlo and writing the query results as a .rel file. This command
|
||||||
// expects the upgrade relation to be a query predicate, which has the advantage
|
// expects the upgrade relation to be a query predicate, which has the advantage
|
||||||
// of allowing multiple upgrade relations to appear in the same .ql file as
|
// of allowing multiple upgrade relations to appear in the same .ql file as
|
||||||
// multiple query predicates. The query file should be named relationname.ql and
|
// multiple query predicates. The query file should be named upgrade.ql and
|
||||||
// should be placed in the upgrade directory. It should avoid using the default
|
// should be placed in the upgrade directory. It should avoid using the default
|
||||||
// QLL library, and will run in the context of the *old* dbscheme.
|
// QLL library, and will run in the context of the *old* dbscheme.
|
||||||
relationname.rel: run relationname.qlo predicatename
|
relation1.rel: run upgrade.qlo predicate1
|
||||||
|
relation2.rel: run upgrade.qlo predicate2
|
||||||
```
|
```
|
||||||
|
|
||||||
### Testing your scripts
|
### Testing your scripts
|
||||||
|
|||||||
30
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.qhelp
Normal file
30
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.qhelp
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE qhelp PUBLIC
|
||||||
|
"-//Semmle//qhelp//EN"
|
||||||
|
"qhelp.dtd">
|
||||||
|
<qhelp>
|
||||||
|
<overview>
|
||||||
|
<p>
|
||||||
|
Sensitive information included in a GitHub Actions artifact can allow an attacker to access
|
||||||
|
the sensitive information if the artifact is published.
|
||||||
|
</p>
|
||||||
|
</overview>
|
||||||
|
|
||||||
|
<recommendation>
|
||||||
|
<p>
|
||||||
|
Only store information that is meant to be publicly available in a GitHub Actions artifact.
|
||||||
|
</p>
|
||||||
|
</recommendation>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<p>
|
||||||
|
The following example uses <code>actions/checkout</code> to checkout code which stores the GITHUB_TOKEN in the `.git/config` file
|
||||||
|
and then stores the contents of the `.git` repository into the artifact:
|
||||||
|
</p>
|
||||||
|
<sample src="examples/actions-artifact-leak.yml"/>
|
||||||
|
<p>
|
||||||
|
The issue has been fixed below, where the <code>actions/upload-artifact</code> uses a version (v4+) which does not include hidden files or
|
||||||
|
directories into the artifact.
|
||||||
|
</p>
|
||||||
|
<sample src="examples/actions-artifact-leak-fixed.yml"/>
|
||||||
|
</example>
|
||||||
|
</qhelp>
|
||||||
111
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.ql
Normal file
111
javascript/ql/src/Security/CWE-312/ActionsArtifactLeak.ql
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
/**
|
||||||
|
* @name Storage of sensitive information in GitHub Actions artifact
|
||||||
|
* @description Including sensitive information in a GitHub Actions artifact can
|
||||||
|
* expose it to an attacker.
|
||||||
|
* @kind problem
|
||||||
|
* @problem.severity error
|
||||||
|
* @security-severity 7.5
|
||||||
|
* @precision high
|
||||||
|
* @id js/actions/actions-artifact-leak
|
||||||
|
* @tags security
|
||||||
|
* external/cwe/cwe-312
|
||||||
|
* external/cwe/cwe-315
|
||||||
|
* external/cwe/cwe-359
|
||||||
|
*/
|
||||||
|
|
||||||
|
import javascript
|
||||||
|
import semmle.javascript.Actions
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A step that uses `actions/checkout` action.
|
||||||
|
*/
|
||||||
|
class ActionsCheckoutStep extends Actions::Step {
|
||||||
|
ActionsCheckoutStep() { this.getUses().getGitHubRepository() = "actions/checkout" }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `with:`/`persist-credentials` field sibling to `uses: actions/checkout`.
|
||||||
|
*/
|
||||||
|
class ActionsCheckoutWithPersistCredentials extends YamlNode, YamlScalar {
|
||||||
|
ActionsCheckoutStep step;
|
||||||
|
|
||||||
|
ActionsCheckoutWithPersistCredentials() {
|
||||||
|
step.lookup("with").(YamlMapping).lookup("persist-credentials") = this
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Gets the step this field belongs to. */
|
||||||
|
ActionsCheckoutStep getStep() { result = step }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `with:`/`path` field sibling to `uses: actions/checkout`.
|
||||||
|
*/
|
||||||
|
class ActionsCheckoutWithPath extends YamlNode, YamlString {
|
||||||
|
ActionsCheckoutStep step;
|
||||||
|
|
||||||
|
ActionsCheckoutWithPath() { step.lookup("with").(YamlMapping).lookup("path") = this }
|
||||||
|
|
||||||
|
/** Gets the step this field belongs to. */
|
||||||
|
ActionsCheckoutStep getStep() { result = step }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A step that uses `actions/upload-artifact` action.
|
||||||
|
*/
|
||||||
|
class ActionsUploadArtifactStep extends Actions::Step {
|
||||||
|
ActionsUploadArtifactStep() { this.getUses().getGitHubRepository() = "actions/upload-artifact" }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `with:`/`path` field sibling to `uses: actions/upload-artifact`.
|
||||||
|
*/
|
||||||
|
class ActionsUploadArtifactWithPath extends YamlNode, YamlString {
|
||||||
|
ActionsUploadArtifactStep step;
|
||||||
|
|
||||||
|
ActionsUploadArtifactWithPath() { step.lookup("with").(YamlMapping).lookup("path") = this }
|
||||||
|
|
||||||
|
/** Gets the step this field belongs to. */
|
||||||
|
ActionsUploadArtifactStep getStep() { result = step }
|
||||||
|
}
|
||||||
|
|
||||||
|
from ActionsCheckoutStep checkout, ActionsUploadArtifactStep upload, Actions::Job job, int i, int j
|
||||||
|
where
|
||||||
|
checkout.getJob() = job and
|
||||||
|
upload.getJob() = job and
|
||||||
|
job.getStep(i) = checkout and
|
||||||
|
job.getStep(j) = upload and
|
||||||
|
j = i + 1 and
|
||||||
|
upload.getUses().getVersion() =
|
||||||
|
[
|
||||||
|
"v4.3.6", "834a144ee995460fba8ed112a2fc961b36a5ec5a", //
|
||||||
|
"v4.3.5", "89ef406dd8d7e03cfd12d9e0a4a378f454709029", //
|
||||||
|
"v4.3.4", "0b2256b8c012f0828dc542b3febcab082c67f72b", //
|
||||||
|
"v4.3.3", "65462800fd760344b1a7b4382951275a0abb4808", //
|
||||||
|
"v4.3.2", "1746f4ab65b179e0ea60a494b83293b640dd5bba", //
|
||||||
|
"v4.3.1", "5d5d22a31266ced268874388b861e4b58bb5c2f3", //
|
||||||
|
"v4.3.0", "26f96dfa697d77e81fd5907df203aa23a56210a8", //
|
||||||
|
"v4.2.0", "694cdabd8bdb0f10b2cea11669e1bf5453eed0a6", //
|
||||||
|
"v4.1.0", "1eb3cb2b3e0f29609092a73eb033bb759a334595", //
|
||||||
|
"v4.0.0", "c7d193f32edcb7bfad88892161225aeda64e9392", //
|
||||||
|
] and
|
||||||
|
(
|
||||||
|
not exists(ActionsCheckoutWithPersistCredentials persist | persist.getStep() = checkout)
|
||||||
|
or
|
||||||
|
exists(ActionsCheckoutWithPersistCredentials persist |
|
||||||
|
persist.getStep() = checkout and
|
||||||
|
persist.getValue() = "true"
|
||||||
|
)
|
||||||
|
) and
|
||||||
|
(
|
||||||
|
not exists(ActionsCheckoutWithPath path | path.getStep() = checkout) and
|
||||||
|
exists(ActionsUploadArtifactWithPath path |
|
||||||
|
path.getStep() = upload and path.getValue() = [".", "*"]
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(ActionsCheckoutWithPath checkout_path, ActionsUploadArtifactWithPath upload_path |
|
||||||
|
checkout_path.getValue() + ["", "/*"] = upload_path.getValue() and
|
||||||
|
checkout_path.getStep() = checkout and
|
||||||
|
upload_path.getStep() = upload
|
||||||
|
)
|
||||||
|
)
|
||||||
|
select upload, "A secret may be exposed in an artifact."
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
name: secrets-in-artifacts
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
a-job: # NOT VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: .
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
name: secrets-in-artifacts
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
a-job: # VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: .
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
category: majorAnalysis
|
||||||
|
---
|
||||||
|
|
||||||
|
- Added a new query (`js/actions/actions-artifact-leak`) to detect GitHub Actions artifacts that may leak the GITHUB_TOKEN token.
|
||||||
87
javascript/ql/test/query-tests/Security/CWE-312/.github/workflows/test.yml
vendored
Normal file
87
javascript/ql/test/query-tests/Security/CWE-312/.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
name: secrets-in-artifacts
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
jobs:
|
||||||
|
test1: # VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: .
|
||||||
|
test2: # NOT VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: .
|
||||||
|
test3: # VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: "*"
|
||||||
|
test4: # VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: foo
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: foo
|
||||||
|
test5: # VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: foo
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: foo/*
|
||||||
|
test6: # NOT VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
path: pr
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: foo
|
||||||
|
test7: # NOT VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: false
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: .
|
||||||
|
test8: # VULNERABLE
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: true
|
||||||
|
- name: "Upload artifact"
|
||||||
|
uses: actions/upload-artifact@1746f4ab65b179e0ea60a494b83293b640dd5bba # v4.3.2
|
||||||
|
with:
|
||||||
|
name: file
|
||||||
|
path: .
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
| .github/workflows/test.yml:9:9:14:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||||
|
| .github/workflows/test.yml:27:9:32:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||||
|
| .github/workflows/test.yml:38:9:43:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||||
|
| .github/workflows/test.yml:49:9:54:2 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||||
|
| .github/workflows/test.yml:82:9:86:18 | name: " ... tifact" | A secret may be exposed in an artifact. |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Security/CWE-312/ActionsArtifactLeak.ql
|
||||||
Reference in New Issue
Block a user