Skip to content

otp scan PRs for vulnerabilities #9790

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: maint
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
386 changes: 382 additions & 4 deletions .github/scripts/otp-compliance.es

Large diffs are not rendered by default.

34 changes: 30 additions & 4 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,31 @@ jobs:
docker run otp "erl ${OPTION} -noshell -s init stop"
done

modified-vendor-files:
name: Check if vendor files changed
runs-on: ubuntu-latest
outputs:
vendor-files: ${{ steps.vendor-files.outputs.MODIFIED_FILES != '0' }}
steps:
- name: Get modified vendor files
id: vendor-files
run: |
echo "MODIFIED_FILES=$(git diff --name-only '${{ github.base_ref }}' 'HEAD' | grep 'vendor\.info$' | wc -l || 1)"

# this is a call to a workflow_call
pr-vendor-vulnerability-analysis:
needs: modified-vendor-files
if: ${{ needs.modified-vendor-files.outputs.vendor-files }}
permissions:
security-events: write
name: Vendor Vulnerability Scanning
uses: ./.github/workflows/reusable-vendor-vulnerability-scanner.yml
with:
sarif: false
fail_if_cve: true
version: ${{ github.event_name == 'pull_request' && github.base_ref || github.ref_name }}
# equivalent of ${{ env.BASE_BRANCH }} but reusable-workflows do not allow to pass env.

build:
name: Build Erlang/OTP
runs-on: ubuntu-latest
Expand Down Expand Up @@ -848,18 +873,17 @@ jobs:
fail-on: ${{ github.ref_type == 'tag' && '' || 'violations,issues' }}
sw-version: ${{ env.OTP_SBOM_VERSION }}

vendor-analysis:
name: Vendor Dependency Analysis
vendor-dependency-upload:
name: Vendor Dependency Upload
runs-on: ubuntu-latest
if: github.event_name == 'push'
needs:
- sbom
- pack
if: github.repository == 'erlang/otp'
## Needed to use Github Dependency API
permissions:
contents: write
id-token: write

steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/[email protected]
- uses: ./.github/actions/build-base-image
Expand All @@ -878,7 +902,9 @@ jobs:
--sbom-file /github/bom.spdx.json"

# allows Dependabot to give us alert of the vendor libraries that use semantic versioning
# it also allows dependencies to be looked up from github dependencies
- name: Upload SBOM to Github Dependency API
if: github.event_name == 'push'
uses: advanced-security/spdx-dependency-submission-action@5530bab9ee4bbe66420ce8280624036c77f89746 # ratchet:advanced-security/[email protected]

## If this is an "OTP-*" tag that has been pushed we do some release work
Expand Down
35 changes: 13 additions & 22 deletions .github/workflows/osv-scanner-scheduled.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,24 @@ jobs:
permissions:
actions: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/[email protected]
with:
ref: ${{ matrix.type }}

# this call to a workflow_dispatch ref=master is important because
# using ref={{matrix.type}} would trigger the workflow
# reusable-vendor-vulnerability-scanner.yml in that ref/branch. since
# there is no such files in maint-25, maint-26, etc, the result would
# ignore the vulnerability scanning for those branches.
#
# we do not need to fail if there are CVEs in the weekly scheduled reporting,
# thus, fail_if_cve can be false. if set to true, finding a CVE in scheduled scanning
# triggers a failure. this is not needed because sarif=true, which means that
# the results are placed in Github Security via SARIF file
- name: Trigger Vulnerability Scanning
env:
GH_TOKEN: ${{ github.token }}
if: ${{ hashFiles('.github/workflows/osv-scanner-scheduled.yml') != '' }}
REPO: ${{ github.repository }} # in testing cases, this is your fork, e.g., kikofernandez/otp
run: |
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository }}/actions/workflows/osv-scanner-scheduled.yml/dispatches \
-f "ref=${{ matrix.type }}"

