Skip to content

Commit 90585a4

Browse files
[CDRIVER-5535] Add a vulnerability report artifact to the repository and release archive (#1649)
* Add a snyk-monitor-snapshot task, and tweak the way secrets are passed * Generate and include a third_party_vulnerabilities file in releases * Documentation and process for 3rd-party vuln tracking * Add steps for long-term Snyk monitoring. Part of vulnerability reporting requirements is that we continually monitor past in-support releases for the discovery of new vulnerabilities within bundled dependencies. Add a release step to create a Snyk target for monitoring a snapshot of the vulnerabilities in the repository at the time of the release.
1 parent d5ff3c8 commit 90585a4

File tree

7 files changed

+461
-15
lines changed

7 files changed

+461
-15
lines changed

.evergreen/config_generator/components/earthly.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,13 +172,12 @@ def earthly_exec(
172172
args: Mapping[str, str] | None = None,
173173
) -> BuiltInCommand:
174174
"""Create a subprocess_exec command that runs Earthly with the given arguments"""
175-
env: dict[str, str] = {}
176-
if secrets:
177-
env["EARTHLY_SECRETS"] = ",".join(f"{k}={v}" for k, v in secrets.items())
175+
env: dict[str, str] = {k: v for k, v in (secrets or {}).items()}
178176
return subprocess_exec(
179177
"bash",
180178
args=[
181179
"tools/earthly.sh",
180+
*(f"--secret={k}" for k in (secrets or ())),
182181
f"+{target}",
183182
*(f"--{arg}={val}" for arg, val in (args or {}).items()),
184183
],

.evergreen/generated_configs/tasks.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1338,9 +1338,12 @@ tasks:
13381338
binary: bash
13391339
working_dir: mongoc
13401340
env:
1341-
EARTHLY_SECRETS: SILK_CLIENT_ID=${silk_client_id},SILK_CLIENT_SECRET=${silk_client_secret}
1341+
SILK_CLIENT_ID: ${silk_client_id}
1342+
SILK_CLIENT_SECRET: ${silk_client_secret}
13421343
args:
13431344
- tools/earthly.sh
1345+
- --secret=SILK_CLIENT_ID
1346+
- --secret=SILK_CLIENT_SECRET
13441347
- +create-silk-asset-group
13451348
- --branch=${branch_name}
13461349
- name: cse-sasl-cyrus-darwinssl-macos-1100-clang-compile

Earthfile

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ release-archive:
183183
COPY --dir .git .
184184
COPY (+sbom-download/augmented-sbom.json --branch=$sbom_branch) cyclonedx.sbom.json
185185
RUN git archive -o release.tar.gz \
186-
--verbose \
187186
--prefix="$prefix/" \ # Set the archive path prefix
188187
"$ref" \ # Add the source tree
189188
--add-file cyclonedx.sbom.json # Add the SBOM
@@ -325,6 +324,53 @@ create-silk-asset-group:
325324
--sbom-lite-path=etc/cyclonedx.sbom.json \
326325
--exist-ok
327326

327+
328+
snyk:
329+
FROM ubuntu:24.04
330+
RUN apt-get update && apt-get -y install curl
331+
RUN curl --location https://github.com/snyk/cli/releases/download/v1.1291.1/snyk-linux -o /usr/local/bin/snyk
332+
RUN chmod a+x /usr/local/bin/snyk
333+
334+
snyk-test:
335+
FROM +snyk
336+
WORKDIR /s
337+
# Take the scan from within the `src/` directory. This seems to help Snyk
338+
# actually find the external dependencies that live there.
339+
COPY --dir src .
340+
WORKDIR src/
341+
# Snaptshot the repository and run the scan
342+
RUN --no-cache --secret SNYK_TOKEN \
343+
snyk test --unmanaged --json > snyk.json
344+
SAVE ARTIFACT snyk.json
345+
346+
# snyk-monitor-snapshot :
347+
# Post a crafted snapshot of the repository to Snyk for monitoring. Refer to "Snyk Scanning"
348+
# in the dev docs for more details.
349+
snyk-monitor-snapshot:
350+
FROM +snyk
351+
WORKDIR /s
352+
ARG remote="https://github.com/mongodb/mongo-c-driver.git"
353+
ARG --required branch
354+
ARG --required name
355+
IF test "$remote" = "local"
356+
COPY --dir src .
357+
ELSE
358+
GIT CLONE --branch $branch $remote clone
359+
RUN mv clone/src .
360+
END
361+
# Take the scan from within the `src/` directory. This seems to help Snyk
362+
# actually find the external dependencies that live there.
363+
WORKDIR src/
364+
# Snaptshot the repository and run the scan
365+
RUN --no-cache --secret SNYK_TOKEN --secret SNYK_ORGANIZATION \
366+
snyk monitor \
367+
--org=$SNYK_ORGANIZATION \
368+
--target-reference=$name \
369+
--unmanaged \
370+
--print-deps \
371+
--project-name=mongo-c-driver \
372+
--remote-repo-url=https://github.com/mongodb/mongo-c-driver
373+
328374
# test-vcpkg-classic :
329375
# Builds src/libmongoc/examples/cmake/vcpkg by using vcpkg to download and
330376
# install a mongo-c-driver build in "classic mode". *Does not* use the local

docs/dev/deps.rst

Lines changed: 203 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ tracked separately from the library itself. These can be classified as:
2121
control over the versions of system dependencies that the user might
2222
provide to us.
2323

24+
.. _snyk: https://app.snyk.io
2425

2526
The Software Bill of Materials (SBOM)
2627
*************************************
@@ -95,14 +96,214 @@ process, as this is primarily a release artifact for end users.
9596

9697
The augmented SBOM contains extra data about the dependencies from the
9798
`SBOM-lite <sbom-lite>`, including vulnerabilities known at the time of the
98-
augmented SBOM's generation.
99+
augmented SBOM's generation. [#asbom-vulns]_
99100

100101
The augmented SBOM is produced automatically and asynchronously as part of an
101102
external process that is not contained within the repository itself. The
102103
augmented SBOM is downloaded from an internal service using the `+sbom-download`
103104
Earthly target, which is automatically included in the release archive for the
104105
`+release-archive` target.
105106

107+
.. _silk-asset-group:
108+
109+
Silk Asset Groups
110+
*****************
111+
112+
.. note:: A Silk asset group will be created automatically for each branch that
113+
is executed in CI.
114+
115+
We use Silk's *asset groups* to allow tracking of multiple versions of the
116+
SBOM-lite_ simultaneously (i.e. one for each release branch). These asset groups
117+
correspond to branches within the repository, and are created automatically when
118+
CI executes for the first time on a particular branch. If you need an asset
119+
group for a branch that has not run in CI, use the `+create-silk-asset-group`
120+
Earthly target to create the asset group on-demand.
121+
122+
Note that Silk pulls from the upstream Git repository for an asset group, so
123+
creating an asset group for a branch that does not exist in the main upstream
124+
repository will not work.
125+
126+
.. file:: tools/create-silk-asset-group.py
127+
128+
A Python script that will create an `asset group <silk-asset-group>` in Silk
129+
based on a set of parameters. Execute with ``--help`` for more information.
130+
For the C driver, it is easier to use the `+create-silk-asset-group` Earthly
131+
target.
132+
133+
134+
.. _snyk scanning:
135+
136+
Snyk Scanning
137+
*************
138+
139+
Snyk_ is a tool that detects dependencies and tracks vulnerabilities in
140+
packages. Snyk is used in a limited fashion to detect vulnerabilities in the
141+
bundled dependencies in the C driver repository.
142+
143+
.. _snyk caveats:
144+
145+
Caveats
146+
=======
147+
148+
At the time of writing (June 20, 2024), Snyk has trouble scanning the C driver
149+
repository for dependencies. If given the raw repository, it will detect the
150+
mongo-c-driver package as the sole "dependency" of itself, and it fails to
151+
detect the other dependencies within the project. The `+snyk-test` Earthly
152+
target is written to avoid this issue and allow Snyk to accurately detect other
153+
dependencies within the project.
154+
155+
Due to difficulty coordinating the behavior of Snyk and Silk at time of
156+
writing, vulnerability collection is partially a manual process. This is
157+
especially viable as the native code contains a very small number of
158+
dependencies and it is trivial to validate the output of Snyk by hand.
159+
160+
.. seealso:: The `releasing.snyk` step of the release process
161+
162+
163+
.. _vuln-reporting:
164+
165+
3rd-Party Dependency Vulnerability Reporting
166+
********************************************
167+
168+
Vulnerabilities in :term:`bundled dependencies <bundled dependency>` are tracked
169+
by Snyk, but we maintain a hand-written document that details the
170+
vulnerabilities in current and past dependencies of in-support release versions.
171+
172+
.. file:: etc/third_party_vulnerabilities.md
173+
174+
The third-party dependency vulnerabily report. This file is stored in the
175+
repository and updated manually as vulnerabilities are added/removed.
176+
177+
.. seealso:: At release-time, this file is added to the release archive. See:
178+
`releasing.vuln-report`
179+
180+
181+
Updating the Vulnerability Report
182+
=================================
183+
184+
When updating `etc/third_party_vulnerabilities.md`, perform the following steps:
185+
186+
1. Open the Snyk_ web UI and sign in via SSO.
187+
2. Open `this Snyk search query`__ (Find the **mongodb/mongo-c-driver** CLI
188+
target within the **dev-prod** organization. Do not use the *GitHub target*:
189+
That one is not currently useful to us.)
190+
191+
__ https://app.snyk.io/org/dev-prod/projects?searchQuery=mongo-c-driver&filters[Integrations]=cli
192+
3. Expand the **mongodb/mongo-c-driver** target, and then expand all **currently
193+
supported release versions**. (If you are preparing for a new release, that
194+
version should also be available and used after the `releasing.snyk` process
195+
has been completed.)
196+
4. Take note of *all unique vulnerabilities amongst all supported versions'*
197+
that are listed in Snyk. These will be the *relevant* vulnerabilities.
198+
5. For each relevant vulnerability that is not already listed in
199+
`etc/third_party_vulnerabilities.md`, add a new entry under its corresponding
200+
package heading that includes the details outlined in the `attribute table`
201+
below. [#fixit]_
202+
203+
6. For each *already recorded* vulnerability :math:`V` listed in
204+
`etc/third_party_vulnerabilities.md`:
205+
206+
1. If :math:`V` is not *relevant* (i.e. it is no longer part of any
207+
supported release version), delete its entry from
208+
`etc/third_party_vulnerabilities.md`.
209+
2. Otherwise, update the entry for of :math:`V` according to the current
210+
details of the codebase and Snyk report. [#fixit]_
211+
212+
It is possible that no details need to be modified e.g. if the
213+
vulnerability is old and already fixed in a past release.
214+
215+
7. Save and commit the changes to `etc/third_party_vulnerabilities.md`.
216+
217+
218+
.. _attribute table:
219+
220+
3rd-Party Dependency Vulnerability Attributes
221+
=============================================
222+
223+
The following attributes of external vulnerabilities must be recorded within
224+
`etc/third_party_vulnerabilities.md`.
225+
226+
.. list-table::
227+
228+
- - Attribute
229+
- Explanation
230+
- - **Date Detected**
231+
- The ISO 8601 date at which the vulnerability was first detected.
232+
- - **CVE Number**
233+
- The CVE record number. Recommended to include a hyperlink to the CVE.
234+
235+
Example: `CVE-2023-45853 <https://www.cve.org/CVERecord?id=CVE-2023-45853>`_
236+
- - **Snyk Entry**
237+
- A link to the Snyk entry in the Snyk Security database.
238+
239+
Example:
240+
`SNYK-UNMANAGED-MADLERZLIB-5969359 <https://security.snyk.io/vuln/SNYK-UNMANAGED-MADLERZLIB-5969359>`_.
241+
- - **Severity**
242+
- The severity of the vulnerability according to Snyk (Critical/High/Medium/Low)
243+
- - **Description**
244+
- Paste the description field from Snyk.
245+
- - **Upstream Fix Status**
246+
- One of "false positive", "won't fix", "fix pending", or "fix available".
247+
If a fix is avilable, this entry should include the version number and
248+
date at which the upstream project released a fix.
249+
- - **mongo-c-driver Fix Status**
250+
- One of "false positive", "won't fix", "fix pending", or "fix available".
251+
If a fix is avilable, this entry should include the version number and
252+
release date of the C driver that includes the fixed version. Use "fix
253+
pending" if the bundled dependency has been upgraded but there has not
254+
been a release that includes this upgrade.
255+
- - **Notes**
256+
- If a fix is available from the upstream package but has been purposefully
257+
omitted from a C driver release, this field should explain the reasoning
258+
for that omission.
259+
260+
Other notes about the vulnerability that may be useful to users and
261+
future developers can also be included here.
262+
263+
264+
.. rubric:: Example
265+
266+
The following is an example for a vulnerability listing in
267+
`etc/third_party_vulnerabilities.md`
268+
269+
.. code-block:: markdown
270+
271+
# Zlib
272+
273+
## CVE-2023-45853 - Integer Overflow or Wraparound
274+
275+
- **Date Detected**: 2024-06-24
276+
- **CVE Number**: [CVE-2023-45853](https://www.cve.org/CVERecord?id=CVE-2023-45853)
277+
- **Snyk Entry**: [SNYK-UNMANAGED-MADLERZLIB-5969359](https://security.snyk.io/vuln/SNYK-UNMANAGED-MADLERZLIB-5969359)
278+
- **Severity**: High
279+
- **Description**: Affected versions of this package are vulnerable to
280+
Integer Overflow or Wraparound via the `MiniZip` function in `zlib`, by
281+
providing a long filename, comment, or extra field.
282+
- **Upstream Fix Status**: Fix available (1.3.1, 2024-01-22)
283+
- **mongo-c-driver Fix Status**: Fix available (1.27.3, 2024-06-26)
284+
- **Notes**: This issue was related to Zip file handling, which was not used
285+
by mongo-c-driver. This errant code was never reachable via the C driver
286+
APIs.
287+
288+
289+
.. rubric:: Footnotes
290+
106291
.. [#f1]
107292
108-
This may change in the future depending on how the process may evolve.
293+
This may change in the future depending on how the process may evolve.
294+
295+
.. [#asbom-vulns]
296+
297+
At time of writing, the vulnerabilities listing in the augmented SBOM is
298+
incomplete and vulnerability collection is partially manual. See:
299+
`snyk caveats` and `releasing.vuln-report`.
300+
301+
.. [#fixit]
302+
303+
If a fix is available and is reasonably easy to introduce, consider upgrading
304+
the associated dependency to include a fix before the next release is
305+
finalized.
306+
307+
If a fix is available but *not* applied, then the rationale for such a
308+
decision will need to be included in the vulnerability listing (See the
309+
**Notes** section in the `attribute table`).

0 commit comments

Comments
 (0)