add reporting source in nuclei-cloud (#3151)

* add reporting source in nuclei-cloud

- `nuclei -cloud -rc reporting-config.yaml`

* update error message

* add severity options for jira,(used for cloud only)
dev
Shubham Rasal 2023-01-10 22:49:01 +05:30 committed by GitHub
parent 63f1b9c2e5
commit 25fcae1493
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 76 additions and 10 deletions

View File

@ -368,3 +368,26 @@ func (r *Runner) processDataSourceItem(repo, token, Type string) (int64, error)
}
return ID, nil
}
// addCloudReportingSource adds reporting sources to cloud
func (r *Runner) addCloudReportingSource() error {
rcOptions := r.issuesClient.GetReportingOptions()
if rcOptions == nil {
return nil
}
if rcOptions.Jira != nil {
payload, err := jsoniter.Marshal(rcOptions.Jira)
if err != nil {
return err
}
requestObj := nucleicloud.AddReportingSourceRequest{
Type: "jira",
Payload: payload,
}
if _, err := r.cloudClient.AddReportingSource(requestObj); err != nil {
return errors.Wrap(err, "could not add reporting source")
}
gologger.Info().Msgf("Reporting source and webhook added for %s: %s", "jira", r.options.CloudURL)
}
return nil
}

View File

@ -582,3 +582,26 @@ func (c *Client) sendRequest(req *retryablehttp.Request) (*http.Response, error)
}
return resp, nil
}
// AddReportingSource adds a new data source
func (c *Client) AddReportingSource(req AddReportingSourceRequest) (*AddReportingSourceResponse, error) {
var buf bytes.Buffer
if err := jsoniter.NewEncoder(&buf).Encode(req); err != nil {
return nil, errors.Wrap(err, "could not encode request")
}
httpReq, err := retryablehttp.NewRequest(http.MethodPost, fmt.Sprintf("%s/reporting/add-source", c.baseURL), bytes.NewReader(buf.Bytes()))
if err != nil {
return nil, errors.Wrap(err, "could not make request")
}
resp, err := c.sendRequest(httpReq)
if err != nil {
return nil, errors.Wrap(err, "could not do request")
}
defer resp.Body.Close()
var data AddReportingSourceResponse
if err := jsoniter.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, errors.Wrap(err, "could not decode resp")
}
return &data, nil
}

View File

@ -1,6 +1,7 @@
package nucleicloud
import (
"encoding/json"
"time"
"github.com/projectdiscovery/nuclei/v2/pkg/model/types/severity"
@ -152,3 +153,14 @@ type ListScanOutput struct {
type ExistsInputResponse struct {
Reference string `json:"reference"`
}
// AddReportingSourceRequest is a add reporting source request item.
type AddReportingSourceRequest struct {
Type string `json:"type"`
Payload json.RawMessage `json:"payload"`
}
// AddReportingSourceResponse is a add reporting source response item.
type AddReportingSourceResponse struct {
Ok string `json:"ok"`
}

View File

@ -516,6 +516,8 @@ func (r *Runner) RunEnumeration() error {
err = r.removeTarget(r.options.RemoveTarget)
} else if r.options.RemoveTemplate != "" {
err = r.removeTemplate(r.options.RemoveTemplate)
} else if r.options.ReportingConfig != "" {
err = r.addCloudReportingSource()
} else {
if len(store.Templates())+len(store.Workflows())+len(cloudTemplates) == 0 {
return errors.New("no templates provided for scan")

View File

@ -272,3 +272,7 @@ func stringSliceContains(slice []string, item string) bool {
}
return false
}
func (c *Client) GetReportingOptions() *Options {
return c.options
}

View File

@ -25,26 +25,28 @@ type Integration struct {
// Options contains the configuration options for jira client
type Options struct {
// Cloud value (optional) is set to true when Jira cloud is used
Cloud bool `yaml:"cloud"`
Cloud bool `yaml:"cloud" json:"cloud"`
// UpdateExisting value (optional) if true, the existing opened issue is updated
UpdateExisting bool `yaml:"update-existing"`
UpdateExisting bool `yaml:"update-existing" json:"update_existing"`
// URL is the URL of the jira server
URL string `yaml:"url" validate:"required"`
URL string `yaml:"url" json:"url" validate:"required"`
// AccountID is the accountID of the jira user.
AccountID string `yaml:"account-id" validate:"required"`
AccountID string `yaml:"account-id" json:"account_id" validate:"required"`
// Email is the email of the user for jira instance
Email string `yaml:"email" validate:"required,email"`
Email string `yaml:"email" json:"email" validate:"required,email"`
// Token is the token for jira instance.
Token string `yaml:"token" validate:"required"`
Token string `yaml:"token" json:"token" validate:"required"`
// ProjectName is the name of the project.
ProjectName string `yaml:"project-name" validate:"required"`
ProjectName string `yaml:"project-name" json:"project_name" validate:"required"`
// IssueType (optional) is the name of the created issue type
IssueType string `yaml:"issue-type"`
IssueType string `yaml:"issue-type" json:"issue_type"`
// SeverityAsLabel (optional) sends the severity as the label of the created
// issue.
SeverityAsLabel bool `yaml:"severity-as-label"`
SeverityAsLabel bool `yaml:"severity-as-label" json:"severity_as_label"`
// Severity (optional) is the severity of the issue.
Severity []string `yaml:"severity" json:"severity"`
HttpClient *retryablehttp.Client `yaml:"-"`
HttpClient *retryablehttp.Client `yaml:"-" json:"-"`
}
// New creates a new issue tracker integration client based on options.