scan-pr:
# run-scheduled-scan triggers this job
# PRs and pushes trigger this job
if: github.event_name != 'schedule'
permissions:
# Require writing security events to upload SARIF file to security tab
security-events: write
# Required to upload SARIF file to CodeQL.
# See: https://github.com/github/codeql-action/issues/2117
actions: read
contents: read
uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@e69cc6c86b31f1e7e23935bbe7031b50e51082de" # ratchet:google/osv-scanner-action/.github/workflows/[email protected]
with:
upload-sarif: ${{ github.repository == 'erlang/otp' }}
/repos/${{ github.repository }}/actions/workflows/reusable-vendor-vulnerability-scanner.yml/dispatches \
-f "ref=master" -f "inputs[version]=${{ matrix.type }}" -f "inputs[sarif]=true" -f "inputs[fail_if_cve]=false"
138 changes: 138 additions & 0 deletions .github/workflows/reusable-vendor-vulnerability-scanner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# %CopyrightBegin%
#
# SPDX-License-Identifier: Apache-2.0
#
# Copyright Ericsson AB 2024-2025. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# %CopyrightEnd%

name: Vendor Vulnerability Scanning
run-name: "[${{ inputs.version }}] Vendor Vulnerability Scanning"
description: 'Vulnerability scanning'

# 'inputs' must be repeated twice for the different use cases.
# there is no current way to share 'inputs' for workflow dispatch
# and call.

# version: reference branch to checkout and analyse for CVE.
# sarif: flag to trigger the upload of a SARIF file that contains vulnerabilities.
# The upload of the SARIF file will make the tool to report issues under GH Security.
# This flag is set 'true' for scheduled vulnerability analysis.
# Does not make sense to add in PRs because each PR should not create a GH Security issue.
# fail_if_cve: makes the job fail if a CVE is found.
# This is 'true' when analysing PRs, as we prefer a failure to detect that the PR
# introduces a vulnerability.
#

on:
workflow_dispatch:
inputs:
version:
description: 'Reference branch to checkout and analyse'
required: true
default: 'master'
type: 'string'
sarif:
description: 'Upload sarif file'
required: true
default: false
type: boolean
fail_if_cve:
# The build fails if a CVE is found. This is ok to activate in PRs, but
# does not make sense in scheduled analysis since CVEs will be reported
# in Github Security
description: 'Fail if CVE is found'
required: true
default: false
type: boolean
workflow_call:
inputs:
version:
description: 'Reference branch to checkout and analyse'
required: true
default: 'master'
type: 'string'
sarif:
description: 'Upload sarif file'
required: true
default: false
type: boolean
fail_if_cve:
# The build fails if a CVE is found. This is ok to activate in PRs, but
# does not make sense in scheduled analysis since CVEs will be reported
# in Github Security.
description: 'Fail if CVE is found'
required: true
default: false
type: boolean

env:
VERSION: ${{ inputs.version }}

jobs:
analysis-vendor-dependencies:
name: "Vulnerability Scanning of Vendor Dependencies"
# This job is always run on the build of a `master` base-image.
# then it copies the branch to be analysed, and scans it.
# the main reason is that maint-25, maint-26, etc do not have this file
# committed into them. thus, a workflow_dispatch or workflow_call would
# not work, and we would not be able to analyse vendor dependecies there.
runs-on: ubuntu-latest
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
permissions:
security-events: write
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # ratchet:actions/[email protected]
- uses: erlef/setup-beam@5304e04ea2b355f03681464e683d92e3b2f18451 # racket:actions/checkout@v1
with:
otp-version: '27'

- name: Download Scanning Alerts
run: |
gh api -H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
/repos/${{ github.repository }}/code-scanning/alerts?tool_name=otp-compliance > "$HOME/gh_alerts.json"

- name: 'Analysis of dependencies in ${{ inputs.version }}'
id: analysis
run: |
git clone -b ${{ env.VERSION }} https://github.com/${{ github.repository }}.git ${{ env.VERSION }}
mkdir -p /home/runner/work/otp/otp/${{ env.VERSION }}/.github/scripts/
curl -LJO https://raw.githubusercontent.com/${{ github.repository }}/refs/heads/master/.github/scripts/otp-compliance.es
chmod +x otp-compliance.es
cp otp-compliance.es \
/home/runner/work/otp/otp/${{ env.VERSION }}/.github/scripts/otp-compliance.es
cd /home/runner/work/otp/otp/${{ env.VERSION }} && \
.github/scripts/otp-compliance.es sbom osv-scan \
--version ${{ inputs.version }} \
--fail_if_cve ${{ inputs.fail_if_cve }} \
--gh_alerts $HOME/gh_alerts.json

