logo

cve-client

CLI-based client / toolbox for CVE.org

CveClient.pm (4711B)


  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.0.5';
  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.0") {
  17. print_cve50($object, $cve_id, $format);
  18. } elsif ($object->{'data_version'} == "4.0") {
  19. print_cve40($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_cve50 {
  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. } else {
  61. print STDERR
  62. "Warning: No CVE metrics (CVSS) could be found! (as required by the spec)\n";
  63. }
  64. print "\n";
  65. my $desc = $object->{'containers'}->{'cna'}->{'descriptions'};
  66. if ($desc) {
  67. foreach (@{$desc}) {
  68. print "Description Language: ", $_->{'lang'}, "\n";
  69. print "Description:\n", $_->{'value'}, "\n\n";
  70. }
  71. } else {
  72. print STDERR
  73. "Warning: No CVE description could be found! (as required by the spec)\n";
  74. }
  75. print "\n";
  76. my $refs = $object->{'containers'}->{'cna'}->{'references'};
  77. if ($refs) {
  78. print "References: \n";
  79. foreach (@{$refs}) {
  80. print "=> ", $_->{'url'}, "\n";
  81. }
  82. } else {
  83. print STDERR
  84. "Warning: No CVE references could be found! (as required by the spec)\n";
  85. }
  86. }
  87. # https://github.com/CVEProject/cve-schema/blob/master/schema/v4.0/
  88. sub print_cve40 {
  89. my ($object, $cve_id, $format) = @_;
  90. if ($object->{'CVE_data_meta'}->{'ID'} ne $cve_id) {
  91. print STDERR "Warning: Got ", $object->{'CVE_data_meta'}->{'ID'},
  92. " instead of ", $cve_id, "\n";
  93. }
  94. print "TITLE: ", $object->{'CVE_data_meta'}->{'TITLE'}, "\n"
  95. if $object->{'CVE_data_meta'}->{'TITLE'};
  96. print "\n";
  97. if ($object->{'affects'}->{'vendor'}) {
  98. foreach (@{$object->{'affects'}->{'vendor'}->{'vendor_data'}}) {
  99. print "Vendor Name: ", $_->{'vendor_name'}, "\n"
  100. if $_->{'vendor_name'};
  101. foreach (@{$_->{'product'}->{'product_data'}}) {
  102. print "Product name: ", $_->{'product_name'}, "\n";
  103. print "Product versions: ";
  104. foreach (@{$_->{'version'}->{'version_data'}}) {
  105. print $_->{'version_value'}, "; ";
  106. }
  107. print "\n";
  108. }
  109. }
  110. }
  111. print "\n";
  112. if ($object->{'description'}->{'description_data'}) {
  113. my $descs = $object->{'description'}->{'description_data'};
  114. foreach (@{$descs}) {
  115. print "Description Language: ", $_->{'lang'}, "\n";
  116. print "Description:\n", $_->{'value'}, "\n\n";
  117. }
  118. } else {
  119. print STDERR "Warning: No CVE description could be found!\n";
  120. }
  121. if ($object->{'references'}->{'reference_data'}) {
  122. my $refs = $object->{'references'}->{'reference_data'};
  123. foreach (@{$refs}) {
  124. if ($format == 'gemini') {
  125. print "Reference Source: ", $_->{'refsource'}, "\n";
  126. print "=> ", $_->{'url'} if $_->{'url'};
  127. if ($_->{'name'}) {
  128. print " ", $_->{'name'}, "\n\n";
  129. } else {
  130. print "\n\n";
  131. }
  132. } else {
  133. print "Reference Source: ", $_->{'refsource'}, "\n";
  134. print "- Name: ", $_->{'name'}, "\n" if $_->{'name'};
  135. print "- URL: ", $_->{'url'}, "\n" if $_->{'url'};
  136. print "\n";
  137. }
  138. }
  139. } else {
  140. print STDERR "Warning: No CVE references could be found!\n";
  141. }
  142. }
  143. 1;