Compare commits
254 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06659f1509 | ||
|
|
a91cc50df7 | ||
|
|
4b8bf874d8 | ||
|
|
5040caefc8 | ||
|
|
28cd5a5537 | ||
|
|
b2f554eb2a | ||
|
|
7a44a7a344 | ||
|
|
18842fbe04 | ||
|
|
12ca3ca6da | ||
|
|
728a3db6c6 | ||
|
|
4e7b5ca365 | ||
|
|
0fca2cda91 | ||
|
|
e50839bb40 | ||
|
|
f95a0f0d52 | ||
|
|
e5bf3d1e30 | ||
|
|
2193fb3c44 | ||
|
|
bbccb5a69d | ||
|
|
a625455f1c | ||
|
|
7e69f4820e | ||
|
|
f6c986b6c0 | ||
|
|
aab6f0bf20 | ||
|
|
eebf9c8f58 | ||
|
|
971092b847 | ||
|
|
2f2d8222e4 | ||
|
|
a2afd6e683 | ||
|
|
a423b99312 | ||
|
|
a069ad7818 | ||
|
|
015055e1f5 | ||
|
|
cbaa363990 | ||
|
|
bec02f098d | ||
|
|
d7f8b92a27 | ||
|
|
59ea0d5781 | ||
|
|
c788676f87 | ||
|
|
58ade462b4 | ||
|
|
77cab6e0b9 | ||
|
|
2ede15d358 | ||
|
|
d266c74941 | ||
|
|
4423396bcc | ||
|
|
356ae30c7e | ||
|
|
477dc7d5f9 | ||
|
|
89b8d7ff30 | ||
|
|
219b71b4fd | ||
|
|
aa6e1eb6f9 | ||
|
|
de6c3cbb6c | ||
|
|
b7d4d1ead4 | ||
|
|
e6c029d08a | ||
|
|
ec6cb1a642 | ||
|
|
7dfc16cf21 | ||
|
|
42d8fd6638 | ||
|
|
c3ef2035b5 | ||
|
|
274103e883 | ||
|
|
e618d83dae | ||
|
|
3b0b2ed4ce | ||
|
|
5c8d098324 | ||
|
|
11f4f81123 | ||
|
|
6db2092c72 | ||
|
|
8898bb0937 | ||
|
|
33d0833717 | ||
|
|
13874d866c | ||
|
|
f26a06b980 | ||
|
|
e2821a4fba | ||
|
|
ef8a1afcdb | ||
|
|
449add24af | ||
|
|
cb9afc8441 | ||
|
|
78b2b899a0 | ||
|
|
52fd3c2e0a | ||
|
|
8d5882be03 | ||
|
|
84dd33f7e9 | ||
|
|
9e903a1d88 | ||
|
|
f4c746a2d2 | ||
|
|
420f8ab13e | ||
|
|
d2827cba06 | ||
|
|
ce703ce4a5 | ||
|
|
50bb938a21 | ||
|
|
a31ddbe971 | ||
|
|
3a4e18ac82 | ||
|
|
8ba68361bd | ||
|
|
f5c5573936 | ||
|
|
eab2b425db | ||
|
|
cabd18daae | ||
|
|
02c3c3659d | ||
|
|
4f7b768369 | ||
|
|
d754cb8c6f | ||
|
|
a936e675c9 | ||
|
|
af116d3c9e | ||
|
|
b507360075 | ||
|
|
7fcbf44bb8 | ||
|
|
478d279919 | ||
|
|
33bd41b40f | ||
|
|
39a10089fc | ||
|
|
37abd612aa | ||
|
|
78de33e8ea | ||
|
|
22054626f3 | ||
|
|
28ddcf1ae8 | ||
|
|
df134c73f8 | ||
|
|
8da20c8c92 | ||
|
|
714b5ca246 | ||
|
|
51e152b01c | ||
|
|
884daff429 | ||
|
|
2a8336b9aa | ||
|
|
1e171af165 | ||
|
|
e65274e0ef | ||
|
|
db35450bbb | ||
|
|
24254d19f6 | ||
|
|
2ee074568c | ||
|
|
0aef82c58e | ||
|
|
8b2a799721 | ||
|
|
42f795fa34 | ||
|
|
8f737cc6eb | ||
|
|
76249bdcf0 | ||
|
|
59957d4c6b | ||
|
|
da8b72d2e7 | ||
|
|
b713ad0fd3 | ||
|
|
56115e9d4f | ||
|
|
7f859afacb | ||
|
|
628a7964d5 | ||
|
|
82fba77141 | ||
|
|
d5269da5ee | ||
|
|
8e57dee86b | ||
|
|
8bfbc84a41 | ||
|
|
1e811de263 | ||
|
|
8b5796f770 | ||
|
|
a2199bb417 | ||
|
|
279e76f704 | ||
|
|
5262590831 | ||
|
|
c275a841fd | ||
|
|
7beed30170 | ||
|
|
f50e1f42a1 | ||
|
|
3ae4de5869 | ||
|
|
6e35b8f53c | ||
|
|
beb60b05f3 | ||
|
|
582e7fd1ba | ||
|
|
11bc290111 | ||
|
|
392f68926c | ||
|
|
101d576025 | ||
|
|
bd3ba68cce | ||
|
|
3860d6e4e9 | ||
|
|
4f82673a61 | ||
|
|
b9a51de862 | ||
|
|
7f248341cc | ||
|
|
af3eaefdb2 | ||
|
|
07c9200eb7 | ||
|
|
8bc8a4ad60 | ||
|
|
9076a49b0f | ||
|
|
bb316d93ca | ||
|
|
efdb29d0d4 | ||
|
|
9bcf9e72f5 | ||
|
|
3147097daf | ||
|
|
33f74b3acb | ||
|
|
5915ffb42b | ||
|
|
ae4c42b975 | ||
|
|
19747d0535 | ||
|
|
da45061f4d | ||
|
|
cb1a4ed3a1 | ||
|
|
69dae54aa1 | ||
|
|
5dc8cfe55d | ||
|
|
798b564ee3 | ||
|
|
21bf5e58f7 | ||
|
|
e0f4ebd7cb | ||
|
|
23a9a5e319 | ||
|
|
1f5d17fe13 | ||
|
|
bcfa0287b9 | ||
|
|
681ab1b889 | ||
|
|
46051d5ec8 | ||
|
|
d8d692b8ba | ||
|
|
cc344dfbe3 | ||
|
|
0dec17fc3f | ||
|
|
f12446d3ba | ||
|
|
1c9ccb5e03 | ||
|
|
a463e794ce | ||
|
|
e0ca5eff38 | ||
|
|
1ebb3296ee | ||
|
|
b37f682ee2 | ||
|
|
da905108b4 | ||
|
|
bd57b4f9b5 | ||
|
|
9027dc3252 | ||
|
|
5750cc2e1a | ||
|
|
bbcce9f7b7 | ||
|
|
6bcb4af10f | ||
|
|
8d13234554 | ||
|
|
982f35b424 | ||
|
|
2e170cd15a | ||
|
|
cc6c67d81c | ||
|
|
669fd1fd1d | ||
|
|
8cd7de276e | ||
|
|
3bf3a46cd4 | ||
|
|
8edcc62a8d | ||
|
|
31c45ffc52 | ||
|
|
d8cc8b550b | ||
|
|
dbc7a83e8c | ||
|
|
19c0b70d26 | ||
|
|
9d617777d5 | ||
|
|
5d57deaa4f | ||
|
|
b5955597a4 | ||
|
|
b1410b27b8 | ||
|
|
0e777d386e | ||
|
|
b6d9c30eea | ||
|
|
5160a2eb53 | ||
|
|
40ed227c23 | ||
|
|
2a4400c147 | ||
|
|
82eb630be7 | ||
|
|
4a8db20a9a | ||
|
|
8db9b6a2a6 | ||
|
|
c159501d0d | ||
|
|
76e63d1124 | ||
|
|
79b6684840 | ||
|
|
214fe82c7e | ||
|
|
c489e31f5d | ||
|
|
efd812cb1a | ||
|
|
3a920dc401 | ||
|
|
7cb1598991 | ||
|
|
6a8800286e | ||
|
|
f3f3029014 | ||
|
|
0e52fde047 | ||
|
|
9b3fba04f9 | ||
|
|
1101634f6a | ||
|
|
499b7a6ecf | ||
|
|
cea9b0bc78 | ||
|
|
dea3428804 | ||
|
|
47d600a9b4 | ||
|
|
eae4bafff3 | ||
|
|
9e08bd44fb | ||
|
|
d9883e4442 | ||
|
|
e6f7e556e8 | ||
|
|
4b84e79cc3 | ||
|
|
05ae22a85c | ||
|
|
a0e5c3a2e2 | ||
|
|
712f9eba35 | ||
|
|
803b2f9a93 | ||
|
|
92f980f4b7 | ||
|
|
52e98f1bd9 | ||
|
|
6cd9a328a4 | ||
|
|
03a73667db | ||
|
|
a29d6d8c5b | ||
|
|
2a08969ddc | ||
|
|
3a94b7399b | ||
|
|
41d000c97e | ||
|
|
78da283c1b | ||
|
|
e362843705 | ||
|
|
097b8d4881 | ||
|
|
3b6122f86d | ||
|
|
f75a36945c | ||
|
|
e4c32cdb77 | ||
|
|
fb19abd09a | ||
|
|
d2afc206b2 | ||
|
|
43ff5f93e8 | ||
|
|
5e6a50b2f9 | ||
|
|
23b9533791 | ||
|
|
d1f8cfcfdc | ||
|
|
aa2336be92 | ||
|
|
e64617212e | ||
|
|
85e45cad95 | ||
|
|
9fa512a652 | ||
|
|
349371bbc9 |
15
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: monthly
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule:
|
||||
interval: monthly
|
||||
- package-ecosystem: gomod
|
||||
open-pull-requests-limit: 10
|
||||
directory: /
|
||||
schedule:
|
||||
interval: monthly
|
||||
18
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
## Description
|
||||
|
||||
## Related issues
|
||||
- Close #XXX
|
||||
|
||||
## Related PRs
|
||||
- [ ] #XXX
|
||||
- [ ] #YYY
|
||||
|
||||
Remove this section if you don't have related PRs.
|
||||
|
||||
## Checklist
|
||||
- [ ] I've read the [guidelines for contributing](https://github.com/aquasecurity/trivy/blob/main/CONTRIBUTING.md) to this repository.
|
||||
- [ ] I've followed the [conventions](https://github.com/aquasecurity/trivy/blob/main/CONTRIBUTING.md#title) in the PR title.
|
||||
- [ ] I've added tests that prove my fix is effective or that my feature works.
|
||||
- [ ] I've updated the [documentation](https://github.com/aquasecurity/trivy/blob/main/docs) with the relevant information (if needed).
|
||||
- [ ] I've added usage information (if the PR introduces new options)
|
||||
- [ ] I've included a "before" and "after" example to the description (if the PR is a user interface change).
|
||||
2
.github/workflows/mkdocs-dev.yaml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Install dependencies
|
||||
|
||||
2
.github/workflows/mkdocs-latest.yaml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Install dependencies
|
||||
|
||||
61
.github/workflows/publish-chart.yaml
vendored
@@ -1,47 +1,84 @@
|
||||
name: Publish Chart Helm
|
||||
|
||||
name: Publish Helm chart
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'helm/trivy/**'
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'helm/trivy/**'
|
||||
workflow_dispatch:
|
||||
env:
|
||||
HELM_REP: helm-charts
|
||||
GH_OWNER: aquasecurity
|
||||
CHART_DIR: helm/trivy
|
||||
KIND_VERSION: "v0.11.1"
|
||||
KIND_IMAGE: "kindest/node:v1.21.1@sha256:69860bda5563ac81e3c0057d654b5253219618a22ec3a346306239bba8cfa1a6"
|
||||
jobs:
|
||||
release:
|
||||
test-chart:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@v1
|
||||
uses: azure/setup-helm@18bc76811624f360dbd7f18c2d4ecb32c7b87bab #v1.1
|
||||
with:
|
||||
version: v3.5.0
|
||||
- name: Set up python
|
||||
uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.7
|
||||
- name: Setup Chart Linting
|
||||
id: lint
|
||||
uses: helm/chart-testing-action@6b64532d456fa490a3da177fbd181ac4c8192b58 #v2.1.0
|
||||
- name: Setup Kubernetes cluster (KIND)
|
||||
uses: helm/kind-action@94729529f85113b88f4f819c17ce61382e6d8478 #v1.2.0
|
||||
with:
|
||||
version: ${{ env.KIND_VERSION }}
|
||||
image: ${{ env.KIND_IMAGE }}
|
||||
- name: Run chart-testing
|
||||
run: ct lint-and-install --validate-maintainers=false --charts helm/trivy
|
||||
- name: Run chart-testing (Ingress enabled)
|
||||
run: |
|
||||
sed -i -e '117s,false,'true',g' ./helm/trivy/values.yaml
|
||||
ct lint-and-install --validate-maintainers=false --charts helm/trivy
|
||||
|
||||
publish-chart:
|
||||
if: github.event_name == 'push'
|
||||
needs:
|
||||
- test-chart
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 #v2.4.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install chart-releaser
|
||||
run: |
|
||||
wget https://github.com/helm/chart-releaser/releases/download/v1.1.1/chart-releaser_1.1.1_linux_amd64.tar.gz
|
||||
tar xzvf chart-releaser_1.1.1_linux_amd64.tar.gz cr
|
||||
wget https://github.com/helm/chart-releaser/releases/download/v1.3.0/chart-releaser_1.3.0_linux_amd64.tar.gz
|
||||
echo "baed2315a9bb799efb71d512c5198a2a3b8dcd139d7f22f878777cffcd649a37 chart-releaser_1.3.0_linux_amd64.tar.gz" | sha256sum -c -
|
||||
tar xzvf chart-releaser_1.3.0_linux_amd64.tar.gz cr
|
||||
- name: Package helm chart
|
||||
run: |
|
||||
./cr package ${{ env.CHART_DIR }}
|
||||
- name: Upload helm chart
|
||||
# Failed with upload the same version: https://github.com/helm/chart-releaser/issues/101
|
||||
continue-on-error: true
|
||||
## Upload the tar in the Releases repository
|
||||
run: |
|
||||
./cr upload -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} --token ${{ secrets.ORG_GITHUB_TOKEN }} -p .cr-release-packages
|
||||
./cr upload -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} --token ${{ secrets.ORG_REPO_TOKEN }} -p .cr-release-packages
|
||||
- name: Index helm chart
|
||||
run: |
|
||||
./cr index -o ${{ env.GH_OWNER }} -r ${{ env.HELM_REP }} -c https://${{ env.GH_OWNER }}.github.io/${{ env.HELM_REP }}/ -i index.yaml
|
||||
|
||||
- name: Push index file
|
||||
uses: dmnemec/copy_file_to_another_repo_action@v1.0.4
|
||||
uses: dmnemec/copy_file_to_another_repo_action@c93037aa10fa8893de271f19978c980d0c1a9b37 #v1.1.1
|
||||
env:
|
||||
API_TOKEN_GITHUB: ${{ secrets.ORG_GITHUB_TOKEN }}
|
||||
API_TOKEN_GITHUB: ${{ secrets.ORG_REPO_TOKEN }}
|
||||
with:
|
||||
source_file: 'index.yaml'
|
||||
destination_repo: '${{ env.GH_OWNER }}/${{ env.HELM_REP }}'
|
||||
|
||||
20
.github/workflows/release.yaml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
tags:
|
||||
- "v*"
|
||||
env:
|
||||
GO_VERSION: "1.16"
|
||||
GO_VERSION: "1.17"
|
||||
GH_USER: "aqua-bot"
|
||||
jobs:
|
||||
release:
|
||||
@@ -12,11 +12,16 @@ jobs:
|
||||
runs-on: ubuntu-18.04 # 20.04 doesn't provide createrepo for now
|
||||
env:
|
||||
DOCKER_CLI_EXPERIMENTAL: "enabled"
|
||||
permissions:
|
||||
id-token: write # For cosign
|
||||
packages: write # For GHCR
|
||||
contents: read # Not required for public repositories, but for clarity
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y install rpm reprepro createrepo distro-info
|
||||
- uses: sigstore/cosign-installer@51f8e5c6fce54e46006ae97d73b2b6315f518752 # pin@v2.0.0
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
@@ -49,27 +54,32 @@ jobs:
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ env.GH_USER }}
|
||||
password: ${{ secrets.ORG_GITHUB_TOKEN }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login to ECR
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: public.ecr.aws
|
||||
username: ${{ secrets.ECR_ACCESS_KEY_ID }}
|
||||
password: ${{ secrets.ECR_SECRET_ACCESS_KEY }}
|
||||
- name: Generate SBOM
|
||||
uses: CycloneDX/gh-gomod-generate-sbom@v1
|
||||
with:
|
||||
args: mod -licenses -json -output bom.json
|
||||
version: ^v1
|
||||
- name: Release
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: v0.164.0
|
||||
version: v1.4.1
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.ORG_REPO_TOKEN }}
|
||||
- name: Checkout trivy-repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: ${{ github.repository_owner }}/trivy-repo
|
||||
path: trivy-repo
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.ORG_GITHUB_TOKEN }}
|
||||
token: ${{ secrets.ORG_REPO_TOKEN }}
|
||||
- name: Setup git settings
|
||||
run: |
|
||||
git config --global user.email "knqyf263@gmail.com"
|
||||
|
||||
23
.github/workflows/scan.yaml
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
name: Scan vulnerabilities
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Scan Go vulnerabilities
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Run Trivy vulnerability scanner and create GitHub issues
|
||||
uses: knqyf263/trivy-issue-action@v0.0.3
|
||||
with:
|
||||
assignee: knqyf263
|
||||
severity: CRITICAL
|
||||
skip-dirs: integration,examples
|
||||
label: vulnerability
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
2
.github/workflows/stale-issues.yaml
vendored
@@ -7,7 +7,7 @@ jobs:
|
||||
timeout-minutes: 1
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
- uses: actions/stale@v4
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue is stale because it has been labeled with inactivity.'
|
||||
|
||||
26
.github/workflows/test.yaml
vendored
@@ -1,7 +1,16 @@
|
||||
name: Test
|
||||
on: pull_request
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- 'docs/**'
|
||||
- 'mkdocs.yml'
|
||||
- 'LICENSE'
|
||||
pull_request:
|
||||
env:
|
||||
GO_VERSION: "1.16"
|
||||
GO_VERSION: "1.17"
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
@@ -15,19 +24,14 @@ jobs:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@v2
|
||||
uses: golangci/golangci-lint-action@v3.1.0
|
||||
with:
|
||||
version: v1.39
|
||||
version: v1.41
|
||||
args: --deadline=30m
|
||||
|
||||
- name: Run unit tests
|
||||
run: make test
|
||||
|
||||
- name: Upload code coverage
|
||||
uses: codecov/codecov-action@v1
|
||||
with:
|
||||
files: ./coverage.txt
|
||||
|
||||
integration:
|
||||
name: Integration Test
|
||||
runs-on: ubuntu-latest
|
||||
@@ -71,7 +75,7 @@ jobs:
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: v0.164.0
|
||||
version: v1.4.1
|
||||
args: release --snapshot --rm-dist --skip-publish
|
||||
|
||||
build-documents:
|
||||
@@ -83,7 +87,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
- uses: actions/setup-python@v2
|
||||
- uses: actions/setup-python@v3
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Install dependencies
|
||||
|
||||
10
.gitignore
vendored
@@ -4,7 +4,7 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
trivy
|
||||
/trivy
|
||||
|
||||
## chart release
|
||||
.cr-release-packages
|
||||
@@ -23,4 +23,10 @@ thumbs.db
|
||||
|
||||
# test fixtures
|
||||
coverage.txt
|
||||
integration/testdata/fixtures/
|
||||
integration/testdata/fixtures/images
|
||||
|
||||
# SBOMs generated during CI
|
||||
/bom.json
|
||||
|
||||
# goreleaser output
|
||||
dist
|
||||
|
||||
@@ -6,12 +6,10 @@ linters-settings:
|
||||
check-shadowing: false
|
||||
gofmt:
|
||||
simplify: false
|
||||
golint:
|
||||
min-confidence: 0
|
||||
revive:
|
||||
ignore-generated-header: true
|
||||
gocyclo:
|
||||
min-complexity: 10
|
||||
maligned:
|
||||
suggest-new: true
|
||||
min-complexity: 20
|
||||
dupl:
|
||||
threshold: 100
|
||||
goconst:
|
||||
@@ -21,6 +19,10 @@ linters-settings:
|
||||
locale: US
|
||||
goimports:
|
||||
local-prefixes: github.com/aquasecurity
|
||||
gosec:
|
||||
excludes:
|
||||
- G204
|
||||
- G402
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
@@ -32,14 +34,13 @@ linters:
|
||||
- errcheck
|
||||
- varcheck
|
||||
- deadcode
|
||||
- golint
|
||||
- revive
|
||||
- gosec
|
||||
- unconvert
|
||||
- goconst
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
- maligned
|
||||
- misspell
|
||||
|
||||
run:
|
||||
@@ -56,9 +57,6 @@ issues:
|
||||
- linters:
|
||||
- gosec
|
||||
text: "Deferring unsafe method"
|
||||
- linters:
|
||||
- gosec
|
||||
text: "G204: Subprocess launched with variable"
|
||||
- linters:
|
||||
- errcheck
|
||||
text: "Close` is not checked"
|
||||
|
||||
100
CONTRIBUTING.md
@@ -1,28 +1,104 @@
|
||||
Thank you for taking interest in contributing to Trivy !
|
||||
Thank you for taking interest in contributing to Trivy!
|
||||
|
||||
## Issues
|
||||
- Feel free to open issues for any reason. When you open a new issue, you'll have to select an issue kind: bug/feature/support and fill the required information based on the selected template.
|
||||
- Please spend a small amount of time giving due diligence to the issue tracker. Your issue might be a duplicate. If it is, please add your comment to the existing issue.
|
||||
- Remember users might be searching for your issue in the future, so please give it a meaningful title to help others.
|
||||
- Remember that users might search for your issue in the future, so please give it a meaningful title to help others.
|
||||
- The issue should clearly explain the reason for opening, the proposal if you have any, and any relevant technical information.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
1. Every Pull Request should have an associated bug or feature issue unless you are fixing a trivial documentation issue.
|
||||
1. Your PR is more likely to be accepted if it focuses on just one change.
|
||||
1. Describe what the PR does. There's no convention enforced, but please try to be concise and descriptive. Treat the PR description as a commit message. Titles that starts with "fix"/"add"/"improve"/"remove" are good examples.
|
||||
1. Please add the associated Issue in the PR description.
|
||||
1. There's no need to add or tag reviewers.
|
||||
1. If a reviewer commented on your code or asked for changes, please remember to mark the discussion as resolved after you address it. PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side).
|
||||
1. Please include a comment with the results before and after your change.
|
||||
1. Your PR is more likely to be accepted if it includes tests (We have not historically been very strict about tests, but we would like to improve this!).
|
||||
1. If your PR affects the user experience in some way, please update the Readme and the CLI help accordingly.
|
||||
4. Please add the associated Issue link in the PR description.
|
||||
2. Your PR is more likely to be accepted if it focuses on just one change.
|
||||
5. There's no need to add or tag reviewers.
|
||||
6. If a reviewer commented on your code or asked for changes, please remember to respond with comment. Do not mark discussion as resolved. It's up to reviewer to mark it resolved (in case if suggested fix addresses problem properly). PRs with unresolved issues should not be merged (even if the comment is unclear or requires no action from your side).
|
||||
7. Please include a comment with the results before and after your change.
|
||||
8. Your PR is more likely to be accepted if it includes tests (We have not historically been very strict about tests, but we would like to improve this!).
|
||||
9. If your PR affects the user experience in some way, please update the README.md and the CLI help accordingly.
|
||||
|
||||
### Title
|
||||
It is not that strict, but we use the title conventions in this repository.
|
||||
Each commit message doesn't have to follow the conventions as long as it is clear and descriptive since it will be squashed and merged.
|
||||
|
||||
#### Format of the title
|
||||
|
||||
```
|
||||
<type>(<scope>): <subject>
|
||||
```
|
||||
|
||||
The `type` and `scope` should always be lowercase as shown below.
|
||||
|
||||
**Allowed `<type>` values:**
|
||||
- **feat** for a new feature for the user, not a new feature for build script. Such commit will trigger a release bumping a MINOR version.
|
||||
- **fix** for a bug fix for the user, not a fix to a build script. Such commit will trigger a release bumping a PATCH version.
|
||||
- **perf** for performance improvements. Such commit will trigger a release bumping a PATCH version.
|
||||
- **docs** for changes to the documentation.
|
||||
- **style** for formatting changes, missing semicolons, etc.
|
||||
- **refactor** for refactoring production code, e.g. renaming a variable.
|
||||
- **test** for adding missing tests, refactoring tests; no production code change.
|
||||
- **build** for updating build configuration, development tools or other changes irrelevant to the user.
|
||||
- **chore** for updates that do not apply to the above, such as dependency updates.
|
||||
|
||||
**Example `<scope>` values:**
|
||||
- alpine
|
||||
- redhat
|
||||
- ruby
|
||||
- python
|
||||
- terraform
|
||||
- report
|
||||
- etc.
|
||||
|
||||
The `<scope>` can be empty (e.g. if the change is a global or difficult to assign to a single component), in which case the parentheses are omitted.
|
||||
|
||||
#### Example titles
|
||||
|
||||
```
|
||||
feat(alma): add support for AlmaLinux
|
||||
```
|
||||
|
||||
```
|
||||
fix(oracle): handle advisories with ksplice versions
|
||||
```
|
||||
|
||||
```
|
||||
docs(misconf): add comparison with Conftest and TFsec
|
||||
```
|
||||
|
||||
```
|
||||
chore(deps): bump go.uber.org/zap from 1.19.1 to 1.20.0
|
||||
```
|
||||
|
||||
**NOTE**: please do not use `chore(deps): update fanal` and something like that if you add new features or fix bugs in Trivy-related projects.
|
||||
The PR title should describe what the PR adds or fixes even though it just updates the dependency in Trivy.
|
||||
|
||||
### Unit tests
|
||||
Your PR must pass all the unit tests. You can test it as below.
|
||||
|
||||
```
|
||||
$ make test
|
||||
```
|
||||
|
||||
### Integration tests
|
||||
Your PR must pass all the integration tests. You can test it as below.
|
||||
|
||||
```
|
||||
$ make test-integration
|
||||
```
|
||||
|
||||
### Documentation
|
||||
You can build the documents as below and view it at http://localhost:8000.
|
||||
|
||||
```
|
||||
$ make mkdocs-serve
|
||||
```
|
||||
|
||||
## Understand where your pull request belongs
|
||||
|
||||
Trivy is composed of several different repositories that work together:
|
||||
|
||||
- [Trivy](https://github.com/aquasecurity/trivy) is the client-side, user-facing, command line tool.
|
||||
- [vuln-list](https://github.com/aquasecurity/vuln-list) is a vulnerabilities database, aggregated from different sources, and normalized for easy consumption. This of this as the "server" side of the trivy command line tool. **There should be no pull requests to this repo**
|
||||
- [vuln-list](https://github.com/aquasecurity/vuln-list) is a vulnerabilities database, aggregated from different sources, and normalized for easy consumption. Think of this as the "server" side of the trivy command line tool. **There should be no pull requests to this repo**
|
||||
- [vuln-list-update](https://github.com/aquasecurity/vuln-list-update) is the code that maintains the vuln-list database.
|
||||
- [fanal](https://github.com/aquasecurity/fanal) is a library for extracting system information containers. It is being used by Trivy to find testable subjects in the container image.
|
||||
- [trivy-db](https://github.com/aquasecurity/trivy-db) maintains the vulnerability database pulled by Trivy CLI.
|
||||
- [fanal](https://github.com/aquasecurity/fanal) is a library for extracting system information from containers. It is being used by Trivy to find testable subjects in the container image.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.13
|
||||
FROM alpine:3.15.0
|
||||
RUN apk --no-cache add ca-certificates git
|
||||
COPY trivy /usr/local/bin/trivy
|
||||
COPY contrib/*.tpl contrib/
|
||||
|
||||
12
Dockerfile.protoc
Normal file
@@ -0,0 +1,12 @@
|
||||
FROM golang:1.17
|
||||
|
||||
# Install protoc (cf. http://google.github.io/proto-lens/installing-protoc.html)
|
||||
ENV PROTOC_ZIP=protoc-3.19.4-linux-x86_64.zip
|
||||
RUN apt-get update && apt-get install -y unzip
|
||||
RUN curl --retry 5 -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.19.4/$PROTOC_ZIP \
|
||||
&& unzip -o $PROTOC_ZIP -d /usr/local bin/protoc \
|
||||
&& unzip -o $PROTOC_ZIP -d /usr/local 'include/*' \
|
||||
&& rm -f $PROTOC_ZIP
|
||||
|
||||
RUN go install github.com/twitchtv/twirp/protoc-gen-twirp@v8.1.0
|
||||
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.27.1
|
||||
22
Makefile
@@ -27,22 +27,22 @@ deps:
|
||||
go mod tidy
|
||||
|
||||
$(GOBIN)/golangci-lint:
|
||||
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(GOBIN) v1.21.0
|
||||
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(GOBIN) v1.41.1
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -v -short -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
integration/testdata/fixtures/*.tar.gz:
|
||||
git clone https://github.com/aquasecurity/trivy-test-images.git integration/testdata/fixtures
|
||||
integration/testdata/fixtures/images/*.tar.gz:
|
||||
git clone https://github.com/aquasecurity/trivy-test-images.git integration/testdata/fixtures/images
|
||||
|
||||
.PHONY: test-integration
|
||||
test-integration: integration/testdata/fixtures/*.tar.gz
|
||||
test-integration: integration/testdata/fixtures/images/*.tar.gz
|
||||
go test -v -tags=integration ./integration/...
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(GOBIN)/golangci-lint
|
||||
$(GOBIN)/golangci-lint run
|
||||
$(GOBIN)/golangci-lint run --timeout 5m
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
@@ -54,7 +54,13 @@ build:
|
||||
|
||||
.PHONY: protoc
|
||||
protoc:
|
||||
find ./rpc/ -name "*.proto" -type f -exec protoc --proto_path=$(GOSRC):. --twirp_out=. --go_out=. {} \;
|
||||
docker build -t trivy-protoc - < Dockerfile.protoc
|
||||
docker run --rm -it -v ${PWD}:/app -w /app trivy-protoc make _$@
|
||||
|
||||
_protoc:
|
||||
for path in `find ./rpc/ -name "*.proto" -type f`; do \
|
||||
protoc --twirp_out=. --twirp_opt=paths=source_relative --go_out=. --go_opt=paths=source_relative $${path} || exit; \
|
||||
done
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
@@ -62,10 +68,10 @@ install:
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf integration/testdata/fixtures/
|
||||
rm -rf integration/testdata/fixtures/images
|
||||
|
||||
$(GOBIN)/labeler:
|
||||
GO111MODULE=off go get github.com/knqyf263/labeler
|
||||
go install github.com/knqyf263/labeler@latest
|
||||
|
||||
.PHONY: label
|
||||
label: $(GOBIN)/labeler
|
||||
|
||||
253
README.md
@@ -1,89 +1,45 @@
|
||||
<img src="docs/imgs/logo.png" width="150">
|
||||
<p align="center">
|
||||
<img src="docs/imgs/logo.png" width="200">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://aquasecurity.github.io/trivy/">Documentation</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues
|
||||
</p>
|
||||
|
||||
[![GitHub Release][release-img]][release]
|
||||
[](https://goreportcard.com/report/github.com/aquasecurity/trivy)
|
||||
[][license]
|
||||
[](https://codecov.io/gh/aquasecurity/trivy)
|
||||
[![Test][test-img]][test]
|
||||
[![Go Report Card][go-report-img]][go-report]
|
||||
[![License: Apache-2.0][license-img]][license]
|
||||
[![GitHub All Releases][github-all-releases-img]][release]
|
||||
![Docker Pulls][docker-pulls]
|
||||
|
||||
[release]: https://github.com/aquasecurity/trivy/releases
|
||||
[release-img]: https://img.shields.io/github/release/aquasecurity/trivy.svg?logo=github
|
||||
[github-all-releases-img]: https://img.shields.io/github/downloads/aquasecurity/trivy/total?logo=github
|
||||
[docker-pulls]: https://img.shields.io/docker/pulls/aquasec/trivy?logo=docker&label=docker%20pulls%20%2F%20trivy
|
||||
[license]: https://github.com/aquasecurity/trivy/blob/main/LICENSE
|
||||
|
||||
|
||||
A Simple and Comprehensive Vulnerability Scanner for Containers and other Artifacts, Suitable for CI.
|
||||
|
||||
# Abstract
|
||||
`Trivy` (`tri` pronounced like **tri**gger, `vy` pronounced like en**vy**) is a simple and comprehensive vulnerability scanner for containers and other artifacts.
|
||||
A software vulnerability is a glitch, flaw, or weakness present in the software or in an Operating System.
|
||||
`Trivy` detects vulnerabilities of OS packages (Alpine, RHEL, CentOS, etc.) and application dependencies (Bundler, Composer, npm, yarn, etc.).
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan. All you need to do for scanning is to specify a target such as an image name of the container.
|
||||
`Trivy` (`tri` pronounced like **tri**gger, `vy` pronounced like en**vy**) is a simple and comprehensive scanner for vulnerabilities in container images, file systems, and Git repositories, as well as for configuration issues.
|
||||
`Trivy` detects vulnerabilities of OS packages (Alpine, RHEL, CentOS, etc.) and language-specific packages (Bundler, Composer, npm, yarn, etc.).
|
||||
In addition, `Trivy` scans Infrastructure as Code (IaC) files such as Terraform, Dockerfile and Kubernetes, to detect potential configuration issues that expose your deployments to the risk of attack.
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan.
|
||||
|
||||
<img src="docs/imgs/overview.png" width="700">
|
||||
<p align="center">
|
||||
<img src="docs/imgs/overview.png" width="800" alt="Trivy Overview">
|
||||
</p>
|
||||
|
||||
Trivy can be run in two different modes:
|
||||
|
||||
- [Standalone](https://aquasecurity.github.io/trivy/latest/modes/standalone/)
|
||||
- [Client/Server](https://aquasecurity.github.io/trivy/latest/modes/client-server/)
|
||||
|
||||
Trivy can scan three different artifacts:
|
||||
|
||||
- [Container Images](https://aquasecurity.github.io/trivy/latest/scanning/image/)
|
||||
- [Filesystem](https://aquasecurity.github.io/trivy/latest/scanning/filesystem/)
|
||||
- [Git Repositories](https://aquasecurity.github.io/trivy/latest/scanning/git-repository/)
|
||||
|
||||
<img src="docs/imgs/usage.gif" width="700">
|
||||
<img src="docs/imgs/usage1.png" width="600">
|
||||
<img src="docs/imgs/usage2.png" width="600">
|
||||
|
||||
It is considered to be used in CI. Before pushing to a container registry or deploying your application, you can scan your local container image and other artifacts easily.
|
||||
See [here](https://aquasecurity.github.io/trivy/latest/integrations/) for details.
|
||||
|
||||
# Features
|
||||
|
||||
- Detect comprehensive vulnerabilities
|
||||
- OS packages (Alpine, **Red Hat Universal Base Image**, Red Hat Enterprise Linux, CentOS, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
|
||||
- **Application dependencies** (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go)
|
||||
- Simple
|
||||
- Specify only an image name or artifact name
|
||||
- See [Quick Start](#quick-start) and [Examples](#examples)
|
||||
- Fast
|
||||
- The first scan will finish within 10 seconds (depending on your network). Consequent scans will finish in single seconds.
|
||||
- Unlike other scanners that take long to fetch vulnerability information (~10 minutes) on the first run, and encourage you to maintain a durable vulnerability database, Trivy is stateless and requires no maintenance or preparation.
|
||||
- Easy installation
|
||||
- `apt-get install`, `yum install` and `brew install` is possible (See [Installation](#installation))
|
||||
- **No pre-requisites** such as installation of DB, libraries, etc.
|
||||
- High accuracy
|
||||
- **Especially Alpine Linux and RHEL/CentOS**
|
||||
- Other OSes are also high
|
||||
- DevSecOps
|
||||
- **Suitable for CI** such as Travis CI, CircleCI, Jenkins, GitLab CI, etc.
|
||||
- See [CI Example](#continuous-integration-ci)
|
||||
- Support multiple formats
|
||||
- container image
|
||||
- A local image in Docker Engine which is running as a daemon
|
||||
- A local image in Podman (>=2.0) which is exposing a socket
|
||||
- A remote image in Docker Registry such as Docker Hub, ECR, GCR and ACR
|
||||
- A tar archive stored in the `docker save` / `podman save` formatted file
|
||||
- An image directory compliant with [OCI Image Format](https://github.com/opencontainers/image-spec)
|
||||
- local filesystem
|
||||
- remote git repository
|
||||
|
||||
Please see [LICENSE][license] for Trivy licensing information. Note that Trivy uses vulnerability information from a variety of sources, some of which are licensed for non-commercial use only.
|
||||
|
||||
# Documentation
|
||||
The official documentation, which provides detailed installation, configuration, and quick start guides, is available at https://aquasecurity.github.io/trivy/.
|
||||
|
||||
# Installation
|
||||
See [here](https://aquasecurity.github.io/trivy/latest/installation/)
|
||||
### Demo: Vulnerability Detection (Container Image)
|
||||
<p align="center">
|
||||
<img src="docs/imgs/vuln-demo.gif" width="1000" alt="Vulnerability Detection">
|
||||
</p>
|
||||
|
||||
### Demo: Misconfiguration Detection (IaC Files)
|
||||
<p align="center">
|
||||
<img src="docs/imgs/misconf-demo.gif" width="1000" alt="Misconfiguration Detection">
|
||||
</p>
|
||||
|
||||
# Quick Start
|
||||
|
||||
## Scan Image for Vulnerabilities
|
||||
Simply specify an image name (and a tag).
|
||||
|
||||
```
|
||||
@@ -114,21 +70,152 @@ Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
| | | | | | with long nonces |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
</details>
|
||||
|
||||
## Scan Filesystem for Vulnerabilities and Misconfigurations
|
||||
Simply specify a directory to scan.
|
||||
|
||||
```bash
|
||||
$ trivy fs --security-checks vuln,config [YOUR_PROJECT_DIR]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
$ trivy fs --security-checks vuln,config myproject/
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```bash
|
||||
2021-07-09T12:03:27.564+0300 INFO Number of language-specific files: 1
|
||||
2021-07-09T12:03:27.564+0300 INFO Detecting pipenv vulnerabilities...
|
||||
2021-07-09T12:03:27.566+0300 INFO Detected config files: 1
|
||||
|
||||
Pipfile.lock (pipenv)
|
||||
=====================
|
||||
Total: 1 (HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
| httplib2 | CVE-2021-21240 | HIGH | 0.12.1 | 0.19.0 | python-httplib2: Regular |
|
||||
| | | | | | expression denial of |
|
||||
| | | | | | service via malicious header |
|
||||
| | | | | | -->avd.aquasec.com/nvd/cve-2021-21240 |
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
```
|
||||
</details>
|
||||
|
||||
## Scan Directory for Misconfigurations
|
||||
|
||||
Simply specify a directory containing IaC files such as Terraform and Dockerfile.
|
||||
|
||||
```
|
||||
$ trivy config [YOUR_IAC_DIR]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ ls build/
|
||||
Dockerfile
|
||||
$ trivy config ./build
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2021-07-09T10:06:29.188+0300 INFO Need to update the built-in policies
|
||||
2021-07-09T10:06:29.188+0300 INFO Downloading the built-in policies...
|
||||
2021-07-09T10:06:30.520+0300 INFO Detected config files: 1
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
# Examples
|
||||
See [here](https://aquasecurity.github.io/trivy/latest/examples/filter/)
|
||||
|
||||
# Continuous Integration (CI)
|
||||
See [here](https://aquasecurity.github.io/trivy/latest/integrations/)
|
||||
# Features
|
||||
|
||||
# Vulnerability Detection
|
||||
See [here](https://aquasecurity.github.io/trivy/latest/vuln-detection/)
|
||||
- Comprehensive vulnerability detection
|
||||
- OS packages (Alpine Linux, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, AlmaLinux, Rocky Linux, CBL-Mariner, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
|
||||
- **Language-specific packages** (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go)
|
||||
- Misconfiguration detection (IaC scanning)
|
||||
- A wide variety of built-in policies are provided **out of the box**
|
||||
- Kubernetes, Docker, Terraform, and more coming soon
|
||||
- Support custom policies
|
||||
- Simple
|
||||
- Specify only an image name, a path to config files, or an artifact name
|
||||
- Fast
|
||||
- The first scan will finish within 10 seconds (depending on your network). Consequent scans will finish in single seconds.
|
||||
- Easy installation
|
||||
- `apt-get install`, `yum install` and `brew install` are possible.
|
||||
- **No pre-requisites** such as installation of DB, libraries, etc.
|
||||
- High accuracy
|
||||
- **Especially [Alpine Linux][alpine] and RHEL/CentOS**
|
||||
- Other OSes are also high
|
||||
- DevSecOps
|
||||
- **Suitable for CI** such as GitHub Actions, Jenkins, GitLab CI, etc.
|
||||
- Support multiple targets
|
||||
- container image, local filesystem and remote git repository
|
||||
- Supply chain security (SBOM support)
|
||||
- Support CycloneDX
|
||||
|
||||
# Usage
|
||||
See [here](https://aquasecurity.github.io/trivy/latest/usage/)
|
||||
# Integrations
|
||||
- [GitHub Actions][action]
|
||||
- [Visual Studio Code][vscode]
|
||||
|
||||
# Author
|
||||
# Documentation
|
||||
The official documentation, which provides detailed installation, configuration, and quick start guides, is available at https://aquasecurity.github.io/trivy/.
|
||||
|
||||
[Teppei Fukuda](https://github.com/knqyf263) (knqyf263)
|
||||
---
|
||||
|
||||
Trivy is an [Aqua Security][aquasec] open source project.
|
||||
Learn about our open source work and portfolio [here][oss].
|
||||
Contact us about any matter by opening a GitHub Discussion [here][discussions]
|
||||
|
||||
[test]: https://github.com/aquasecurity/trivy/actions/workflows/test.yaml
|
||||
[test-img]: https://github.com/aquasecurity/trivy/actions/workflows/test.yaml/badge.svg
|
||||
[go-report]: https://goreportcard.com/report/github.com/aquasecurity/trivy
|
||||
[go-report-img]: https://goreportcard.com/badge/github.com/aquasecurity/trivy
|
||||
[release]: https://github.com/aquasecurity/trivy/releases
|
||||
[release-img]: https://img.shields.io/github/release/aquasecurity/trivy.svg?logo=github
|
||||
[github-all-releases-img]: https://img.shields.io/github/downloads/aquasecurity/trivy/total?logo=github
|
||||
[docker-pulls]: https://img.shields.io/docker/pulls/aquasec/trivy?logo=docker&label=docker%20pulls%20%2F%20trivy
|
||||
[license]: https://github.com/aquasecurity/trivy/blob/main/LICENSE
|
||||
[license-img]: https://img.shields.io/badge/License-Apache%202.0-blue.svg
|
||||
|
||||
[alpine]: https://ariadne.space/2021/06/08/the-vulnerability-remediation-lifecycle-of-alpine-containers/
|
||||
[action]: https://github.com/aquasecurity/trivy-action
|
||||
[vscode]: https://github.com/aquasecurity/trivy-vscode-extension
|
||||
|
||||
[aquasec]: https://aquasec.com
|
||||
[oss]: https://www.aquasec.com/products/open-source-projects/
|
||||
[discussions]: https://github.com/aquasecurity/trivy/discussions
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
DEBIAN_RELEASES=$(debian-distro-info --supported)
|
||||
UBUNTU_RELEASES=$(ubuntu-distro-info --supported)
|
||||
UBUNTU_RELEASES=$(sort -u <(ubuntu-distro-info --supported-esm) <(ubuntu-distro-info --supported))
|
||||
|
||||
cd trivy-repo/deb
|
||||
|
||||
@@ -9,12 +9,14 @@ for release in ${DEBIAN_RELEASES[@]} ${UBUNTU_RELEASES[@]}; do
|
||||
echo "Removing deb package of $release"
|
||||
reprepro -A i386 remove $release trivy
|
||||
reprepro -A amd64 remove $release trivy
|
||||
reprepro -A arm64 remove $release trivy
|
||||
done
|
||||
|
||||
for release in ${DEBIAN_RELEASES[@]} ${UBUNTU_RELEASES[@]}; do
|
||||
echo "Adding deb package to $release"
|
||||
reprepro includedeb $release ../../dist/*Linux-64bit.deb
|
||||
reprepro includedeb $release ../../dist/*Linux-32bit.deb
|
||||
reprepro includedeb $release ../../dist/*Linux-ARM64.deb
|
||||
done
|
||||
|
||||
git add .
|
||||
|
||||
12
codecov.yml
@@ -1,12 +0,0 @@
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
target: auto
|
||||
threshold: 100%
|
||||
patch:
|
||||
default:
|
||||
informational: true
|
||||
target: auto
|
||||
threshold: 100%
|
||||
@@ -10,7 +10,7 @@ Trivy_container_scanning:
|
||||
IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
|
||||
allow_failure: true
|
||||
before_script:
|
||||
- export TRIVY_VERSION=${TRIVY_VERSION:-v0.4.3}
|
||||
- export TRIVY_VERSION=${TRIVY_VERSION:-v0.19.2}
|
||||
- apk add --no-cache curl docker-cli
|
||||
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
|
||||
- curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin ${TRIVY_VERSION}
|
||||
|
||||
142
contrib/asff.tpl
@@ -1,78 +1,68 @@
|
||||
[
|
||||
{{- $t_first := true -}}
|
||||
{{- range . -}}
|
||||
{{- $target := .Target -}}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{- else -}}
|
||||
,
|
||||
{{- end -}}
|
||||
{{- $trivyProductSev := 0 -}}
|
||||
{{- $trivyNormalizedSev := 0 -}}
|
||||
{{- if eq .Severity "LOW" -}}
|
||||
{{- $trivyProductSev = 1 -}}
|
||||
{{- $trivyNormalizedSev = 10 -}}
|
||||
{{- else if eq .Severity "MEDIUM" -}}
|
||||
{{- $trivyProductSev = 4 -}}
|
||||
{{- $trivyNormalizedSev = 40 -}}
|
||||
{{- else if eq .Severity "HIGH" -}}
|
||||
{{- $trivyProductSev = 7 -}}
|
||||
{{- $trivyNormalizedSev = 70 -}}
|
||||
{{- else if eq .Severity "CRITICAL" -}}
|
||||
{{- $trivyProductSev = 9 -}}
|
||||
{{- $trivyNormalizedSev = 90 -}}
|
||||
{{- end }}
|
||||
{{- $description := .Description -}}
|
||||
{{- if gt (len $description ) 1021 -}}
|
||||
{{- $description = (slice $description 0 1021) | printf "%v .." -}}
|
||||
{{- end}}
|
||||
{
|
||||
"SchemaVersion": "2018-10-08",
|
||||
"Id": "{{ $target }}/{{ .VulnerabilityID }}",
|
||||
"ProductArn": "arn:aws:securityhub:{{ getEnv "AWS_REGION" }}::product/aquasecurity/aquasecurity",
|
||||
"GeneratorId": "Trivy",
|
||||
"AwsAccountId": "{{ getEnv "AWS_ACCOUNT_ID" }}",
|
||||
"Types": [ "Software and Configuration Checks/Vulnerabilities/CVE" ],
|
||||
"CreatedAt": "{{ getCurrentTime }}",
|
||||
"UpdatedAt": "{{ getCurrentTime }}",
|
||||
"Severity": {
|
||||
"Product": {{ $trivyProductSev }},
|
||||
"Normalized": {{ $trivyNormalizedSev }}
|
||||
},
|
||||
"Title": "Trivy found a vulnerability to {{ .VulnerabilityID }} in container {{ $target }}",
|
||||
"Description": {{ escapeString $description | printf "%q" }},
|
||||
"Remediation": {
|
||||
"Recommendation": {
|
||||
"Text": "More information on this vulnerability is provided in the hyperlink",
|
||||
"Url": "{{ .PrimaryURL }}"
|
||||
}
|
||||
},
|
||||
"ProductFields": { "Product Name": "Trivy" },
|
||||
"Resources": [
|
||||
{
|
||||
"Type": "Container",
|
||||
"Id": "{{ $target }}",
|
||||
"Partition": "aws",
|
||||
"Region": "{{ getEnv "AWS_REGION" }}",
|
||||
"Details": {
|
||||
"Container": { "ImageName": "{{ $target }}" },
|
||||
"Other": {
|
||||
"CVE ID": "{{ .VulnerabilityID }}",
|
||||
"CVE Title": {{ .Title | printf "%q" }},
|
||||
"PkgName": "{{ .PkgName }}",
|
||||
"Installed Package": "{{ .InstalledVersion }}",
|
||||
"Patched Package": "{{ .FixedVersion }}",
|
||||
"NvdCvssScoreV3": "{{ (index .CVSS "nvd").V3Score }}",
|
||||
"NvdCvssVectorV3": "{{ (index .CVSS "nvd").V3Vector }}",
|
||||
"NvdCvssScoreV2": "{{ (index .CVSS "nvd").V2Score }}",
|
||||
"NvdCvssVectorV2": "{{ (index .CVSS "nvd").V2Vector }}"
|
||||
{
|
||||
"Findings": [
|
||||
{{- $t_first := true -}}
|
||||
{{- range . -}}
|
||||
{{- $target := .Target -}}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{- else -}}
|
||||
,
|
||||
{{- end -}}
|
||||
{{- $severity := .Severity -}}
|
||||
{{- if eq $severity "UNKNOWN" -}}
|
||||
{{- $severity = "INFORMATIONAL" -}}
|
||||
{{- end -}}
|
||||
{{- $description := .Description -}}
|
||||
{{- if gt (len $description ) 1021 -}}
|
||||
{{- $description = (substr 0 1021 $description) | printf "%v .." -}}
|
||||
{{- end}}
|
||||
{
|
||||
"SchemaVersion": "2018-10-08",
|
||||
"Id": "{{ $target }}/{{ .VulnerabilityID }}",
|
||||
"ProductArn": "arn:aws:securityhub:{{ env "AWS_REGION" }}::product/aquasecurity/aquasecurity",
|
||||
"GeneratorId": "Trivy",
|
||||
"AwsAccountId": "{{ env "AWS_ACCOUNT_ID" }}",
|
||||
"Types": [ "Software and Configuration Checks/Vulnerabilities/CVE" ],
|
||||
"CreatedAt": "{{ now | date "2006-01-02T15:04:05.999999999Z07:00" }}",
|
||||
"UpdatedAt": "{{ now | date "2006-01-02T15:04:05.999999999Z07:00" }}",
|
||||
"Severity": {
|
||||
"Label": "{{ $severity }}"
|
||||
},
|
||||
"Title": "Trivy found a vulnerability to {{ .VulnerabilityID }} in container {{ $target }}",
|
||||
"Description": {{ escapeString $description | printf "%q" }},
|
||||
"Remediation": {
|
||||
"Recommendation": {
|
||||
"Text": "More information on this vulnerability is provided in the hyperlink",
|
||||
"Url": "{{ .PrimaryURL }}"
|
||||
}
|
||||
},
|
||||
"ProductFields": { "Product Name": "Trivy" },
|
||||
"Resources": [
|
||||
{
|
||||
"Type": "Container",
|
||||
"Id": "{{ $target }}",
|
||||
"Partition": "aws",
|
||||
"Region": "{{ env "AWS_REGION" }}",
|
||||
"Details": {
|
||||
"Container": { "ImageName": "{{ $target }}" },
|
||||
"Other": {
|
||||
"CVE ID": "{{ .VulnerabilityID }}",
|
||||
"CVE Title": {{ .Title | printf "%q" }},
|
||||
"PkgName": "{{ .PkgName }}",
|
||||
"Installed Package": "{{ .InstalledVersion }}",
|
||||
"Patched Package": "{{ .FixedVersion }}",
|
||||
"NvdCvssScoreV3": "{{ (index .CVSS (sourceID "nvd")).V3Score }}",
|
||||
"NvdCvssVectorV3": "{{ (index .CVSS (sourceID "nvd")).V3Vector }}",
|
||||
"NvdCvssScoreV2": "{{ (index .CVSS (sourceID "nvd")).V2Score }}",
|
||||
"NvdCvssVectorV2": "{{ (index .CVSS (sourceID "nvd")).V2Vector }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"RecordState": "ACTIVE"
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
]
|
||||
],
|
||||
"RecordState": "ACTIVE"
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,30 +5,42 @@ import data.lib.trivy
|
||||
default ignore = false
|
||||
|
||||
nvd_v3_vector = v {
|
||||
v := input.CVSS.nvd.v3
|
||||
v := input.CVSS.nvd.V3Vector
|
||||
}
|
||||
|
||||
redhat_v3_vector = v {
|
||||
v := input.CVSS.redhat.V3Vector
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires high privilege
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.PrivilegesRequired == "High"
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector.PrivilegesRequired == "High"
|
||||
|
||||
# Check against RedHat scores as well as NVD
|
||||
redhat_cvss_vector := trivy.parse_cvss_vector_v3(redhat_v3_vector)
|
||||
redhat_cvss_vector.PrivilegesRequired == "High"
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires user interaction
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.UserInteraction == "Required"
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector.UserInteraction == "Required"
|
||||
|
||||
# Check against RedHat scores as well as NVD
|
||||
redhat_cvss_vector := trivy.parse_cvss_vector_v3(redhat_v3_vector)
|
||||
redhat_cvss_vector.UserInteraction == "Required"
|
||||
}
|
||||
|
||||
ignore {
|
||||
input.PkgName == "openssl"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate Attack Vector
|
||||
ignore_attack_vectors := {"Physical", "Local"}
|
||||
cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
nvd_cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
}
|
||||
|
||||
ignore {
|
||||
@@ -50,11 +62,11 @@ ignore {
|
||||
input.PkgName == "bash"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate Attack Vector
|
||||
ignore_attack_vectors := {"Physical", "Local", "Adjacent"}
|
||||
cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
nvd_cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
|
||||
# Evaluate severity
|
||||
input.Severity == {"LOW", "MEDIUM", "HIGH"}[_]
|
||||
@@ -64,11 +76,11 @@ ignore {
|
||||
input.PkgName == "django"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate Attack Vector
|
||||
ignore_attack_vectors := {"Physical", "Local"}
|
||||
cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
nvd_cvss_vector.AttackVector == ignore_attack_vectors[_]
|
||||
|
||||
# Evaluate severity
|
||||
input.Severity == {"LOW", "MEDIUM"}[_]
|
||||
@@ -86,7 +98,7 @@ ignore {
|
||||
input.PkgName == "jquery"
|
||||
|
||||
# Split CVSSv3 vector
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
|
||||
# Evaluate CWE-ID
|
||||
deny_cwe_ids := {"CWE-79"} # XSS
|
||||
|
||||
@@ -9,7 +9,11 @@ ignore_pkgs := {"bash", "bind-license", "rpm", "vim", "vim-minimal"}
|
||||
ignore_severities := {"LOW", "MEDIUM"}
|
||||
|
||||
nvd_v3_vector = v {
|
||||
v := input.CVSS.nvd.v3
|
||||
v := input.CVSS.nvd.V3Vector
|
||||
}
|
||||
|
||||
redhat_v3_vector = v {
|
||||
v := input.CVSS.redhat.V3Vector
|
||||
}
|
||||
|
||||
ignore {
|
||||
@@ -22,20 +26,29 @@ ignore {
|
||||
|
||||
# Ignore a vulnerability which is not remotely exploitable
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.AttackVector != "Network"
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector.AttackVector != "Network"
|
||||
|
||||
redhat_cvss_vector := trivy.parse_cvss_vector_v3(redhat_v3_vector)
|
||||
redhat_cvss_vector.AttackVector != "Network"
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires high privilege
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.PrivilegesRequired == "High"
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector.PrivilegesRequired == "High"
|
||||
|
||||
redhat_cvss_vector := trivy.parse_cvss_vector_v3(redhat_v3_vector)
|
||||
redhat_cvss_vector.PrivilegesRequired == "High"
|
||||
}
|
||||
|
||||
# Ignore a vulnerability which requires user interaction
|
||||
ignore {
|
||||
cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
cvss_vector.UserInteraction == "Required"
|
||||
nvd_cvss_vector := trivy.parse_cvss_vector_v3(nvd_v3_vector)
|
||||
nvd_cvss_vector.UserInteraction == "Required"
|
||||
|
||||
redhat_cvss_vector := trivy.parse_cvss_vector_v3(redhat_v3_vector)
|
||||
redhat_cvss_vector.UserInteraction == "Required"
|
||||
}
|
||||
|
||||
# Ignore CSRF
|
||||
|
||||
39
contrib/gitlab-codequality.tpl
Normal file
@@ -0,0 +1,39 @@
|
||||
{{- /* Template based on https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#data-types */ -}}
|
||||
[
|
||||
{{- $t_first := true }}
|
||||
{{- range . }}
|
||||
{{- $target := .Target }}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{ else -}}
|
||||
,
|
||||
{{- end }}
|
||||
{
|
||||
"type": "issue",
|
||||
"check_name": "container_scanning",
|
||||
"categories": [ "Security" ],
|
||||
"description": {{ list .VulnerabilityID .Title | join ": " | printf "%q" }},
|
||||
"fingerprint": "{{ .VulnerabilityID | sha1sum }}",
|
||||
"content": {{ .Description | printf "%q" }},
|
||||
"severity": {{ if eq .Severity "LOW" -}}
|
||||
"info"
|
||||
{{- else if eq .Severity "MEDIUM" -}}
|
||||
"minor"
|
||||
{{- else if eq .Severity "HIGH" -}}
|
||||
"major"
|
||||
{{- else if eq .Severity "CRITICAL" -}}
|
||||
"critical"
|
||||
{{- else -}}
|
||||
"info"
|
||||
{{- end }},
|
||||
"location": {
|
||||
"path": "{{ .PkgName }}-{{ .InstalledVersion }}",
|
||||
"lines": {
|
||||
"begin": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
]
|
||||
@@ -52,7 +52,7 @@
|
||||
}
|
||||
a.toggle-more-links { cursor: pointer; }
|
||||
</style>
|
||||
<title>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ getCurrentTime }}</title>
|
||||
<title>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ now }} </title>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
document.querySelectorAll('td.links').forEach(function(linkCell) {
|
||||
@@ -82,7 +82,7 @@
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ getCurrentTime }}</h1>
|
||||
<h1>{{- escapeXML ( index . 0 ).Target }} - Trivy Report - {{ now }}</h1>
|
||||
<table>
|
||||
{{- range . }}
|
||||
<tr class="group-header"><th colspan="6">{{ escapeXML .Type }}</th></tr>
|
||||
@@ -112,6 +112,31 @@
|
||||
</tr>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if (eq (len .Misconfigurations ) 0) }}
|
||||
<tr><th colspan="6">No Misconfigurations found</th></tr>
|
||||
{{- else }}
|
||||
<tr class="sub-header">
|
||||
<th>Type</th>
|
||||
<th>Misconf ID</th>
|
||||
<th>Check</th>
|
||||
<th>Severity</th>
|
||||
<th>Message</th>
|
||||
</tr>
|
||||
{{- range .Misconfigurations }}
|
||||
<tr class="severity-{{ escapeXML .Severity }}">
|
||||
<td class="misconf-type">{{ escapeXML .Type }}</td>
|
||||
<td>{{ escapeXML .ID }}</td>
|
||||
<td class="misconf-check">{{ escapeXML .Title }}</td>
|
||||
<td class="severity">{{ escapeXML .Severity }}</td>
|
||||
<td class="link" data-more-links="off" style="white-space:normal;"">
|
||||
{{ escapeXML .Message }}
|
||||
<br>
|
||||
<a href={{ escapeXML .PrimaryURL | printf "%q" }}>{{ escapeXML .PrimaryURL }}</a>
|
||||
</br>
|
||||
</td>
|
||||
</tr>
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
</table>
|
||||
{{- else }}
|
||||
|
||||
@@ -182,11 +182,11 @@ log_tag() {
|
||||
}
|
||||
log_debug() {
|
||||
log_priority 7 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 7)" "$@"
|
||||
echo "$(log_prefix)" "$(log_tag 7)" "$@"
|
||||
}
|
||||
log_info() {
|
||||
log_priority 6 || return 0
|
||||
echoerr "$(log_prefix)" "$(log_tag 6)" "$@"
|
||||
echo "$(log_prefix)" "$(log_tag 6)" "$@"
|
||||
}
|
||||
log_err() {
|
||||
log_priority 3 || return 0
|
||||
|
||||
@@ -14,5 +14,18 @@
|
||||
</testcase>
|
||||
{{- end }}
|
||||
</testsuite>
|
||||
{{- $failures := len .Misconfigurations }}
|
||||
<testsuite tests="{{ $failures }}" failures="{{ $failures }}" name="{{ .Target }}" errors="0" skipped="0" time="">
|
||||
{{- if not (eq .Type "") }}
|
||||
<properties>
|
||||
<property name="type" value="{{ .Type }}"></property>
|
||||
</properties>
|
||||
{{- end -}}
|
||||
{{ range .Misconfigurations }}
|
||||
<testcase classname="{{ .Type }}" name="[{{ .Severity }}] {{ .ID }}" time="">
|
||||
<failure message="{{ escapeXML .Title }}" type="description">{{ escapeXML .Description }}</failure>
|
||||
</testcase>
|
||||
{{- end }}
|
||||
</testsuite>
|
||||
{{- end }}
|
||||
</testsuites>
|
||||
@@ -1,95 +0,0 @@
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
||||
"version": "2.1.0",
|
||||
"runs": [
|
||||
{
|
||||
"tool": {
|
||||
"driver": {
|
||||
"name": "Trivy",
|
||||
"informationUri": "https://github.com/aquasecurity/trivy",
|
||||
"fullName": "Trivy Vulnerability Scanner",
|
||||
"version": "0.15.0",
|
||||
"rules": [
|
||||
{{- $t_first := true }}
|
||||
{{- range $result := . }}
|
||||
{{- $vulnerabilityType := .Type }}
|
||||
{{- range .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{ else -}}
|
||||
,
|
||||
{{- end }}
|
||||
{
|
||||
"id": {{ printf "%s: %s-%s %s" $result.Target .PkgName .InstalledVersion .VulnerabilityID | toJson }},
|
||||
"name": "{{ toSarifRuleName $vulnerabilityType }}",
|
||||
"shortDescription": {
|
||||
"text": {{ printf "%v Package: %v" .VulnerabilityID .PkgName | printf "%q" }}
|
||||
},
|
||||
"fullDescription": {
|
||||
"text": {{ endWithPeriod (escapeString .Title) | printf "%q" }}
|
||||
},
|
||||
"defaultConfiguration": {
|
||||
"level": "{{ toSarifErrorLevel .Vulnerability.Severity }}"
|
||||
}
|
||||
{{- with $help_uri := .PrimaryURL -}}
|
||||
,
|
||||
{{ $help_uri | printf "\"helpUri\": %q," -}}
|
||||
{{- else -}}
|
||||
,
|
||||
{{- end }}
|
||||
"help": {
|
||||
"text": {{ printf "Vulnerability %v\nSeverity: %v\nPackage: %v\nInstalled Version: %v\nFixed Version: %v\nLink: [%v](%v)" .VulnerabilityID .Vulnerability.Severity .PkgName .InstalledVersion .FixedVersion .VulnerabilityID .PrimaryURL | printf "%q"}},
|
||||
"markdown": {{ printf "**Vulnerability %v**\n| Severity | Package | Installed Version | Fixed Version | Link |\n| --- | --- | --- | --- | --- |\n|%v|%v|%v|%v|[%v](%v)|\n" .VulnerabilityID .Vulnerability.Severity .PkgName .InstalledVersion .FixedVersion .VulnerabilityID .PrimaryURL | printf "%q"}}
|
||||
},
|
||||
"properties": {
|
||||
"tags": [
|
||||
"vulnerability",
|
||||
"{{ .Vulnerability.Severity }}",
|
||||
{{ .PkgName | printf "%q" }}
|
||||
],
|
||||
"precision": "very-high"
|
||||
}
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"results": [
|
||||
{{- $t_first := true }}
|
||||
{{- range $result := . }}
|
||||
{{- $filePath := .Target }}
|
||||
{{- range $index, $vulnerability := .Vulnerabilities -}}
|
||||
{{- if $t_first -}}
|
||||
{{- $t_first = false -}}
|
||||
{{ else -}}
|
||||
,
|
||||
{{- end }}
|
||||
{
|
||||
"ruleId": {{ printf "%s: %s-%s %s" $result.Target .PkgName .InstalledVersion .VulnerabilityID | toJson }},
|
||||
"ruleIndex": {{ $index }},
|
||||
"level": "{{ toSarifErrorLevel $vulnerability.Vulnerability.Severity }}",
|
||||
"message": {
|
||||
"text": {{ endWithPeriod (escapeString $vulnerability.Description) | printf "%q" }}
|
||||
},
|
||||
"locations": [{
|
||||
"physicalLocation": {
|
||||
"artifactLocation": {
|
||||
"uri": "{{ toPathUri $filePath }}",
|
||||
"uriBaseId": "ROOTPATH"
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
],
|
||||
"columnKind": "utf16CodeUnits",
|
||||
"originalUriBaseIds": {
|
||||
"ROOTPATH": {
|
||||
"uri": "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
113
docs/advanced/air-gap.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Air-Gapped Environment
|
||||
|
||||
Trivy can be used in air-gapped environments. Note that an allowlist is [here][allowlist].
|
||||
|
||||
## Air-Gapped Environment for vulnerabilities
|
||||
|
||||
### Download the vulnerability database
|
||||
At first, you need to download the vulnerability database for use in air-gapped environments.
|
||||
Please follow [oras installation instruction][oras].
|
||||
|
||||
Download `db.tar.gz`:
|
||||
|
||||
```
|
||||
$ oras pull ghcr.io/aquasecurity/trivy-db:2 -a
|
||||
```
|
||||
|
||||
### Transfer the DB file into the air-gapped environment
|
||||
The way of transfer depends on the environment.
|
||||
|
||||
```
|
||||
$ rsync -av -e ssh /path/to/db.tar.gz [user]@[host]:dst
|
||||
```
|
||||
|
||||
### Put the DB file in Trivy's cache directory
|
||||
You have to know where to put the DB file. The following command shows the default cache directory.
|
||||
|
||||
```
|
||||
$ ssh user@host
|
||||
$ trivy -h | grep cache
|
||||
--cache-dir value cache directory (default: "/home/myuser/.cache/trivy") [$TRIVY_CACHE_DIR]
|
||||
```
|
||||
|
||||
Put the DB file in the cache directory + `/db`.
|
||||
|
||||
```
|
||||
$ mkdir -p /home/myuser/.cache/trivy/db
|
||||
$ cd /home/myuser/.cache/trivy/db
|
||||
$ tar xvf /path/to/db.tar.gz -C /home/myuser/.cache/trivy/db
|
||||
x trivy.db
|
||||
x metadata.json
|
||||
$ rm /path/to/db.tar.gz
|
||||
```
|
||||
|
||||
In an air-gapped environment it is your responsibility to update the Trivy database on a regular basis, so that the scanner can detect recently-identified vulnerabilities.
|
||||
|
||||
### Run Trivy with --skip-update and --offline-scan option
|
||||
In an air-gapped environment, specify `--skip-update` so that Trivy doesn't attempt to download the latest database file.
|
||||
In addition, if you want to scan Java dependencies such as JAR and pom.xml, you need to specify `--offline-scan` since Trivy tries to issue API requests for scanning Java applications by default.
|
||||
|
||||
```
|
||||
$ trivy image --skip-update --offline-scan alpine:3.12
|
||||
```
|
||||
|
||||
## Air-Gapped Environment for misconfigurations
|
||||
|
||||
### Download misconfiguration policies
|
||||
At first, you need to download misconfiguration policies for use in air-gapped environments.
|
||||
Please follow [oras installation instruction][oras].
|
||||
|
||||
Download `bundle.tar.gz`:
|
||||
|
||||
```
|
||||
$ oras pull ghcr.io/aquasecurity/appshield:latest -a
|
||||
```
|
||||
|
||||
### Transfer misconfiguration policies into the air-gapped environment
|
||||
The way of transfer depends on the environment.
|
||||
|
||||
```
|
||||
$ rsync -av -e ssh /path/to/bundle.tar.gz [user]@[host]:dst
|
||||
```
|
||||
|
||||
### Put the misconfiguration policies in Trivy's cache directory
|
||||
You have to know where to put the misconfiguration policies file. The following command shows the default cache directory.
|
||||
|
||||
```
|
||||
$ ssh user@host
|
||||
$ trivy -h | grep cache
|
||||
--cache-dir value cache directory (default: "/home/myuser/.cache/trivy") [$TRIVY_CACHE_DIR]
|
||||
```
|
||||
|
||||
Put the misconfiguration policies file in the cache directory + `/policy/content`.
|
||||
|
||||
```
|
||||
$ mkdir -p /home/myuser/.cache/trivy/policy/content
|
||||
$ cd /home/myuser/.cache/trivy/policy/content
|
||||
$ mv /path/to/bundle.tar.gz .
|
||||
```
|
||||
|
||||
Then, decompress it.
|
||||
`bundle.tar.gz ` file includes two folders: `docker`, `kubernetes` and file: `.manifest`.
|
||||
|
||||
```
|
||||
$ tar xvf bundle.tar.gz
|
||||
x ./docker/
|
||||
...
|
||||
x ./kubernetes/
|
||||
...
|
||||
x ./.manifest
|
||||
$ rm bundle.tar.gz
|
||||
```
|
||||
|
||||
In an air-gapped environment it is your responsibility to update policies on a regular basis, so that the scanner can detect recently-identified misconfigurations.
|
||||
|
||||
### Run Trivy with --skip-policy-update option
|
||||
In an air-gapped environment, specify `--skip-policy-update` so that Trivy doesn't attempt to download the latest misconfiguration policies.
|
||||
|
||||
```
|
||||
$ trivy conf --skip-policy-update /path/to/conf
|
||||
```
|
||||
|
||||
[allowlist]: ../getting-started/troubleshooting.md
|
||||
[oras]: https://oras.land/cli/
|
||||
19
docs/advanced/community/references.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# External References
|
||||
There are external blogs and evaluations.
|
||||
|
||||
## Blogs
|
||||
- [the vulnerability remediation lifecycle of Alpine containers][alpine]
|
||||
- [Continuous Container Vulnerability Testing with Trivy][semaphore]
|
||||
- [Open Source CVE Scanner Round-Up: Clair vs Anchore vs Trivy][round-up]
|
||||
- [Docker Image Security: Static Analysis Tool Comparison – Anchore Engine vs Clair vs Trivy][tool-comparison]
|
||||
|
||||
## Links
|
||||
- [Research Spike: evaluate Trivy for scanning running containers][gitlab]
|
||||
- [Istio evaluates scanners][istio]
|
||||
|
||||
[alpine]: https://ariadne.space/2021/06/08/the-vulnerability-remediation-lifecycle-of-alpine-containers/
|
||||
[semaphore]: https://semaphoreci.com/blog/continuous-container-vulnerability-testing-with-trivy
|
||||
[round-up]: https://boxboat.com/2020/04/24/image-scanning-tech-compared/
|
||||
[tool-comparison]: https://www.a10o.net/devsecops/docker-image-security-static-analysis-tool-comparison-anchore-engine-vs-clair-vs-trivy/
|
||||
[gitlab]: https://gitlab.com/gitlab-org/gitlab/-/issues/270888
|
||||
[istio]: https://github.com/istio/release-builder/pull/687#issuecomment-874938417
|
||||
37
docs/advanced/community/tools.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Community Tools
|
||||
The open source community has been hard at work developing new tools for Trivy. You can check out some of them here.
|
||||
|
||||
Have you created a tool that’s not listed? Add the name and description of your integration and open a pull request in the GitHub repository to get your change merged.
|
||||
|
||||
## GitHub Actions
|
||||
|
||||
| Actions | Description |
|
||||
| ------------------------------------------ | -------------------------------------------------------------------------------- |
|
||||
| [gitrivy][gitrivy] | GitHub Issue + Trivy |
|
||||
| [trivy-github-issues][trivy-github-issues] | GitHub Actions for creating GitHub Issues according to the Trivy scanning result |
|
||||
|
||||
## Semaphore
|
||||
|
||||
| Name | Description |
|
||||
| -------------------------------------------------------| ----------------------------------------- |
|
||||
| [Continuous Vulnerability Testing with Trivy][semaphore-tutorial] | Tutorial on scanning code, containers, infrastructure, and Kubernetes with Semaphore CI/CD. |
|
||||
|
||||
|
||||
## CircleCI
|
||||
|
||||
| Orb | Description |
|
||||
| -----------------------------------------| ----------------------------------------- |
|
||||
| [fifteen5/trivy-orb][fifteen5/trivy-orb] | Orb for running Trivy, a security scanner |
|
||||
|
||||
## Others
|
||||
|
||||
| Name | Description |
|
||||
| -----------------------------------------| ----------------------------------------- |
|
||||
| [Trivy Vulnerability Explorer][explorer] | Explore trivy vulnerability reports in your browser and create .trivyignore files interactively. Can be integrated in your CI/CD tooling with deep links. |
|
||||
|
||||
|
||||
[trivy-github-issues]: https://github.com/marketplace/actions/trivy-github-issues
|
||||
[fifteen5/trivy-orb]: https://circleci.com/developer/orbs/orb/fifteen5/trivy-orb
|
||||
[gitrivy]: https://github.com/marketplace/actions/trivy-action
|
||||
[explorer]: https://dbsystel.github.io/trivy-vulnerability-explorer/
|
||||
[semaphore-tutorial]: https://semaphoreci.com/blog/continuous-container-vulnerability-testing-with-trivy
|
||||
@@ -10,7 +10,7 @@ FROM alpine:3.7
|
||||
|
||||
RUN apk add curl \
|
||||
&& curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin \
|
||||
&& trivy filesystem --exit-code 1 --no-progress /
|
||||
&& trivy rootfs --exit-code 1 --no-progress /
|
||||
|
||||
$ docker build -t vulnerable-image .
|
||||
```
|
||||
@@ -21,7 +21,7 @@ insecure `curl | sh`. Also the image is not changed.
|
||||
# Run vulnerability scan on build image
|
||||
FROM build AS vulnscan
|
||||
COPY --from=aquasec/trivy:latest /usr/local/bin/trivy /usr/local/bin/trivy
|
||||
RUN trivy filesystem --exit-code 1 --no-progress /
|
||||
RUN trivy rootfs --exit-code 1 --no-progress /
|
||||
[...]
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# OCI
|
||||
# OCI Image Layout
|
||||
|
||||
An image directory compliant with "Open Container Image Layout Specification".
|
||||
An image directory compliant with [Open Container Image Layout Specification](https://github.com/opencontainers/image-spec/blob/master/spec.md).
|
||||
|
||||
Buildah:
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
# Podman
|
||||
|
||||
[EXPERIMENTAL] This feature might change without preserving backwards compatibility.
|
||||
!!! warning "EXPERIMENTAL"
|
||||
This feature might change without preserving backwards compatibility.
|
||||
|
||||
Scan your image in Podman (>=2.0) running locally. The remote Podman is not supported.
|
||||
Before performing Trivy commands, you must enable the podman.sock systemd service on your machine.
|
||||
For more details, see [here][sock]
|
||||
For more details, see [here][sock].
|
||||
|
||||
|
||||
```bash
|
||||
$ systemctl --user enable --now podman.socket
|
||||
@@ -1,12 +1,12 @@
|
||||
# Unpacked Filesystem
|
||||
|
||||
Scan aan unpacked container image filesystem.
|
||||
Scan an unpacked container image filesystem.
|
||||
|
||||
In this case, Trivy works the same way when scanning containers
|
||||
|
||||
```bash
|
||||
$ docker export $(docker create alpine:3.10.2) | tar -C /tmp/rootfs -xvf -
|
||||
$ trivy fs /tmp/rootfs
|
||||
$ trivy rootfs /tmp/rootfs
|
||||
```
|
||||
|
||||
<details>
|
||||
@@ -185,7 +185,7 @@ We use two labels [help wanted](https://github.com/aquasecurity/trivy/issues?q=i
|
||||
and [good first issue](https://github.com/aquasecurity/trivy/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
|
||||
to identify issues that have been specially groomed for new contributors.
|
||||
|
||||
We have specific [guidelines](/docs/contrib/help-wanted.md)
|
||||
We have specific [guidelines](/docs/advanced/contribd/contrib/help-wanted.md)
|
||||
for how to use these labels. If you see an issue that satisfies these
|
||||
guidelines, you can add the `help wanted` label and the `good first issue` label.
|
||||
Please note that adding the `good first issue` label must also
|
||||
2
docs/advanced/index.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Advanced
|
||||
This section describes advanced features, integrations, etc.
|
||||
5
docs/advanced/integrations/bitbucket.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Bitbucket Pipelines
|
||||
|
||||
See [trivy-pipe][trivy-pipe] for the details.
|
||||
|
||||
[trivy-pipe]: https://github.com/aquasecurity/trivy-pipe
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
|
||||
- run:
|
||||
name: Scan the local image with trivy
|
||||
command: trivy --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1}
|
||||
command: trivy image --exit-code 0 --no-progress trivy-ci-test:${CIRCLE_SHA1}
|
||||
workflows:
|
||||
version: 2
|
||||
release:
|
||||
@@ -1,7 +1,7 @@
|
||||
# GitHub Actions
|
||||
|
||||
- Here is the [Trivy Github Action][action]
|
||||
- The Microsoft Azure team have written a [container-scan action][azuer] that uses Trivy and Dockle
|
||||
- The Microsoft Azure team have written a [container-scan action][azure] that uses Trivy and Dockle
|
||||
- For full control over the options specified to Trivy, this [blog post][blog] describes adding Trivy into your own GitHub action workflows
|
||||
|
||||
[action]: https://github.com/aquasecurity/trivy-action
|
||||
163
docs/advanced/integrations/gitlab-ci.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# GitLab CI
|
||||
|
||||
If you're a GitLab Ultimate customer, GitLab 14.0 and above include out-of-the-box integration with Trivy. To enable it for your project, simply add the container scanning template to your `.gitlab-ci.yml` file. For more details, please refer to [GitLab's documentation](https://docs.gitlab.com/ee/user/application_security/container_scanning/).
|
||||
|
||||
If you're using an earlier version of GitLab, you can still use the new integration by copying the [contents of the 14.0 template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml) to your configuration.
|
||||
|
||||
Alternatively, you can always use the example configurations below.
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- test
|
||||
|
||||
trivy:
|
||||
stage: test
|
||||
image: docker:stable
|
||||
services:
|
||||
- name: docker:dind
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
command: ["dockerd-entrypoint.sh"]
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_DRIVER: overlay2
|
||||
# See https://github.com/docker-library/docker/pull/166
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
IMAGE: trivy-ci-test:$CI_COMMIT_SHA
|
||||
TRIVY_NO_PROGRESS: "true"
|
||||
TRIVY_CACHE_DIR: ".trivycache/"
|
||||
before_script:
|
||||
- export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
|
||||
- echo $TRIVY_VERSION
|
||||
- wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -
|
||||
allow_failure: true
|
||||
script:
|
||||
# Build image
|
||||
- docker build -t $IMAGE .
|
||||
# Build report
|
||||
- ./trivy image --exit-code 0 --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
|
||||
# Print report
|
||||
- ./trivy image --exit-code 0 --severity HIGH $IMAGE
|
||||
# Fail on severe vulnerabilities
|
||||
- ./trivy image --exit-code 1 --severity CRITICAL $IMAGE
|
||||
cache:
|
||||
paths:
|
||||
- .trivycache/
|
||||
# Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
|
||||
artifacts:
|
||||
reports:
|
||||
container_scanning: gl-container-scanning-report.json
|
||||
```
|
||||
|
||||
[Example][example]
|
||||
[Repository][repository]
|
||||
|
||||
### GitLab CI using Trivy container
|
||||
|
||||
To scan a previously built image that has already been pushed into the
|
||||
GitLab container registry the following CI job manifest can be used.
|
||||
Note that `entrypoint` needs to be unset for the `script` section to work.
|
||||
In case of a non-public GitLab project Trivy additionally needs to
|
||||
authenticate to the registry to be able to pull your application image.
|
||||
Finally, it is not necessary to clone the project repo as we only work
|
||||
with the container image.
|
||||
|
||||
```yaml
|
||||
container_scanning:
|
||||
image:
|
||||
name: docker.io/aquasec/trivy:latest
|
||||
entrypoint: [""]
|
||||
variables:
|
||||
# No need to clone the repo, we exclusively work on artifacts. See
|
||||
# https://docs.gitlab.com/ee/ci/runners/README.html#git-strategy
|
||||
GIT_STRATEGY: none
|
||||
TRIVY_USERNAME: "$CI_REGISTRY_USER"
|
||||
TRIVY_PASSWORD: "$CI_REGISTRY_PASSWORD"
|
||||
TRIVY_AUTH_URL: "$CI_REGISTRY"
|
||||
TRIVY_NO_PROGRESS: "true"
|
||||
TRIVY_CACHE_DIR: ".trivycache/"
|
||||
FULL_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
|
||||
script:
|
||||
- trivy --version
|
||||
# cache cleanup is needed when scanning images with the same tags, it does not remove the database
|
||||
- time trivy image --clear-cache
|
||||
# update vulnerabilities db
|
||||
- time trivy image --download-db-only
|
||||
# Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there
|
||||
- time trivy image --exit-code 0 --format template --template "@/contrib/gitlab.tpl"
|
||||
--output "$CI_PROJECT_DIR/gl-container-scanning-report.json" "$FULL_IMAGE_NAME"
|
||||
# Prints full report
|
||||
- time trivy image --exit-code 0 "$FULL_IMAGE_NAME"
|
||||
# Fail on critical vulnerabilities
|
||||
- time trivy image --exit-code 1 --severity CRITICAL "$FULL_IMAGE_NAME"
|
||||
cache:
|
||||
paths:
|
||||
- .trivycache/
|
||||
# Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
container_scanning: gl-container-scanning-report.json
|
||||
tags:
|
||||
- docker-runner
|
||||
```
|
||||
|
||||
[example]: https://gitlab.com/aquasecurity/trivy-ci-test/pipelines
|
||||
[repository]: https://github.com/aquasecurity/trivy-ci-test
|
||||
|
||||
### Gitlab CI alternative template
|
||||
|
||||
Depending on the edition of gitlab you have or your desired workflow, the
|
||||
container scanning template may not meet your needs. As an addition to the
|
||||
above container scanning template, a template for
|
||||
[code climate](https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html)
|
||||
has been included. The key things to update from the above examples are
|
||||
the `template` and `report` type. An updated example is below.
|
||||
|
||||
```yaml
|
||||
stages:
|
||||
- test
|
||||
|
||||
trivy:
|
||||
stage: test
|
||||
image: docker:stable
|
||||
services:
|
||||
- name: docker:dind
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
command: ["dockerd-entrypoint.sh"]
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_DRIVER: overlay2
|
||||
# See https://github.com/docker-library/docker/pull/166
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
IMAGE: trivy-ci-test:$CI_COMMIT_SHA
|
||||
TRIVY_NO_PROGRESS: "true"
|
||||
TRIVY_CACHE_DIR: ".trivycache/"
|
||||
before_script:
|
||||
- export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
|
||||
- echo $TRIVY_VERSION
|
||||
- wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -
|
||||
allow_failure: true
|
||||
script:
|
||||
# Build image
|
||||
- docker build -t $IMAGE .
|
||||
# Build report
|
||||
- ./trivy image --exit-code 0 --format template --template "@contrib/gitlab-codequality.tpl" -o gl-codeclimate.json $IMAGE
|
||||
cache:
|
||||
paths:
|
||||
- .trivycache/
|
||||
# Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
|
||||
artifacts:
|
||||
paths:
|
||||
- gl-codeclimate.json
|
||||
reports:
|
||||
codequality: gl-codeclimate.json
|
||||
```
|
||||
|
||||
Currently gitlab only supports a single code quality report. There is an
|
||||
open [feature request](https://gitlab.com/gitlab-org/gitlab/-/issues/9014)
|
||||
to support multiple reports. Until this has been implemented, if you
|
||||
already have a code quality report in your pipeline, you can use
|
||||
`jq` to combine reports. Depending on how you name your artifacts, it may
|
||||
be necessary to rename the artifact if you want to reuse the name. To then
|
||||
combine the previous artifact with the output of trivy, the following `jq`
|
||||
command can be used, `jq -s 'add' prev-codeclimate.json trivy-codeclimate.json > gl-codeclimate.json`.
|
||||
2
docs/advanced/integrations/index.md
Normal file
@@ -0,0 +1,2 @@
|
||||
# Integrations
|
||||
Scan your image automatically as part of your CI workflow, failing the workflow if a vulnerability is found. When you don't want to fail the test, specify `--exit-code 0`.
|
||||
@@ -15,8 +15,8 @@ before_install:
|
||||
- wget https://github.com/aquasecurity/trivy/releases/download/v${VERSION}/trivy_${VERSION}_Linux-64bit.tar.gz
|
||||
- tar zxvf trivy_${VERSION}_Linux-64bit.tar.gz
|
||||
script:
|
||||
- ./trivy --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT}
|
||||
- ./trivy --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT}
|
||||
- ./trivy image --exit-code 0 --severity HIGH --no-progress trivy-ci-test:${COMMIT}
|
||||
- ./trivy image --exit-code 1 --severity CRITICAL --no-progress trivy-ci-test:${COMMIT}
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/trivy
|
||||
@@ -55,5 +55,5 @@ $ trivy client --remote http://localhost:8080 --token dummy alpine:3.10
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
## Image
|
||||
|
||||

|
||||

|
||||
|
||||
## Filesystem
|
||||
|
||||

|
||||

|
||||
|
||||
## Git Repository
|
||||
|
||||

|
||||

|
||||
|
||||
27
docs/advanced/private-registries/acr.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Requirements
|
||||
None, Trivy uses Azure SDK for Go. You don't need to install `az` command.
|
||||
|
||||
# Privileges
|
||||
Service principal must have the `AcrPull` permissions.
|
||||
|
||||
## Creation of a service principal
|
||||
```bash
|
||||
export SP_DATA=$(az ad sp create-for-rbac --name TrivyTest --role AcrPull --scope "/subscriptions/<subscription_id>/resourceGroups/<resource_group>/providers/Microsoft.ContainerRegistry/registries/<registry_name>")
|
||||
```
|
||||
|
||||
# Usage
|
||||
```bash
|
||||
# must set TRIVY_USERNAME empty char
|
||||
export AZURE_CLIENT_ID$(echo $SP_DATA | jq -r .appId)
|
||||
export AZURE_CLIENT_SECRET$(echo $SP_DATA | jq -r .password)
|
||||
export AZURE_TENANT_ID$(echo $SP_DATA | jq -r .tenant)
|
||||
```
|
||||
|
||||
# Testing
|
||||
You can test credentials in the following manner.
|
||||
|
||||
```bash
|
||||
docker run -it --rm -v /tmp:/tmp\
|
||||
-e AZURE_CLIENT_ID=${AZURE_CLIENT_ID} -e AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET} \
|
||||
-e AZURE_TENANT_ID=${AZURE_TENANT_ID} aquasec/trivy image your_special_project.azurecr.io/your_special_image:your_special_tag
|
||||
```
|
||||
40
docs/advanced/private-registries/gcr.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Requirements
|
||||
None, Trivy uses Google Cloud SDK. You don't need to install `gcloud` command.
|
||||
|
||||
# Privileges
|
||||
Credential file must have the `roles/storage.objectViewer` permissions.
|
||||
More information can be found in [Google's documentation](https://cloud.google.com/container-registry/docs/access-control)
|
||||
|
||||
## JSON File Format
|
||||
The JSON file specified should have the following format provided by google's service account mechanisms:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "service_account",
|
||||
"project_id": "your_special_project",
|
||||
"private_key_id": "XXXXXXXXXXXXXXXXXXXXxx",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\nNONONONO\n-----END PRIVATE KEY-----\n",
|
||||
"client_email": "somedude@your_special_project.iam.gserviceaccount.com",
|
||||
"client_id": "1234567890",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/somedude%40your_special_project.iam.gserviceaccount.com"
|
||||
}
|
||||
```
|
||||
|
||||
# Usage
|
||||
If you want to use target project's repository, you can set them via `GOOGLE_APPLICATION_CREDENTIALS`.
|
||||
```bash
|
||||
# must set TRIVY_USERNAME empty char
|
||||
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credential.json
|
||||
```
|
||||
|
||||
# Testing
|
||||
You can test credentials in the following manner (assuming they are in `/tmp` on host machine).
|
||||
|
||||
```bash
|
||||
docker run -it --rm -v /tmp:/tmp\
|
||||
-e GOOGLE_APPLICATION_CREDENTIALS=/tmp/service_account.json\
|
||||
aquasec/trivy image gcr.io/your_special_project/your_special_image:your_special_tag
|
||||
```
|
||||
175
docs/advanced/sbom/cyclonedx.md
Normal file
@@ -0,0 +1,175 @@
|
||||
# CycloneDX
|
||||
Trivy generates JSON reports in the [CycloneDX][cyclonedx] format.
|
||||
Note that XML format is not supported at the moment.
|
||||
|
||||
|
||||
You can specify `cyclonedx` with the `--format` option.
|
||||
|
||||
```
|
||||
$ trivy image --format cyclonedx --output result.json alpine:3.15
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
$ cat result.json | jq .
|
||||
{
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.3",
|
||||
"serialNumber": "urn:uuid:2be5773d-7cd3-4b4b-90a5-e165474ddace",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"timestamp": "2022-02-22T15:11:40.270597Z",
|
||||
"tools": [
|
||||
{
|
||||
"vendor": "aquasecurity",
|
||||
"name": "trivy",
|
||||
"version": "dev"
|
||||
}
|
||||
],
|
||||
"component": {
|
||||
"bom-ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
|
||||
"type": "container",
|
||||
"name": "alpine:3.15",
|
||||
"version": "",
|
||||
"purl": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:SchemaVersion",
|
||||
"value": "2"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:ImageID",
|
||||
"value": "sha256:c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:RepoDigest",
|
||||
"value": "alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:DiffID",
|
||||
"value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:RepoTag",
|
||||
"value": "alpine:3.15"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"bom-ref": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
|
||||
"type": "library",
|
||||
"name": "alpine-baselayout",
|
||||
"version": "3.2.0-r18",
|
||||
"licenses": [
|
||||
{
|
||||
"expression": "GPL-2.0-only"
|
||||
}
|
||||
],
|
||||
"purl": "pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:SrcName",
|
||||
"value": "alpine-baselayout"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:SrcVersion",
|
||||
"value": "3.2.0-r18"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:LayerDigest",
|
||||
"value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:LayerDiffID",
|
||||
"value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
|
||||
}
|
||||
]
|
||||
},
|
||||
...(snip)...
|
||||
{
|
||||
"bom-ref": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
|
||||
"type": "library",
|
||||
"name": "zlib",
|
||||
"version": "1.2.11-r3",
|
||||
"licenses": [
|
||||
{
|
||||
"expression": "Zlib"
|
||||
}
|
||||
],
|
||||
"purl": "pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:SrcName",
|
||||
"value": "zlib"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:SrcVersion",
|
||||
"value": "1.2.11-r3"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:LayerDigest",
|
||||
"value": "sha256:59bf1c3509f33515622619af21ed55bbe26d24913cedbca106468a5fb37a50c3"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:LayerDiffID",
|
||||
"value": "sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bom-ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
|
||||
"type": "operating-system",
|
||||
"name": "alpine",
|
||||
"version": "3.15.0",
|
||||
"properties": [
|
||||
{
|
||||
"name": "aquasecurity:trivy:Type",
|
||||
"value": "alpine"
|
||||
},
|
||||
{
|
||||
"name": "aquasecurity:trivy:Class",
|
||||
"value": "os-pkgs"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"ref": "3da6a469-964d-4b4e-b67d-e94ec7c88d37",
|
||||
"dependsOn": [
|
||||
"pkg:apk/alpine/alpine-baselayout@3.2.0-r18?distro=3.15.0",
|
||||
"pkg:apk/alpine/alpine-keys@2.4-r1?distro=3.15.0",
|
||||
"pkg:apk/alpine/apk-tools@2.12.7-r3?distro=3.15.0",
|
||||
"pkg:apk/alpine/busybox@1.34.1-r3?distro=3.15.0",
|
||||
"pkg:apk/alpine/ca-certificates-bundle@20191127-r7?distro=3.15.0",
|
||||
"pkg:apk/alpine/libc-utils@0.7.2-r3?distro=3.15.0",
|
||||
"pkg:apk/alpine/libcrypto1.1@1.1.1l-r7?distro=3.15.0",
|
||||
"pkg:apk/alpine/libretls@3.3.4-r2?distro=3.15.0",
|
||||
"pkg:apk/alpine/libssl1.1@1.1.1l-r7?distro=3.15.0",
|
||||
"pkg:apk/alpine/musl@1.2.2-r7?distro=3.15.0",
|
||||
"pkg:apk/alpine/musl-utils@1.2.2-r7?distro=3.15.0",
|
||||
"pkg:apk/alpine/scanelf@1.3.3-r0?distro=3.15.0",
|
||||
"pkg:apk/alpine/ssl_client@1.34.1-r3?distro=3.15.0",
|
||||
"pkg:apk/alpine/zlib@1.2.11-r3?distro=3.15.0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"ref": "pkg:oci/alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300?repository_url=index.docker.io%2Flibrary%2Falpine&arch=amd64",
|
||||
"dependsOn": [
|
||||
"3da6a469-964d-4b4e-b67d-e94ec7c88d37"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
</details>
|
||||
|
||||
!!! caution
|
||||
It doesn't support vulnerabilities yet, but installed packages.
|
||||
|
||||
[cyclonedx]: https://cyclonedx.org/
|
||||
@@ -1,57 +0,0 @@
|
||||
# Air-Gapped Environment
|
||||
|
||||
Trivy can be used in air-gapped environments.
|
||||
|
||||
## Download the vulnerability database
|
||||
At first, you need to download the vulnerability database for use in air-gapped environments.
|
||||
Go to [trivy-db][trivy-db] and download `trivy-offline.db.tgz` in the latest release.
|
||||
If you download `trivy-light-offline.db.tgz`, you have to run Trivy with `--light` option.
|
||||
|
||||
```
|
||||
$ wget https://github.com/aquasecurity/trivy-db/releases/latest/download/trivy-offline.db.tgz
|
||||
```
|
||||
|
||||
## Transfer the DB file into the air-gapped environment
|
||||
The way of transfer depends on the environment.
|
||||
|
||||
```
|
||||
$ rsync -av -e ssh /path/to/trivy-offline.db.tgz [user]@[host]:dst
|
||||
```
|
||||
|
||||
## Put the DB file in Trivy's cache directory
|
||||
You have to know where to put the DB file. The following command shows the default cache directory.
|
||||
|
||||
```
|
||||
$ ssh user@host
|
||||
$ trivy -h | grep cache
|
||||
--cache-dir value cache directory (default: "/home/myuser/.cache/trivy") [$TRIVY_CACHE_DIR]
|
||||
```
|
||||
|
||||
Put the DB file in the cache directory + `/db`.
|
||||
|
||||
```
|
||||
$ mkdir -p /home/myuser/.cache/trivy/db
|
||||
$ cd /home/myuser/.cache/trivy/db
|
||||
$ mv /path/to/trivy-offline.db.tgz .
|
||||
```
|
||||
|
||||
Then, decompress it.
|
||||
`trivy-offline.db.tgz` file includes two files, `trivy.db` and `metadata.json`.
|
||||
|
||||
```
|
||||
$ tar xvf trivy-offline.db.tgz
|
||||
x trivy.db
|
||||
x metadata.json
|
||||
$ rm trivy-offline.db.tgz
|
||||
```
|
||||
|
||||
In an air-gapped environment it is your responsibility to update the Trivy database on a regular basis, so that the scanner can detect recently-identified vulnerabilities.
|
||||
|
||||
## Run Trivy with --skip-update option
|
||||
In an air-gapped environment, specify `--skip-update` so that Trivy doesn't attempt to download the latest database file.
|
||||
|
||||
```
|
||||
$ trivy image --skip-update alpine:3.12
|
||||
```
|
||||
|
||||
[trivy-db]: https://github.com/aquasecurity/trivy-db/releases
|
||||
2
docs/build/Dockerfile
vendored
@@ -1,4 +1,4 @@
|
||||
FROM squidfunk/mkdocs-material
|
||||
FROM squidfunk/mkdocs-material:7.0.6
|
||||
|
||||
## If you want to see exactly the same version as is published to GitHub pages
|
||||
## use a private image for insiders, which requires authentication.
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# Comparison with other scanners
|
||||
|
||||
| Scanner | OS<br>Packages | Application<br>Dependencies | Easy to use | Accuracy | Suitable<br>for CI |
|
||||
| -------------- | :-------------: | :-------------------------: | :----------: | :---------: | :-----------------: |
|
||||
| Trivy | ✅ | ✅<br>(8 languages) | ⭐ ⭐ ⭐ | ⭐ ⭐ ⭐ | ⭐ ⭐ ⭐ |
|
||||
| Clair | ✅ | × | ⭐ | ⭐ ⭐ | ⭐ ⭐ |
|
||||
| Anchore Engine | ✅ | ✅<br>(4 languages) | ⭐ ⭐ | ⭐ ⭐ | ⭐ ⭐ ⭐ |
|
||||
| Quay | ✅ | × | ⭐ ⭐ ⭐ | ⭐ ⭐ | × |
|
||||
| Docker Hub | ✅ | × | ⭐ ⭐ ⭐ | ⭐ | × |
|
||||
| GCR | ✅ | × | ⭐ ⭐ ⭐ | ⭐ ⭐ | × |
|
||||
|
||||
- [Open Source CVE Scanner Round-Up: Clair vs Anchore vs Trivy][round-up]
|
||||
- [Docker Image Security: Static Analysis Tool Comparison – Anchore Engine vs Clair vs Trivy][tool-comparison]
|
||||
- [Research Spike: evaluate Trivy for scanning running containers](https://gitlab.com/gitlab-org/gitlab/-/issues/270888)
|
||||
|
||||
[round-up]: https://boxboat.com/2020/04/24/image-scanning-tech-compared/
|
||||
[tool-comparison]: https://www.a10o.net/devsecops/docker-image-security-static-analysis-tool-comparison-anchore-engine-vs-clair-vs-trivy/
|
||||
@@ -1,14 +0,0 @@
|
||||
# Special Thanks to
|
||||
|
||||
- [Tomoya Amachi][tomoyamachi]
|
||||
- [Masahiro Fujimura][masahiro331]
|
||||
- [Naoki Harima][XapiMa]
|
||||
|
||||
# Author
|
||||
|
||||
[Teppei Fukuda][knqyf263] (knqyf263)
|
||||
|
||||
[tomoyamachi]: https://github.com/tomoyamachi
|
||||
[masahiro331]: https://github.com/masahiro331
|
||||
[XapiMa]: https://github.com/XapiMa
|
||||
[knqyf263]: https://github.com/knqyf263
|
||||
@@ -1,74 +0,0 @@
|
||||
# Vulnerability DB
|
||||
|
||||
## Skip update of vulnerability DB
|
||||
`Trivy` downloads its vulnerability database every 12 hours when it starts operating.
|
||||
This is usually fast, as the size of the DB is only 10~30MB.
|
||||
But if you want to skip even that, use the `--skip-update` option.
|
||||
|
||||
```
|
||||
$ trivy image --skip-update python:3.4-alpine3.9
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T12:48:08.703+0900 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
python:3.4-alpine3.9 (alpine 3.9.2)
|
||||
===================================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
|
||||
| | | | | | with long nonces |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Only download vulnerability database
|
||||
You can also ask `Trivy` to simply retrieve the vulnerability database.
|
||||
This is useful to initialize workers in Continuous Integration systems.
|
||||
|
||||
```
|
||||
$ trivy image --download-db-only
|
||||
```
|
||||
|
||||
## Lightweight DB
|
||||
The lightweight DB doesn't contain vulnerability detail such as descriptions and references. Because of that, the size of the DB is smaller and the download is faster.
|
||||
|
||||
This option is useful when you don't need vulnerability details and is suitable for CI/CD.
|
||||
To find the additional information, you can search vulnerability details on the NVD website.
|
||||
https://nvd.nist.gov/vuln/search
|
||||
|
||||
```
|
||||
$ trivy image --light alpine:3.10
|
||||
```
|
||||
|
||||
`--light` option doesn't display titles like the following example.
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-11-14T10:21:01.553+0200 INFO Reopening vulnerability DB
|
||||
2019-11-14T10:21:02.574+0200 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
alpine:3.10 (alpine 3.10.2)
|
||||
===========================
|
||||
Total: 3 (UNKNOWN: 0, LOW: 1, MEDIUM: 2, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |
|
||||
+---------+------------------+----------+-------------------+---------------+
|
||||
| openssl | CVE-2019-1549 | MEDIUM | 1.1.1c-r0 | 1.1.1d-r0 |
|
||||
+ +------------------+ + + +
|
||||
| | CVE-2019-1563 | | | |
|
||||
+ +------------------+----------+ + +
|
||||
| | CVE-2019-1547 | LOW | | |
|
||||
+---------+------------------+----------+-------------------+---------------+
|
||||
```
|
||||
</details>
|
||||
@@ -1,3 +0,0 @@
|
||||
# Examples
|
||||
|
||||
There are plenty of examples.
|
||||
@@ -1,17 +0,0 @@
|
||||
# Skip Traversal of Files/Directories
|
||||
|
||||
## Skip Files
|
||||
Trivy traversals directories and looks for all lock files by default.
|
||||
If your image contains lock files which are not maintained by you, you can skip the file.
|
||||
|
||||
```
|
||||
$ trivy image --skip-files "/Gemfile.lock" --skip-files "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0/Gemfile.lock" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
|
||||
```
|
||||
|
||||
## Skip Directories
|
||||
Trivy traversals directories and look for all lock files by default.
|
||||
If your image contains lock files which are not maintained by you, you can skip traversal in the specific directory.
|
||||
|
||||
```
|
||||
$ trivy image --skip-dirs /var/lib/gems/2.5.0/gems/fluent-plugin-detect-exceptions-0.0.13 --skip-dirs "/var/lib/gems/2.5.0/gems/http_parser.rb-0.6.0" quay.io/fluentd_elasticsearch/fluentd:v2.9.0
|
||||
```
|
||||
@@ -9,7 +9,7 @@ USAGE:
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
@@ -21,6 +21,8 @@ OPTIONS:
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN]
|
||||
--token value for authentication [$TRIVY_TOKEN]
|
||||
--token-header value specify a header name for token (default: "Trivy-Token") [$TRIVY_TOKEN_HEADER]
|
||||
--remote value server address (default: "http://localhost:4954") [$TRIVY_REMOTE]
|
||||
29
docs/getting-started/cli/config.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Config
|
||||
|
||||
``` bash
|
||||
NAME:
|
||||
trivy config - scan config files
|
||||
|
||||
USAGE:
|
||||
trivy config [command options] dir
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
|
||||
--reset remove all caches and database (default: false) [$TRIVY_RESET]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--policy value, --config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_POLICY]
|
||||
--data value, --config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_DATA]
|
||||
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
|
||||
--file-patterns value specify file patterns [$TRIVY_FILE_PATTERNS]
|
||||
--include-successes include successes of misconfigurations (default: false) [$TRIVY_INCLUDE_SUCCESSES]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
35
docs/getting-started/cli/fs.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Filesystem
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy filesystem - scan local filesystem
|
||||
|
||||
USAGE:
|
||||
trivy filesystem [command options] dir
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-db-update, --skip-update skip updating vulnerability database (default: false) [$TRIVY_SKIP_UPDATE, $TRIVY_SKIP_DB_UPDATE]
|
||||
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN]
|
||||
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_CONFIG_POLICY]
|
||||
--config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_CONFIG_DATA]
|
||||
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
@@ -9,7 +9,7 @@ USAGE:
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
@@ -24,9 +24,9 @@ OPTIONS:
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--light light mode: it's faster, but vulnerability descriptions and references are not displayed (default: false) [$TRIVY_LIGHT]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN]
|
||||
--skip-files value specify the file path to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directory where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
@@ -1,6 +1,6 @@
|
||||
Trivy has several sub commands, image, fs, repo, client and server.
|
||||
|
||||
```
|
||||
``` bash
|
||||
NAME:
|
||||
trivy - A simple and comprehensive vulnerability scanner for containers
|
||||
|
||||
@@ -8,7 +8,7 @@ USAGE:
|
||||
trivy [global options] command [command options] target
|
||||
|
||||
VERSION:
|
||||
v0.15.0
|
||||
dev
|
||||
|
||||
COMMANDS:
|
||||
image, i scan an image
|
||||
@@ -16,6 +16,8 @@ COMMANDS:
|
||||
repository, repo scan remote repository
|
||||
client, c client mode
|
||||
server, s server mode
|
||||
config, conf scan config files
|
||||
plugin, p manage plugins
|
||||
help, h Shows a list of commands or help for one command
|
||||
|
||||
GLOBAL OPTIONS:
|
||||
@@ -24,4 +26,5 @@ GLOBAL OPTIONS:
|
||||
--cache-dir value cache directory (default: "/Users/teppei/Library/Caches/trivy") [$TRIVY_CACHE_DIR]
|
||||
--help, -h show help (default: false)
|
||||
--version, -v print the version (default: false)
|
||||
|
||||
```
|
||||
@@ -9,7 +9,7 @@ USAGE:
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--input value, -i value input file path instead of image name [$TRIVY_INPUT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
@@ -23,8 +23,10 @@ OPTIONS:
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
|
||||
--quiet, -q suppress progress bar and log output (default: false) [$TRIVY_QUIET]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN]
|
||||
--skip-files value specify the file path to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directory where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--help, -h show help (default: false)
|
||||
35
docs/getting-started/cli/rootfs.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Rootfs
|
||||
|
||||
```bash
|
||||
NAME:
|
||||
trivy rootfs - scan rootfs
|
||||
|
||||
USAGE:
|
||||
trivy rootfs [command options] dir
|
||||
|
||||
OPTIONS:
|
||||
--template value, -t value output template [$TRIVY_TEMPLATE]
|
||||
--format value, -f value format (table, json, sarif, template) (default: "table") [$TRIVY_FORMAT]
|
||||
--severity value, -s value severities of vulnerabilities to be displayed (comma separated) (default: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL") [$TRIVY_SEVERITY]
|
||||
--output value, -o value output file name [$TRIVY_OUTPUT]
|
||||
--exit-code value Exit code when vulnerabilities were found (default: 0) [$TRIVY_EXIT_CODE]
|
||||
--skip-db-update, --skip-update skip updating vulnerability database (default: false) [$TRIVY_SKIP_UPDATE, $TRIVY_SKIP_DB_UPDATE]
|
||||
--skip-policy-update skip updating built-in policies (default: false) [$TRIVY_SKIP_POLICY_UPDATE]
|
||||
--clear-cache, -c clear image caches without scanning (default: false) [$TRIVY_CLEAR_CACHE]
|
||||
--ignore-unfixed display only fixed vulnerabilities (default: false) [$TRIVY_IGNORE_UNFIXED]
|
||||
--vuln-type value comma-separated list of vulnerability types (os,library) (default: "os,library") [$TRIVY_VULN_TYPE]
|
||||
--security-checks value comma-separated list of what security issues to detect (vuln,config) (default: "vuln") [$TRIVY_SECURITY_CHECKS]
|
||||
--ignorefile value specify .trivyignore file (default: ".trivyignore") [$TRIVY_IGNOREFILE]
|
||||
--cache-backend value cache backend (e.g. redis://localhost:6379) (default: "fs") [$TRIVY_CACHE_BACKEND]
|
||||
--timeout value timeout (default: 5m0s) [$TRIVY_TIMEOUT]
|
||||
--no-progress suppress progress bar (default: false) [$TRIVY_NO_PROGRESS]
|
||||
--ignore-policy value specify the Rego file to evaluate each vulnerability [$TRIVY_IGNORE_POLICY]
|
||||
--list-all-pkgs enabling the option will output all packages regardless of vulnerability (default: false) [$TRIVY_LIST_ALL_PKGS]
|
||||
--offline-scan do not issue API requests to identify dependencies (default: false) [$TRIVY_OFFLINE_SCAN]
|
||||
--skip-files value specify the file paths to skip traversal [$TRIVY_SKIP_FILES]
|
||||
--skip-dirs value specify the directories where the traversal is skipped [$TRIVY_SKIP_DIRS]
|
||||
--config-policy value specify paths to the Rego policy files directory, applying config files [$TRIVY_CONFIG_POLICY]
|
||||
--config-data value specify paths from which data for the Rego policies will be recursively loaded [$TRIVY_CONFIG_DATA]
|
||||
--policy-namespaces value, --namespaces value Rego namespaces (default: "users") [$TRIVY_POLICY_NAMESPACES]
|
||||
--help, -h show help (default: false)
|
||||
```
|
||||
10
docs/getting-started/credit.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Author
|
||||
|
||||
[Teppei Fukuda][knqyf263] (knqyf263)
|
||||
|
||||
# Contributors
|
||||
|
||||
Thanks to all [contributors][contributors]
|
||||
|
||||
[knqyf263]: https://github.com/knqyf263
|
||||
[contributors]: https://github.com/aquasecurity/trivy/graphs/contributors
|
||||
@@ -18,7 +18,6 @@
|
||||
- [Find Image Vulnerabilities Using GitHub and Aqua Security Trivy Action][actions2]
|
||||
- [Using Trivy to Discover Vulnerabilities in VS Code Projects][vscode]
|
||||
|
||||
|
||||
[intro]: https://www.youtube.com/watch?v=AzOBGm7XxOA
|
||||
[cncf]: https://www.youtube.com/watch?v=XnYxX9uueoQ
|
||||
[server]: https://www.youtube.com/watch?v=tNQ-VlahtYM
|
||||
@@ -2,56 +2,63 @@
|
||||
|
||||
## RHEL/CentOS
|
||||
|
||||
Add repository setting to `/etc/yum.repos.d`.
|
||||
|
||||
```bash
|
||||
$ sudo vim /etc/yum.repos.d/trivy.repo
|
||||
[trivy]
|
||||
name=Trivy repository
|
||||
baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$releasever/$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
$ sudo yum -y update
|
||||
$ sudo yum -y install trivy
|
||||
```
|
||||
=== "Repository"
|
||||
Add repository setting to `/etc/yum.repos.d`.
|
||||
|
||||
or
|
||||
``` bash
|
||||
$ sudo vim /etc/yum.repos.d/trivy.repo
|
||||
[trivy]
|
||||
name=Trivy repository
|
||||
baseurl=https://aquasecurity.github.io/trivy-repo/rpm/releases/$releasever/$basearch/
|
||||
gpgcheck=0
|
||||
enabled=1
|
||||
$ sudo yum -y update
|
||||
$ sudo yum -y install trivy
|
||||
```
|
||||
|
||||
```bash
|
||||
rpm -ivh https://github.com/aquasecurity/trivy/releases/download/{{ git.tag }}/trivy_{{ git.tag[1:] }}_Linux-64bit.rpm
|
||||
```
|
||||
=== "RPM"
|
||||
|
||||
``` bash
|
||||
rpm -ivh https://github.com/aquasecurity/trivy/releases/download/{{ git.tag }}/trivy_{{ git.tag[1:] }}_Linux-64bit.rpm
|
||||
```
|
||||
|
||||
## Debian/Ubuntu
|
||||
|
||||
Add repository to `/etc/apt/sources.list.d`.
|
||||
=== "Repository"
|
||||
Add repository setting to `/etc/apt/sources.list.d`.
|
||||
|
||||
```bash
|
||||
sudo apt-get install wget apt-transport-https gnupg lsb-release
|
||||
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
|
||||
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install trivy
|
||||
```
|
||||
``` bash
|
||||
sudo apt-get install wget apt-transport-https gnupg lsb-release
|
||||
wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
|
||||
echo deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main | sudo tee -a /etc/apt/sources.list.d/trivy.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install trivy
|
||||
```
|
||||
|
||||
or
|
||||
=== "DEB"
|
||||
|
||||
```bash
|
||||
wget https://github.com/aquasecurity/trivy/releases/download/{{ git.tag }}/trivy_{{ git.tag[1:] }}_Linux-64bit.deb
|
||||
sudo dpkg -i trivy_{{ git.tag[1:] }}_Linux-64bit.deb
|
||||
```
|
||||
``` bash
|
||||
wget https://github.com/aquasecurity/trivy/releases/download/{{ git.tag }}/trivy_{{ git.tag[1:] }}_Linux-64bit.deb
|
||||
sudo dpkg -i trivy_{{ git.tag[1:] }}_Linux-64bit.deb
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Arch Linux
|
||||
Package trivy-bin can be installed from the Arch User Repository. Examples:
|
||||
Package trivy-bin can be installed from the Arch User Repository.
|
||||
|
||||
```bash
|
||||
pikaur -Sy trivy-bin
|
||||
```
|
||||
or
|
||||
```bash
|
||||
yay -Sy trivy-bin
|
||||
```
|
||||
=== "pikaur"
|
||||
|
||||
``` bash
|
||||
pikaur -Sy trivy-bin
|
||||
```
|
||||
|
||||
=== "yay"
|
||||
|
||||
``` bash
|
||||
yay -Sy trivy-bin
|
||||
```
|
||||
|
||||
## Homebrew
|
||||
|
||||
@@ -106,17 +113,19 @@ Replace [YOUR_CACHE_DIR] with the cache directory on your machine.
|
||||
docker pull aquasec/trivy:{{ git.tag[1:] }}
|
||||
```
|
||||
|
||||
Example for Linux:
|
||||
Example:
|
||||
|
||||
```bash
|
||||
docker run --rm -v [YOUR_CACHE_DIR]:/root/.cache/ aquasec/trivy:{{ git.tag[1:] }} [YOUR_IMAGE_NAME]
|
||||
```
|
||||
=== "Linux"
|
||||
|
||||
Example for macOS:
|
||||
``` bash
|
||||
docker run --rm -v [YOUR_CACHE_DIR]:/root/.cache/ aquasec/trivy:{{ git.tag[1:] }} image [YOUR_IMAGE_NAME]
|
||||
```
|
||||
|
||||
```bash
|
||||
docker run --rm -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:{{ git.tag[1:] }} python:3.4-alpine
|
||||
```
|
||||
=== "macOS"
|
||||
|
||||
``` bash
|
||||
docker run --rm -v $HOME/Library/Caches:/root/.cache/ aquasec/trivy:{{ git.tag[1:] }} image [YOUR_IMAGE_NAME
|
||||
```
|
||||
|
||||
If you would like to scan the image on your host machine, you need to mount `docker.sock`.
|
||||
|
||||
@@ -156,11 +165,10 @@ The same image is hosted on [GitHub Container Registry][registry] as well.
|
||||
docker pull ghcr.io/aquasecurity/trivy:{{ git.tag[1:] }}
|
||||
```
|
||||
|
||||
[registry]: https://github.com/orgs/aquasecurity/packages/container/package/trivy
|
||||
|
||||
### Amazon ECR Public
|
||||
|
||||
The same image is hosted on [Amazon ECR Public](https://gallery.ecr.aws/aquasecurity/trivy) as well.
|
||||
The same image is hosted on [Amazon ECR Public][ecr] as well.
|
||||
|
||||
```bash
|
||||
docker pull public.ecr.aws/aquasecurity/trivy:{{ git.tag[1:] }}
|
||||
@@ -183,7 +191,11 @@ To install the chart with the release name `my-release`:
|
||||
helm install my-release .
|
||||
```
|
||||
|
||||
The command deploys Trivy on the Kubernetes cluster in the default configuration. The [Parameters](#parameters)
|
||||
The command deploys Trivy on the Kubernetes cluster in the default configuration. The [Parameters][helm]
|
||||
section lists the parameters that can be configured during installation.
|
||||
|
||||
> **Tip**: List all releases using `helm list`.
|
||||
|
||||
[ecr]: https://gallery.ecr.aws/aquasecurity/trivy
|
||||
[registry]: https://github.com/orgs/aquasecurity/packages/container/package/trivy
|
||||
[helm]: https://github.com/aquasecurity/trivy/tree/{{ git.tag }}/helm/trivy
|
||||
82
docs/getting-started/overview.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Overview
|
||||
|
||||
Trivy detects two types of security issues:
|
||||
|
||||
- [Vulnerabilities][vuln]
|
||||
- [Misconfigurations][misconf]
|
||||
|
||||
Trivy can scan three different artifacts:
|
||||
|
||||
- [Container Images][container]
|
||||
- [Filesystem][filesystem] and [Rootfs][rootfs]
|
||||
- [Git Repositories][repo]
|
||||
|
||||
Trivy can be run in two different modes:
|
||||
|
||||
- [Standalone][standalone]
|
||||
- [Client/Server][client-server]
|
||||
|
||||
It is designed to be used in CI. Before pushing to a container registry or deploying your application, you can scan your local container image and other artifacts easily.
|
||||
See [Integrations][integrations] for details.
|
||||
|
||||
## Features
|
||||
|
||||
- Comprehensive vulnerability detection
|
||||
- [OS packages][os] (Alpine, Red Hat Universal Base Image, Red Hat Enterprise Linux, CentOS, AlmaLinux, Rocky Linux, CBL-Mariner, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
|
||||
- [**Language-specific packages**][lang] (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go)
|
||||
- Detect IaC misconfigurations
|
||||
- A wide variety of [built-in policies][builtin] are provided **out of the box**:
|
||||
- Kubernetes
|
||||
- Docker
|
||||
- Terraform
|
||||
- more coming soon
|
||||
- Support custom policies
|
||||
- Simple
|
||||
- Specify only an image name, a directory containing IaC configs, or an artifact name
|
||||
- See [Quick Start][quickstart]
|
||||
- Fast
|
||||
- The first scan will finish within 10 seconds (depending on your network). Consequent scans will finish in single seconds.
|
||||
- Unlike other scanners that take long to fetch vulnerability information (~10 minutes) on the first run, and encourage you to maintain a durable vulnerability database, Trivy is stateless and requires no maintenance or preparation.
|
||||
- Easy installation
|
||||
- `apt-get install`, `yum install` and `brew install` is possible (See [Installation](installation.md))
|
||||
- **No pre-requisites** such as installation of DB, libraries, etc.
|
||||
- High accuracy
|
||||
- **Especially Alpine Linux and RHEL/CentOS**
|
||||
- Other OSes are also high
|
||||
- DevSecOps
|
||||
- **Suitable for CI** such as Travis CI, CircleCI, Jenkins, GitLab CI, etc.
|
||||
- See [CI Example][integrations]
|
||||
- Support multiple formats
|
||||
- container image
|
||||
- A local image in Docker Engine which is running as a daemon
|
||||
- A local image in [Podman][podman] (>=2.0) which is exposing a socket
|
||||
- A remote image in Docker Registry such as Docker Hub, ECR, GCR and ACR
|
||||
- A tar archive stored in the `docker save` / `podman save` formatted file
|
||||
- An image directory compliant with [OCI Image Format][oci]
|
||||
- local filesystem and rootfs
|
||||
- remote git repository
|
||||
- SBOM (Software Bill of Materials) support
|
||||
- CycloneDX
|
||||
|
||||
Please see [LICENSE][license] for Trivy licensing information.
|
||||
|
||||
[vuln]: ../vulnerability/scanning/index.md
|
||||
[misconf]: ../misconfiguration/index.md
|
||||
[container]: ../vulnerability/scanning/image.md
|
||||
[rootfs]: ../vulnerability/scanning/rootfs.md
|
||||
[filesystem]: ../vulnerability/scanning/filesystem.md
|
||||
[repo]: ../vulnerability/scanning/git-repository.md
|
||||
|
||||
[standalone]: ../advanced/modes/standalone.md
|
||||
[client-server]: ../advanced/modes/client-server.md
|
||||
[integrations]: ../advanced/integrations/index.md
|
||||
|
||||
[os]: ../vulnerability/detection/os.md
|
||||
[lang]: ../vulnerability/detection/language.md
|
||||
|
||||
[builtin]: ../misconfiguration/policy/builtin.md
|
||||
[quickstart]: quickstart.md
|
||||
[podman]: ../advanced/container/podman.md
|
||||
|
||||
[oci]: https://github.com/opencontainers/image-spec
|
||||
[license]: https://github.com/aquasecurity/trivy/blob/main/LICENSE
|
||||
83
docs/getting-started/quickstart.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Quick Start
|
||||
|
||||
## Scan image for vulnerabilities
|
||||
|
||||
Simply specify an image name (and a tag).
|
||||
|
||||
```
|
||||
$ trivy image [YOUR_IMAGE_NAME]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ trivy image python:3.4-alpine
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2019-05-16T01:20:43.180+0900 INFO Updating vulnerability database...
|
||||
2019-05-16T01:20:53.029+0900 INFO Detecting Alpine vulnerabilities...
|
||||
|
||||
python:3.4-alpine3.9 (alpine 3.9.2)
|
||||
===================================
|
||||
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 1, HIGH: 0, CRITICAL: 0)
|
||||
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
| openssl | CVE-2019-1543 | MEDIUM | 1.1.1a-r1 | 1.1.1b-r1 | openssl: ChaCha20-Poly1305 |
|
||||
| | | | | | with long nonces |
|
||||
+---------+------------------+----------+-------------------+---------------+--------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
For more details, see [here][vulnerability].
|
||||
|
||||
## Scan directory for misconfigurations
|
||||
|
||||
Simply specify a directory containing IaC files such as Terraform and Dockerfile.
|
||||
|
||||
```
|
||||
$ trivy config [YOUR_IAC_DIR]
|
||||
```
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
$ ls build/
|
||||
Dockerfile
|
||||
$ trivy config ./build
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Result</summary>
|
||||
|
||||
```
|
||||
2021-07-09T10:06:29.188+0300 INFO Need to update the built-in policies
|
||||
2021-07-09T10:06:29.188+0300 INFO Downloading the built-in policies...
|
||||
2021-07-09T10:06:30.520+0300 INFO Detected config files: 1
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
For more details, see [here][misconf].
|
||||
|
||||
[vulnerability]: ../vulnerability/scanning/index.md
|
||||
[misconf]: ../misconfiguration/index.md
|
||||
@@ -1,11 +1,90 @@
|
||||
# FAQ
|
||||
# Troubleshooting
|
||||
|
||||
## Scan
|
||||
### analyze error: timeout: context deadline exceeded
|
||||
### Timeout
|
||||
|
||||
!!! error
|
||||
``` bash
|
||||
$ trivy image ...
|
||||
...
|
||||
analyze error: timeout: context deadline exceeded
|
||||
```
|
||||
|
||||
Your scan may time out. Java takes a particularly long time to scan. Try increasing the value of the ---timeout option such as `--timeout 15m`.
|
||||
|
||||
### Certification
|
||||
|
||||
!!! error
|
||||
Error: x509: certificate signed by unknown authority
|
||||
|
||||
`TRIVY_INSECURE` can be used to allow insecure connections to a container registry when using SSL.
|
||||
|
||||
```
|
||||
$ TRIVY_INSECURE=true trivy image [YOUR_IMAGE]
|
||||
```
|
||||
|
||||
### GitHub Rate limiting
|
||||
|
||||
!!! error
|
||||
``` bash
|
||||
$ trivy image ...
|
||||
...
|
||||
API rate limit exceeded for xxx.xxx.xxx.xxx.
|
||||
```
|
||||
|
||||
Specify GITHUB_TOKEN for authentication
|
||||
https://developer.github.com/v3/#rate-limiting
|
||||
|
||||
```
|
||||
$ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10
|
||||
```
|
||||
|
||||
### Maven rate limiting
|
||||
|
||||
!!! error
|
||||
``` bash
|
||||
$ trivy image ...
|
||||
...
|
||||
status 403 Forbidden from http://search.maven.org/solrsearch/select
|
||||
```
|
||||
|
||||
Trivy calls Maven API for better detection of JAR files, but many requests may exceed rate limiting.
|
||||
If it happens frequently, try the `--offline-scan` option to stop Trivy from making API requests.
|
||||
This option affects only vulnerability scanning. The vulnerability database and builtin policies are downloaded as usual.
|
||||
If you want to skip them as well, you can try `--skip-update` and `--skip-policy-update`.
|
||||
|
||||
Note that a number of vulnerabilities might be fewer than without the `--offline-scan` option.
|
||||
|
||||
### Running in parallel takes same time as series run
|
||||
When running trivy on multiple images simultaneously, it will take same time as running trivy in series.
|
||||
This is because of a limitation of boltdb.
|
||||
> Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it.
|
||||
|
||||
Reference : [boltdb: Opening a database][boltdb].
|
||||
|
||||
[boltdb]: https://github.com/boltdb/bolt#opening-a-database
|
||||
|
||||
### Error downloading vulnerability DB
|
||||
|
||||
!!! error
|
||||
FATAL failed to download vulnerability DB
|
||||
|
||||
If trivy is running behind corporate firewall, you have to add the following urls to your allowlist.
|
||||
|
||||
- ghcr.io
|
||||
- pkg-containers.githubusercontent.com
|
||||
|
||||
### Old DB schema
|
||||
|
||||
!!! error
|
||||
--skip-update cannot be specified with the old DB schema.
|
||||
|
||||
Trivy v0.23.0 or later requires Trivy DB v2. Please update your local database or follow [the instruction of air-gapped environment][air-gapped].
|
||||
|
||||
## Homebrew
|
||||
### Error: Your macOS keychain GitHub credentials do not have sufficient scope!
|
||||
### Scope error
|
||||
!!! error
|
||||
Error: Your macOS keychain GitHub credentials do not have sufficient scope!
|
||||
|
||||
```
|
||||
$ brew tap aquasecurity/trivy
|
||||
@@ -23,7 +102,9 @@ Try:
|
||||
$ printf "protocol=https\nhost=github.com\n" | git credential-osxkeychain erase
|
||||
```
|
||||
|
||||
### Error: aquasecurity/trivy/trivy 64 already installed
|
||||
### Already installed
|
||||
!!! error
|
||||
Error: aquasecurity/trivy/trivy 64 already installed
|
||||
|
||||
```
|
||||
$ brew upgrade
|
||||
@@ -39,31 +120,8 @@ $ brew unlink trivy && brew uninstall trivy
|
||||
$ brew install aquasecurity/trivy/trivy
|
||||
```
|
||||
|
||||
### Error: x509: certificate signed by unknown authority
|
||||
`TRIVY_INSECURE` can be used to allow insecure connections to a container registry when using SSL.
|
||||
|
||||
```
|
||||
$ TRIVY_INSECURE=true trivy image [YOUR_IMAGE]
|
||||
```
|
||||
|
||||
### Running in parallel takes same time as series run
|
||||
When running trivy on multiple images simultaneously, it will take same time as running trivy in series.
|
||||
This is because of a limitation of boltdb.
|
||||
> Bolt obtains a file lock on the data file so multiple processes cannot open the same database at the same time. Opening an already open Bolt database will cause it to hang until the other process closes it.
|
||||
Reference : [boltdb: Opening a database][boltdb].
|
||||
|
||||
[boltdb]: https://github.com/boltdb/bolt#opening-a-database
|
||||
|
||||
## Others
|
||||
### GitHub Rate limiting
|
||||
|
||||
Specify GITHUB_TOKEN for authentication
|
||||
https://developer.github.com/v3/#rate-limiting
|
||||
|
||||
```
|
||||
$ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10
|
||||
```
|
||||
|
||||
### Unknown error
|
||||
|
||||
Try again with `--reset` option:
|
||||
@@ -71,3 +129,5 @@ Try again with `--reset` option:
|
||||
```
|
||||
$ trivy image --reset
|
||||
```
|
||||
|
||||
[air-gapped]: ../advanced/air-gap.md
|
||||
352
docs/imgs/excalidraw/misconf.excalidraw
Normal file
@@ -0,0 +1,352 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 573,
|
||||
"versionNonce": 2034670720,
|
||||
"isDeleted": false,
|
||||
"id": "BkXuq_6BxgqZGZWc8oCtu",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 599.211669921875,
|
||||
"y": 376.32061767578125,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fd7e14",
|
||||
"width": 867.8921508789062,
|
||||
"height": 151.39703369140625,
|
||||
"seed": 1632394695,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 572,
|
||||
"versionNonce": 425683840,
|
||||
"isDeleted": false,
|
||||
"id": "YQURTHNPSe05RPSlYRcok",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 983.89404296875,
|
||||
"y": 399.98724365234375,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 88,
|
||||
"height": 45,
|
||||
"seed": 891391049,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 36,
|
||||
"fontFamily": 1,
|
||||
"text": "Trivy",
|
||||
"baseline": 32,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 822,
|
||||
"versionNonce": 1061096576,
|
||||
"isDeleted": false,
|
||||
"id": "6dpF2EyZBtYgO6MrvGj0-",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 771.2554931640625,
|
||||
"y": 469.7777099609375,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 507,
|
||||
"height": 35,
|
||||
"seed": 687997545,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability/Misconfiguration Scanner",
|
||||
"baseline": 25,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 763,
|
||||
"versionNonce": 560331648,
|
||||
"isDeleted": false,
|
||||
"id": "cpnTMy7L2AUg9IDJppF4H",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 602.28369140625,
|
||||
"y": 258.8445587158203,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fab005",
|
||||
"width": 397.493408203125,
|
||||
"height": 103.28388977050778,
|
||||
"seed": 77164935,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 1072,
|
||||
"versionNonce": 212434048,
|
||||
"isDeleted": false,
|
||||
"id": "9-blmNVtLesthMSY_f60t",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 630.9301147460938,
|
||||
"y": 292.4002990722656,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 331,
|
||||
"height": 35,
|
||||
"seed": 860091815,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Infrastructure as Code",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1194,
|
||||
"versionNonce": 131337088,
|
||||
"isDeleted": false,
|
||||
"id": "gugZxhi7ThlcjWY_MFO7q",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1021.5928955078125,
|
||||
"y": 261.56090545654297,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#be4bdb",
|
||||
"width": 441.0702514648438,
|
||||
"height": 99.05134582519533,
|
||||
"seed": 1232790121,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 1270,
|
||||
"versionNonce": 591785088,
|
||||
"isDeleted": false,
|
||||
"id": "K48gtpesBxIGJxLTnI2CB",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1173.3179931640625,
|
||||
"y": 294.12510681152344,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 137,
|
||||
"height": 35,
|
||||
"seed": 449264361,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Filesystem",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1319,
|
||||
"versionNonce": 1264839808,
|
||||
"isDeleted": false,
|
||||
"id": "BYJwfkhd1BilbLQGc973f",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1233.3157348632812,
|
||||
"y": 168.29967880249023,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 229.03393554687523,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1923498546,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 659,
|
||||
"versionNonce": 2122259328,
|
||||
"isDeleted": false,
|
||||
"id": "eedUyCpr8i1aY_3PHsHAB",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1241.1352844238281,
|
||||
"y": 191.2939567565918,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 216,
|
||||
"height": 35,
|
||||
"seed": 595309038,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1397,
|
||||
"versionNonce": 20077696,
|
||||
"isDeleted": false,
|
||||
"id": "SPkrBrH6DGvkgQXtZQjIJ",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1023.8157043457031,
|
||||
"y": 168.7816276550293,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 200.7496337890626,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1896460914,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 840,
|
||||
"versionNonce": 655338368,
|
||||
"isDeleted": false,
|
||||
"id": "n06MNIqirDmVZBkDg_UPV",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1040.526611328125,
|
||||
"y": 194.3111228942871,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 160,
|
||||
"height": 35,
|
||||
"seed": 1131832750,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1441,
|
||||
"versionNonce": 1393118080,
|
||||
"isDeleted": false,
|
||||
"id": "8SHSNGf7PNddFLi2ZA3Vi",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 673.6463928222656,
|
||||
"y": 167.8159294128418,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 278.48516845703136,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1986948530,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 851,
|
||||
"versionNonce": 2114620544,
|
||||
"isDeleted": false,
|
||||
"id": "3Z5w3RXdgpvP43dlHqq26",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 701.5146789550781,
|
||||
"y": 189.60757064819336,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 216,
|
||||
"height": 35,
|
||||
"seed": 1077804654,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
}
|
||||
}
|
||||
@@ -5,31 +5,8 @@
|
||||
"elements": [
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 560,
|
||||
"versionNonce": 1400582380,
|
||||
"isDeleted": false,
|
||||
"id": "zULZ64ij5HLsp2cFZILSX",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 50,
|
||||
"angle": 0,
|
||||
"x": 904.2628784179688,
|
||||
"y": 99.2658462524414,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#15aabf",
|
||||
"width": 130.58160400390628,
|
||||
"height": 79.7976837158203,
|
||||
"seed": 1174361836,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 283,
|
||||
"versionNonce": 431858644,
|
||||
"version": 476,
|
||||
"versionNonce": 916788210,
|
||||
"isDeleted": false,
|
||||
"id": "BkXuq_6BxgqZGZWc8oCtu",
|
||||
"fillStyle": "hachure",
|
||||
@@ -38,11 +15,11 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 760.100830078125,
|
||||
"x": 599.211669921875,
|
||||
"y": 376.32061767578125,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fd7e14",
|
||||
"width": 792.3008422851561,
|
||||
"width": 1076.4584350585938,
|
||||
"height": 151.39703369140625,
|
||||
"seed": 1632394695,
|
||||
"groupIds": [],
|
||||
@@ -51,8 +28,8 @@
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 217,
|
||||
"versionNonce": 605539564,
|
||||
"version": 423,
|
||||
"versionNonce": 931200686,
|
||||
"isDeleted": false,
|
||||
"id": "YQURTHNPSe05RPSlYRcok",
|
||||
"fillStyle": "hachure",
|
||||
@@ -61,12 +38,12 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1106.6643676757812,
|
||||
"y": 411.25714111328125,
|
||||
"x": 1119.1937866210938,
|
||||
"y": 403.56756591796875,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 86,
|
||||
"height": 46,
|
||||
"width": 88,
|
||||
"height": 45,
|
||||
"seed": 891391049,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
@@ -80,8 +57,8 @@
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 222,
|
||||
"versionNonce": 1855404140,
|
||||
"version": 758,
|
||||
"versionNonce": 813811122,
|
||||
"isDeleted": false,
|
||||
"id": "6dpF2EyZBtYgO6MrvGj0-",
|
||||
"fillStyle": "hachure",
|
||||
@@ -90,27 +67,27 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 941.25830078125,
|
||||
"y": 471.68231201171875,
|
||||
"x": 922.1328735351562,
|
||||
"y": 470.18975830078125,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 474,
|
||||
"height": 25,
|
||||
"width": 507,
|
||||
"height": 35,
|
||||
"seed": 687997545,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "A Simple and Comprehensive Vulnerability Scanner",
|
||||
"baseline": 18,
|
||||
"text": "Vulnerability/Misconfiguration Scanner",
|
||||
"baseline": 25,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 297,
|
||||
"versionNonce": 239159404,
|
||||
"version": 595,
|
||||
"versionNonce": 1705780846,
|
||||
"isDeleted": false,
|
||||
"id": "cpnTMy7L2AUg9IDJppF4H",
|
||||
"fillStyle": "hachure",
|
||||
@@ -119,12 +96,12 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 759.0067749023438,
|
||||
"y": 192.9658660888672,
|
||||
"x": 597.4796142578125,
|
||||
"y": 258.9286651611328,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 283.0587768554687,
|
||||
"height": 79.7976837158203,
|
||||
"backgroundColor": "#fab005",
|
||||
"width": 349.1224975585937,
|
||||
"height": 103.28388977050778,
|
||||
"seed": 77164935,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
@@ -132,8 +109,8 @@
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 527,
|
||||
"versionNonce": 1738982484,
|
||||
"version": 921,
|
||||
"versionNonce": 929185650,
|
||||
"isDeleted": false,
|
||||
"id": "9-blmNVtLesthMSY_f60t",
|
||||
"fillStyle": "hachure",
|
||||
@@ -142,27 +119,27 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 851.9727783203125,
|
||||
"y": 206.49542236328125,
|
||||
"x": 655.6057739257812,
|
||||
"y": 292.4844055175781,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 94,
|
||||
"height": 50,
|
||||
"width": 238,
|
||||
"height": 35,
|
||||
"seed": 860091815,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Container\nImages",
|
||||
"baseline": 43,
|
||||
"text": "Container Images",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 475,
|
||||
"versionNonce": 1582652140,
|
||||
"version": 853,
|
||||
"versionNonce": 377039022,
|
||||
"isDeleted": false,
|
||||
"id": "gugZxhi7ThlcjWY_MFO7q",
|
||||
"fillStyle": "hachure",
|
||||
@@ -171,12 +148,12 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1052.2297973632812,
|
||||
"y": 191.91817474365234,
|
||||
"x": 955.929443359375,
|
||||
"y": 262.11351776123047,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#be4bdb",
|
||||
"width": 272.31054687500006,
|
||||
"height": 79.7976837158203,
|
||||
"width": 359.85211181640625,
|
||||
"height": 99.05134582519533,
|
||||
"seed": 1232790121,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
@@ -184,8 +161,8 @@
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 705,
|
||||
"versionNonce": 1618155988,
|
||||
"version": 1065,
|
||||
"versionNonce": 126714162,
|
||||
"isDeleted": false,
|
||||
"id": "K48gtpesBxIGJxLTnI2CB",
|
||||
"fillStyle": "hachure",
|
||||
@@ -194,27 +171,27 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1137.923828125,
|
||||
"y": 218.9615020751953,
|
||||
"x": 1064.449462890625,
|
||||
"y": 296.9230194091797,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 98,
|
||||
"height": 25,
|
||||
"width": 137,
|
||||
"height": 35,
|
||||
"seed": 449264361,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Filesystem",
|
||||
"baseline": 18,
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 509,
|
||||
"versionNonce": 1528748884,
|
||||
"version": 896,
|
||||
"versionNonce": 585884398,
|
||||
"isDeleted": false,
|
||||
"id": "La6f87LDZ0uEIZB947bXo",
|
||||
"fillStyle": "hachure",
|
||||
@@ -223,12 +200,12 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1342.2451782226562,
|
||||
"y": 190.3844223022461,
|
||||
"x": 1329.0839233398438,
|
||||
"y": 264.9097213745117,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#12b886",
|
||||
"width": 202.7937011718749,
|
||||
"height": 79.7976837158203,
|
||||
"width": 346.5517578125,
|
||||
"height": 96.3990020751953,
|
||||
"seed": 2005637801,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
@@ -236,8 +213,8 @@
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 866,
|
||||
"versionNonce": 27928788,
|
||||
"version": 1186,
|
||||
"versionNonce": 1013615346,
|
||||
"isDeleted": false,
|
||||
"id": "aOgRPVQ81jhOfkvzjWTMF",
|
||||
"fillStyle": "hachure",
|
||||
@@ -246,450 +223,282 @@
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1380.880859375,
|
||||
"y": 202.2483367919922,
|
||||
"x": 1392.300048828125,
|
||||
"y": 294.1288604736328,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 122,
|
||||
"height": 50,
|
||||
"width": 223,
|
||||
"height": 35,
|
||||
"seed": 1284472935,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Git\nRepositories",
|
||||
"baseline": 43,
|
||||
"text": "Git Repositories",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 247,
|
||||
"versionNonce": 653112532,
|
||||
"isDeleted": false,
|
||||
"id": "p_mUPP7FjgXD4cyuwbbDb",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 918.9429321289062,
|
||||
"y": 104.1267318725586,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 106,
|
||||
"height": 80,
|
||||
"seed": 2021123719,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 16,
|
||||
"fontFamily": 1,
|
||||
"text": "Programming\nLanguage\nDependencies\n",
|
||||
"baseline": 75,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 223,
|
||||
"versionNonce": 1335079532,
|
||||
"version": 974,
|
||||
"versionNonce": 1011959534,
|
||||
"isDeleted": false,
|
||||
"id": "JPMgfRuI6H4FPW8-vegMJ",
|
||||
"id": "BYJwfkhd1BilbLQGc973f",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 759.9201354980469,
|
||||
"y": 286.07564544677734,
|
||||
"x": 1141.5093994140625,
|
||||
"y": 171.09759140014648,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#868e96",
|
||||
"width": 157.08227539062494,
|
||||
"height": 79.7976837158203,
|
||||
"seed": 1163532908,
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1923498546,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"id": "i6l1cTY8BN5dM9gV3TY1q",
|
||||
"type": "text",
|
||||
"x": 774.47998046875,
|
||||
"y": 303.88873291015625,
|
||||
"width": 127,
|
||||
"height": 50,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1614647380,
|
||||
"version": 88,
|
||||
"versionNonce": 1787296340,
|
||||
"version": 403,
|
||||
"versionNonce": 1635608306,
|
||||
"isDeleted": false,
|
||||
"boundElementIds": null,
|
||||
"text": "Client/Server\nMode",
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 43
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 298,
|
||||
"versionNonce": 1573553388,
|
||||
"isDeleted": false,
|
||||
"id": "zmjzAP9R7DY9tKjqvFBoB",
|
||||
"id": "eedUyCpr8i1aY_3PHsHAB",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 927.6312561035156,
|
||||
"y": 285.23946380615234,
|
||||
"x": 1149.8379821777344,
|
||||
"y": 197.31159591674805,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#ced4da",
|
||||
"width": 621.8212890625001,
|
||||
"height": 79.7976837158203,
|
||||
"seed": 1660611796,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"id": "cvVouJIyT22r3RP8klygl",
|
||||
"type": "text",
|
||||
"x": 1137.06494140625,
|
||||
"y": 312.9378967285156,
|
||||
"width": 164,
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 155,
|
||||
"height": 25,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1325348180,
|
||||
"version": 130,
|
||||
"versionNonce": 498962388,
|
||||
"isDeleted": false,
|
||||
"boundElementIds": null,
|
||||
"text": "Standalone Mode",
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 18
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 452,
|
||||
"versionNonce": 1384318828,
|
||||
"isDeleted": false,
|
||||
"id": "uZJjI0NYZ64gKin-_7cR5",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 761.1866760253906,
|
||||
"y": 100.00330352783203,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#4c6ef5",
|
||||
"width": 128.17041015625003,
|
||||
"height": 79.7976837158203,
|
||||
"seed": 401388012,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"id": "zeDNXaEe6KkqqNB6hWn2v",
|
||||
"type": "text",
|
||||
"x": 778.9382934570312,
|
||||
"y": 115.62533569335938,
|
||||
"width": 91,
|
||||
"height": 50,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 2105824340,
|
||||
"version": 137,
|
||||
"versionNonce": 1352955220,
|
||||
"isDeleted": false,
|
||||
"boundElementIds": null,
|
||||
"text": "OS\nPackages",
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 43
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 332,
|
||||
"versionNonce": 1376205292,
|
||||
"isDeleted": false,
|
||||
"id": "8af38RMLhE245Uzw94tk3",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1205.6143035888672,
|
||||
"y": 103.33536529541016,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 106,
|
||||
"height": 80,
|
||||
"seed": 1813092204,
|
||||
"seed": 595309038,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 16,
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Programming\nLanguage\nDependencies\n",
|
||||
"baseline": 75,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 523,
|
||||
"versionNonce": 546482900,
|
||||
"version": 1035,
|
||||
"versionNonce": 1646453614,
|
||||
"isDeleted": false,
|
||||
"id": "EW10DZBtAPDl2g3lG4Khk",
|
||||
"id": "SPkrBrH6DGvkgQXtZQjIJ",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1050.4884185791016,
|
||||
"y": 98.33513641357422,
|
||||
"x": 959.9851989746094,
|
||||
"y": 170.4835319519043,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#4c6ef5",
|
||||
"width": 128.3895263671875,
|
||||
"height": 79.7976837158203,
|
||||
"seed": 1225188692,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"id": "rAQf9FyIl2L5AB1n9JzFk",
|
||||
"type": "text",
|
||||
"x": 1069.5552215576172,
|
||||
"y": 113.51881408691406,
|
||||
"width": 91,
|
||||
"height": 50,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1531169260,
|
||||
"version": 213,
|
||||
"versionNonce": 1734417516,
|
||||
"isDeleted": false,
|
||||
"boundElementIds": null,
|
||||
"text": "OS\nPackages",
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 43
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 705,
|
||||
"versionNonce": 270413908,
|
||||
"isDeleted": false,
|
||||
"id": "nMqoqCtyNfMXk8kWry8kH",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 50,
|
||||
"angle": 0,
|
||||
"x": 1191.5499114990234,
|
||||
"y": 97.8214340209961,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#15aabf",
|
||||
"width": 130.7032470703125,
|
||||
"height": 79.7976837158203,
|
||||
"seed": 1126636244,
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1896460914,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 412,
|
||||
"versionNonce": 1904079212,
|
||||
"version": 532,
|
||||
"versionNonce": 1887556210,
|
||||
"isDeleted": false,
|
||||
"id": "J5C9c2LNI5fqAAEYp_jI2",
|
||||
"id": "n06MNIqirDmVZBkDg_UPV",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1385.1761474609375,
|
||||
"y": 103.10254669189453,
|
||||
"x": 988.8137817382812,
|
||||
"y": 196.69753646850586,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 106,
|
||||
"height": 80,
|
||||
"seed": 546673900,
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 114,
|
||||
"height": 25,
|
||||
"seed": 1131832750,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 16,
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Programming\nLanguage\nDependencies\n",
|
||||
"baseline": 75,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 701,
|
||||
"versionNonce": 1654991700,
|
||||
"version": 1072,
|
||||
"versionNonce": 789595566,
|
||||
"isDeleted": false,
|
||||
"id": "PFi9vxp5euUTYOTLNztVZ",
|
||||
"id": "0JP6OL7EFfoH4E4vFARFl",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 50,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1344.9087524414062,
|
||||
"y": 96.26885223388672,
|
||||
"x": 1508.9087371826172,
|
||||
"y": 170.7038917541504,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#15aabf",
|
||||
"width": 198.17065429687491,
|
||||
"height": 79.7976837158203,
|
||||
"seed": 216760276,
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 101784622,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"id": "Uk7ac4Fk6B7eXS2IYB51e",
|
||||
"type": "text",
|
||||
"x": 1613.747314453125,
|
||||
"y": 305.670166015625,
|
||||
"width": 81,
|
||||
"height": 35,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"version": 496,
|
||||
"versionNonce": 1027781682,
|
||||
"isDeleted": false,
|
||||
"id": "jRmlh5MZuRKm3FtbC6qdZ",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1517.237319946289,
|
||||
"y": 196.91789627075195,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 155,
|
||||
"height": 25,
|
||||
"seed": 1950385586,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1115855212,
|
||||
"version": 77,
|
||||
"versionNonce": 1712645100,
|
||||
"isDeleted": false,
|
||||
"boundElementIds": null,
|
||||
"text": "Modes",
|
||||
"fontSize": 28,
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Misconfiguration",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 25
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"id": "AP0rLiNYZgZh6NpOg7FQl",
|
||||
"type": "text",
|
||||
"x": 1587.2977294921875,
|
||||
"y": 214.689453125,
|
||||
"width": 128,
|
||||
"height": 35,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"type": "rectangle",
|
||||
"version": 1133,
|
||||
"versionNonce": 882335726,
|
||||
"isDeleted": false,
|
||||
"id": "EQRF92xU4o9CfeHHvbd-a",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1327.384536743164,
|
||||
"y": 170.0898323059082,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 169.93957519531259,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1379493486,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 1133151724,
|
||||
"version": 172,
|
||||
"versionNonce": 1561108692,
|
||||
"isDeleted": false,
|
||||
"boundElementIds": null,
|
||||
"text": "Artifacts",
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 25
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"id": "hyBBGwYCM6J4CIKDn9IYh",
|
||||
"type": "text",
|
||||
"x": 1592.9608154296875,
|
||||
"y": 118.49179077148438,
|
||||
"width": 110,
|
||||
"height": 35,
|
||||
"angle": 0,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"version": 569,
|
||||
"versionNonce": 184638962,
|
||||
"isDeleted": false,
|
||||
"id": "_04YR8geM-ar9vZhNZtSj",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 1356.213119506836,
|
||||
"y": 196.30383682250977,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 114,
|
||||
"height": 25,
|
||||
"seed": 357105522,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"seed": 733312980,
|
||||
"version": 248,
|
||||
"versionNonce": 1076463212,
|
||||
"boundElementIds": [],
|
||||
"fontSize": 20,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 18,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 1215,
|
||||
"versionNonce": 650195502,
|
||||
"isDeleted": false,
|
||||
"boundElementIds": null,
|
||||
"text": "Targets",
|
||||
"id": "8SHSNGf7PNddFLi2ZA3Vi",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 599.9767150878906,
|
||||
"y": 169.0025749206543,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fa5252",
|
||||
"width": 344.1738281250001,
|
||||
"height": 77.80606079101562,
|
||||
"seed": 1986948530,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": []
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 680,
|
||||
"versionNonce": 113561522,
|
||||
"isDeleted": false,
|
||||
"id": "3Z5w3RXdgpvP43dlHqq26",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 700.3721618652344,
|
||||
"y": 190.79421615600586,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#82c91e",
|
||||
"width": 160,
|
||||
"height": 35,
|
||||
"seed": 1077804654,
|
||||
"groupIds": [],
|
||||
"strokeSharpness": "sharp",
|
||||
"boundElementIds": [],
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vulnerability",
|
||||
"baseline": 25,
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "top",
|
||||
"baseline": 25
|
||||
"verticalAlign": "middle"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
|
||||
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 49 KiB |
BIN
docs/imgs/misconf-demo.gif
Normal file
|
After Width: | Height: | Size: 3.4 MiB |
BIN
docs/imgs/misconf.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 622 KiB After Width: | Height: | Size: 878 KiB |
|
Before Width: | Height: | Size: 3.6 MiB |
|
Before Width: | Height: | Size: 315 KiB |
|
Before Width: | Height: | Size: 215 KiB |
BIN
docs/imgs/vuln-demo.gif
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
docs/imgs/vulnerability.png
Normal file
|
After Width: | Height: | Size: 846 KiB |
@@ -1,64 +1,49 @@
|
||||
# Welcome to {{ config.site_name }}
|
||||
---
|
||||
hide:
|
||||
- navigation
|
||||
- toc
|
||||
---
|
||||
|
||||
A Simple and Comprehensive Vulnerability Scanner for Containers and other Artifacts, Suitable for CI.
|
||||
{ align=left }
|
||||
|
||||
# Abstract
|
||||
`Trivy` (`tri` pronounced like **tri**gger, `vy` pronounced like en**vy**) is a simple and comprehensive vulnerability scanner for containers and other artifacts.
|
||||
`Trivy` (`tri` pronounced like **tri**gger, `vy` pronounced like en**vy**) is a simple and comprehensive [vulnerability][vulnerability]/[misconfiguration][misconf] scanner for containers and other artifacts.
|
||||
A software vulnerability is a glitch, flaw, or weakness present in the software or in an Operating System.
|
||||
`Trivy` detects vulnerabilities of OS packages (Alpine, RHEL, CentOS, etc.) and application dependencies (Bundler, Composer, npm, yarn, etc.).
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan. All you need to do for scanning is to specify a target such as an image name of the container.
|
||||
`Trivy` detects vulnerabilities of [OS packages][os] (Alpine, RHEL, CentOS, etc.) and [language-specific packages][lang] (Bundler, Composer, npm, yarn, etc.).
|
||||
In addition, `Trivy` scans [Infrastructure as Code (IaC) files][iac] such as Terraform and Kubernetes, to detect potential configuration issues that expose your deployments to the risk of attack.
|
||||
`Trivy` is easy to use. Just install the binary and you're ready to scan.
|
||||
All you need to do for scanning is to specify a target such as an image name of the container.
|
||||
|
||||
<img src="imgs/overview.png" width="700">
|
||||
<div style="text-align: center">
|
||||
<img src="imgs/overview.png" width="800">
|
||||
</div>
|
||||
|
||||
Trivy can be run in two different modes:
|
||||
|
||||
- [Standalone](./modes/standalone.md)
|
||||
- [Client/Server](./modes/client-server.md)
|
||||
<div style="text-align: center; margin-top: 150px">
|
||||
<h1 id="demo">Demo</h1>
|
||||
</div>
|
||||
|
||||
Trivy can scan three different artifacts:
|
||||
<figure style="text-aligh: center">
|
||||
<img src="imgs/vuln-demo.gif" width="1000">
|
||||
<figcaption>Demo: Vulnerability Detection</figcaption>
|
||||
</figure>
|
||||
|
||||
- [Container Images](./scanning/image.md)
|
||||
- [Filesystem](./scanning/filesystem.md)
|
||||
- [Git Repositories](./scanning/git-repository.md)
|
||||
<figure style="text-aligh: center">
|
||||
<img src="imgs/misconf-demo.gif" width="1000">
|
||||
<figcaption>Demo: Misconfiguration Detection</figcaption>
|
||||
</figure>
|
||||
|
||||
<img src="imgs/usage.gif" width="700">
|
||||
<img src="imgs/usage1.png" width="600">
|
||||
<img src="imgs/usage2.png" width="600">
|
||||
---
|
||||
|
||||
It is considered to be used in CI. Before pushing to a container registry or deploying your application, you can scan your local container image and other artifacts easily.
|
||||
See [here](./integrations/index.md) for details.
|
||||
Trivy is an [Aqua Security][aquasec] open source project.
|
||||
Learn about our open source work and portfolio [here][oss].
|
||||
Contact us about any matter by opening a GitHub Discussion [here][discussions]
|
||||
|
||||
## Features
|
||||
[vulnerability]: vulnerability/scanning/index.md
|
||||
[misconf]: misconfiguration/index.md
|
||||
[os]: vulnerability/detection/os.md
|
||||
[lang]: vulnerability/detection/language.md
|
||||
[iac]: misconfiguration/iac.md
|
||||
|
||||
- Detect comprehensive vulnerabilities
|
||||
- OS packages (Alpine, **Red Hat Universal Base Image**, Red Hat Enterprise Linux, CentOS, Oracle Linux, Debian, Ubuntu, Amazon Linux, openSUSE Leap, SUSE Enterprise Linux, Photon OS and Distroless)
|
||||
- **Application dependencies** (Bundler, Composer, Pipenv, Poetry, npm, yarn, Cargo, NuGet, Maven, and Go)
|
||||
- Simple
|
||||
- Specify only an image name or artifact name
|
||||
- See [Quick Start](quickstart.md) and [Examples](examples/index.md)
|
||||
- Fast
|
||||
- The first scan will finish within 10 seconds (depending on your network). Consequent scans will finish in single seconds.
|
||||
- Unlike other scanners that take long to fetch vulnerability information (~10 minutes) on the first run, and encourage you to maintain a durable vulnerability database, Trivy is stateless and requires no maintenance or preparation.
|
||||
- Easy installation
|
||||
- `apt-get install`, `yum install` and `brew install` is possible (See [Installation](installation.md))
|
||||
- **No pre-requisites** such as installation of DB, libraries, etc.
|
||||
- High accuracy
|
||||
- **Especially Alpine Linux and RHEL/CentOS**
|
||||
- Other OSes are also high
|
||||
- DevSecOps
|
||||
- **Suitable for CI** such as Travis CI, CircleCI, Jenkins, GitLab CI, etc.
|
||||
- See [CI Example](integrations/index.md)
|
||||
- Support multiple formats
|
||||
- container image
|
||||
- A local image in Docker Engine which is running as a daemon
|
||||
- A local image in Podman (>=2.0) which is exposing a socket
|
||||
- A remote image in Docker Registry such as Docker Hub, ECR, GCR and ACR
|
||||
- A tar archive stored in the `docker save` / `podman save` formatted file
|
||||
- An image directory compliant with [OCI Image Format](https://github.com/opencontainers/image-spec)
|
||||
- local filesystem
|
||||
- remote git repository
|
||||
|
||||
Please see [LICENSE](https://github.com/aquasecurity/trivy/blob/main/LICENSE) for Trivy licensing information.
|
||||
|
||||
!!! note
|
||||
Trivy uses vulnerability information from a variety of sources, some of which are licensed for non-commercial use only.
|
||||
[aquasec]: https://aquasec.com
|
||||
[oss]: https://www.aquasec.com/products/open-source-projects/
|
||||
[discussions]: https://github.com/aquasecurity/trivy/discussions
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
# GitLab CI
|
||||
|
||||
```
|
||||
$ cat .gitlab-ci.yml
|
||||
stages:
|
||||
- test
|
||||
|
||||
trivy:
|
||||
stage: test
|
||||
image: docker:stable
|
||||
services:
|
||||
- name: docker:dind
|
||||
entrypoint: ["env", "-u", "DOCKER_HOST"]
|
||||
command: ["dockerd-entrypoint.sh"]
|
||||
variables:
|
||||
DOCKER_HOST: tcp://docker:2375/
|
||||
DOCKER_DRIVER: overlay2
|
||||
# See https://github.com/docker-library/docker/pull/166
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
IMAGE: trivy-ci-test:$CI_COMMIT_SHA
|
||||
before_script:
|
||||
- export TRIVY_VERSION=$(wget -qO - "https://api.github.com/repos/aquasecurity/trivy/releases/latest" | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/')
|
||||
- echo $TRIVY_VERSION
|
||||
- wget --no-verbose https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz -O - | tar -zxvf -
|
||||
allow_failure: true
|
||||
script:
|
||||
# Build image
|
||||
- docker build -t $IMAGE .
|
||||
# Build report
|
||||
- ./trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $IMAGE
|
||||
# Print report
|
||||
- ./trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --severity HIGH $IMAGE
|
||||
# Fail on severe vulnerabilities
|
||||
- ./trivy --exit-code 1 --cache-dir .trivycache/ --severity CRITICAL --no-progress $IMAGE
|
||||
cache:
|
||||
paths:
|
||||
- .trivycache/
|
||||
# Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
|
||||
artifacts:
|
||||
reports:
|
||||
container_scanning: gl-container-scanning-report.json
|
||||
```
|
||||
|
||||
[Example][example]
|
||||
[Repository][repository]
|
||||
|
||||
### GitLab CI using Trivy container
|
||||
|
||||
To scan a previously built image that has already been pushed into the
|
||||
GitLab container registry the following CI job manifest can be used.
|
||||
Note that `entrypoint` needs to be unset for the `script` section to work.
|
||||
In case of a non-public GitLab project Trivy additionally needs to
|
||||
authenticate to the registry to be able to pull your application image.
|
||||
Finally, it is not necessary to clone the project repo as we only work
|
||||
with the container image.
|
||||
|
||||
```yaml
|
||||
container_scanning:
|
||||
image:
|
||||
name: docker.io/aquasec/trivy:latest
|
||||
entrypoint: [""]
|
||||
variables:
|
||||
# No need to clone the repo, we exclusively work on artifacts. See
|
||||
# https://docs.gitlab.com/ee/ci/runners/README.html#git-strategy
|
||||
GIT_STRATEGY: none
|
||||
TRIVY_USERNAME: "$CI_REGISTRY_USER"
|
||||
TRIVY_PASSWORD: "$CI_REGISTRY_PASSWORD"
|
||||
TRIVY_AUTH_URL: "$CI_REGISTRY"
|
||||
FULL_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
|
||||
script:
|
||||
- trivy --version
|
||||
# cache cleanup is needed when scanning images with the same tags, it does not remove the database
|
||||
- time trivy image --clear-cache
|
||||
# update vulnerabilities db
|
||||
- time trivy --download-db-only --no-progress --cache-dir .trivycache/
|
||||
# Builds report and puts it in the default workdir $CI_PROJECT_DIR, so `artifacts:` can take it from there
|
||||
- time trivy --exit-code 0 --cache-dir .trivycache/ --no-progress --format template --template "@/contrib/gitlab.tpl"
|
||||
--output "$CI_PROJECT_DIR/gl-container-scanning-report.json" "$FULL_IMAGE_NAME"
|
||||
# Prints full report
|
||||
- time trivy --exit-code 0 --cache-dir .trivycache/ --no-progress "$FULL_IMAGE_NAME"
|
||||
# Fails on high and critical vulnerabilities
|
||||
- time trivy --exit-code 1 --cache-dir .trivycache/ --severity CRITICAL --no-progress "$FULL_IMAGE_NAME"
|
||||
cache:
|
||||
paths:
|
||||
- .trivycache/
|
||||
# Enables https://docs.gitlab.com/ee/user/application_security/container_scanning/ (Container Scanning report is available on GitLab EE Ultimate or GitLab.com Gold)
|
||||
artifacts:
|
||||
when: always
|
||||
reports:
|
||||
container_scanning: gl-container-scanning-report.json
|
||||
tags:
|
||||
- docker-runner
|
||||
```
|
||||
|
||||
[example]: https://gitlab.com/aquasecurity/trivy-ci-test/pipelines
|
||||
[repository]: https://github.com/aquasecurity/trivy-ci-test
|
||||
@@ -1,3 +0,0 @@
|
||||
Scan your image automatically as part of your CI workflow, failing the workflow if a vulnerability is found. When you don't want to fail the test, specify `--exit-code 0`.
|
||||
|
||||
Since in automated scenarios such as CI/CD you are only interested in the end result, and not the full report, use the `--light` flag to optimize for this scenario and get fast results.
|
||||
25
docs/misconfiguration/comparison/cfsec.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# vs cfsec
|
||||
[cfsec][cfsec] uses static analysis of your CloudFormation templates to spot potential security issues.
|
||||
Trivy uses cfsec internally to scan both JSON and YAML configuration files, but Trivy doesn't support some features provided by cfsec.
|
||||
This section describes the differences between Trivy and cfsec.
|
||||
|
||||
| Feature | Trivy | cfsec |
|
||||
| --------------------------- | --------------------------------------- | -------------------- |
|
||||
| Built-in Policies | :material-check: | :material-check: |
|
||||
| Custom Policies | Rego[^1] | :material-close: |
|
||||
| Policy Metadata[^2] | :material-check: | :material-check: |
|
||||
| Show Successes | :material-check: | :material-check: |
|
||||
| Disable Policies | :material-check: | :material-check: |
|
||||
| Show Issue Lines | :material-close: | :material-check: |
|
||||
| View Statistics | :material-close: | :material-check: |
|
||||
| Filtering by Severity | :material-check: | :material-close: |
|
||||
| Supported Formats | Dockerfile, JSON, YAML, Terraform, etc. | CloudFormation JSON and YAML |
|
||||
|
||||
[^1]: CloudFormation files are not supported
|
||||
[^2]: To enrich the results such as ID, Title, Description, Severity, etc.
|
||||
|
||||
cfsec is designed for CloudFormation.
|
||||
People who use only want to scan their CloudFormation templates should use cfsec.
|
||||
People who want to scan a wide range of configuration files should use Trivy.
|
||||
|
||||
[cfsec]: https://github.com/aquasecurity/cfsec
|
||||
43
docs/misconfiguration/comparison/conftest.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# vs Conftest
|
||||
[Conftest][conftest] is a really nice tool to help you write tests against structured configuration data.
|
||||
Misconfiguration detection in Trivy is heavily inspired by Conftest and provides similar features Conftest has.
|
||||
This section describes the differences between Trivy and Conftest.
|
||||
|
||||
| Feature | Trivy | Conftest |
|
||||
| --------------------------- | -------------------- | -------------------- |
|
||||
| Support Rego Language | :material-check: | :material-check: |
|
||||
| Built-in Policies | :material-check: | :material-close: |
|
||||
| Custom Policies | :material-check: | :material-check: |
|
||||
| Custom Data | :material-check: | :material-check: |
|
||||
| Combine | :material-check: | :material-check: |
|
||||
| Combine per Policy | :material-check: | :material-close: |
|
||||
| Policy Input Selector[^1] | :material-check: | :material-close: |
|
||||
| Policy Metadata[^2] | :material-check: | :material-close:[^3] |
|
||||
| Filtering by Severity | :material-check: | :material-close: |
|
||||
| Rule-based Exceptions | :material-check: | :material-check: |
|
||||
| Namespace-based Exceptions | :material-check: | :material-close: |
|
||||
| Sharing Policies | :material-close: | :material-check: |
|
||||
| Show Successes | :material-check: | :material-close: |
|
||||
| Flexible Exit Code | :material-check: | :material-close: |
|
||||
| Rego Unit Tests | :material-close:[^4] | :material-check: |
|
||||
| Go Testing | :material-check: | :material-close: |
|
||||
| Verbose Trace | :material-check: | :material-check: |
|
||||
| Supported Formats | 6 formats[^5] | 14 formats[^6] |
|
||||
|
||||
Trivy offers built-in policies and a variety of options, while Conftest only supports custom policies.
|
||||
In other words, Conftest is simpler and lighter.
|
||||
|
||||
Conftest is a general testing tool for configuration files, and Trivy is more security-focused.
|
||||
People who need an out-of-the-box misconfiguration scanner should use Trivy.
|
||||
People who don't need built-in policies and write your policies should use Conftest.
|
||||
|
||||
[^1]: Pass only the types of configuration file as input, specified in selector
|
||||
[^2]: To enrich the results such as ID, Title, Description, etc.
|
||||
[^3]: Conftest supports [structured errors in rules][conftest-structured], but they are free format and not natively supported by Conftest.
|
||||
[^4]: Trivy is not able to run `*_test.rego` like `conftest verify`.
|
||||
[^5]: Dockerfile, HCL, HCL2, JSON, TOML, and YAML
|
||||
[^6]: CUE, Dockerfile, EDN, HCL, HCL2, HOCON, Ignore files, INI, JSON, Jsonnet, TOML, VCL, XML, and YAML
|
||||
|
||||
|
||||
[conftest-structured]: https://github.com/open-policy-agent/conftest/pull/243
|
||||
[conftest]: https://github.com/open-policy-agent/conftest
|
||||
26
docs/misconfiguration/comparison/tfsec.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# vs tfsec
|
||||
[tfsec][tfsec] uses static analysis of your Terraform templates to spot potential security issues.
|
||||
Trivy uses tfsec internally to scan Terraform HCL files, but Trivy doesn't support some features provided by tfsec.
|
||||
This section describes the differences between Trivy and tfsec.
|
||||
|
||||
| Feature | Trivy | tfsec |
|
||||
| --------------------------- | --------------------------------------- | -------------------- |
|
||||
| Built-in Policies | :material-check: | :material-check: |
|
||||
| Custom Policies | Rego[^1] | JSON and YAML |
|
||||
| Policy Metadata[^2] | :material-check: | :material-check: |
|
||||
| Show Successes | :material-check: | :material-check: |
|
||||
| Disable Policies | :material-check: | :material-check: |
|
||||
| Show Issue Lines | :material-close: | :material-check: |
|
||||
| Support .tfvars | :material-close: | :material-check: |
|
||||
| View Statistics | :material-close: | :material-check: |
|
||||
| Filtering by Severity | :material-check: | :material-close: |
|
||||
| Supported Formats | Dockerfile, JSON, YAML, Terraform, etc. | Terraform |
|
||||
|
||||
[^1]: Terraform HCL files are not supported.
|
||||
[^2]: To enrich the results such as ID, Title, Description, Severity, etc.
|
||||
|
||||
tfsec is designed for Terraform.
|
||||
People who use only Terraform should use tfsec.
|
||||
People who want to scan a wide range of configuration files should use Trivy.
|
||||
|
||||
[tfsec]: https://github.com/aquasecurity/tfsec
|
||||
44
docs/misconfiguration/custom/combine.md
Normal file
@@ -0,0 +1,44 @@
|
||||
# Combined input
|
||||
|
||||
## Overview
|
||||
Trivy usually scans each configuration file individually.
|
||||
Sometimes it might be useful to compare values from different configuration files simultaneously.
|
||||
|
||||
When `combine` is set to true, all config files under the specified directory are combined into one input data structure.
|
||||
|
||||
!!! example
|
||||
```
|
||||
__rego_input__ := {
|
||||
"combine": false,
|
||||
}
|
||||
```
|
||||
|
||||
In "combine" mode, the `input` document becomes an array, where each element is an object with two fields:
|
||||
|
||||
- `"path": "path/to/file"`: the relative file path of the respective file
|
||||
- `"contents": ...`: the parsed content of the respective file
|
||||
|
||||
Now you can ensure that duplicate values match across the entirety of your configuration files.
|
||||
|
||||
## Return value
|
||||
In "combine" mode, the `deny` entrypoint must return an object with two keys
|
||||
|
||||
`filepath` (required)
|
||||
: the relative file path of the file being evaluated
|
||||
|
||||
`msg` (required)
|
||||
: the message describing an issue
|
||||
|
||||
!!! example
|
||||
```
|
||||
deny[res] {
|
||||
resource := input[i].contents
|
||||
... some logic ...
|
||||
|
||||
res := {
|
||||
"filepath": input[i].path,
|
||||
"msg": "something bad",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
35
docs/misconfiguration/custom/data.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Custom Data
|
||||
|
||||
Custom policies may require additional data in order to determine an answer.
|
||||
|
||||
For example, an allowed list of resources that can be created.
|
||||
Instead of hardcoding this information inside of your policy, Trivy allows passing paths to data files with the `--data` flag.
|
||||
|
||||
Given the following yaml file:
|
||||
|
||||
```bash
|
||||
$ cd examples/misconf/custom-data
|
||||
$ cat data/ports.yaml [~/src/github.com/aquasecurity/trivy/examples/misconf/custom-data]
|
||||
services:
|
||||
ports:
|
||||
- "20"
|
||||
- "20/tcp"
|
||||
- "20/udp"
|
||||
- "23"
|
||||
- "23/tcp"
|
||||
```
|
||||
|
||||
This can be imported into your policy:
|
||||
|
||||
```rego
|
||||
import data.services
|
||||
|
||||
ports := services.ports
|
||||
```
|
||||
|
||||
Then, you need to pass data paths through `--data` option.
|
||||
Trivy recursively searches the specified paths for JSON (`*.json`) and YAML (`*.yaml`) files.
|
||||
|
||||
```bash
|
||||
$ trivy conf --policy ./policy --data data --namespaces user ./configs
|
||||
```
|
||||
225
docs/misconfiguration/custom/debug.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# Debugging policies
|
||||
When working on more complex queries (or when learning Rego), it's useful to see exactly how the policy is applied.
|
||||
For this purpose you can use the `--trace` flag.
|
||||
This will output a large trace from Open Policy Agent like the following:
|
||||
|
||||
!!! tip
|
||||
Only failed policies show traces. If you want to debug a passed policy, you need to make it fail on purpose.
|
||||
|
||||
```bash
|
||||
$ trivy conf --trace configs/
|
||||
2021-07-11T16:45:58.493+0300 INFO Detected config files: 1
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
|
||||
ID: DS002
|
||||
File: Dockerfile
|
||||
Namespace: appshield.dockerfile.DS002
|
||||
Query: data.appshield.dockerfile.DS002.deny
|
||||
Message: Last USER command in Dockerfile should not be 'root'
|
||||
TRACE Enter data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE | Eval data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE | Index data.appshield.dockerfile.DS002.deny matched 2 rules)
|
||||
TRACE | Enter data.appshield.dockerfile.DS002.deny
|
||||
TRACE | | Eval data.appshield.dockerfile.DS002.fail_user_count
|
||||
TRACE | | Index data.appshield.dockerfile.DS002.fail_user_count (matched 1 rule)
|
||||
TRACE | | Enter data.appshield.dockerfile.DS002.fail_user_count
|
||||
TRACE | | | Eval __local559__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Index data.appshield.dockerfile.DS002.get_user (matched 1 rule)
|
||||
TRACE | | | Enter data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Eval user = data.lib.docker.user[_]
|
||||
TRACE | | | | Index data.lib.docker.user (matched 1 rule)
|
||||
TRACE | | | | Enter data.lib.docker.user
|
||||
TRACE | | | | | Eval instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = data.lib.docker.user[_]
|
||||
TRACE | | | | Redo data.lib.docker.user
|
||||
TRACE | | | | | Redo instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = data.lib.docker.user[_]
|
||||
TRACE | | | | Redo data.lib.docker.user
|
||||
TRACE | | | | | Redo instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | Eval count(__local559__, __local391__)
|
||||
TRACE | | | Eval lt(__local391__, 1)
|
||||
TRACE | | | Fail lt(__local391__, 1)
|
||||
TRACE | | | Redo count(__local559__, __local391__)
|
||||
TRACE | | | Redo __local559__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | Fail data.appshield.dockerfile.DS002.fail_user_count
|
||||
TRACE | Enter data.appshield.dockerfile.DS002.deny
|
||||
TRACE | | Eval data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | Index data.appshield.dockerfile.DS002.fail_last_user_root (matched 1 rule)
|
||||
TRACE | | Enter data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | | Eval __local560__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Index data.appshield.dockerfile.DS002.get_user (matched 1 rule)
|
||||
TRACE | | | Enter data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Eval user = data.lib.docker.user[_]
|
||||
TRACE | | | | Index data.lib.docker.user (matched 1 rule)
|
||||
TRACE | | | | Enter data.lib.docker.user
|
||||
TRACE | | | | | Eval instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = data.lib.docker.user[_]
|
||||
TRACE | | | | Redo data.lib.docker.user
|
||||
TRACE | | | | | Redo instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = data.lib.docker.user[_]
|
||||
TRACE | | | | Redo data.lib.docker.user
|
||||
TRACE | | | | | Redo instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | Eval cast_array(__local560__, __local392__)
|
||||
TRACE | | | Eval user = __local392__
|
||||
TRACE | | | Eval __local561__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Index data.appshield.dockerfile.DS002.get_user (matched 1 rule)
|
||||
TRACE | | | Enter data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Eval user = data.lib.docker.user[_]
|
||||
TRACE | | | | Index data.lib.docker.user (matched 1 rule)
|
||||
TRACE | | | | Enter data.lib.docker.user
|
||||
TRACE | | | | | Eval instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = data.lib.docker.user[_]
|
||||
TRACE | | | | Redo data.lib.docker.user
|
||||
TRACE | | | | | Redo instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Exit data.lib.docker.user
|
||||
TRACE | | | | Eval username = user.Value[_]
|
||||
TRACE | | | | Exit data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | | Redo username = user.Value[_]
|
||||
TRACE | | | | Redo user = data.lib.docker.user[_]
|
||||
TRACE | | | | Redo data.lib.docker.user
|
||||
TRACE | | | | | Redo instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | | | Eval instruction.Cmd = "user"
|
||||
TRACE | | | | | Fail instruction.Cmd = "user"
|
||||
TRACE | | | | | Redo instruction = input.stages[_][_]
|
||||
TRACE | | | Eval count(__local561__, __local393__)
|
||||
TRACE | | | Eval len = __local393__
|
||||
TRACE | | | Eval minus(len, 1, __local394__)
|
||||
TRACE | | | Eval user[__local394__] = "root"
|
||||
TRACE | | | Exit data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | Eval res = "Last USER command in Dockerfile should not be 'root'"
|
||||
TRACE | | Exit data.appshield.dockerfile.DS002.deny
|
||||
TRACE | Redo data.appshield.dockerfile.DS002.deny
|
||||
TRACE | | Redo res = "Last USER command in Dockerfile should not be 'root'"
|
||||
TRACE | | Redo data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | Redo data.appshield.dockerfile.DS002.fail_last_user_root
|
||||
TRACE | | | Redo user[__local394__] = "root"
|
||||
TRACE | | | Redo minus(len, 1, __local394__)
|
||||
TRACE | | | Redo len = __local393__
|
||||
TRACE | | | Redo count(__local561__, __local393__)
|
||||
TRACE | | | Redo __local561__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | | | Redo user = __local392__
|
||||
TRACE | | | Redo cast_array(__local560__, __local392__)
|
||||
TRACE | | | Redo __local560__ = data.appshield.dockerfile.DS002.get_user
|
||||
TRACE | Exit data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE Redo data.appshield.dockerfile.DS002.deny = _
|
||||
TRACE | Redo data.appshield.dockerfile.DS002.deny = _
|
||||
```
|
||||
296
docs/misconfiguration/custom/examples.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# Examples
|
||||
|
||||
## Custom Policy
|
||||
### Kubernetes
|
||||
See [here][k8s].
|
||||
|
||||
The custom policy is defined in `user.kubernetes.ID001` package.
|
||||
You need to pass the package prefix you want to evaluate through `--namespaces` option.
|
||||
In this case, the package prefix should be `user`, `user.kuberntes`, or `user.kubernetes.ID001`.
|
||||
|
||||
### Dockerfile
|
||||
See [here][dockerfile].
|
||||
|
||||
The input will be a dictionary of stages.
|
||||
|
||||
#### Single Stage
|
||||
|
||||
??? example
|
||||
Dockerfile
|
||||
```dockerfile
|
||||
FROM foo
|
||||
COPY . /
|
||||
RUN echo hello
|
||||
```
|
||||
|
||||
Rego Input
|
||||
```json
|
||||
{
|
||||
"stages": {
|
||||
"foo": [
|
||||
{
|
||||
"Cmd": "from",
|
||||
"EndLine": 1,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "FROM foo",
|
||||
"Stage": 0,
|
||||
"StartLine": 1,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "copy",
|
||||
"EndLine": 2,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "COPY . /",
|
||||
"Stage": 0,
|
||||
"StartLine": 2,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
".",
|
||||
"/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 3,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN echo hello",
|
||||
"Stage": 0,
|
||||
"StartLine": 3,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"echo hello"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Multi Stage
|
||||
|
||||
??? example
|
||||
Dockerfile
|
||||
```dockerfile
|
||||
FROM golang:1.16 AS builder
|
||||
WORKDIR /go/src/github.com/alexellis/href-counter/
|
||||
RUN go get -d -v golang.org/x/net/html
|
||||
COPY app.go .
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add ca-certificates \
|
||||
&& apk add --no-cache bash
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /go/src/github.com/alexellis/href-counter/app .
|
||||
CMD ["./app"]
|
||||
```
|
||||
|
||||
Rego Input
|
||||
```json
|
||||
{
|
||||
"stages": {
|
||||
"alpine:latest": [
|
||||
{
|
||||
"Cmd": "from",
|
||||
"EndLine": 7,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "FROM alpine:latest",
|
||||
"Stage": 1,
|
||||
"StartLine": 7,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"alpine:latest"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 9,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN apk --no-cache add ca-certificates \u0026\u0026 apk add --no-cache bash",
|
||||
"Stage": 1,
|
||||
"StartLine": 8,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"apk --no-cache add ca-certificates \u0026\u0026 apk add --no-cache bash"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "workdir",
|
||||
"EndLine": 10,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "WORKDIR /root/",
|
||||
"Stage": 1,
|
||||
"StartLine": 10,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"/root/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "copy",
|
||||
"EndLine": 11,
|
||||
"Flags": [
|
||||
"--from=builder"
|
||||
],
|
||||
"JSON": false,
|
||||
"Original": "COPY --from=builder /go/src/github.com/alexellis/href-counter/app .",
|
||||
"Stage": 1,
|
||||
"StartLine": 11,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"/go/src/github.com/alexellis/href-counter/app",
|
||||
"."
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "cmd",
|
||||
"EndLine": 12,
|
||||
"Flags": [],
|
||||
"JSON": true,
|
||||
"Original": "CMD [\"./app\"]",
|
||||
"Stage": 1,
|
||||
"StartLine": 12,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"./app"
|
||||
]
|
||||
}
|
||||
],
|
||||
"golang:1.16 AS builder": [
|
||||
{
|
||||
"Cmd": "from",
|
||||
"EndLine": 1,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "FROM golang:1.16 AS builder",
|
||||
"Stage": 0,
|
||||
"StartLine": 1,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"golang:1.16",
|
||||
"AS",
|
||||
"builder"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "workdir",
|
||||
"EndLine": 2,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "WORKDIR /go/src/github.com/alexellis/href-counter/",
|
||||
"Stage": 0,
|
||||
"StartLine": 2,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"/go/src/github.com/alexellis/href-counter/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 3,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN go get -d -v golang.org/x/net/html",
|
||||
"Stage": 0,
|
||||
"StartLine": 3,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"go get -d -v golang.org/x/net/html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "copy",
|
||||
"EndLine": 4,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "COPY app.go .",
|
||||
"Stage": 0,
|
||||
"StartLine": 4,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"app.go",
|
||||
"."
|
||||
]
|
||||
},
|
||||
{
|
||||
"Cmd": "run",
|
||||
"EndLine": 5,
|
||||
"Flags": [],
|
||||
"JSON": false,
|
||||
"Original": "RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .",
|
||||
"Stage": 0,
|
||||
"StartLine": 5,
|
||||
"SubCmd": "",
|
||||
"Value": [
|
||||
"CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app ."
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
See [here][compose].
|
||||
|
||||
Docker Compose uses YAML format for configurations. You can apply your Rego policies to `docker-compose.yml`.
|
||||
|
||||
### HCL
|
||||
See [here][hcl].
|
||||
|
||||
Trivy parses HCL files and converts into structured data.
|
||||
|
||||
!!! warning
|
||||
Terraform HCL files are not supported yet.
|
||||
|
||||
### Terraform Plan
|
||||
See [here][tfplan].
|
||||
|
||||
Use the command [terraform show][terraform-show] to convert the Terraform plan into JSON so that OPA can read the plan.
|
||||
|
||||
```bash
|
||||
$ terraform init
|
||||
$ terraform plan --out tfplan.binary
|
||||
$ terraform show -json tfplan.binary > tfplan.json
|
||||
```
|
||||
|
||||
For more details, see also [OPA document][opa-terraform].
|
||||
|
||||
### Serverless Framework
|
||||
See [here][serverless].
|
||||
|
||||
Server Framework uses YAML format for configurations. You can apply your Rego policies to `serverless.yaml`.
|
||||
|
||||
## Custom Data
|
||||
See [here][data].
|
||||
|
||||
## Combined Input
|
||||
See [here][combine].
|
||||
|
||||
## Go Testing
|
||||
See [here][go-testing].
|
||||
|
||||
[k8s]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/kubernetes/
|
||||
[dockerfile]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/dockerfile/
|
||||
[compose]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/docker-compose/
|
||||
[hcl]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/hcl/
|
||||
[serverless]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/serverless/
|
||||
[tfplan]:https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy/terraform-plan/
|
||||
[terraform-show]: https://www.terraform.io/docs/cli/commands/show.html
|
||||
[opa-terraform]: https://www.openpolicyagent.org/docs/latest/terraform/
|
||||
|
||||
[custom]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-policy
|
||||
[data]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/custom-data
|
||||
[combine]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/combine
|
||||
[go-testing]: https://github.com/aquasecurity/trivy/tree/{{ git.commit }}/examples/misconf/go-testing
|
||||
|
||||
183
docs/misconfiguration/custom/index.md
Normal file
@@ -0,0 +1,183 @@
|
||||
# Custom Policies
|
||||
|
||||
## Overview
|
||||
You can write custom policies in [Rego][rego].
|
||||
Once you finish writing custom policies, you can pass the directory where those policies are stored with `--policy` option.
|
||||
|
||||
``` bash
|
||||
trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir
|
||||
```
|
||||
|
||||
As for `--namespaces` option, the detail is described as below.
|
||||
|
||||
### File formats
|
||||
If a file name matches the following file patterns, Trivy will parse the file and pass it as input to your Rego policy.
|
||||
|
||||
| File format | File pattern |
|
||||
| -------------- | ------------------------------------------------ |
|
||||
| JSON | `*.json` |
|
||||
| YAML | `*.yaml` |
|
||||
| TOML | `*.toml` |
|
||||
| HCL | `*.hcl`, `*.hcl1`, and `*.hcl2` |
|
||||
| Dockerfile | `Dockerfile`, `Dockerfile.*`, and `*.Dockerfile` |
|
||||
|
||||
### Configuration languages
|
||||
In the above general file formats, Trivy automatically identifies the following types of configuration files:
|
||||
|
||||
- Ansible (YAML)
|
||||
- CloudFormation (JSON/YAML)
|
||||
- Kubernetes (JSON/YAML)
|
||||
|
||||
This is useful for filtering inputs, as described below.
|
||||
|
||||
!!! warning
|
||||
Custom policies do not support Terraform at the moment.
|
||||
|
||||
## Rego format
|
||||
A single package must contain only one policy.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
package user.kubernetes.ID001
|
||||
|
||||
__rego_metadata__ := {
|
||||
"id": "ID001",
|
||||
"title": "Deployment not allowed",
|
||||
"severity": "LOW",
|
||||
"type": "Custom Kubernetes Check",
|
||||
"description": "Deployments are not allowed because of some reasons.",
|
||||
}
|
||||
|
||||
__rego_input__ := {
|
||||
"selector": [
|
||||
{"type": "kubernetes"},
|
||||
],
|
||||
}
|
||||
|
||||
deny[msg] {
|
||||
input.kind == "Deployment"
|
||||
msg = sprintf("Found deployment '%s' but deployments are not allowed", [input.metadata.name])
|
||||
}
|
||||
```
|
||||
|
||||
In this example, ID001 "Deployment not allowed" is defined under `user.kubernetes.ID001`.
|
||||
If you add a new custom policy, it must be defined under a new package like `user.kubernetes.ID002`.
|
||||
|
||||
### Policy structure
|
||||
|
||||
`package` (required)
|
||||
: - MUST follow the Rego's [specification][package]
|
||||
- MUST be unique per policy
|
||||
- SHOULD include policy id for uniqueness
|
||||
- MAY include the group name such as `kubernetes` for clarity
|
||||
- Group name has no effect on policy evaluation
|
||||
|
||||
`__rego_metadata__` (optional)
|
||||
: - SHOULD be defined for clarity since these values will be displayed in the scan results
|
||||
|
||||
`__rego_input__` (optional)
|
||||
: - MAY be defined when you want to specify input format
|
||||
|
||||
`deny` (required)
|
||||
: - SHOULD be `deny` or start with `deny_`
|
||||
- Although `warn`, `warn_*`, `violation`, `violation_` also work for compatibility, `deny` is recommended as severity can be defined in `__rego_metadata__`.
|
||||
- SHOULD return `string`
|
||||
- Although `object` with `msg` field is accepted, other fields are dropped and `string` is recommended.
|
||||
- e.g. `{"msg": "deny message", "details": "something"}`
|
||||
|
||||
|
||||
### Package
|
||||
A package name must be unique per policy.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
package user.kubernetes.ID001
|
||||
```
|
||||
|
||||
By default, only `appshield.*` packages will be evaluated.
|
||||
If you define custom packages, you have to specify the package prefix via `--namespaces` option.
|
||||
|
||||
``` bash
|
||||
trivy conf --policy /path/to/custom_policies --namespaces user /path/to/config_dir
|
||||
```
|
||||
|
||||
In this case, `user.*` will be evaluated.
|
||||
Any package prefixes such as `main` and `user` are allowed.
|
||||
|
||||
### Metadata
|
||||
Metadata helps enrich Trivy's scan results with useful information.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
__rego_metadata__ := {
|
||||
"id": "ID001",
|
||||
"title": "Deployment not allowed",
|
||||
"severity": "LOW",
|
||||
"type": "Custom Kubernetes Check",
|
||||
"description": "Deployments are not allowed because of some reasons.",
|
||||
"recommended_actions": "Remove Deployment",
|
||||
"url": "https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits",
|
||||
}
|
||||
```
|
||||
|
||||
All fields under `__rego_metadata__` are optional.
|
||||
|
||||
| Field name | Allowed values | Default value | In table | In JSON |
|
||||
| ------------------ | ------------------------------------| :-----------: | :----------------: |:---------------: |
|
||||
| id | Any characters | N/A | :material-check: | :material-check: |
|
||||
| title | Any characters | N/A | :material-check: | :material-check: |
|
||||
| severity | `LOW`, `MEDIUM`, `HIGH`, `CRITICAL` | UNKNOWN | :material-check: | :material-check: |
|
||||
| type | Any characters | N/A | :material-check: | :material-check: |
|
||||
| description | Any characters | | :material-close: | :material-check: |
|
||||
| recommended_actions| Any characters | | :material-close: | :material-check: |
|
||||
| url | Any characters | | :material-close: | :material-check: |
|
||||
|
||||
Some fields are displayed in scan results.
|
||||
|
||||
``` bash
|
||||
deployment.yaml (kubernetes)
|
||||
============================
|
||||
Tests: 28 (SUCCESSES: 14, FAILURES: 14, EXCEPTIONS: 0)
|
||||
Failures: 14 (HIGH: 1)
|
||||
|
||||
+---------------------------+------------+-------------------------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+-------------------------------------+----------+------------------------------------------+
|
||||
| Custom Kubernetes Check | ID001 | Deployment not allowed | LOW | Found deployment 'test' but deployments |
|
||||
| | | | | are not allowed |
|
||||
+---------------------------+------------+-------------------------------------+----------+------------------------------------------+
|
||||
```
|
||||
|
||||
### Input
|
||||
You can specify input format via `__rego_input__`.
|
||||
All fields under `__rego_input` are optional.
|
||||
|
||||
!!!example
|
||||
``` rego
|
||||
__rego_input__ := {
|
||||
"combine": false,
|
||||
"selector": [
|
||||
{"type": "kubernetes"},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
`combine` (boolean)
|
||||
: The details is [here](combine.md).
|
||||
|
||||
`selector` (array)
|
||||
: This option filters the input by file formats or configuration languages.
|
||||
In the above example, Trivy passes only Kubernetes files to this policy.
|
||||
Even if Dockerfile exists in the specified directory, it will not be passed to the policy as input.
|
||||
|
||||
When configuration language such as Kubernetes is not identified, file format such as JSON will be used as `type`.
|
||||
When configuration language is identified, it will overwrite `type`.
|
||||
|
||||
!!! example
|
||||
`pod.yaml` including Kubernetes Pod will be handled as `kubernetes`, not `yaml`.
|
||||
`type` is overwritten by `kubernetes` from `yaml`.
|
||||
|
||||
`type` accepts `kubernetes`, `dockerfile`, `ansible`, `cloudformation`, `json`, `yaml`, `toml`, or `hcl`.
|
||||
|
||||
[rego]: https://www.openpolicyagent.org/docs/latest/policy-language/
|
||||
[package]: https://www.openpolicyagent.org/docs/latest/policy-language/#packages
|
||||
90
docs/misconfiguration/custom/testing.md
Normal file
@@ -0,0 +1,90 @@
|
||||
# Testing
|
||||
It is highly recommended to write tests for your custom policies.
|
||||
|
||||
## Rego testing
|
||||
To help you verify the correctness of your custom policies, OPA gives you a framework that you can use to write tests for your policies.
|
||||
By writing tests for your custom policies you can speed up the development process of new rules and reduce the amount of time it takes to modify rules as requirements evolve.
|
||||
|
||||
For more details, see [Policy Testing][opa-testing].
|
||||
|
||||
!!! example
|
||||
```
|
||||
package user.dockerfile.ID002
|
||||
|
||||
test_add_denied {
|
||||
r := deny with input as {"stages": {"alpine:3.13": [
|
||||
{"Cmd": "add", "Value": ["/target/resources.tar.gz", "resources.jar"]},
|
||||
{"Cmd": "add", "Value": ["/target/app.jar", "app.jar"]},
|
||||
]}}
|
||||
|
||||
count(r) == 1
|
||||
r[_] == "Consider using 'COPY /target/app.jar app.jar' command instead of 'ADD /target/app.jar app.jar'"
|
||||
}
|
||||
```
|
||||
|
||||
To write tests for custom policies, you can refer to existing tests under [AppShield][appshield].
|
||||
|
||||
## Go testing
|
||||
[Fanal][fanal] which is a core library of Trivy can be imported as a Go library.
|
||||
You can scan config files in Go and test your custom policies using Go's testing methods, such as [table-driven tests][table].
|
||||
This allows you to use the actual configuration file as input, making it easy to prepare test data and ensure that your custom policies work in practice.
|
||||
|
||||
In particular, Dockerfile and HCL need to be converted to structural data as input, which may be different from the expected input format.
|
||||
|
||||
!!! tip
|
||||
We recommend writing OPA and Go tests both since they have different roles, like unit tests and integration tests.
|
||||
|
||||
The following example stores allowed and denied configuration files in a directory.
|
||||
`Successes` contains the result of successes, and `Failures` contains the result of failures.
|
||||
|
||||
``` go
|
||||
{
|
||||
name: "disallowed ports",
|
||||
input: "configs/",
|
||||
fields: fields{
|
||||
policyPaths: []string{"policy"},
|
||||
dataPaths: []string{"data"},
|
||||
namespaces: []string{"user"},
|
||||
},
|
||||
want: []types.Misconfiguration{
|
||||
{
|
||||
FileType: types.Dockerfile,
|
||||
FilePath: "Dockerfile.allowed",
|
||||
Successes: types.MisconfResults{
|
||||
{
|
||||
Namespace: "user.dockerfile.ID002",
|
||||
PolicyMetadata: types.PolicyMetadata{
|
||||
ID: "ID002",
|
||||
Type: "Docker Custom Check",
|
||||
Title: "Disallowed ports exposed",
|
||||
Severity: "HIGH",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
FileType: types.Dockerfile,
|
||||
FilePath: "Dockerfile.denied",
|
||||
Failures: types.MisconfResults{
|
||||
{
|
||||
Namespace: "user.dockerfile.ID002",
|
||||
Message: "Port 23 should not be exposed",
|
||||
PolicyMetadata: types.PolicyMetadata{
|
||||
ID: "ID002",
|
||||
Type: "Docker Custom Check",
|
||||
Title: "Disallowed ports exposed",
|
||||
Severity: "HIGH",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
```
|
||||
|
||||
`Dockerfile.allowed` has one successful result in `Successes`, while `Dockerfile.denied` has one failure result in `Failures`.
|
||||
|
||||
[opa-testing]: https://www.openpolicyagent.org/docs/latest/policy-testing/
|
||||
[appshield]: https://github.com/aquasecurity/appshield
|
||||
[table]: https://github.com/golang/go/wiki/TableDrivenTests
|
||||
[fanal]: https://github.com/aquasecurity/fanal
|
||||
56
docs/misconfiguration/filesystem.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Filesystem
|
||||
|
||||
## Quick start
|
||||
|
||||
Trivy scans a filesystem such as a virtual machine to detect misconfigurations.
|
||||
|
||||
You have to specify `--security-checks config` to enable misconfiguration detection.
|
||||
|
||||
```bash
|
||||
$ trivy fs --security-checks config /path/to/dir
|
||||
```
|
||||
|
||||
Internally, it is the same as [config subcommand](iac.md).
|
||||
|
||||
## Vulnerability and Misconfiguration scanning
|
||||
The difference between `fs` and `config` subcommand is that `fs` can detect both vulnerabilities and misconfiguration at the same time.
|
||||
|
||||
You have to specify `--security-checks vuln,config` to enable vulnerability and misconfiguration detection.
|
||||
|
||||
``` bash
|
||||
$ ls myapp/
|
||||
Dockerfile Pipfile.lock
|
||||
$ trivy fs --security-checks vuln,config --severity HIGH,CRITICAL myapp/
|
||||
2021-07-09T12:03:27.564+0300 INFO Detected OS: unknown
|
||||
2021-07-09T12:03:27.564+0300 INFO Number of language-specific files: 1
|
||||
2021-07-09T12:03:27.564+0300 INFO Detecting pipenv vulnerabilities...
|
||||
2021-07-09T12:03:27.566+0300 INFO Detected config files: 1
|
||||
|
||||
Pipfile.lock (pipenv)
|
||||
=====================
|
||||
Total: 1 (HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE |
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
| httplib2 | CVE-2021-21240 | HIGH | 0.12.1 | 0.19.0 | python-httplib2: Regular |
|
||||
| | | | | | expression denial of |
|
||||
| | | | | | service via malicious header |
|
||||
| | | | | | -->avd.aquasec.com/nvd/cve-2021-21240 |
|
||||
+----------+------------------+----------+-------------------+---------------+---------------------------------------+
|
||||
|
||||
Dockerfile (dockerfile)
|
||||
=======================
|
||||
Tests: 23 (SUCCESSES: 22, FAILURES: 1, EXCEPTIONS: 0)
|
||||
Failures: 1 (HIGH: 1, CRITICAL: 0)
|
||||
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| TYPE | MISCONF ID | CHECK | SEVERITY | MESSAGE |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
| Dockerfile Security Check | DS002 | Image user is 'root' | HIGH | Last USER command in |
|
||||
| | | | | Dockerfile should not be 'root' |
|
||||
| | | | | -->avd.aquasec.com/appshield/ds002 |
|
||||
+---------------------------+------------+----------------------+----------+------------------------------------------+
|
||||
```
|
||||
|
||||
In the above example, Trivy detected vulnerabilities of Python dependencies and misconfigurations in Dockerfile.
|
||||