Add scanning to released images and process to track vulnerabilities (#28087)

For #25902.

---------

Co-authored-by: Sharon Katz <121527325+sharon-fdm@users.noreply.github.com>
This commit is contained in:
Lucas Manuel Rodriguez 2025-04-16 11:50:10 -03:00 committed by GitHub
parent 83a358f588
commit 895194d63b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 980 additions and 30 deletions

View file

@ -15,10 +15,6 @@ defaults:
# fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
shell: bash
env:
AWS_REGION: us-east-2
AWS_IAM_ROLE: arn:aws:iam::160035666661:role/github-actions-role
permissions:
contents: read
@ -37,17 +33,6 @@ jobs:
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2
with:
role-to-assume: ${{env.AWS_IAM_ROLE}}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Docker Hub
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_ACCESS_TOKEN }}
- name: Set up Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with:
@ -62,6 +47,32 @@ jobs:
- name: Build fleetdm/fleetctl
run: make fleetctl-docker
- name: List VEX files
id: generate_vex_files
run: |
echo "VEX_FILES=$(ls -1 ./security/vex/fleetctl/ | while IFS= read -r line; do echo "./security/vex/fleetctl/$line"; done | tr '\n' ',' | sed 's/.$//')" >> $GITHUB_OUTPUT
# We use the trivy command and not the github action because it doesn't support loading VEX files yet.
- name: Run Trivy vulnerability scanner on fleetdm/fleetctl
env:
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db
run: |
mkdir trivy-download
cd trivy-download
curl -L https://github.com/aquasecurity/trivy/releases/download/v0.61.0/trivy_0.61.0_Linux-64bit.tar.gz --output trivy_0.61.0_Linux-64bit.tar.gz
tar -xf trivy_0.61.0_Linux-64bit.tar.gz
mv trivy ..
cd ..
chmod +x ./trivy
./trivy image \
--exit-code=1 \
--ignore-unfixed \
--pkg-types=os,library \
--severity=HIGH,CRITICAL \
--vex="${{ steps.generate_vex_files.outputs.VEX_FILES }}" \
fleetdm/fleetctl
- name: Run Trivy vulnerability scanner on fleetdm/wix
uses: aquasecurity/trivy-action@6e7b7d1fd3e4fef0c5fa8cce1229c54b2c9bd0d8
env:
@ -88,15 +99,23 @@ jobs:
vuln-type: "os,library"
severity: "CRITICAL"
- name: Run Trivy vulnerability scanner on fleetdm/fleetctl
uses: aquasecurity/trivy-action@6e7b7d1fd3e4fef0c5fa8cce1229c54b2c9bd0d8
env:
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db
- name: Slack root notification
if: github.event.schedule == '0 6 * * *' && failure()
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0
with:
image-ref: "fleetdm/fleetctl"
format: "table"
exit-code: "1"
ignore-unfixed: true
vuln-type: "os,library"
severity: "CRITICAL"
payload: |
{
"text": "${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head.html_url }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "⚠️ Build fleetctl docker dependencies and check vulnerabilities failed.\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_G_HELP_ENGINEERING_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

View file

@ -0,0 +1,122 @@
name: Check critical vulnerabilities in released docker images
on:
workflow_dispatch:
pull_request:
schedule:
- cron: "0 6 * * *"
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id}}
cancel-in-progress: true
defaults:
run:
# fail-fast using bash -eo pipefail. See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
shell: bash
permissions:
contents: read
jobs:
build-and-check:
runs-on: ubuntu-22.04
environment: Docker Hub
steps:
- name: Harden Runner
uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3
- name: Set up Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
with:
go-version-file: "go.mod"
- name: Get last 5 minor releases
id: get_latest_releases
run: |
echo "FLEET_LATEST_RELEASES=$(go run ./tools/github-releases --last-minor-releases 5)" >> $GITHUB_OUTPUT
- name: Pull docker images
run: |
RELEASES="${{ steps.get_latest_releases.outputs.FLEET_LATEST_RELEASES }}"
for version in $RELEASES; do
docker pull fleetdm/fleet:$version
done
- name: List fleet VEX files
id: generate_fleet_vex_files
run: |
VEX_FILES=$(ls -1 ./security/vex/fleet/ | while IFS= read -r line; do echo "./security/vex/fleet/$line"; done | tr '\n' ',' | sed 's/.$//')
echo $VEX_FILES
echo "FLEET_VEX_FILES=$VEX_FILES" >> $GITHUB_OUTPUT
# We use the trivy command and not the github action because it doesn't support loading
# VEX files yet and looks like we can't run the action on multiple images.
- name: Run trivy vulnerability scanner on fleetdm/fleet images
env:
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db
run: |
mkdir trivy-download
cd trivy-download
curl -L https://github.com/aquasecurity/trivy/releases/download/v0.61.0/trivy_0.61.0_Linux-64bit.tar.gz --output trivy_0.61.0_Linux-64bit.tar.gz
tar -xf trivy_0.61.0_Linux-64bit.tar.gz
mv trivy ..
cd ..
chmod +x ./trivy
RELEASES="${{ steps.get_latest_releases.outputs.FLEET_LATEST_RELEASES }}"
for version in $RELEASES; do
./trivy image \
--exit-code=1 \
--pkg-types=os,library \
--severity=CRITICAL \
--vex="${{ steps.generate_fleet_vex_files.outputs.FLEET_VEX_FILES }}" \
fleetdm/fleet:$version
done
- name: List fleetctl VEX files
id: generate_fleetctl_vex_files
run: |
VEX_FILES=$(ls -1 ./security/vex/fleetctl/ | while IFS= read -r line; do echo "./security/vex/fleetctl/$line"; done | tr '\n' ',' | sed 's/.$//')
echo $VEX_FILES
echo "FLEETCTL_VEX_FILES=$VEX_FILES" >> $GITHUB_OUTPUT
# We use the trivy command and not the github action because it doesn't support loading VEX files yet.
- name: Run trivy vulnerability scanner on latest released fleetdm/fleetctl image
env:
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db
run: |
./trivy image \
--exit-code=1 \
--pkg-types=os,library \
--severity=CRITICAL \
--vex="${{ steps.generate_fleetctl_vex_files.outputs.FLEETCTL_VEX_FILES }}" \
fleetdm/fleetctl:latest
- name: Slack notification
if: github.event.schedule == '0 6 * * *' && failure()
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0
with:
payload: |
{
"text": "${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head.html_url }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "⚠️ Check vulnerabilities in released docker images failed.\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_G_HELP_ENGINEERING_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

View file

@ -16,6 +16,8 @@ on:
- "website/**"
- "mdm-profiles/**"
workflow_dispatch: # Manual
schedule:
- cron: '0 4 * * *' # Every day at 4 AM
# This allows a subsequently queued workflow run to interrupt previous runs
concurrency:
@ -80,11 +82,57 @@ jobs:
- name: Tag image with branch name
run: docker tag fleetdm/fleet:$(git rev-parse --short HEAD) fleetdm/fleet:$(git rev-parse --abbrev-ref HEAD)
- name: Generate tag
id: generate_tag
run: |
echo "FLEET_IMAGE_TAG=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_OUTPUT
- name: List VEX files
id: generate_vex_files
run: |
echo "VEX_FILES=$(ls -1 ./security/vex/fleet/ | while IFS= read -r line; do echo "./security/vex/fleet/$line"; done | tr '\n' ',' | sed 's/.$//')" >> $GITHUB_OUTPUT
# We use the trivy command and not the github action because it doesn't support loading VEX files yet.
- name: Check high/critical vulnerabilities before publishing (trivy)
# Only run this on the schedule run or when tagging RCs.
if: startsWith(github.ref, 'rc-minor-') || startsWith(github.ref, 'rc-patch-') || github.event.schedule == '0 4 * * *'
env:
TRIVY_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-db
TRIVY_JAVA_DB_REPOSITORY: public.ecr.aws/aquasecurity/trivy-java-db
run: |
mkdir trivy-download
cd trivy-download
curl -L https://github.com/aquasecurity/trivy/releases/download/v0.61.0/trivy_0.61.0_Linux-64bit.tar.gz --output trivy_0.61.0_Linux-64bit.tar.gz
tar -xf trivy_0.61.0_Linux-64bit.tar.gz
mv trivy ..
cd ..
chmod +x ./trivy
./trivy image \
--ignore-unfixed \
--exit-code=1 \
--pkg-types=os,library \
--severity=HIGH,CRITICAL \
--vex="${{ steps.generate_vex_files.outputs.VEX_FILES }}" \
fleetdm/fleet:${{ steps.generate_tag.outputs.FLEET_IMAGE_TAG }}
- name: Check high/critical vulnerabilities before publishing (docker scout)
# Only run this on the schedule run or when tagging RCs.
if: startsWith(github.ref, 'rc-minor-') || startsWith(github.ref, 'rc-patch-') || github.event.schedule == '0 4 * * *'
uses: docker/scout-action@v1
with:
command: cves
image: fleetdm/fleet:${{ steps.generate_tag.outputs.FLEET_IMAGE_TAG }}
only-severities: critical,high
only-fixed: true
only-vex-affected: true
write-comment: false
vex-location: ./security/vex/fleet
# Explicitly push the docker images as GoReleaser will not do so in snapshot mode
- name: Publish Docker images
run: docker push fleetdm/fleet --all-tags
- name: Get tag
- name: Get tags
run: |
echo "TAG=$(git rev-parse --abbrev-ref HEAD) $(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
id: docker
@ -106,3 +154,24 @@ jobs:
docker tag fleetdm/fleet:${TAG} quay.io/fleetdm/fleet:${TAG}
docker push quay.io/fleetdm/fleet:${TAG}
done
- name: Slack notification
if: github.event.schedule == '0 4 * * *' && failure()
uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0
with:
payload: |
{
"text": "${{ job.status }}\n${{ github.event.pull_request.html_url || github.event.head.html_url }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "⚠️ Docker publish failed.\nhttps://github.com/fleetdm/fleet/actions/runs/${{ github.run_id }}"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_G_HELP_ENGINEERING_WEBHOOK_URL }}
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK

View file

@ -63,7 +63,7 @@ jobs:
format: "sarif"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH,MEDIUM,LOW"
trivyignores: ".trivyignore"
trivyignores: "./security/code/.trivyignore"
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@8a470fddafa5cbb6266ee11b37ef4d8aae19c571 # v3.24.6

View file

@ -409,7 +409,8 @@ generate-mock: mock
doc: .prefix
go generate github.com/fleetdm/fleet/v4/server/fleet
go generate github.com/fleetdm/fleet/v4/server/service/osquery_utils
generate-doc: doc
generate-doc: doc vex-report
.help-short--deps:
@echo "Install dependent programs and libraries"
@ -827,4 +828,11 @@ db-replica-reset: fleet
db-replica-run: fleet
FLEET_MYSQL_ADDRESS=127.0.0.1:3308 FLEET_MYSQL_READ_REPLICA_ADDRESS=127.0.0.1:3309 FLEET_MYSQL_READ_REPLICA_USERNAME=fleet FLEET_MYSQL_READ_REPLICA_DATABASE=fleet FLEET_MYSQL_READ_REPLICA_PASSWORD=insecure ./build/fleet serve --dev --dev_license
vex-report:
sh -c 'echo "<!-- DO NOT EDIT. This document is automatically generated by running \`make vex-report\`. -->\n# Vulnerability Report\n\nFollowing is the vulnerability report of Fleet components.\n" > security/status.md'
sh -c 'echo "## \`fleetdm/fleet\` docker image\n" >> security/status.md'
sh -c 'go run ./tools/vex-parser ./security/vex/fleet >> security/status.md'
sh -c 'echo "## \`fleetdm/fleetctl\` docker image\n" >> security/status.md'
sh -c 'go run ./tools/vex-parser ./security/vex/fleetctl >> security/status.md'
include ./tools/makefile-support/helpsystem-targets

View file

@ -13,4 +13,7 @@ To encrypt vulnerability reports before sending them, please use this [PGP key](
The fingerprint of the key is `23A1 9D1F 16D7 1846 57D1  6D67 320D B57D E4F0 EE8F`.
### Vulnerability tracking
GitHub issues concerning vulnerabilities will be tagged with the **security** label to differentiate them from other issues and maintain SOC2 compliance.
See [security/README.md](./security/README.md) for more information on our process to keep Fleet products secure.

2
go.mod
View file

@ -134,7 +134,7 @@ require (
golang.org/x/image v0.18.0
golang.org/x/mod v0.19.0
golang.org/x/net v0.36.0
golang.org/x/oauth2 v0.22.0
golang.org/x/oauth2 v0.27.0
golang.org/x/sync v0.11.0
golang.org/x/sys v0.30.0
golang.org/x/term v0.29.0

2
go.sum
View file

@ -1044,6 +1044,8 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

80
security/README.md Normal file
View file

@ -0,0 +1,80 @@
# Security
## Directory contents
- [status.md](status.md): Current status of vulnerabilities reported on Fleet software components by security scanners (trivy). This document is currently auto-generated from files in the `vex/` directory.
- `code/`: Files used for vulnerability scanning on Fleet's source code.
- `vex/`: OpenVEX files to report status of vulnerabilities detected by Trivy on Fleet docker images.
## Vulnerability scanning
The following Github CI actions perform daily vulnerability scanning on Fleet software components.
- [trivy-scan.yml](https://github.com/fleetdm/fleet/blob/main/.github/workflows/trivy-scan.yml): Scan source code for vulnerabilities.
- [build-and-check-fleetctl-docker-and-deps.yml](https://github.com/fleetdm/fleet/blob/main/.github/workflows/build-and-check-fleetctl-docker-and-deps.yml): Scans for `HIGH` and `CRITICAL` vulnerabilities in `fleetctl` docker image dependencies (`fleetdm/fleetctl`, `fleetdm/wix`, and `fleetdm/bomutils`).
- [goreleaser-snapshot-fleet.yaml](https://github.com/fleetdm/fleet/blob/main/.github/workflows/goreleaser-snapshot-fleet.yaml): Scans for HIGH and CRITICAL vulnerabilities in `fleetdm/fleet` docker image before pushing to the Docker registry (runs daily and is triggered for every change in Fleet's source code).
- [check-vulnerabilities-in-released-docker-images.yml](https://github.com/fleetdm/fleet/blob/main/.github/workflows/check-vulnerabilities-in-released-docker-images.yml): Scans for `CRITICAL` vulnerabilities in the last 5 minor released versions of the `fleetdm/fleet` and on the latest release of `fleetdm/fleetctl`.
## Process to run when a CVE is reported
### 1. Update report (status.md)
If trivy reports a HIGH or CRITICAL CVE on one of Fleet's docker images (reported by the previously mentioned Github Actions), then we need to assess the report and track it with a status of "not affected", "affected", "fixed", or "under investigation".
We use the OpenVEX format to track the status of reported vulnerabilities (`vex/` folder).
Once the status is determined, we use the [vexctl](https://github.com/openvex/vexctl) tool to create a VEX file.
```sh
brew install vexctl
```
Example for `CVE-2023-32698` on package `github.com/goreleaser/nfpm/v2` which we know doesn't affect `fleetdm/fleetctl`:
```sh
vexctl create --product="fleetctl,pkg:golang/github.com/goreleaser/nfpm/v2" \
--vuln="CVE-2023-32698" \
--status="not_affected" \
--author="@getvictor" \
--justification="vulnerable_code_cannot_be_controlled_by_adversary" \
--status-note="When packaging linux files, fleetctl does not use global permissions. It was verified that packed fleetd package files do not have group/global write permissions." > security/vex/fleetctl/CVE-2023-32698.vex.json
```
Similarly, for `CVE-2024-8260` on package `github.com/open-policy-agent/opa` which we know doesn't affect `fleetdm/fleet`:
```sh
vexctl create --product="fleet,pkg:golang/github.com/open-policy-agent/opa" \
--vuln="CVE-2024-8260" \
--status="not_affected" \
--author="@luacsmrod" \
--justification="vulnerable_code_cannot_be_controlled_by_adversary" \
--status-note="Fleet doesn't run on Windows, so it's not affected by this vulnerability." > security/vex/fleetctl/CVE-2024-8260.vex.json
```
Examples of `--product` flag values (which accept "PURLs"):
- `liblzma5` debian package: `pkg:deb/debian/liblzma5`.
- `github.com/goreleaser/nfpm/v2` golang package: `pkg:golang/github.com/goreleaser/nfpm/v2`.
- `xerces/xercesImpl` java package: `pkg:maven/xerces/xercesImpl`.
When new VEX files are generated or updated we can update the `security/status.md` file by running:
```sh
make vex-report
```
### 2. Update software
If the detected vulnerability can be fixed by updating the base docker image or removing/changing components in the docker image then we do so and the update will be present on the next release. (It is good practice to keep software up-to-date.)
### 3. Process for "affected" CRITICAL vulnerabilities
#### fleetdm/fleet
Following is the process to run when a `CRITICAL` CVE affects any of the five last releases of `fleetdm/fleet` docker image (reported by [check-vulnerabilities-in-released-docker-images.yml](https://github.com/fleetdm/fleet/blob/main/.github/workflows/check-vulnerabilities-in-released-docker-images.yml)).
1. We will use the information reported by the scanner and update our `status.md` to keep users/customers informed.
2. If the `CRITICAL` vulnerability (that has a fix) is on the `latest` release, we'll file a critical/P0 bug and release a patch ASAP (within 1 business day). The previous four versions scanned won't be retroactively patched, only `latest` will be patched.
#### fleetdm/fleetctl
Following is the process to run when a `CRITICAL` CVE affects the released `fleetdm/fleetctl:latest` docker image:
1. After `security/status.md` is updated, notify users/customers about the CVE in the `fleetdm/fleetctl` image and possible remediations.
2. Create a Github issue with a `P0`/`security` label to track the fix.
3. The fix will be released on the next release of the `fleetdm/fleetctl` docker image.

120
security/status.md Normal file
View file

@ -0,0 +1,120 @@
<!-- DO NOT EDIT. This document is automatically generated by running `make vex-report`. -->
# Vulnerability Report
Following is the vulnerability report of Fleet components.
## `fleetdm/fleet` docker image
### CVE-2023-32698
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** The fleetctl executable is unused in the fleetdm/fleet docker image. The executable was removed in v4.64.0.
- **Products:**
- `fleet`
- `pkg:golang/github.com/goreleaser/nfpm/v2`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-10T15:28:30.406734-03:00
### CVE-2024-12797
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** fleet uses Go TLS implementation
- **Products:**
- `fleet`
- `pkg:apk/alpine/libcrypto3`
- `pkg:apk/alpine/libssl3`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-10T15:15:53.847365-03:00
### CVE-2025-21613
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** The fleetctl executable is unused in the fleetdm/fleet docker image. The executable was removed in v4.64.0.
- **Products:**
- `fleet`
- `pkg:golang/github.com/go-git/go-git/v5`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-10T15:42:55.967763-03:00
### CVE-2025-21614
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** The fleetctl executable is unused in the fleetdm/fleet docker image. The executable was removed in v4.64.0.
- **Products:**
- `fleet`
- `pkg:golang/github.com/go-git/go-git/v5`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-10T15:43:15.232143-03:00
### CVE-2025-26519
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** fleet does not perform any EUC-KR to UTF-8 translation by libc
- **Products:**
- `fleet`
- `pkg:apk/alpine/musl@1.2.5-r8?os_name=alpine&os_version=3.21`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-14T16:30:01.904498-03:00
### CVE-2025-30204
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** The token format being validated before the call to ParseUnverified
- **Products:**
- `fleet`
- `pkg:golang/github.com/golang-jwt/jwt/v4`
- **Justification:** `inline_mitigations_already_exist`
- **Timestamp:** 2025-04-10T15:23:54.60648-03:00
## `fleetdm/fleetctl` docker image
### CVE-2012-0881
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** fleetctl does not use Java
- **Products:**
- `fleetctl`
- `pkg:maven/xerces/xercesImpl`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-10T14:46:52.709835-03:00
### CVE-2013-4002
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** fleetctl does not use Java
- **Products:**
- `fleetctl`
- `pkg:maven/xerces/xercesImpl`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-10T07:36:31.1157-03:00
### CVE-2023-32698
- **Author:** @getvictor
- **Status:** `not_affected`
- **Status notes:** When packaging linux files, fleetctl does not use global permissions. It was verified that packed fleetd package files do not have group/global write permissions.
- **Products:**
- `fleetctl`
- `pkg:golang/github.com/goreleaser/nfpm/v2`
- **Justification:** `vulnerable_code_cannot_be_controlled_by_adversary`
- **Timestamp:** 2025-04-09T10:26:02.350338-03:00
### CVE-2024-7254
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** fleetctl does not use Java
- **Products:**
- `fleetctl`
- `pkg:maven/com.google.protobuf/protobuf-java`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-10T07:34:26.535559-03:00
### CVE-2025-31115
- **Author:** @lucasmrod
- **Status:** `not_affected`
- **Status notes:** fleetctl does not use liblzma5
- **Products:**
- `fleetctl`
- `pkg:deb/debian/liblzma5`
- **Justification:** `vulnerable_code_not_in_execute_path`
- **Timestamp:** 2025-04-09T13:24:20.950928-03:00

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-5ee3fede62f0769d4669c8760aa6ea30f61f85c87dc49d9518062cad868ee559",
"author": "@lucasmrod",
"timestamp": "2025-04-10T15:28:30.406729-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2023-32698"
},
"timestamp": "2025-04-10T15:28:30.406734-03:00",
"products": [
{
"@id": "fleet"
},
{
"@id": "pkg:golang/github.com/goreleaser/nfpm/v2"
}
],
"status": "not_affected",
"status_notes": "The fleetctl executable is unused in the fleetdm/fleet docker image. The executable was removed in v4.64.0.",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,29 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-fdaba329936f0fd22015a46e3ec50795935a124977a1b1f1b5f16b76793bcdad",
"author": "@lucasmrod",
"timestamp": "2025-04-10T15:15:53.847361-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2024-12797"
},
"timestamp": "2025-04-10T15:15:53.847365-03:00",
"products": [
{
"@id": "fleet"
},
{
"@id": "pkg:apk/alpine/libcrypto3"
},
{
"@id": "pkg:apk/alpine/libssl3"
}
],
"status": "not_affected",
"status_notes": "fleet uses Go TLS implementation",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-42f66c75dd4500dd15cabd90d6ecf60539c98b2965f974af9f6ab4d06ee5d244",
"author": "@lucasmrod",
"timestamp": "2025-04-10T15:42:55.96775-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2025-21613"
},
"timestamp": "2025-04-10T15:42:55.967763-03:00",
"products": [
{
"@id": "fleet"
},
{
"@id": "pkg:golang/github.com/go-git/go-git/v5"
}
],
"status": "not_affected",
"status_notes": "The fleetctl executable is unused in the fleetdm/fleet docker image. The executable was removed in v4.64.0.",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-5b022ff6db71befabda751db57d8a680dcee0c653e2cba9fc7562275ca9bd283",
"author": "@lucasmrod",
"timestamp": "2025-04-10T15:43:15.232137-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2025-21614"
},
"timestamp": "2025-04-10T15:43:15.232143-03:00",
"products": [
{
"@id": "fleet"
},
{
"@id": "pkg:golang/github.com/go-git/go-git/v5"
}
],
"status": "not_affected",
"status_notes": "The fleetctl executable is unused in the fleetdm/fleet docker image. The executable was removed in v4.64.0.",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-cef4f9875ecaa9e8f27f8ba99337c635c31b801f0d071eaf60de2cc5e05ef780",
"author": "@lucasmrod",
"timestamp": "2025-04-14T16:30:01.904493-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2025-26519"
},
"timestamp": "2025-04-14T16:30:01.904498-03:00",
"products": [
{
"@id": "fleet"
},
{
"@id": "pkg:apk/alpine/musl@1.2.5-r8?os_name=alpine&os_version=3.21"
}
],
"status": "not_affected",
"status_notes": "fleet does not perform any EUC-KR to UTF-8 translation by libc",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-a183e8cd49f44ec1818dcbaadcea8a43d42f8e3b6c599a613b107752e8bf35f5",
"author": "@lucasmrod",
"timestamp": "2025-04-10T15:23:54.606468-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2025-30204"
},
"timestamp": "2025-04-10T15:23:54.60648-03:00",
"products": [
{
"@id": "fleet"
},
{
"@id": "pkg:golang/github.com/golang-jwt/jwt/v4"
}
],
"status": "not_affected",
"status_notes": "The token format being validated before the call to ParseUnverified",
"justification": "inline_mitigations_already_exist"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-45767dc61272aac34a6e7995372d80b8e9cdfb956d3e2d92c068e94f56d4c741",
"author": "@lucasmrod",
"timestamp": "2025-04-10T14:46:52.70983-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2012-0881"
},
"timestamp": "2025-04-10T14:46:52.709835-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:maven/xerces/xercesImpl"
}
],
"status": "not_affected",
"status_notes": "fleetctl does not use Java",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-eac272349912fc8e15ba454df1f7ad8fe080b1326e1fab24b1b2a0ff1a7f8a33",
"author": "@lucasmrod",
"timestamp": "2025-04-10T07:36:31.115694-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2013-4002"
},
"timestamp": "2025-04-10T07:36:31.1157-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:maven/xerces/xercesImpl"
}
],
"status": "not_affected",
"status_notes": "fleetctl does not use Java",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-469d711e005a8d3393e8a278cd6989fdf46a6b883f5e9387bebe5d7e5d277d61",
"author": "@lucasmrod",
"timestamp": "2025-04-15T10:31:31.924948-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2019-10202"
},
"timestamp": "2025-04-15T10:31:31.924953-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:maven/org.codehaus.jackson/jackson-mapper-asl"
}
],
"status": "not_affected",
"status_notes": "fleetctl does not use Java",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-4ae6be0524ed5bb8eb3a53965dfe5622e11934c5fd45fbc45d4d647fdefed395",
"author": "@getvictor",
"timestamp": "2025-04-09T10:26:02.350331-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2023-32698"
},
"timestamp": "2025-04-09T10:26:02.350338-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:golang/github.com/goreleaser/nfpm/v2"
}
],
"status": "not_affected",
"status_notes": "When packaging linux files, fleetctl does not use global permissions. It was verified that packed fleetd package files do not have group/global write permissions.",
"justification": "vulnerable_code_cannot_be_controlled_by_adversary"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-5b2b06d8e0527002fb6c8d507d7f34bf29922b47e546a1b6050faeba7e9d7630",
"author": "@lucasmrod",
"timestamp": "2025-04-15T10:17:19.625095-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2023-45853"
},
"timestamp": "2025-04-15T10:17:19.625099-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:deb/debian/zlib1g"
}
],
"status": "not_affected",
"status_notes": "fleetctl does not use zlib C library",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-cd47567372016fff85e01a8b70ef5f3c31c8df9c1634c4143633137c44809d1f",
"author": "@lucasmrod",
"timestamp": "2025-04-15T10:28:21.796432-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2023-6879"
},
"timestamp": "2025-04-15T10:28:21.796437-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:deb/debian/libaom3"
}
],
"status": "not_affected",
"status_notes": "fleetctl does not use libaom3",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-4cff85f80b944b78a8b5100dd0320e0cd86452461a330bfeb6cc1708cba5aadb",
"author": "@lucasmrod",
"timestamp": "2025-04-10T07:34:26.535554-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2024-7254"
},
"timestamp": "2025-04-10T07:34:26.535559-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:maven/com.google.protobuf/protobuf-java"
}
],
"status": "not_affected",
"status_notes": "fleetctl does not use Java",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,26 @@
{
"@context": "https://openvex.dev/ns/v0.2.0",
"@id": "https://openvex.dev/docs/public/vex-b00fa9494ed92db550cc2d471d8a6323c77edea4ca5e6ecdfc9222fc4a92c30a",
"author": "@lucasmrod",
"timestamp": "2025-04-09T13:24:20.950924-03:00",
"version": 1,
"statements": [
{
"vulnerability": {
"name": "CVE-2025-31115"
},
"timestamp": "2025-04-09T13:24:20.950928-03:00",
"products": [
{
"@id": "fleetctl"
},
{
"@id": "pkg:deb/debian/liblzma5"
}
],
"status": "not_affected",
"status_notes": "fleetctl does not use liblzma5",
"justification": "vulnerable_code_not_in_execute_path"
}
]
}