- name: "Get SHA"
if: ${{ !failure() && steps.analysis.outcome != 'skipped' && inputs.sarif }}
id: sha
run: |
echo "sha=$(cd /home/runner/work/otp/otp/${{ env.VERSION }} && git rev-parse HEAD)" >> $GITHUB_OUTPUT

- name: "Upload to code-scanning"
if: ${{ !failure() && steps.analysis.outcome != 'skipped' && inputs.sarif }}
env:
SHA: ${{ steps.sha.outputs.sha }}
uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # ratchet:github/codeql-action/upload-sarif@v3
with:
sarif_file: ${{ env.VERSION }}/results.sarif
ref: refs/heads/${{ env.VERSION }}
sha: ${{ env.SHA }}
7 changes: 6 additions & 1 deletion HOWTO/SBOM.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ This file may be a list of JSON objects. For simplicity, we document the fields
"licenseDeclared": "Zlib",
"name": "asmjit",
"versionInfo": "029075b84bf0161a761beb63e6eda519a29020db",
"sha": "029075b84bf0161a761beb63e6eda519a29020db",
"path": "./erts/emulator/asmjit",
"exclude": ["./erts/emulator/asmjit/vendor.info"],
"supplier": "Person: Petr Kobalicek",
Expand All @@ -201,11 +202,15 @@ Fields summary:
- If you are unsure about the name of the `SPDX-TOP-LEVEL-PACKAGE`, take a look at the source SBOM to identify packages (under key `packages` in the SBOM).
- `description`: a brief description of what this vendor library does.
- `copyrightText`: copyright text associated with the top-level package/library/3pp using [SPDX License Identifiers](https://spdx.org/licenses/).
- `downloadLocation`: URI of the vendor library to download.
- `downloadLocation`: URI of the vendor library to download. If using Github, use preferably `https//` rather than `git+https//` or similars.
This is because the download location is used for vulnerability scanning in `.github/scripts/otp-compliance.es`.
- `homepage`: homepage of the vendor library.
- `licenseDeclared`: license as declared by the vendor, following a [SPDX license identifier](https://spdx.org/licenses/).
- `name`: name of the library.
- `versionInfo`: version of the library/project/3pp. In case of no version number being available, write the commit sha.
- `sha`: sha commit for `versionInfo`, they need to be updated together!
- `ecosystem`: List of valid ecosystems in [OSV Ecosystems](https://ossf.github.io/osv-schema/#defined-ecosystems)
where this value is omitted for C/C++ code (e.g., `asmjit`, `pcre2`, `zlib`, `zstd`, etc), and used in `vendor.json` for `jquery`.
- `path`: path to the vendor library inside Erlang/OTP. This can point to a folder or a list of files.
- Folder: any file inside the folder is considered part of the vendor library (e.g., asmjit [vendor.info](../erts/emulator/asmjit/vendor.info)).
- List of files: only the files listed here are part of a vendor library (e.g., erts-config [vendor.info](../erts/autoconf/vendor.info)).
Expand Down
1 change: 1 addition & 0 deletions erts/emulator/openssl/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"licenseDeclared": "Apache-2.0",
"name": "openssl",
"versionInfo": "3.5",
"sha": "636dfadc70ce26f2473870570bfd9ec352806b1d",
"path": "./erts/emulator/openssl",
"exclude": ["./erts/emulator/openssl/vendor.info",
"./erts/emulator/openssl/README",
Expand Down
3 changes: 2 additions & 1 deletion erts/emulator/pcre/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"ID": "erts-pcre2",
"description": "PCRE2 library",
"copyrightText": "NOASSERTION",
"downloadLocation": "git+https://github.com/PCRE2Project/pcre2.git",
"downloadLocation": "https://github.com/PCRE2Project/pcre2",
"homepage": "https://pcre2project.github.io/pcre2/",
"licenseDeclared": "BSD-3-Clause",
"name": "pcre2",
Expand All @@ -19,6 +19,7 @@
"exclude": ["./erts/emulator/pcre/vendor.info",
"./erts/emulator/pcre/README.pcre_update.md",
"./erts/emulator/pcre/pcre.mk"],
"sha": "2dce7761b1831fd3f82a9c2bd5476259d945da4d",
"supplier": "Person: Philip Hazel",
"purl": "pkg:generic/pcre2"
}
Expand Down
3 changes: 1 addition & 2 deletions erts/emulator/ryu/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
"./erts/emulator/ryu/digit_table.h",
"./erts/emulator/ryu/ryu.h",
"./erts/emulator/ryu/LICENSE-Apache2",
"./erts/emulator/ryu/LICENSE-Boost"
],
"./erts/emulator/ryu/LICENSE-Boost"],
"supplier": "Person: Ulf Adams",
"purl": "pkg:github/ulfjack/ryu#ryu",
"update": "./erts/emulator/ryu/update.sh",
Expand Down
5 changes: 3 additions & 2 deletions erts/emulator/zlib/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@
"ID": "erts-zlib",
"description": "interface of the 'zlib' general purpose compression library",
"copyrightText": "Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler",
"downloadLocation": "https://zlib.net/",
"downloadLocation": "https://github.com/madler/zlib",
"homepage": "https://zlib.net/",
"licenseDeclared": "Zlib",
"name": "zlib",
"versionInfo": "1.3.1",
"sha": "1a8db63788c34a50e39e273d39b7e1033208aea2",
"path": "./erts/emulator/zlib",
"exclude": ["./erts/emulator/zlib/vendor.info",
"./erts/emulator/zlib/zlib.mk"],
"supplier": "Person: Mark Adler ([email protected])",
"purl": "pkg:generic/zlib"
"purl": "pkg:github/madler/zlib"
}
]
1 change: 1 addition & 0 deletions erts/emulator/zstd/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"licenseDeclared": "BSD-3-Clause OR GPL-2.0-only",
"name": "zstd",
"versionInfo": "v1.5.7",
"sha": "f8745da6ff1ad1e7bab384bd1f9d742439278e99",
"path": "./erts/emulator/zstd",
"exclude": ["./erts/emulator/zstd/vendor.info",
"./erts/emulator/zstd/update.sh",
Expand Down
4 changes: 3 additions & 1 deletion lib/common_test/priv/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"downloadLocation": "https://github.com/jquery/jquery",
"homepage": "https://jquery.com",
"licenseDeclared": "MIT",
"ecosystem": "npm",
"name": "jquery",
"versionInfo": "3.7.1",
"path": ["./lib/common_test/priv/jquery-latest.js"],
Expand All @@ -26,7 +27,8 @@
"downloadLocation": "https://github.com/Mottie/tablesorter",
"homepage": "https://github.com/Mottie/tablesorter",
"licenseDeclared": "BSD-3-Clause OR GPL-2.0-only",
"name": "jquery-tablesorter",
"ecosystem": "npm",
"name": "tablesorter",
"versionInfo": "2.32",
"path": ["./lib/common_test/priv/jquery.tablesorter.min.js"],
"supplier": "Person: Christian Bach",
Expand Down
1 change: 1 addition & 0 deletions lib/erl_interface/src/openssl/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"licenseDeclared": "Apache-2.0",
"name": "openssl",
"versionInfo": "3.5",
"sha": "636dfadc70ce26f2473870570bfd9ec352806b1d",
"path": "./lib/erl_interface/src/openssl",
"exclude": ["./lib/erl_interface/src/openssl/vendor.info",
"./lib/erl_interface/src/openssl/README",
Expand Down
1 change: 1 addition & 0 deletions lib/wx/vendor.info
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"licenseDeclared": "LicenseRef-scancode-wxwindows-free-doc-3",
"name": "wx",
"versionInfo": "dc585039bbd426829e3433002023a93f9bedd0c2",
"sha": "dc585039bbd426829e3433002023a93f9bedd0c2",
"path": "./lib/wx",
"comments": "This only applies to the source code of Erlang files in 'src', and specifically to the documentation embedded in them",
"supplier": "NOASSERTION",
Expand Down
Loading