package app import ( "encoding/json" "fmt" "io" "net/http" ) // CveHasExploits fetches the fprox report for the given CVE and reports // whether it contains any proof-of-concept or exploitation artifacts. func CveHasExploits(cve string) (bool, error) { url := fmt.Sprintf("https://fprox.hrbrmstr.app/cve/%s", cve) resp, err := http.Get(url) if err != nil { return false, err } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return false, err } r, err := UnmarshalFproxResponse(body) if err != nil { return false, err } if len(r.Props.PageProps.CveInfo.ProofOfConcepts) > 0 { return true, nil } if len(r.Props.PageProps.CveInfo.ExploitedAt) > 0 { return true, nil } return false, nil } // This file was generated from JSON Schema using quicktype, do not modify it directly. // To parse and unparse this JSON data, add this code to your project and do: // // fproxResponse, err := UnmarshalFproxResponse(bytes) // bytes, err = fproxResponse.Marshal() func UnmarshalFproxResponse(data []byte) (FproxResponse, error) { var r FproxResponse err := json.Unmarshal(data, &r) return r, err } func (r *FproxResponse) Marshal() ([]byte, error) { return json.Marshal(r) } type FproxResponse struct { Props Props `json:"props"` Page string `json:"page"` Query Query `json:"query"` BuildID string `json:"buildId"` AssetPrefix string `json:"assetPrefix"` IsFallback bool `json:"isFallback"` IsExperimentalCompile bool `json:"isExperimentalCompile"` Gsp bool `json:"gsp"` ScriptLoader []interface{} `json:"scriptLoader"` } type Props struct { PageProps PageProps `json:"pageProps"` NSsg bool `json:"__N_SSG"` } type PageProps struct { AdvisoryEntry Entry `json:"advisoryEntry"` Categories []Category `json:"categories"` ChatterEntries []Entry `json:"chatterEntries"` CveInfo CveInfo `json:"cveInfo"` Events []Event `json:"events"` GraphMarkup string `json:"graphMarkup"` ReferenceEntries []interface{} `json:"referenceEntries"` TotalChatterEntries int64 `json:"totalChatterEntries"` TotalReferenceEntries int64 `json:"totalReferenceEntries"` } type Entry struct { Crawled int64 `json:"crawled"` ID string `json:"id"` Origin Origin `json:"origin"` Title string `json:"title"` Description string `json:"description"` SourceLink string `json:"sourceLink"` Visual *Visual `json:"visual,omitempty"` } type Origin struct { StreamID string `json:"streamId"` Title string `json:"title"` HTMLURL string `json:"htmlUrl"` } type Visual struct { URL string `json:"url"` ContentType *string `json:"contentType,omitempty"` Height *int64 `json:"height,omitempty"` Processor *string `json:"processor,omitempty"` Width *int64 `json:"width,omitempty"` } type Category struct { NumSimilarVulnerabilities int64 `json:"numSimilarVulnerabilities"` Label string `json:"label"` URI string `json:"uri"` } type CveInfo struct { Cveid string `json:"cveid"` ID string `json:"id"` Type string `json:"type"` Label string `json:"label"` HasSalience bool `json:"hasSalience"` AdvisoryURL string `json:"advisoryUrl"` CveStatus string `json:"cveStatus"` Description string `json:"description"` CvssCategoryEstimate string `json:"cvssCategoryEstimate"` CvssV3 CvssV3 `json:"cvssV3"` CweIDS []CweID `json:"cweIds"` SmallGraphURL string `json:"smallGraphUrl"` GraphURL string `json:"graphUrl"` EpssScore string `json:"epssScore"` PatchDetails []PatchDetail `json:"patchDetails"` Patched bool `json:"patched"` DetectedBy []DetectedBy `json:"detectedBy"` FeedlyInsertedDate string `json:"feedlyInsertedDate"` FeedlyUpdatedDate string `json:"feedlyUpdatedDate"` PublishedDate string `json:"publishedDate"` PublicationDateInfo []PublicationDateInfo `json:"publicationDateInfo"` AffectedProductsEstimate []AffectedProductsEstimate `json:"affectedProductsEstimate"` IDMapping []interface{} `json:"idMapping"` Timeline []Timeline `json:"timeline"` ExecutiveSummary ExecutiveSummary `json:"executiveSummary"` Stats Stats `json:"stats"` ExploitedAt []interface{} `json:"exploitedAt"` ProofOfConcepts []interface{} `json:"proofOfConcepts"` Products []VendorElement `json:"products"` Vendors []VendorElement `json:"vendors"` } type AffectedProductsEstimate struct { Products []AffectedProductsEstimateProduct `json:"products"` Vendor string `json:"vendor"` } type AffectedProductsEstimateProduct struct { Name string `json:"name"` } type CvssV3 struct { PrivilegesRequired string `json:"privilegesRequired"` VectorString string `json:"vectorString"` BaseScore float64 `json:"baseScore"` Scope string `json:"scope"` UserInteraction string `json:"userInteraction"` ConfidentialityImpact string `json:"confidentialityImpact"` AvailabilityImpact string `json:"availabilityImpact"` AttackComplexity string `json:"attackComplexity"` AttackVector string `json:"attackVector"` Version string `json:"version"` IntegrityImpact string `json:"integrityImpact"` } type CweID struct { CweID string `json:"cweID"` Name string `json:"name"` } type DetectedBy struct { ScannerName string `json:"scannerName"` DetectionID string `json:"detectionId"` } type ExecutiveSummary struct { Description string `json:"description"` Patch string `json:"patch"` Mitigation string `json:"mitigation"` Exploitation string `json:"exploitation"` Impact string `json:"impact"` } type PatchDetail struct { Title string `json:"title"` Source string `json:"source"` PatchAddedDate string `json:"patchAddedDate"` URL string `json:"url"` FeedlyPatchAddedDate string `json:"feedlyPatchAddedDate"` } type VendorElement struct { ID string `json:"id"` Label string `json:"label"` Origin string `json:"origin"` } type PublicationDateInfo struct { FeedlyUpdatedDate *string `json:"feedlyUpdatedDate,omitempty"` Source string `json:"source"` PublishedDate string `json:"publishedDate"` FeedlyInsertedDate *string `json:"feedlyInsertedDate,omitempty"` LastModifiedDate string `json:"lastModifiedDate"` } type Stats struct { FirstEntryID string `json:"firstEntryId"` TimeSeries map[string][]TimeSery `json:"timeSeries"` AdvisoryEntryID string `json:"advisoryEntryId"` FirstTimestamp int64 `json:"firstTimestamp"` } type TimeSery struct { URL string `json:"url"` FirstEntryID string `json:"firstEntryId"` Age int64 `json:"age"` Timestamp int64 `json:"timestamp"` SourceType []string `json:"sourceType,omitempty"` } type Timeline struct { Event string `json:"event"` Date string `json:"date"` Source string `json:"source"` } type Event struct { ID string `json:"id"` Type string `json:"type"` Ts int64 `json:"ts"` Updated int64 `json:"updated"` EntryID *string `json:"entryId,omitempty"` SourceName *string `json:"sourceName,omitempty"` CvssCategoryEstimate *string `json:"cvssCategoryEstimate,omitempty"` Score *float64 `json:"score,omitempty"` Update *bool `json:"update,omitempty"` Percentile *float64 `json:"percentile,omitempty"` URL *string `json:"url,omitempty"` VendorName *string `json:"vendorName,omitempty"` ModuleID *string `json:"moduleId,omitempty"` ScannerName *string `json:"scannerName,omitempty"` GroupedEvents []GroupedEvent `json:"groupedEvents,omitempty"` AdvisoryID *string `json:"advisoryId,omitempty"` } type GroupedEvent struct { ID string `json:"id"` Type string `json:"type"` Ts int64 `json:"ts"` Updated int64 `json:"updated"` ModuleID string `json:"moduleId"` ScannerName string `json:"scannerName"` } type Query struct { CveID string `json:"cveId"` }