View file

@ -0,0 +1,58 @@
package main
import (
"context"
"flag"
"fmt"
"log"
"sort"
"strings"
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
"github.com/google/go-github/v37/github"
)
func main() {
n := flag.Int("last-minor-releases", 0, "Output number of Fleet minor releases (with highest patch number)")
flag.Parse()
if *n <= 0 {
log.Fatal("Set a valid --last-minor-releases value")
}
c := github.NewClient(fleethttp.NewGithubClient()).Repositories
githubReleases, _, err := c.ListReleases(context.Background(), "fleetdm", "fleet", &github.ListOptions{})
if err != nil {
log.Fatal(err)
}
var releaseVersions []string
for _, gr := range githubReleases {
releaseVersions = append(releaseVersions, strings.TrimPrefix(*gr.Name, "fleet-"))
}
sort.Slice(releaseVersions, func(i, j int) bool {
return releaseVersions[i] > releaseVersions[j]
})
lastMinor := releaseVersions[0]
outputReleases := []string{lastMinor}
for _, version := range releaseVersions {
if len(outputReleases) >= *n {
break
}
lastMinorPart := strings.Split(lastMinor, ".")[1]
minor := strings.Split(version, ".")[1]
if minor < lastMinorPart {
outputReleases = append(outputReleases, version)
lastMinor = version
}
}
for i, version := range outputReleases {
if i != 0 {
fmt.Printf(" ")
}
fmt.Printf("%s", version)
}
}

