|
1 | 1 | # Dependency Scan |
2 | 2 |
|
3 | | -- [Dependency Scan](#dependency-scan) |
4 | | - - [Problem](#problem) |
5 | | - - [Software Bill of Materials](#software-bill-of-materials) |
6 | | - - [Standards](#standards) |
7 | | - - [Design](#design) |
8 | | - - [Tools](#tools) |
9 | | - - [syft](#syft) |
10 | | - - [grype](#grype) |
11 | | - - [Solution](#solution) |
12 | | - - [Recipe 1a: Docker images as targets](#recipe-1a-docker-images-as-targets) |
13 | | - - [Recipe 1b: Filesystem](#recipe-1b-filesystem) |
14 | | - - [Recipe 2: Using Docker images, Makefile and shell scripting](#recipe-2-using-docker-images-makefile-and-shell-scripting) |
15 | | - - [Recipe 3: Using GitHub Workflow Action](#recipe-3-using-github-workflow-action) |
16 | | - - [Recipe 4: Jenkins Pipeline](#recipe-4-jenkins-pipeline) |
17 | | - - [How It Works](#how-it-works) |
18 | | - - [Further Comments](#further-comments) |
19 | | - |
20 | 3 | ## Problem |
21 | 4 |
|
22 | 5 | The dependency scan feature can automatically find security vulnerabilities in your dependencies while you are developing and testing your applications. For example, dependency scanning lets you know if your application uses an external (open source) library that is known to be vulnerable. You can then take action to protect your application. |
@@ -283,59 +266,147 @@ zlib 1.2.11-r3 apk CVE-2018-25032 High |
283 | 266 |
|
284 | 267 | ### Recipe 3: Using GitHub Workflow Action |
285 | 268 |
|
286 | | -An action to generate software bill of materials for the repository and a Docker image |
| 269 | +> You may wish to change the `severity-cutoff` value in the examples from `low` to `high` or `critical` (see [here](https://github.com/anchore/scan-action?tab=readme-ov-file#failing-a-build-on-vulnerability-severity) for details). |
| 270 | +
|
| 271 | +#### Recipe 3a: Static Code Analysis |
| 272 | + |
| 273 | +Drop the following file into `.github/workflows/` to provide static code analysis for your repository: |
287 | 274 |
|
288 | 275 | ```yaml |
289 | | -name: "Generate SBOM" |
| 276 | +name: 'Z-AUTOMATED: SBOM Repo Scan' |
| 277 | + |
290 | 278 | on: |
291 | | - push: |
292 | | - branches: [main] |
293 | 279 | pull_request: |
294 | 280 | types: [opened, synchronize, reopened] |
| 281 | + |
| 282 | +permissions: |
| 283 | + actions: read # Required for anchore/sbom-action |
| 284 | + contents: write # Required for anchore/sbom-action |
| 285 | + id-token: write # Required for requesting the JWT |
| 286 | + pull-requests: write |
| 287 | + |
295 | 288 | jobs: |
296 | | - generate-sbom: |
| 289 | + sbom_scan: |
| 290 | + name: SBOM Repo Scan |
297 | 291 | runs-on: ubuntu-latest |
298 | 292 | steps: |
299 | | - - uses: actions/checkout@master |
300 | | - - uses: anchore/sbom-action@v0 |
301 | | - with: |
302 | | - path: ./ |
303 | | - format: cyclonedx-json |
304 | | - artifact-name: sbom-repo.cdx.json |
305 | | - - uses: anchore/sbom-action@v0 |
306 | | - with: |
307 | | - image: my-registry.com/my/awesome/image |
308 | | - registry-username: ${{ secrets.REGISTRY_USERNAME }} |
309 | | - registry-password: ${{ secrets.REGISTRY_PASSWORD }} |
310 | | - format: cyclonedx-json |
311 | | - artifact-name: sbom-image.cdx.json |
| 293 | + - uses: actions/checkout@v5 |
| 294 | + with: |
| 295 | + fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis |
| 296 | + |
| 297 | + - uses: anchore/sbom-action@v0 |
| 298 | + with: |
| 299 | + path: "." |
| 300 | + format: cyclonedx-json |
| 301 | + output-file: sbom-repo-${{ github.event.repository.name }}-${{ github.sha }}.cdx.json |
| 302 | + |
| 303 | + - uses: anchore/scan-action@v7 |
| 304 | + id: sbom-scan |
| 305 | + with: |
| 306 | + sbom: sbom-repo-${{ github.event.repository.name }}-${{ github.sha }}.cdx.json |
| 307 | + fail-build: true |
| 308 | + severity-cutoff: low |
| 309 | + only-fixed: true |
| 310 | + output-format: sarif |
| 311 | + |
| 312 | + - name: Upload Anchore scan SARIF report |
| 313 | + uses: github/codeql-action/upload-sarif@v3 |
| 314 | + if: always() |
| 315 | + with: |
| 316 | + sarif_file: ${{ steps.sbom-scan.outputs.sarif }} |
| 317 | + |
| 318 | + - name: Add/Update SBOM failure comment |
| 319 | + uses: actions/github-script@v8 |
| 320 | + if: always() && failure() |
| 321 | + with: |
| 322 | + script: | |
| 323 | + // 1. Retrieve existing bot comments for the PR |
| 324 | + const { data: comments } = await github.rest.issues.listComments({ |
| 325 | + owner: context.repo.owner, |
| 326 | + repo: context.repo.repo, |
| 327 | + issue_number: context.issue.number, |
| 328 | + }) |
| 329 | + |
| 330 | + const botComment = comments.find(comment => { |
| 331 | + return comment.user.type === 'Bot' && comment.body.includes('Code security issues found') |
| 332 | + }) |
| 333 | +
|
| 334 | + // 2. Prepare format of the comment |
| 335 | + const output = `### Code security issues found |
| 336 | + |
| 337 | + View full details [here](https://github.com/${{ github.repository }}/security/code-scanning?query=is%3Aopen+pr%3A${{ github.event.pull_request.number }}).`; |
| 338 | +
|
| 339 | + // 3. If we have a comment, update it, otherwise create a new one |
| 340 | + if (botComment) { |
| 341 | + github.rest.issues.deleteComment({ |
| 342 | + owner: context.repo.owner, |
| 343 | + repo: context.repo.repo, |
| 344 | + comment_id: botComment.id, |
| 345 | + body: output |
| 346 | + }) |
| 347 | + } |
| 348 | + |
| 349 | + github.rest.issues.createComment({ |
| 350 | + issue_number: context.issue.number, |
| 351 | + owner: context.repo.owner, |
| 352 | + repo: context.repo.repo, |
| 353 | + body: output |
| 354 | + }) |
| 355 | +
|
| 356 | + - name: Delete SBOM failure comment |
| 357 | + uses: actions/github-script@v8 |
| 358 | + if: always() && success() |
| 359 | + with: |
| 360 | + script: | |
| 361 | + // 1. Retrieve existing bot comments for the PR |
| 362 | + const { data: comments } = await github.rest.issues.listComments({ |
| 363 | + owner: context.repo.owner, |
| 364 | + repo: context.repo.repo, |
| 365 | + issue_number: context.issue.number, |
| 366 | + }) |
| 367 | + |
| 368 | + const botComment = comments.find(comment => { |
| 369 | + return comment.user.type === 'Bot' && comment.body.includes('Code security issues found') |
| 370 | + }) |
| 371 | +
|
| 372 | + // 2. If we have a comment, update it, otherwise create a new one |
| 373 | + if (botComment) { |
| 374 | + github.rest.issues.deleteComment({ |
| 375 | + owner: context.repo.owner, |
| 376 | + repo: context.repo.repo, |
| 377 | + comment_id: botComment.id |
| 378 | + }) |
| 379 | + } |
312 | 380 | ``` |
313 | 381 |
|
314 | | -An action to scan vulnerabilities based on the content of the generated sbom json file |
| 382 | +#### Recipe 3b: Image Scanning |
| 383 | +
|
| 384 | +Modify an existing workflow file which creates/uses an image to scan it for vunrubilities prior to use: |
| 385 | +
|
| 386 | +> This outputs issues as a table in its logs. |
315 | 387 |
|
316 | 388 | ```yaml |
317 | | -name: "Scan vulnerabilities" |
318 | | -on: |
319 | | - push: |
320 | | - branches: [main] |
321 | | - pull_request: |
322 | | - types: [opened, synchronize, reopened] |
323 | | -jobs: |
324 | | - scan-vulnerabilities: |
325 | | - runs-on: ubuntu-latest |
| 389 | +... |
| 390 | +permissions: |
| 391 | + actions: read # Required for anchore/sbom-action |
| 392 | + contents: write # Required for anchore/sbom-action |
| 393 | +... |
326 | 394 | steps: |
327 | | - - uses: anchore/scan-action@v3 |
328 | | - with: |
329 | | - sbom: sbom-repo.cdx.json |
330 | | - fail-build: true |
331 | | - severity-cutoff: critical |
332 | | - acs-report-enable: true |
333 | | - - uses: anchore/scan-action@v3 |
334 | | - with: |
335 | | - sbom: sbom-image.cdx.json |
336 | | - fail-build: true |
337 | | - severity-cutoff: critical |
338 | | - acs-report-enable: true |
| 395 | + ... |
| 396 | + - uses: anchore/sbom-action@v0 |
| 397 | + with: |
| 398 | + image: <image_location>/<image_name>:<image_tag> |
| 399 | + format: cyclonedx-json |
| 400 | + output-file: sbom-image-${{ github.event.repository.name }}-${{ github.sha }}.cdx.json |
| 401 | + |
| 402 | + - uses: anchore/scan-action@v7 |
| 403 | + with: |
| 404 | + sbom: sbom-image-${{ github.event.repository.name }}-${{ github.sha }}.cdx.json |
| 405 | + fail-build: true |
| 406 | + severity-cutoff: low |
| 407 | + only-fixed: true |
| 408 | + output-format: table |
| 409 | +... |
339 | 410 | ``` |
340 | 411 |
|
341 | 412 | ### Recipe 4: Jenkins Pipeline |
|
0 commit comments