Skip to content

Commit

Permalink
Merge pull request #984 from k2io/develop
Browse files Browse the repository at this point in the history
New config for nrsecurityagent
  • Loading branch information
nr-swilloughby authored Nov 8, 2024
2 parents 4e0598e + 45f11f2 commit b8458f1
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 4 deletions.
2 changes: 1 addition & 1 deletion v3/integrations/nrsecurityagent/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/newrelic/go-agent/v3/integrations/nrsecurityagent
go 1.21

require (
github.com/newrelic/csec-go-agent v1.4.0
github.com/newrelic/csec-go-agent v1.5.0
github.com/newrelic/go-agent/v3 v3.35.0
github.com/newrelic/go-agent/v3/integrations/nrsqlite3 v1.2.0
gopkg.in/yaml.v2 v2.4.0
Expand Down
97 changes: 95 additions & 2 deletions v3/integrations/nrsecurityagent/nrsecurityagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io/ioutil"
"os"
"strconv"
"strings"

securityAgent "github.com/newrelic/csec-go-agent"
"github.com/newrelic/go-agent/v3/internal"
Expand All @@ -31,6 +32,11 @@ func defaultSecurityConfig() SecurityConfig {
cfg.Security.Agent.Enabled = true
cfg.Security.Detection.Rxss.Enabled = true
cfg.Security.Request.BodyLimit = 300
cfg.Security.ExcludeFromIastScan.HttpRequestParameters.Header = make([]string, 0)
cfg.Security.ExcludeFromIastScan.HttpRequestParameters.Body = make([]string, 0)
cfg.Security.ExcludeFromIastScan.HttpRequestParameters.Query = make([]string, 0)
cfg.Security.ExcludeFromIastScan.API = make([]string, 0)
cfg.Security.ScanControllers.IastScanRequestRateLimit = 3600
return cfg
}

Expand Down Expand Up @@ -63,7 +69,7 @@ func InitSecurityAgent(app *newrelic.Application, opts ...ConfigOption) error {

appConfig, isValid := app.Config()
if !isValid {
return fmt.Errorf("Newrelic application value cannot be read; did you call newrelic.NewApplication?")
return fmt.Errorf("Newrelic application value cannot be read; did you call newrelic.NewApplication?")
}
app.UpdateSecurityConfig(c.Security)
if !appConfig.HighSecurity && isSecurityAgentEnabled() {
Expand Down Expand Up @@ -109,8 +115,24 @@ func ConfigSecurityFromYaml() ConfigOption {
// NEW_RELIC_SECURITY_VALIDATOR_SERVICE_URL provides URL for the security validator service
// NEW_RELIC_SECURITY_MODE scanning mode: "IAST" for now
// NEW_RELIC_SECURITY_AGENT_ENABLED (boolean)
// NEW_RELIC_SECURITY_DETECTION_RXSS_ENABLED (boolean)
// NEW_RELIC_SECURITY_REQUEST_BODY_LIMIT (integer) set limit on read request body in kb. By default, this is "300"
//
// NEW_RELIC_SECURITY_SCAN_SCHEDULE_DELAY (integer) The delay field indicated time in minutes before the IAST scan starts after the application starts. By default is 0 min.
// NEW_RELIC_SECURITY_SCAN_SCHEDULE_DURATION (integer) The duration field specifies the duration of the IAST scan in minutes. This determines how long the scan will run. By default is forever.
// NEW_RELIC_SECURITY_SCAN_SCHEDULE_SCHEDULE (string) The schedule field specifies a cron expression that defines when the IAST scan should run.
// NEW_RELIC_SECURITY_SCAN_SCHEDULE_ALWAYS_SAMPLE_TRACES (boolean) always_sample_traces permits IAST to actively gather trace data in the background, and the collected data will be used by Security Agent to perform an IAST Scan at the scheduled time.
// NEW_RELIC_SECURITY_SCAN_CONTROLLERS_IAST_SCAN_REQUEST_RATE_LIMIT (integer) The IAST Scan Rate Limit settings limit the maximum number of analysis probes or requests that can be sent to the application in a minute, By default is 3600.
//
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_INSECURE_SETTINGS (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_INVALID_FILE_ACCESS (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_SQL_INJECTION (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_NOSQL_INJECTION (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_LDAP_INJECTION (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_JAVASCRIPT_INJECTION (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_COMMAND_INJECTION (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_XPATH_INJECTION (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_SSRF (boolean)
// NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_RXSS (boolean)

func ConfigSecurityFromEnvironment() ConfigOption {
return func(cfg *SecurityConfig) {
Expand Down Expand Up @@ -145,6 +167,37 @@ func ConfigSecurityFromEnvironment() ConfigOption {
assignBool(&cfg.Security.Agent.Enabled, "NEW_RELIC_SECURITY_AGENT_ENABLED")
assignBool(&cfg.Security.Detection.Rxss.Enabled, "NEW_RELIC_SECURITY_DETECTION_RXSS_ENABLED")
assignInt(&cfg.Security.Request.BodyLimit, "NEW_RELIC_SECURITY_REQUEST_BODY_LIMIT")

assignInt(&cfg.Security.ScanSchedule.Delay, "NEW_RELIC_SECURITY_SCAN_SCHEDULE_DELAY")
assignInt(&cfg.Security.ScanSchedule.Duration, "NEW_RELIC_SECURITY_SCAN_SCHEDULE_DURATION")
assignString(&cfg.Security.ScanSchedule.Schedule, "NEW_RELIC_SECURITY_SCAN_SCHEDULE_SCHEDULE")
assignBool(&cfg.Security.ScanSchedule.AllowIastSampleCollection, "NEW_RELIC_SECURITY_SCAN_SCHEDULE_ALWAYS_SAMPLE_TRACES")
assignInt(&cfg.Security.ScanControllers.IastScanRequestRateLimit, "NEW_RELIC_SECURITY_SCAN_CONTROLLERS_IAST_SCAN_REQUEST_RATE_LIMIT")

assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.InsecureSettings, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_INSECURE_SETTINGS")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.InvalidFileAccess, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_INVALID_FILE_ACCESS")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.SQLInjection, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_SQL_INJECTION")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.NosqlInjection, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_NOSQL_INJECTION")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.LdapInjection, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_LDAP_INJECTION")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.JavascriptInjection, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_JAVASCRIPT_INJECTION")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.CommandInjection, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_COMMAND_INJECTION")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.XpathInjection, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_XPATH_INJECTION")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.Ssrf, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_SSRF")
assignBool(&cfg.Security.ExcludeFromIastScan.IastDetectionCategory.Rxss, "NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_IAST_DETECTION_CATEGORY_RXSS")

if env := os.Getenv("NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_API"); env != "" {
cfg.Security.ExcludeFromIastScan.API = strings.Split(env, ",")
}
if env := os.Getenv("NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_HTTP_REQUEST_PARAMETERS_HEADER"); env != "" {
cfg.Security.ExcludeFromIastScan.HttpRequestParameters.Header = strings.Split(env, ",")
}
if env := os.Getenv("NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_HTTP_REQUEST_PARAMETERS_QUERY"); env != "" {
cfg.Security.ExcludeFromIastScan.HttpRequestParameters.Query = strings.Split(env, ",")
}
if env := os.Getenv("NEW_RELIC_SECURITY_EXCLUDE_FROM_IAST_SCAN_HTTP_REQUEST_PARAMETERS_BODY"); env != "" {
cfg.Security.ExcludeFromIastScan.HttpRequestParameters.Body = strings.Split(env, ",")
}

}
}

Expand Down Expand Up @@ -182,3 +235,43 @@ func ConfigSecurityRequestBodyLimit(bodyLimit int) ConfigOption {
cfg.Security.Request.BodyLimit = bodyLimit
}
}

// ConfigScanScheduleDelay is used to set delay for scan schedule.
// The delay field indicated time in minutes before the IAST scan starts after the application starts
func ConfigScanScheduleDelay(delay int) ConfigOption {
return func(cfg *SecurityConfig) {
cfg.Security.ScanSchedule.Delay = delay
}
}

// ConfigScanScheduleDuration is used to set duration for scan schedule.
// The duration field specifies the duration of the IAST scan in minutes. This determines how long the scan will run.
func ConfigScanScheduleDuration(duration int) ConfigOption {
return func(cfg *SecurityConfig) {
cfg.Security.ScanSchedule.Duration = duration
}
}

// ConfigScanScheduleSetSchedule is used to set schedule for scan schedule.
// The schedule field specifies a cron expression that defines when the IAST scan should run.
func ConfigScanScheduleSetSchedule(schedule string) ConfigOption {
return func(cfg *SecurityConfig) {
cfg.Security.ScanSchedule.Schedule = schedule
}
}

// ConfigScanScheduleAllowIastSampleCollection is used to allow or disallow IAST sample collection
// always_sample_traces permits IAST to actively gather trace data in the background, and the collected data will be used by Security Agent to perform an IAST Scan at the scheduled time.
func ConfigScanScheduleAllowIastSampleCollection(isAllowed bool) ConfigOption {
return func(cfg *SecurityConfig) {
cfg.Security.ScanSchedule.AllowIastSampleCollection = isAllowed
}
}

// ConfigScanControllersIastScanRequestRateLimit is used to set IAST scan request rate limit.
// The IAST Scan Rate Limit settings limit the maximum number of analysis probes or requests that can be sent to the application in a minute
func ConfigIastScanRequestRateLimit(limit int) ConfigOption {
return func(cfg *SecurityConfig) {
cfg.Security.ScanControllers.IastScanRequestRateLimit = limit
}
}
2 changes: 1 addition & 1 deletion v3/newrelic/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func (txn *Transaction) SetWebRequest(r WebRequest) {
return
}
if IsSecurityAgentPresent() {
secureAgent.SendEvent("INBOUND", r, txn.GetCsecAttributes())
secureAgent.SendEvent("INBOUND", r, txn.GetCsecAttributes(), txn.GetLinkingMetadata().TraceID)
}
txn.thread.logAPIError(txn.thread.SetWebRequest(r), "set web request", nil)
}
Expand Down

0 comments on commit b8458f1

Please sign in to comment.