From 2a273760e5f61c381edb0c1ccc22e9351f529f91 Mon Sep 17 00:00:00 2001 From: abhisek Date: Thu, 28 Dec 2023 12:42:09 +0530 Subject: [PATCH] feat: Extend JSON report spec to support threats --- api/json_report_spec.proto | 42 +++ gen/jsonreport/json_report_spec.pb.go | 512 +++++++++++++++++++++----- pkg/analyzer/analyzer.go | 2 + pkg/analyzer/lfp.go | 12 +- pkg/analyzer/lfp_npm.go | 39 +- pkg/reporter/json_report.go | 75 ++-- 6 files changed, 553 insertions(+), 129 deletions(-) diff --git a/api/json_report_spec.proto b/api/json_report_spec.proto index 953d7df..00b6f5c 100644 --- a/api/json_report_spec.proto +++ b/api/json_report_spec.proto @@ -22,10 +22,49 @@ message RemediationAdvice { string target_alternate_package_version = 6; } +// We are introducing the concept of Threat as a reporting entity so +// that we can report threats like lockfile poisoning using a standard schema. +// But why do we need threats? Why not just use vet's paradigm of policy over +// enriched packages? The reason is, there are threats that are applicable in +// an environment, against a manifest or other entities or even group of entities. +// Hence it is required to introduce a threat as a reporting entity so that external +// tools can consume vet's reports and take actions based on the threats. +message ReportThreat { + enum Confidence { + UnknownConfidence = 0; + + High = 1; + Medium = 2; + Low = 3; + } + + enum Source { + UnknownSource = 0; + + CWE = 1; + } + + enum Subject { + UnknownSubject = 0; + + Package = 1; + Manifest = 2; + } + + string id = 1; + string message = 2; + Subject subject_type = 3; + string subject = 4; + Confidence confidence = 5; + Source source = 6; + string source_id = 7; +} + message PackageManifestReport { string id = 1; Ecosystem ecosystem = 2; string path = 3; + repeated ReportThreat threats = 4; } // PackageReport represents the first class entity for which we have different type @@ -42,6 +81,9 @@ message PackageReport { // Insights data repeated InsightVulnerability vulnerabilities = 5; repeated InsightLicenseInfo licenses = 6; + + // Threats + repeated ReportThreat threats = 7; } message ReportMeta { diff --git a/gen/jsonreport/json_report_spec.pb.go b/gen/jsonreport/json_report_spec.pb.go index ea4bb87..563ea5e 100644 --- a/gen/jsonreport/json_report_spec.pb.go +++ b/gen/jsonreport/json_report_spec.pb.go @@ -74,6 +74,153 @@ func (RemediationAdviceType) EnumDescriptor() ([]byte, []int) { return file_json_report_spec_proto_rawDescGZIP(), []int{0} } +type ReportThreat_Confidence int32 + +const ( + ReportThreat_UnknownConfidence ReportThreat_Confidence = 0 + ReportThreat_High ReportThreat_Confidence = 1 + ReportThreat_Medium ReportThreat_Confidence = 2 + ReportThreat_Low ReportThreat_Confidence = 3 +) + +// Enum value maps for ReportThreat_Confidence. +var ( + ReportThreat_Confidence_name = map[int32]string{ + 0: "UnknownConfidence", + 1: "High", + 2: "Medium", + 3: "Low", + } + ReportThreat_Confidence_value = map[string]int32{ + "UnknownConfidence": 0, + "High": 1, + "Medium": 2, + "Low": 3, + } +) + +func (x ReportThreat_Confidence) Enum() *ReportThreat_Confidence { + p := new(ReportThreat_Confidence) + *p = x + return p +} + +func (x ReportThreat_Confidence) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ReportThreat_Confidence) Descriptor() protoreflect.EnumDescriptor { + return file_json_report_spec_proto_enumTypes[1].Descriptor() +} + +func (ReportThreat_Confidence) Type() protoreflect.EnumType { + return &file_json_report_spec_proto_enumTypes[1] +} + +func (x ReportThreat_Confidence) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ReportThreat_Confidence.Descriptor instead. +func (ReportThreat_Confidence) EnumDescriptor() ([]byte, []int) { + return file_json_report_spec_proto_rawDescGZIP(), []int{1, 0} +} + +type ReportThreat_Source int32 + +const ( + ReportThreat_UnknownSource ReportThreat_Source = 0 + ReportThreat_CWE ReportThreat_Source = 1 +) + +// Enum value maps for ReportThreat_Source. +var ( + ReportThreat_Source_name = map[int32]string{ + 0: "UnknownSource", + 1: "CWE", + } + ReportThreat_Source_value = map[string]int32{ + "UnknownSource": 0, + "CWE": 1, + } +) + +func (x ReportThreat_Source) Enum() *ReportThreat_Source { + p := new(ReportThreat_Source) + *p = x + return p +} + +func (x ReportThreat_Source) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ReportThreat_Source) Descriptor() protoreflect.EnumDescriptor { + return file_json_report_spec_proto_enumTypes[2].Descriptor() +} + +func (ReportThreat_Source) Type() protoreflect.EnumType { + return &file_json_report_spec_proto_enumTypes[2] +} + +func (x ReportThreat_Source) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ReportThreat_Source.Descriptor instead. +func (ReportThreat_Source) EnumDescriptor() ([]byte, []int) { + return file_json_report_spec_proto_rawDescGZIP(), []int{1, 1} +} + +type ReportThreat_Subject int32 + +const ( + ReportThreat_UnknownSubject ReportThreat_Subject = 0 + ReportThreat_Package ReportThreat_Subject = 1 + ReportThreat_Manifest ReportThreat_Subject = 2 +) + +// Enum value maps for ReportThreat_Subject. +var ( + ReportThreat_Subject_name = map[int32]string{ + 0: "UnknownSubject", + 1: "Package", + 2: "Manifest", + } + ReportThreat_Subject_value = map[string]int32{ + "UnknownSubject": 0, + "Package": 1, + "Manifest": 2, + } +) + +func (x ReportThreat_Subject) Enum() *ReportThreat_Subject { + p := new(ReportThreat_Subject) + *p = x + return p +} + +func (x ReportThreat_Subject) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ReportThreat_Subject) Descriptor() protoreflect.EnumDescriptor { + return file_json_report_spec_proto_enumTypes[3].Descriptor() +} + +func (ReportThreat_Subject) Type() protoreflect.EnumType { + return &file_json_report_spec_proto_enumTypes[3] +} + +func (x ReportThreat_Subject) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use ReportThreat_Subject.Descriptor instead. +func (ReportThreat_Subject) EnumDescriptor() ([]byte, []int) { + return file_json_report_spec_proto_rawDescGZIP(), []int{1, 2} +} + type RemediationAdvice struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -161,6 +308,108 @@ func (x *RemediationAdvice) GetTargetAlternatePackageVersion() string { return "" } +// We are introducing the concept of Threat as a reporting entity so +// that we can report threats like lockfile poisoning using a standard schema. +// But why do we need threats? Why not just use vet's paradigm of policy over +// enriched packages? The reason is, there are threats that are applicable in +// an environment, against a manifest or other entities or even group of entities. +// Hence it is required to introduce a threat as a reporting entity so that external +// tools can consume vet's reports and take actions based on the threats. +type ReportThreat struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + SubjectType ReportThreat_Subject `protobuf:"varint,3,opt,name=subject_type,json=subjectType,proto3,enum=ReportThreat_Subject" json:"subject_type,omitempty"` + Subject string `protobuf:"bytes,4,opt,name=subject,proto3" json:"subject,omitempty"` + Confidence ReportThreat_Confidence `protobuf:"varint,5,opt,name=confidence,proto3,enum=ReportThreat_Confidence" json:"confidence,omitempty"` + Source ReportThreat_Source `protobuf:"varint,6,opt,name=source,proto3,enum=ReportThreat_Source" json:"source,omitempty"` + SourceId string `protobuf:"bytes,7,opt,name=source_id,json=sourceId,proto3" json:"source_id,omitempty"` +} + +func (x *ReportThreat) Reset() { + *x = ReportThreat{} + if protoimpl.UnsafeEnabled { + mi := &file_json_report_spec_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReportThreat) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReportThreat) ProtoMessage() {} + +func (x *ReportThreat) ProtoReflect() protoreflect.Message { + mi := &file_json_report_spec_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReportThreat.ProtoReflect.Descriptor instead. +func (*ReportThreat) Descriptor() ([]byte, []int) { + return file_json_report_spec_proto_rawDescGZIP(), []int{1} +} + +func (x *ReportThreat) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ReportThreat) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *ReportThreat) GetSubjectType() ReportThreat_Subject { + if x != nil { + return x.SubjectType + } + return ReportThreat_UnknownSubject +} + +func (x *ReportThreat) GetSubject() string { + if x != nil { + return x.Subject + } + return "" +} + +func (x *ReportThreat) GetConfidence() ReportThreat_Confidence { + if x != nil { + return x.Confidence + } + return ReportThreat_UnknownConfidence +} + +func (x *ReportThreat) GetSource() ReportThreat_Source { + if x != nil { + return x.Source + } + return ReportThreat_UnknownSource +} + +func (x *ReportThreat) GetSourceId() string { + if x != nil { + return x.SourceId + } + return "" +} + type PackageManifestReport struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -169,12 +418,13 @@ type PackageManifestReport struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Ecosystem models.Ecosystem `protobuf:"varint,2,opt,name=ecosystem,proto3,enum=Ecosystem" json:"ecosystem,omitempty"` Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + Threats []*ReportThreat `protobuf:"bytes,4,rep,name=threats,proto3" json:"threats,omitempty"` } func (x *PackageManifestReport) Reset() { *x = PackageManifestReport{} if protoimpl.UnsafeEnabled { - mi := &file_json_report_spec_proto_msgTypes[1] + mi := &file_json_report_spec_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -187,7 +437,7 @@ func (x *PackageManifestReport) String() string { func (*PackageManifestReport) ProtoMessage() {} func (x *PackageManifestReport) ProtoReflect() protoreflect.Message { - mi := &file_json_report_spec_proto_msgTypes[1] + mi := &file_json_report_spec_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -200,7 +450,7 @@ func (x *PackageManifestReport) ProtoReflect() protoreflect.Message { // Deprecated: Use PackageManifestReport.ProtoReflect.Descriptor instead. func (*PackageManifestReport) Descriptor() ([]byte, []int) { - return file_json_report_spec_proto_rawDescGZIP(), []int{1} + return file_json_report_spec_proto_rawDescGZIP(), []int{2} } func (x *PackageManifestReport) GetId() string { @@ -224,6 +474,13 @@ func (x *PackageManifestReport) GetPath() string { return "" } +func (x *PackageManifestReport) GetThreats() []*ReportThreat { + if x != nil { + return x.Threats + } + return nil +} + // PackageReport represents the first class entity for which we have different type // of reporting information type PackageReport struct { @@ -239,12 +496,14 @@ type PackageReport struct { // Insights data Vulnerabilities []*models.InsightVulnerability `protobuf:"bytes,5,rep,name=vulnerabilities,proto3" json:"vulnerabilities,omitempty"` Licenses []*models.InsightLicenseInfo `protobuf:"bytes,6,rep,name=licenses,proto3" json:"licenses,omitempty"` + // Threats + Threats []*ReportThreat `protobuf:"bytes,7,rep,name=threats,proto3" json:"threats,omitempty"` } func (x *PackageReport) Reset() { *x = PackageReport{} if protoimpl.UnsafeEnabled { - mi := &file_json_report_spec_proto_msgTypes[2] + mi := &file_json_report_spec_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -257,7 +516,7 @@ func (x *PackageReport) String() string { func (*PackageReport) ProtoMessage() {} func (x *PackageReport) ProtoReflect() protoreflect.Message { - mi := &file_json_report_spec_proto_msgTypes[2] + mi := &file_json_report_spec_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -270,7 +529,7 @@ func (x *PackageReport) ProtoReflect() protoreflect.Message { // Deprecated: Use PackageReport.ProtoReflect.Descriptor instead. func (*PackageReport) Descriptor() ([]byte, []int) { - return file_json_report_spec_proto_rawDescGZIP(), []int{2} + return file_json_report_spec_proto_rawDescGZIP(), []int{3} } func (x *PackageReport) GetPackage() *models.Package { @@ -315,6 +574,13 @@ func (x *PackageReport) GetLicenses() []*models.InsightLicenseInfo { return nil } +func (x *PackageReport) GetThreats() []*ReportThreat { + if x != nil { + return x.Threats + } + return nil +} + type ReportMeta struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -328,7 +594,7 @@ type ReportMeta struct { func (x *ReportMeta) Reset() { *x = ReportMeta{} if protoimpl.UnsafeEnabled { - mi := &file_json_report_spec_proto_msgTypes[3] + mi := &file_json_report_spec_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -341,7 +607,7 @@ func (x *ReportMeta) String() string { func (*ReportMeta) ProtoMessage() {} func (x *ReportMeta) ProtoReflect() protoreflect.Message { - mi := &file_json_report_spec_proto_msgTypes[3] + mi := &file_json_report_spec_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -354,7 +620,7 @@ func (x *ReportMeta) ProtoReflect() protoreflect.Message { // Deprecated: Use ReportMeta.ProtoReflect.Descriptor instead. func (*ReportMeta) Descriptor() ([]byte, []int) { - return file_json_report_spec_proto_rawDescGZIP(), []int{3} + return file_json_report_spec_proto_rawDescGZIP(), []int{4} } func (x *ReportMeta) GetToolName() string { @@ -391,7 +657,7 @@ type Report struct { func (x *Report) Reset() { *x = Report{} if protoimpl.UnsafeEnabled { - mi := &file_json_report_spec_proto_msgTypes[4] + mi := &file_json_report_spec_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -404,7 +670,7 @@ func (x *Report) String() string { func (*Report) ProtoMessage() {} func (x *Report) ProtoReflect() protoreflect.Message { - mi := &file_json_report_spec_proto_msgTypes[4] + mi := &file_json_report_spec_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -417,7 +683,7 @@ func (x *Report) ProtoReflect() protoreflect.Message { // Deprecated: Use Report.ProtoReflect.Descriptor instead. func (*Report) Descriptor() ([]byte, []int) { - return file_json_report_spec_proto_rawDescGZIP(), []int{4} + return file_json_report_spec_proto_rawDescGZIP(), []int{5} } func (x *Report) GetMeta() *ReportMeta { @@ -470,58 +736,91 @@ var file_json_report_spec_proto_rawDesc = []byte{ 0x74, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x65, 0x0a, 0x15, 0x50, 0x61, 0x63, 0x6b, 0x61, - 0x67, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x28, 0x0a, 0x09, 0x65, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x45, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, - 0x09, 0x65, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, - 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x9d, - 0x02, 0x0a, 0x0d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x12, 0x22, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x08, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x07, 0x70, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, - 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x0a, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x56, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x0a, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2c, - 0x0a, 0x07, 0x61, 0x64, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x52, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x76, - 0x69, 0x63, 0x65, 0x52, 0x07, 0x61, 0x64, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x0f, - 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x56, - 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0f, 0x76, 0x75, - 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x2f, 0x0a, - 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x22, 0x6b, - 0x0a, 0x0a, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, - 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x74, 0x6f, 0x6f, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x6f, - 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x74, 0x6f, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, - 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x8b, 0x01, 0x0a, 0x06, - 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, - 0x61, 0x52, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x12, 0x34, 0x0a, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, - 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x50, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, - 0x72, 0x74, 0x52, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x12, 0x2a, 0x0a, - 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0e, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, - 0x08, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x73, 0x2a, 0x7b, 0x0a, 0x15, 0x52, 0x65, 0x6d, - 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x41, 0x64, 0x76, - 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x70, 0x67, - 0x72, 0x61, 0x64, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x10, 0x01, 0x12, 0x1b, 0x0a, - 0x17, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, - 0x72, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x6c, - 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x50, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x10, 0x03, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x61, 0x66, 0x65, 0x64, 0x65, 0x70, 0x2f, 0x76, 0x65, 0x74, - 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, - 0x70, 0x65, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xb5, 0x03, 0x0a, 0x0c, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x38, 0x0a, 0x0c, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x74, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, + 0x0b, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, + 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x38, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, + 0x65, 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x18, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, + 0x65, 0x6e, 0x63, 0x65, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, + 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x14, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x74, 0x2e, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x1b, + 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x22, 0x42, 0x0a, 0x0a, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x55, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x10, 0x00, + 0x12, 0x08, 0x0a, 0x04, 0x48, 0x69, 0x67, 0x68, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x4d, 0x65, + 0x64, 0x69, 0x75, 0x6d, 0x10, 0x02, 0x12, 0x07, 0x0a, 0x03, 0x4c, 0x6f, 0x77, 0x10, 0x03, 0x22, + 0x24, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x55, 0x6e, 0x6b, + 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, + 0x43, 0x57, 0x45, 0x10, 0x01, 0x22, 0x38, 0x0a, 0x07, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x75, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x10, + 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x10, 0x02, 0x22, + 0x8e, 0x01, 0x0a, 0x15, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4d, 0x61, 0x6e, 0x69, 0x66, + 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x09, 0x65, 0x63, 0x6f, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x45, + 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52, 0x09, 0x65, 0x63, 0x6f, 0x73, 0x79, 0x73, + 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x27, 0x0a, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, + 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x74, 0x52, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x73, + 0x22, 0xc6, 0x02, 0x0a, 0x0d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x22, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x52, 0x07, 0x70, + 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, + 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, + 0x65, 0x73, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x0a, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x56, 0x69, 0x6f, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x76, 0x69, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x2c, 0x0a, 0x07, 0x61, 0x64, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x52, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, + 0x64, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x61, 0x64, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x3f, + 0x0a, 0x0f, 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, + 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, + 0x74, 0x56, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0f, + 0x76, 0x75, 0x6c, 0x6e, 0x65, 0x72, 0x61, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, + 0x2f, 0x0a, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x13, 0x2e, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x69, 0x63, 0x65, 0x6e, + 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, + 0x12, 0x27, 0x0a, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x68, 0x72, 0x65, 0x61, 0x74, + 0x52, 0x07, 0x74, 0x68, 0x72, 0x65, 0x61, 0x74, 0x73, 0x22, 0x6b, 0x0a, 0x0a, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x6f, 0x6f, 0x6c, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x6f, 0x6f, 0x6c, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, 0x8b, 0x01, 0x0a, 0x06, 0x52, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x6d, 0x65, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0b, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x52, 0x04, 0x6d, 0x65, + 0x74, 0x61, 0x12, 0x34, 0x0a, 0x09, 0x6d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x4d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x09, 0x6d, + 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x08, 0x70, 0x61, 0x63, 0x6b, + 0x61, 0x67, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x50, 0x61, 0x63, + 0x6b, 0x61, 0x67, 0x65, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x08, 0x70, 0x61, 0x63, 0x6b, + 0x61, 0x67, 0x65, 0x73, 0x2a, 0x7b, 0x0a, 0x15, 0x52, 0x65, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x41, 0x64, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x15, 0x0a, + 0x11, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x41, 0x64, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, + 0x70, 0x65, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x50, + 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x41, 0x6c, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x74, 0x65, 0x50, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x72, 0x50, 0x61, 0x63, 0x6b, + 0x61, 0x67, 0x65, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x41, 0x6c, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x74, 0x65, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x10, + 0x03, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x73, 0x61, 0x66, 0x65, 0x64, 0x65, 0x70, 0x2f, 0x76, 0x65, 0x74, 0x2f, 0x67, 0x65, 0x6e, 0x2f, + 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x70, 0x65, 0x63, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -536,38 +835,47 @@ func file_json_report_spec_proto_rawDescGZIP() []byte { return file_json_report_spec_proto_rawDescData } -var file_json_report_spec_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_json_report_spec_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_json_report_spec_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_json_report_spec_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_json_report_spec_proto_goTypes = []interface{}{ (RemediationAdviceType)(0), // 0: RemediationAdviceType - (*RemediationAdvice)(nil), // 1: RemediationAdvice - (*PackageManifestReport)(nil), // 2: PackageManifestReport - (*PackageReport)(nil), // 3: PackageReport - (*ReportMeta)(nil), // 4: ReportMeta - (*Report)(nil), // 5: Report - (*models.Package)(nil), // 6: Package - (models.Ecosystem)(0), // 7: Ecosystem - (*violations.Violation)(nil), // 8: Violation - (*models.InsightVulnerability)(nil), // 9: InsightVulnerability - (*models.InsightLicenseInfo)(nil), // 10: InsightLicenseInfo + (ReportThreat_Confidence)(0), // 1: ReportThreat.Confidence + (ReportThreat_Source)(0), // 2: ReportThreat.Source + (ReportThreat_Subject)(0), // 3: ReportThreat.Subject + (*RemediationAdvice)(nil), // 4: RemediationAdvice + (*ReportThreat)(nil), // 5: ReportThreat + (*PackageManifestReport)(nil), // 6: PackageManifestReport + (*PackageReport)(nil), // 7: PackageReport + (*ReportMeta)(nil), // 8: ReportMeta + (*Report)(nil), // 9: Report + (*models.Package)(nil), // 10: Package + (models.Ecosystem)(0), // 11: Ecosystem + (*violations.Violation)(nil), // 12: Violation + (*models.InsightVulnerability)(nil), // 13: InsightVulnerability + (*models.InsightLicenseInfo)(nil), // 14: InsightLicenseInfo } var file_json_report_spec_proto_depIdxs = []int32{ 0, // 0: RemediationAdvice.type:type_name -> RemediationAdviceType - 6, // 1: RemediationAdvice.package:type_name -> Package - 7, // 2: PackageManifestReport.ecosystem:type_name -> Ecosystem - 6, // 3: PackageReport.package:type_name -> Package - 8, // 4: PackageReport.violations:type_name -> Violation - 1, // 5: PackageReport.advices:type_name -> RemediationAdvice - 9, // 6: PackageReport.vulnerabilities:type_name -> InsightVulnerability - 10, // 7: PackageReport.licenses:type_name -> InsightLicenseInfo - 4, // 8: Report.meta:type_name -> ReportMeta - 2, // 9: Report.manifests:type_name -> PackageManifestReport - 3, // 10: Report.packages:type_name -> PackageReport - 11, // [11:11] is the sub-list for method output_type - 11, // [11:11] is the sub-list for method input_type - 11, // [11:11] is the sub-list for extension type_name - 11, // [11:11] is the sub-list for extension extendee - 0, // [0:11] is the sub-list for field type_name + 10, // 1: RemediationAdvice.package:type_name -> Package + 3, // 2: ReportThreat.subject_type:type_name -> ReportThreat.Subject + 1, // 3: ReportThreat.confidence:type_name -> ReportThreat.Confidence + 2, // 4: ReportThreat.source:type_name -> ReportThreat.Source + 11, // 5: PackageManifestReport.ecosystem:type_name -> Ecosystem + 5, // 6: PackageManifestReport.threats:type_name -> ReportThreat + 10, // 7: PackageReport.package:type_name -> Package + 12, // 8: PackageReport.violations:type_name -> Violation + 4, // 9: PackageReport.advices:type_name -> RemediationAdvice + 13, // 10: PackageReport.vulnerabilities:type_name -> InsightVulnerability + 14, // 11: PackageReport.licenses:type_name -> InsightLicenseInfo + 5, // 12: PackageReport.threats:type_name -> ReportThreat + 8, // 13: Report.meta:type_name -> ReportMeta + 6, // 14: Report.manifests:type_name -> PackageManifestReport + 7, // 15: Report.packages:type_name -> PackageReport + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name } func init() { file_json_report_spec_proto_init() } @@ -589,7 +897,7 @@ func file_json_report_spec_proto_init() { } } file_json_report_spec_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PackageManifestReport); i { + switch v := v.(*ReportThreat); i { case 0: return &v.state case 1: @@ -601,7 +909,7 @@ func file_json_report_spec_proto_init() { } } file_json_report_spec_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PackageReport); i { + switch v := v.(*PackageManifestReport); i { case 0: return &v.state case 1: @@ -613,7 +921,7 @@ func file_json_report_spec_proto_init() { } } file_json_report_spec_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReportMeta); i { + switch v := v.(*PackageReport); i { case 0: return &v.state case 1: @@ -625,6 +933,18 @@ func file_json_report_spec_proto_init() { } } file_json_report_spec_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReportMeta); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_json_report_spec_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Report); i { case 0: return &v.state @@ -642,8 +962,8 @@ func file_json_report_spec_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_json_report_spec_proto_rawDesc, - NumEnums: 1, - NumMessages: 5, + NumEnums: 4, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 23a1267..137785d 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -2,6 +2,7 @@ package analyzer import ( "github.com/safedep/vet/gen/filtersuite" + jsonreportspec "github.com/safedep/vet/gen/jsonreport" "github.com/safedep/vet/pkg/models" ) @@ -23,6 +24,7 @@ type AnalyzerEvent struct { // Message / Error / Filter Message interface{} Filter *filtersuite.Filter + Threat *jsonreportspec.ReportThreat Err error // Entities on which event was generated diff --git a/pkg/analyzer/lfp.go b/pkg/analyzer/lfp.go index b29b15e..4026d53 100644 --- a/pkg/analyzer/lfp.go +++ b/pkg/analyzer/lfp.go @@ -3,12 +3,18 @@ package analyzer import ( "fmt" + jsonreportspec "github.com/safedep/vet/gen/jsonreport" specmodels "github.com/safedep/vet/gen/models" "github.com/safedep/vet/pkg/common/logger" "github.com/safedep/vet/pkg/models" ) const lfpAnalyzerName = "LockfilePoisoningAnalyzer" +const lfpThreatSource = jsonreportspec.ReportThreat_CWE + +// https://cwe.mitre.org/data/definitions/349.html +// Acceptance of Extraneous Untrusted Data With Trusted Data +const lfpThreatSourceId = "CWE-349" type LockfilePoisoningAnalyzerConfig struct { FailFast bool @@ -60,12 +66,16 @@ func (lfp *lockfilePoisoningAnalyzer) Analyze(manifest *models.PackageManifest, return plugin.Analyze(manifest, func(event *AnalyzerEvent) error { lfp.detections = append(lfp.detections, event) if lfp.config.FailFast { - _ = handler(&AnalyzerEvent{ + err := handler(&AnalyzerEvent{ Source: lfpAnalyzerName, Type: ET_AnalyzerFailOnError, Message: "Identified lockfile poisoning attempt in " + manifest.GetDisplayPath(), Err: fmt.Errorf("fail-fast on lockfile poisoning at %s", manifest.GetDisplayPath()), }) + + if err != nil { + logger.Errorf("LockfilePoisoningAnalyzer: Error handling fail-fast event: %v", err) + } } return handler(event) diff --git a/pkg/analyzer/lfp_npm.go b/pkg/analyzer/lfp_npm.go index 516b219..6723e6c 100644 --- a/pkg/analyzer/lfp_npm.go +++ b/pkg/analyzer/lfp_npm.go @@ -8,6 +8,7 @@ import ( "os" "strings" + jsonreportspec "github.com/safedep/vet/gen/jsonreport" "github.com/safedep/vet/pkg/common/logger" "github.com/safedep/vet/pkg/models" "github.com/safedep/vet/pkg/readers" @@ -111,13 +112,23 @@ func (npm *npmLockfilePoisoningAnalyzer) Analyze(manifest *models.PackageManifes logger.Debugf("npmLockfilePoisoningAnalyzer: Package [%s] resolved to an untrusted host [%s]", packageName, lockfilePackage.Resolved) + message := fmt.Sprintf("Package [%s] resolved to an untrusted host [%s]", + packageName, lockfilePackage.Resolved) + _ = handler(&AnalyzerEvent{ - Source: lfpAnalyzerName, - Type: ET_LockfilePoisoningSignal, - Message: fmt.Sprintf("Package [%s] resolved to an untrusted host [%s]", - packageName, lockfilePackage.Resolved), + Source: lfpAnalyzerName, + Type: ET_LockfilePoisoningSignal, + Message: message, Manifest: manifest, Package: pkg, + Threat: &jsonreportspec.ReportThreat{ + Message: message, + SubjectType: jsonreportspec.ReportThreat_Manifest, + Subject: manifest.GetDisplayPath(), + Confidence: jsonreportspec.ReportThreat_Medium, + Source: lfpThreatSource, + SourceId: lfpThreatSourceId, + }, }) } @@ -125,17 +136,25 @@ func (npm *npmLockfilePoisoningAnalyzer) Analyze(manifest *models.PackageManifes logger.Debugf("npmLockfilePoisoningAnalyzer: Package [%s] resolved to an unconventional URL [%s]", packageName, lockfilePackage.Resolved) + message := fmt.Sprintf("Package [%s] resolved to an URL [%s] that does not follow the "+ + "package name path convention", packageName, lockfilePackage.Resolved) + _ = handler(&AnalyzerEvent{ - Source: lfpAnalyzerName, - Type: ET_LockfilePoisoningSignal, - Message: fmt.Sprintf("Package [%s] resolved to an URL [%s] that does not follow the "+ - "package name path convention", packageName, lockfilePackage.Resolved), + Source: lfpAnalyzerName, + Type: ET_LockfilePoisoningSignal, + Message: message, Manifest: manifest, Package: pkg, + Threat: &jsonreportspec.ReportThreat{ + Message: message, + SubjectType: jsonreportspec.ReportThreat_Manifest, + Subject: manifest.GetDisplayPath(), + Confidence: jsonreportspec.ReportThreat_Medium, + Source: lfpThreatSource, + SourceId: lfpThreatSourceId, + }, }) } - - // TODO: Handle the 3rd case of new entry added to package-lock.json dependency list } return nil diff --git a/pkg/reporter/json_report.go b/pkg/reporter/json_report.go index 6f71a7a..e1a0486 100644 --- a/pkg/reporter/json_report.go +++ b/pkg/reporter/json_report.go @@ -47,23 +47,15 @@ func (r *jsonReportGenerator) Name() string { } func (r *jsonReportGenerator) AddManifest(manifest *models.PackageManifest) { - manifestId := manifest.Id() - if _, ok := r.manifests[manifestId]; !ok { - r.manifests[manifestId] = &jsonreportspec.PackageManifestReport{ - Id: manifestId, - Path: manifest.GetDisplayPath(), - Ecosystem: manifest.GetSpecEcosystem(), - } - } + // Eager load the package manifest in the cache + _ = r.findPackageManifestReport(manifest) err := readers.NewManifestModelReader(manifest).EnumPackages(func(p *models.Package) error { - pkgId := p.Id() - if _, ok := r.packages[pkgId]; !ok { - r.packages[pkgId] = r.buildJsonPackageReportFromPackage(p) - } + // Eager load the package in the cache + _ = r.findPackageReport(p) - if !slices.Contains(r.packages[pkgId].Manifests, manifestId) { - r.packages[pkgId].Manifests = append(r.packages[p.Id()].Manifests, manifestId) + if !slices.Contains(r.packages[p.Id()].Manifests, manifest.Id()) { + r.packages[p.Id()].Manifests = append(r.packages[p.Id()].Manifests, manifest.Id()) } return nil @@ -75,10 +67,31 @@ func (r *jsonReportGenerator) AddManifest(manifest *models.PackageManifest) { } func (r *jsonReportGenerator) AddAnalyzerEvent(event *analyzer.AnalyzerEvent) { - if !event.IsFilterMatch() { + if event.IsFilterMatch() { + r.handleFilterEvent(event) + } else if event.IsLockfilePoisoningSignal() { + r.handleThreatEvent(event) + } +} + +func (r *jsonReportGenerator) handleThreatEvent(event *analyzer.AnalyzerEvent) { + if event.Threat == nil { return } + switch event.Threat.SubjectType { + case jsonreportspec.ReportThreat_Manifest: + manifest := r.findPackageManifestReport(event.Manifest) + manifest.Threats = append(manifest.Threats, event.Threat) + + case jsonreportspec.ReportThreat_Package: + pkg := r.findPackageReport(event.Package) + pkg.Threats = append(pkg.Threats, event.Threat) + } + +} + +func (r *jsonReportGenerator) handleFilterEvent(event *analyzer.AnalyzerEvent) { if event.Package == nil { logger.Warnf("Analyzer event with nil package") return @@ -94,14 +107,8 @@ func (r *jsonReportGenerator) AddAnalyzerEvent(event *analyzer.AnalyzerEvent) { return } - // Create a reportable package model if it does not already exist - pkgId := event.Package.Id() - if _, ok := r.packages[pkgId]; !ok { - r.packages[pkgId] = r.buildJsonPackageReportFromPackage(event.Package) - } - // All subsequent operations are on this pkg - pkg := r.packages[pkgId] + pkg := r.findPackageReport(event.Package) // We avoid duplicate violation for a package. Duplicates can occur because same package // is in multiple manifests hence raising same violation @@ -129,6 +136,29 @@ func (r *jsonReportGenerator) AddAnalyzerEvent(event *analyzer.AnalyzerEvent) { } } +func (r *jsonReportGenerator) findPackageManifestReport(manifest *models.PackageManifest) *jsonreportspec.PackageManifestReport { + manifestId := manifest.Id() + if _, ok := r.manifests[manifestId]; !ok { + r.manifests[manifestId] = &jsonreportspec.PackageManifestReport{ + Id: manifestId, + Path: manifest.GetDisplayPath(), + Ecosystem: manifest.GetSpecEcosystem(), + Threats: make([]*schema.ReportThreat, 0), + } + } + + return r.manifests[manifestId] +} + +func (r *jsonReportGenerator) findPackageReport(pkg *models.Package) *jsonreportspec.PackageReport { + pkgId := pkg.Id() + if _, ok := r.packages[pkgId]; !ok { + r.packages[pkgId] = r.buildJsonPackageReportFromPackage(pkg) + } + + return r.packages[pkgId] +} + func (r *jsonReportGenerator) AddPolicyEvent(event *policy.PolicyEvent) {} func (r *jsonReportGenerator) Finish() error { @@ -187,6 +217,7 @@ func (j *jsonReportGenerator) buildJsonPackageReportFromPackage(p *models.Packag Advices: make([]*schema.RemediationAdvice, 0), Vulnerabilities: make([]*modelspec.InsightVulnerability, 0), Licenses: make([]*modelspec.InsightLicenseInfo, 0), + Threats: make([]*schema.ReportThreat, 0), } insights := utils.SafelyGetValue(p.Insights)