forked from ecomtech-oss/pisc
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathscan-trivy.sh
More file actions
193 lines (176 loc) · 6.06 KB
/
Copy pathscan-trivy.sh
File metadata and controls
193 lines (176 loc) · 6.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#!/bin/bash
# Public OCI-Image Security Checker
# Author: @kapistka, 2026
# Usage
# ./scan-trivy.sh [-i image_link | --tar /path/to/private-image.tar]
# Available options:
# --ignore-errors ignore errors (instead, write to $ERROR_FILE)
# -i, --image string only this image will be checked. Example: -i kapistka/log4shell:0.0.3-nonroot
# --offline-feeds use a self-contained offline image with pre-downloaded vulnerability feeds (e.g., :latest-feeds)
# --tar string check local image-tar. Example: --tar /path/to/private-image.tar
# --trivy-server string use trivy server if you can. Specify trivy URL, example: --trivy-server http://trivy.something.io:8080
# --trivy-token string use trivy server if you can. Specify trivy token, example: --trivy-token 0123456789abZ
# Example
# ./scan-trivy.sh -i kapistka/log4shell:0.0.3-nonroot
set -Eeo pipefail
# var init
IGNORE_ERRORS=false
IMAGE_LINK=''
IS_ERROR=false
RESULT_MESSAGE=''
OFFLINE_FEEDS_FLAG=''
TRIVY_SERVER=''
TRIVY_TOKEN=''
# it is important for run *.sh by ci-runner
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
# get exported var with default value if it is empty
: "${PISC_OUT_DIR:=/tmp}"
: "${PISC_FEEDS_DIR:=$PISC_OUT_DIR/.cache}"
# check debug mode to debug child scripts
DEBUG=''
DEBUG_TRIVY='2>/dev/null'
if [[ "$-" == *x* ]]; then
DEBUG='-x '
DEBUG_TRIVY='--debug'
fi
# turn on/off debugging for hide sensetive data
debug_set() {
if [ "$1" = false ] ; then
set +x
else
if [ "$DEBUG" != "" ]; then
set -x
fi
fi
}
# trivy feeds dir
TRIVY_DB_CACHE_DIR=$PISC_FEEDS_DIR'/trivy'
# default tar path
INPUT_FILE=$PISC_OUT_DIR/image.tar
# trivy output
CSV_FILE=$PISC_OUT_DIR'/scan-trivy.csv'
# result this script for main output
RES_FILE=$PISC_OUT_DIR'/scan-trivy.result'
# error file
ERROR_FILE=$PISC_OUT_DIR'/scan-trivy.error'
# template file
TMPL_FILE=$SCRIPTPATH'/trivy.tmpl'
eval "rm -f $CSV_FILE $RES_FILE $ERROR_FILE"
touch $RES_FILE
# exception handling
error_exit()
{
if [ "$IS_ERROR" = false ]; then
IS_ERROR=true
if [ "$IGNORE_ERRORS" = true ]; then
printf " $1" > $ERROR_FILE
return 0
else
echo " $IMAGE_LINK >>> $1 "
exit 2
fi
fi
}
# read the options
debug_set false
ARGS=$(getopt -o i: --long ignore-errors,image:,offline-feeds,tar:,trivy-server:,trivy-token: -n $0 -- "$@")
eval set -- "$ARGS"
debug_set true
# extract options and their arguments into variables.
while true ; do
case "$1" in
--ignore-errors)
case "$2" in
"") shift 1 ;;
*) IGNORE_ERRORS=true ; shift 1 ;;
esac ;;
-i|--image)
case "$2" in
"") shift 2 ;;
*) IMAGE_LINK=$2 ; shift 2 ;;
esac ;;
--offline-feeds)
case "$2" in
"") shift 1 ;;
*) OFFLINE_FEEDS_FLAG='--skip-db-update --skip-java-db-update' ; shift 1 ;;
esac ;;
--tar)
case "$2" in
"") shift 2 ;;
*) INPUT_FILE=$2 ; shift 2 ;;
esac ;;
--trivy-server)
case "$2" in
"") shift 2 ;;
*) TRIVY_SERVER=$2 ; shift 2 ;;
esac ;;
--trivy-token)
case "$2" in
"") shift 2 ;;
*) debug_set false ; TRIVY_TOKEN=$2 ; debug_set true ; shift 2 ;;
esac ;;
--) shift ; break ;;
*) echo "Wrong usage! Try '$0 --help' for more information." ; exit 2 ;;
esac
done
# check cache dir
mkdir -p "$TRIVY_DB_CACHE_DIR" 2>/dev/null \
|| error_exit "error access to trivy --cache-dir $TRIVY_DB_CACHE_DIR"
echo -ne " $(date +"%H:%M:%S") $IMAGE_LINK >>> scan vulnerabilities by trivy\033[0K\r"
# use template
# {{- range . }}
# {{- range .Vulnerabilities }}
# {{- $score := "" -}}
# {{- range $key, $cvss := .CVSS }}
# {{- if eq (printf "%s" $key) "nvd" }}
# {{- $score = printf "%.1f" $cvss.V3Score }}
# {{- end }}
# {{- end }}
# {{ .VulnerabilityID }}|{{ .Severity }}|{{ $score }}|{{ .FixedVersion }}|{{ .PkgName }}
# {{- end }}
# {{- end }}
# if trivy-token is not specified, then use the local database (slow, if the script is in a OCI-image, the CI/CD speed suffers)
debug_set false
if [ -z "$TRIVY_TOKEN" ]; then
debug_set true
eval "trivy image --disable-telemetry --cache-dir $TRIVY_DB_CACHE_DIR --scanners vuln $OFFLINE_FEEDS_FLAG --format template --template @$TMPL_FILE -o $CSV_FILE --input $INPUT_FILE $DEBUG_TRIVY" || \
error_exit "error trivy"
# if trivy-token is specified, then we use the trivy-server
else
eval "trivy image --disable-telemetry --cache-dir $TRIVY_DB_CACHE_DIR --scanners vuln $OFFLINE_FEEDS_FLAG --format template --template @$TMPL_FILE -o $CSV_FILE --input $INPUT_FILE --server $TRIVY_SERVER --token $TRIVY_TOKEN --timeout 15m $DEBUG_TRIVY" || \
eval "trivy image --disable-telemetry --cache-dir $TRIVY_DB_CACHE_DIR --scanners vuln $OFFLINE_FEEDS_FLAG --format template --template @$TMPL_FILE -o $CSV_FILE --input $INPUT_FILE $DEBUG_TRIVY" || \
error_exit "error trivy client/server"
fi
debug_set true
# get values
LIST_CVE=()
LIST_SEVERITY=()
LIST_SCORE=()
LIST_FIXED=()
LIST_PKG=()
while IFS='|' read -r cve severity score fix package; do
if [[ "$cve" =~ CVE ]]; then
LIST_CVE+=("$cve")
LIST_SEVERITY+=("$severity")
LIST_SCORE+=("$score")
LIST_FIXED+=("$fix")
# remove windows line-ending
package=${package//$'\r'/}
LIST_PKG+=("$package")
fi
done < "$CSV_FILE"
LIST_length=${#LIST_CVE[@]}
# normalize and print values
for (( i=0; i<$LIST_length; i++ ));
do
if [ "${LIST_FIXED[$i]}" = "" ]; then
LIST_FIXED[$i]='-'
else
LIST_FIXED[$i]='+'
fi
if [ "${LIST_SCORE[$i]}" = "" ]; then
LIST_SCORE[$i]='-'
fi
echo "${LIST_PKG[$i]} ${LIST_CVE[$i]} ${LIST_SEVERITY[$i]} ${LIST_SCORE[$i]} ${LIST_FIXED[$i]}" >> $RES_FILE
done
exit 0