| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
# CVE-Client: CLI-based client / toolbox for CVE.org |
|
2
|
|
|
|
|
|
|
# Copyright © 2021-2023 CVE-Client Authors |
|
3
|
|
|
|
|
|
|
# SPDX-License-Identifier: AGPL-3.0-only |
|
4
|
|
|
|
|
|
|
package App::CveClient; |
|
5
|
|
|
|
|
|
|
our $VERSION = 'v1.0.5'; |
|
6
|
|
|
|
|
|
|
|
|
7
|
1
|
|
|
1
|
|
111876
|
use warnings; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
32
|
|
|
8
|
1
|
|
|
1
|
|
6
|
use strict; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
22
|
|
|
9
|
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
5
|
use Exporter qw(import); |
|
|
1
|
|
|
|
|
9
|
|
|
|
1
|
|
|
|
|
1174
|
|
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our @EXPORT_OK = qw(print_cve print_cve50 print_cve40); |
|
13
|
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
sub print_cve { |
|
15
|
2
|
|
|
2
|
0
|
4054
|
my ($object, $cve_id, $format) = @_; |
|
16
|
|
|
|
|
|
|
|
|
17
|
2
|
|
|
|
|
85
|
print "CVE ID: ", $cve_id, "\n"; |
|
18
|
|
|
|
|
|
|
|
|
19
|
2
|
0
|
33
|
|
|
13
|
if ($object->{'error'} and $object->{'message'}) { |
|
20
|
0
|
|
|
|
|
0
|
die "Error ($object->{'error'}): $object->{'message'}\n"; |
|
21
|
|
|
|
|
|
|
} |
|
22
|
|
|
|
|
|
|
|
|
23
|
2
|
50
|
|
|
|
10
|
if ($object->{'dataVersion'} == "5.0") { |
|
|
|
0
|
|
|
|
|
|
|
24
|
2
|
|
|
|
|
7
|
print_cve50($object, $cve_id, $format); |
|
25
|
|
|
|
|
|
|
} elsif ($object->{'data_version'} == "4.0") { |
|
26
|
0
|
|
|
|
|
0
|
print_cve40($object, $cve_id, $format); |
|
27
|
|
|
|
|
|
|
} else { |
|
28
|
0
|
|
|
|
|
0
|
print STDERR "Error: unknown CVE format:\n"; |
|
29
|
|
|
|
|
|
|
print STDERR "- data_version: ", $object->{'data_version'}, "\n" |
|
30
|
0
|
0
|
|
|
|
0
|
if $object->{'data_version'}; |
|
31
|
|
|
|
|
|
|
print STDERR "- dataVersion: ", $object->{'dataVersion'}, "\n" |
|
32
|
0
|
0
|
|
|
|
0
|
if $object->{'dataVersion'}; |
|
33
|
|
|
|
|
|
|
} |
|
34
|
|
|
|
|
|
|
} |
|
35
|
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
# https://github.com/CVEProject/cve-schema/blob/master/schema/v5.0/ |
|
37
|
|
|
|
|
|
|
sub print_cve50 { |
|
38
|
2
|
|
|
2
|
0
|
5
|
my ($object, $cve_id, $format) = @_; |
|
39
|
|
|
|
|
|
|
|
|
40
|
2
|
100
|
|
|
|
6
|
if ($object->{'cveMetadata'}->{'cveId'} ne $cve_id) { |
|
41
|
1
|
|
|
|
|
22
|
print STDERR "Warning: Got <", $object->{'cveMetadata'}->{'cveId'}, |
|
42
|
|
|
|
|
|
|
"> instead of <", $cve_id, ">\n"; |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
|
|
45
|
2
|
|
|
|
|
6
|
my $affected = $object->{'containers'}->{'cna'}->{'affected'}; |
|
46
|
2
|
50
|
|
|
|
5
|
if ($affected) { |
|
47
|
2
|
|
|
|
|
4
|
foreach (@{$affected}) { |
|
|
2
|
|
|
|
|
4
|
|
|
48
|
2
|
|
|
|
|
26
|
print "Vendor Name: ", $_->{'vendor'}, "\n"; # vendor required |
|
49
|
2
|
|
|
|
|
22
|
print "Product Name: ", $_->{'product'}, "\n"; # product required |
|
50
|
|
|
|
|
|
|
|
|
51
|
2
|
|
|
|
|
6
|
foreach (@{$_->{'versions'}}) { |
|
|
2
|
|
|
|
|
5
|
|
|
52
|
2
|
|
|
|
|
22
|
print "- ", $_->{'status'}, ": ", $_->{'version'}, "\n"; |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
} |
|
55
|
|
|
|
|
|
|
} else { |
|
56
|
0
|
|
|
|
|
0
|
print STDERR |
|
57
|
|
|
|
|
|
|
"Warning: No CVE affected versions could be found! (as required by the spec)\n"; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
2
|
|
|
|
|
21
|
print "\n"; |
|
61
|
|
|
|
|
|
|
|
|
62
|
2
|
|
|
|
|
6
|
my $metrics = $object->{'containers'}->{'cna'}->{'metrics'}; |
|
63
|
2
|
50
|
|
|
|
5
|
if ($metrics) { |
|
64
|
2
|
|
|
|
|
3
|
foreach (@{$metrics}) { |
|
|
2
|
|
|
|
|
4
|
|
|
65
|
2
|
50
|
|
|
|
5
|
if ($_->{'cvssV3_1'}) { |
|
66
|
2
|
|
|
|
|
2
|
my $metric = $_->{'cvssV3_1'}; |
|
67
|
|
|
|
|
|
|
print "- Score: ", $metric->{'baseScore'}, " ", |
|
68
|
2
|
|
|
|
|
37
|
$metric->{'baseSeverity'}, "\n"; |
|
69
|
|
|
|
|
|
|
} else { |
|
70
|
0
|
|
|
|
|
0
|
print "Notice: unhandled metrics (CVSS) data\n"; |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
} |
|
73
|
|
|
|
|
|
|
} else { |
|
74
|
0
|
|
|
|
|
0
|
print STDERR |
|
75
|
|
|
|
|
|
|
"Warning: No CVE metrics (CVSS) could be found! (as required by the spec)\n"; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
2
|
|
|
|
|
21
|
print "\n"; |
|
79
|
|
|
|
|
|
|
|
|
80
|
2
|
|
|
|
|
7
|
my $desc = $object->{'containers'}->{'cna'}->{'descriptions'}; |
|
81
|
2
|
50
|
|
|
|
5
|
if ($desc) { |
|
82
|
2
|
|
|
|
|
3
|
foreach (@{$desc}) { |
|
|
2
|
|
|
|
|
4
|
|
|
83
|
2
|
|
|
|
|
19
|
print "Description Language: ", $_->{'lang'}, "\n"; |
|
84
|
2
|
|
|
|
|
30
|
print "Description:\n", $_->{'value'}, "\n\n"; |
|
85
|
|
|
|
|
|
|
} |
|
86
|
|
|
|
|
|
|
} else { |
|
87
|
0
|
|
|
|
|
0
|
print STDERR |
|
88
|
|
|
|
|
|
|
"Warning: No CVE description could be found! (as required by the spec)\n"; |
|
89
|
|
|
|
|
|
|
} |
|
90
|
|
|
|
|
|
|
|
|
91
|
2
|
|
|
|
|
21
|
print "\n"; |
|
92
|
|
|
|
|
|
|
|
|
93
|
2
|
|
|
|
|
7
|
my $refs = $object->{'containers'}->{'cna'}->{'references'}; |
|
94
|
2
|
50
|
|
|
|
12
|
if ($refs) { |
|
95
|
2
|
|
|
|
|
30
|
print "References: \n"; |
|
96
|
|
|
|
|
|
|
|
|
97
|
2
|
|
|
|
|
6
|
foreach (@{$refs}) { |
|
|
2
|
|
|
|
|
5
|
|
|
98
|
12
|
|
|
|
|
134
|
print "=> ", $_->{'url'}, "\n"; |
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
} else { |
|
101
|
0
|
|
|
|
|
|
print STDERR |
|
102
|
|
|
|
|
|
|
"Warning: No CVE references could be found! (as required by the spec)\n"; |
|
103
|
|
|
|
|
|
|
} |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# https://github.com/CVEProject/cve-schema/blob/master/schema/v4.0/ |
|
107
|
|
|
|
|
|
|
sub print_cve40 { |
|
108
|
0
|
|
|
0
|
0
|
|
my ($object, $cve_id, $format) = @_; |
|
109
|
|
|
|
|
|
|
|
|
110
|
0
|
0
|
|
|
|
|
if ($object->{'CVE_data_meta'}->{'ID'} ne $cve_id) { |
|
111
|
0
|
|
|
|
|
|
print STDERR "Warning: Got ", $object->{'CVE_data_meta'}->{'ID'}, |
|
112
|
|
|
|
|
|
|
" instead of ", $cve_id, "\n"; |
|
113
|
|
|
|
|
|
|
} |
|
114
|
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
print "TITLE: ", $object->{'CVE_data_meta'}->{'TITLE'}, "\n" |
|
116
|
0
|
0
|
|
|
|
|
if $object->{'CVE_data_meta'}->{'TITLE'}; |
|
117
|
|
|
|
|
|
|
|
|
118
|
0
|
|
|
|
|
|
print "\n"; |
|
119
|
|
|
|
|
|
|
|
|
120
|
0
|
0
|
|
|
|
|
if ($object->{'affects'}->{'vendor'}) { |
|
121
|
0
|
|
|
|
|
|
foreach (@{$object->{'affects'}->{'vendor'}->{'vendor_data'}}) { |
|
|
0
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
print "Vendor Name: ", $_->{'vendor_name'}, "\n" |
|
123
|
0
|
0
|
|
|
|
|
if $_->{'vendor_name'}; |
|
124
|
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
foreach (@{$_->{'product'}->{'product_data'}}) { |
|
|
0
|
|
|
|
|
|
|
|
126
|
0
|
|
|
|
|
|
print "Product name: ", $_->{'product_name'}, "\n"; |
|
127
|
0
|
|
|
|
|
|
print "Product versions: "; |
|
128
|
|
|
|
|
|
|
|
|
129
|
0
|
|
|
|
|
|
foreach (@{$_->{'version'}->{'version_data'}}) { |
|
|
0
|
|
|
|
|
|
|
|
130
|
0
|
|
|
|
|
|
print $_->{'version_value'}, "; "; |
|
131
|
|
|
|
|
|
|
} |
|
132
|
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
print "\n"; |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
} |
|
136
|
|
|
|
|
|
|
} |
|
137
|
|
|
|
|
|
|
|
|
138
|
0
|
|
|
|
|
|
print "\n"; |
|
139
|
|
|
|
|
|
|
|
|
140
|
0
|
0
|
|
|
|
|
if ($object->{'description'}->{'description_data'}) { |
|
141
|
0
|
|
|
|
|
|
my $descs = $object->{'description'}->{'description_data'}; |
|
142
|
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
foreach (@{$descs}) { |
|
|
0
|
|
|
|
|
|
|
|
144
|
0
|
|
|
|
|
|
print "Description Language: ", $_->{'lang'}, "\n"; |
|
145
|
0
|
|
|
|
|
|
print "Description:\n", $_->{'value'}, "\n\n"; |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
} else { |
|
148
|
0
|
|
|
|
|
|
print STDERR "Warning: No CVE description could be found!\n"; |
|
149
|
|
|
|
|
|
|
} |
|
150
|
|
|
|
|
|
|
|
|
151
|
0
|
0
|
|
|
|
|
if ($object->{'references'}->{'reference_data'}) { |
|
152
|
0
|
|
|
|
|
|
my $refs = $object->{'references'}->{'reference_data'}; |
|
153
|
|
|
|
|
|
|
|
|
154
|
0
|
|
|
|
|
|
foreach (@{$refs}) { |
|
|
0
|
|
|
|
|
|
|
|
155
|
0
|
0
|
|
|
|
|
if ($format == 'gemini') { |
|
156
|
0
|
|
|
|
|
|
print "Reference Source: ", $_->{'refsource'}, "\n"; |
|
157
|
|
|
|
|
|
|
|
|
158
|
0
|
0
|
|
|
|
|
print "=> ", $_->{'url'} if $_->{'url'}; |
|
159
|
0
|
0
|
|
|
|
|
if ($_->{'name'}) { |
|
160
|
0
|
|
|
|
|
|
print " ", $_->{'name'}, "\n\n"; |
|
161
|
|
|
|
|
|
|
} else { |
|
162
|
0
|
|
|
|
|
|
print "\n\n"; |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
} else { |
|
165
|
0
|
|
|
|
|
|
print "Reference Source: ", $_->{'refsource'}, "\n"; |
|
166
|
0
|
0
|
|
|
|
|
print "- Name: ", $_->{'name'}, "\n" if $_->{'name'}; |
|
167
|
0
|
0
|
|
|
|
|
print "- URL: ", $_->{'url'}, "\n" if $_->{'url'}; |
|
168
|
0
|
|
|
|
|
|
print "\n"; |
|
169
|
|
|
|
|
|
|
} |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
} else { |
|
172
|
0
|
|
|
|
|
|
print STDERR "Warning: No CVE references could be found!\n"; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
} |
|
175
|
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
1; |