// POSTBatchLayersVulnerabilities returns the complete list of vulnerabilities // that the provided layers have, if they all exist. func POSTBatchLayersVulnerabilities(w http.ResponseWriter, r *http.Request, p httprouter.Params) { // Parse body var parameters POSTBatchLayersVulnerabilitiesParameters if s, err := jsonhttp.ParseBody(r, ¶meters); err != nil { jsonhttp.RenderError(w, s, err) return } if len(parameters.LayersIDs) == 0 { jsonhttp.RenderError(w, http.StatusBadRequest, errors.New("at least one LayerID query parameter must be provided")) return } // Get minumum priority parameter. minimumPriority := types.Priority(r.URL.Query().Get("minimumPriority")) if minimumPriority == "" { minimumPriority = "High" // Set default priority to High } else if !minimumPriority.IsValid() { jsonhttp.RenderError(w, 0, cerrors.NewBadRequestError("invalid priority")) return } response := make(map[string]interface{}) // For each LayerID parameter for _, layerID := range parameters.LayersIDs { // Find layer layer, err := database.FindOneLayerByID(layerID, []string{database.FieldLayerParent, database.FieldLayerPackages}) if err != nil { jsonhttp.RenderError(w, 0, err) return } // Find layer's packages. packagesNodes, err := layer.AllPackages() if err != nil { jsonhttp.RenderError(w, 0, err) return } // Find vulnerabilities. vulnerabilities, err := getVulnerabilitiesFromLayerPackagesNodes(packagesNodes, minimumPriority, []string{database.FieldVulnerabilityID, database.FieldVulnerabilityLink, database.FieldVulnerabilityPriority, database.FieldVulnerabilityDescription}) if err != nil { jsonhttp.RenderError(w, 0, err) return } response[layerID] = struct{ Vulnerabilities []*database.Vulnerability }{Vulnerabilities: vulnerabilities} } jsonhttp.Render(w, http.StatusOK, response) }
// POSTLayers analyzes a layer and returns the engine version that has been used // for the analysis. func POSTLayers(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { var parameters POSTLayersParameters if s, err := jsonhttp.ParseBody(r, ¶meters); err != nil { jsonhttp.RenderError(w, s, err) return } // Process data. if err := worker.Process(parameters.ID, parameters.ParentID, parameters.Path); err != nil { jsonhttp.RenderError(w, 0, err) return } // Get engine version and return. jsonhttp.Render(w, http.StatusCreated, struct{ Version string }{Version: strconv.Itoa(worker.Version)}) }
// POSTVulnerabilities manually inserts a vulnerability into the database if it // does not exist yet. func POSTVulnerabilities(w http.ResponseWriter, r *http.Request, p httprouter.Params) { var parameters *database.AbstractVulnerability if s, err := jsonhttp.ParseBody(r, ¶meters); err != nil { jsonhttp.RenderError(w, s, err) return } // Ensure that the vulnerability does not exist. vulnerability, err := database.FindOneVulnerability(parameters.ID, []string{}) if err != nil && err != cerrors.ErrNotFound { jsonhttp.RenderError(w, 0, err) return } if vulnerability != nil { jsonhttp.RenderError(w, 0, cerrors.NewBadRequestError("vulnerability already exists")) return } // Insert packages. packages := database.AbstractPackagesToPackages(parameters.AffectedPackages) err = database.InsertPackages(packages) if err != nil { jsonhttp.RenderError(w, 0, err) return } var pkgNodes []string for _, p := range packages { pkgNodes = append(pkgNodes, p.Node) } // Insert vulnerability. notifications, err := database.InsertVulnerabilities([]*database.Vulnerability{parameters.ToVulnerability(pkgNodes)}) if err != nil { jsonhttp.RenderError(w, 0, err) return } // Insert notifications. err = database.InsertNotifications(notifications, database.GetDefaultNotificationWrapper()) if err != nil { jsonhttp.RenderError(w, 0, err) return } jsonhttp.Render(w, http.StatusCreated, nil) }
// POSTVulnerabilitiesAffectedLayers returns whether the specified layers // (by their IDs) are vulnerable to the given Vulnerability or not. func POSTVulnerabilitiesAffectedLayers(w http.ResponseWriter, r *http.Request, p httprouter.Params) { // Parse body. var parameters POSTBatchLayersVulnerabilitiesParameters if s, err := jsonhttp.ParseBody(r, ¶meters); err != nil { jsonhttp.RenderError(w, s, err) return } if len(parameters.LayersIDs) == 0 { jsonhttp.RenderError(w, http.StatusBadRequest, errors.New("getting the entire list of affected layers is not supported yet: at least one LayerID query parameter must be provided")) return } // Find vulnerability. vulnerability, err := database.FindOneVulnerability(p.ByName("id"), []string{database.FieldVulnerabilityFixedIn}) if err != nil { jsonhttp.RenderError(w, 0, err) return } // Save the fixed in nodes into a map for fast check. fixedInPackagesMap := make(map[string]struct{}) for _, fixedInNode := range vulnerability.FixedInNodes { fixedInPackagesMap[fixedInNode] = struct{}{} } response := make(map[string]interface{}) // For each LayerID parameter. for _, layerID := range parameters.LayersIDs { // Find layer layer, err := database.FindOneLayerByID(layerID, []string{database.FieldLayerParent, database.FieldLayerPackages, database.FieldLayerPackages}) if err != nil { jsonhttp.RenderError(w, 0, err) return } // Find layer's packages. packagesNodes, err := layer.AllPackages() if err != nil { jsonhttp.RenderError(w, 0, err) return } // Get successors packages of layer' packages. successors, err := getSuccessorsFromPackagesNodes(packagesNodes) if err != nil { jsonhttp.RenderError(w, 0, err) return } // Determine if the layer is vulnerable by verifying if one of the successors // of its packages are fixed by the vulnerability. vulnerable := false for _, p := range successors { if _, fixed := fixedInPackagesMap[p]; fixed { vulnerable = true break } } response[layerID] = struct{ Vulnerable bool }{Vulnerable: vulnerable} } jsonhttp.Render(w, http.StatusOK, response) }