View file

@ -0,0 +1,102 @@
package main
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
)
type OpenVEXDocument struct {
Context string `json:"context"`
Statements []Statement `json:"statements"`
Author string `json:"author"`
}
type Statement struct {
Vulnerability Vulnerability `json:"vulnerability"`
Status string `json:"status"`
StatusNotes string `json:"status_notes"`
Products []Product `json:"products"`
Justification string `json:"justification,omitempty"`
Timestamp string `json:"timestamp,omitempty"`
}
type Vulnerability struct {
Name string `json:"name"`
}
type Product struct {
ID string `json:"@id"`
}
func parseOpenVEX(filePath string) (*OpenVEXDocument, error) {
data, err := os.ReadFile(filePath)
if err != nil {
return nil, err
}
var vex OpenVEXDocument
err = json.Unmarshal(data, &vex)
if err != nil {
return nil, err
}
return &vex, nil
}
func generateMarkdown(vex *OpenVEXDocument) string {
var sb strings.Builder
for _, stmt := range vex.Statements {
sb.WriteString(fmt.Sprintf("### %s\n", stmt.Vulnerability.Name))
sb.WriteString(fmt.Sprintf("- **Author:** %s\n", vex.Author))
sb.WriteString(fmt.Sprintf("- **Status:** `%s`\n", stmt.Status))
sb.WriteString(fmt.Sprintf("- **Status notes:** %s\n", stmt.StatusNotes))
if len(stmt.Products) > 0 {
sb.WriteString("- **Products:**\n")
for _, product := range stmt.Products {
sb.WriteString(fmt.Sprintf(" - `%s`\n", product.ID))
}
}
if stmt.Justification != "" {
sb.WriteString(fmt.Sprintf("- **Justification:** `%s`\n", stmt.Justification))
}
if stmt.Timestamp != "" {
sb.WriteString(fmt.Sprintf("- **Timestamp:** %s\n", stmt.Timestamp))
}
sb.WriteString("\n")
}
return sb.String()
}
func outputMarkdown(vexPath string) {
vex, err := parseOpenVEX(vexPath)
if err != nil {
fmt.Printf("Error parsing OpenVEX file %q: %s\n", vexPath, err)
return
}
md := generateMarkdown(vex)
fmt.Print(md)
}
func main() {
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go /path/to/directory/with/vex.json/files/")
return
}
vexPath := os.Args[1]
vexPaths, err := filepath.Glob(filepath.Join(vexPath, "*.vex.json"))
if err != nil {
fmt.Printf("Error processing directory %q: %v\n", vexPath, err)
}
if len(vexPaths) == 0 {
fmt.Printf("No vulnerabilities tracked at the moment.\n\n")
return
}
for _, vexPath := range vexPaths {
outputMarkdown(vexPath)
}
}