logo

cve-client

CLI-based client / toolbox for CVE.org git clone https://anongit.hacktivis.me/git/cve-client.git/

CveClient.pm (4604B)


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