Skip to content

Commit

Permalink
Added implementation to send http response event
Browse files Browse the repository at this point in the history
  • Loading branch information
aayush-ap committed Nov 4, 2024
1 parent b9df343 commit 473c89c
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 23 deletions.
12 changes: 6 additions & 6 deletions internal/security_utils/global_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@

package security_utils

import "net/http"

const MaxReadBodyLen = 300000

type Info_req struct {
ResponseBody string
ResponseHeader http.Header
ResponseContentType string
GrpcBody []interface{}
ReqTraceData string
RequestIdentifier NrRequestIdentifier
Request RequestInfo
Response ResponseInfo
VulnerabilityDetails VulnerabilityDetails
ReflectedMetaData ReflectedMetaData
ParentID string
Expand All @@ -30,7 +26,11 @@ type ReflectedMetaData struct {
}

type ResponseInfo struct {
ContentType string `json:"contentType"`
ContentType string `json:"contentType"`
StatusCode int `json:"statusCode"`
Headers map[string]string `json:"headers"`
Body string `json:"body"`
HeadersMap map[string][]string `json:"-"`
}

type RequestInfo struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/security_utils/xss_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ func decodeRequestData(rq *Info_req) []string {

func decodeResponseData(rq *Info_req) []string {
var processedData []string
decodedBodyValue := processURLEncodedDataForXSS(rq.ResponseBody)
decodedBodyValue := processURLEncodedDataForXSS(rq.Response.Body)
processedData = append(processedData, decodedBodyValue...)
for _, st := range decodedBodyValue {
newprocessedBody := safeDecode(st)
Expand Down
6 changes: 6 additions & 0 deletions security_config/global_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ func (info *Info_struct) ScanScheduleSchedule() string {
return info.security.ScanSchedule.Schedule
}

func (info *Info_struct) ReportHttpResponseBody() bool {
info.securityMutex.Lock()
defer info.securityMutex.Unlock()
return info.security.ScanControllers.ReportHttpResponseBody
}

func (info *Info_struct) SecurityHomePath() string {
return info.security.SecurityHomePath
}
Expand Down
1 change: 1 addition & 0 deletions security_config/limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ package security_config
const (
MaxStackTraceFrames = 100
ValidatorDefaultEndpoint = "wss://csec.nr-data.net"
HttpResponseBodyLimit = 500 * 1000 //500kb
)
3 changes: 2 additions & 1 deletion security_config/secure_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ type Security struct {
AllowIastSampleCollection bool `yaml:"always_sample_traces"`
} `yaml:"scan_schedule"`
ScanControllers struct {
IastScanRequestRateLimit int `yaml:"iast_scan_request_rate_limit"`
IastScanRequestRateLimit int `yaml:"iast_scan_request_rate_limit"`
ReportHttpResponseBody bool `yaml:"report_http_response_body: true"`
} `yaml:"scan_controllers"`
}

Expand Down
21 changes: 20 additions & 1 deletion security_event_generation/event_generation.go
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ func SendVulnerableEvent(req *secUtils.Info_req, category, eventCategory string,
tmp_event.VulnerabilityDetails = vulnerabilityDetails
tmp_event.ApplicationIdentifiers = getApplicationIdentifiers("Event")
tmp_event.EventGenerationTime = strconv.FormatInt(time.Now().Unix()*1000, 10)
tmp_event.HTTPResponse = secUtils.ResponseInfo{ContentType: req.ResponseContentType}
tmp_event.HTTPResponse = req.Response
tmp_event.MetaData.AppServerInfo.ApplicationDirectory = secConfig.GlobalInfo.EnvironmentInfo.Wd
tmp_event.MetaData.AppServerInfo.ServerBaseDirectory = secConfig.GlobalInfo.EnvironmentInfo.Wd
tmp_event.MetaData.SkipScanParameters = secConfig.GlobalInfo.SkipIastScanParameters()
Expand Down Expand Up @@ -395,6 +395,25 @@ func SendVulnerableEvent(req *secUtils.Info_req, category, eventCategory string,

}

func SendResponseEvent(req *secUtils.Info_req) {

if req != nil && secUtils.CaseInsensitiveEquals(req.RequestIdentifier.NextStage, "VULNERABLE") {

var tmp_event SecHttpResponse
tmp_event.ApplicationIdentifiers = getApplicationIdentifiers("sec-http-response")
tmp_event.HTTPRequest = nil
tmp_event.HTTPResponse = req.Response
tmp_event.TraceId = req.TraceId
tmp_event.IsIASTRequest = true
tmp_event.LinkingMetadata = copyMap(secConfig.GlobalInfo.MetaData.GetLinkingMetadata())
tmp_event.LinkingMetadata["trace.id"] = req.TraceId
_, err := sendEvent(tmp_event, "", "sec-http-response")
if err != nil {
logger.Errorln(err)
}
}
}

func SendExitEvent(eventTracker *secUtils.EventTracker, requestIdentifier string) {

var tmp_event Exitevent
Expand Down
8 changes: 8 additions & 0 deletions security_event_generation/event_generation_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,14 @@ type ApplicationIdentifiers struct {
LinkingMetadata map[string]string `json:"linkingMetadata"`
}

type SecHttpResponse struct {
ApplicationIdentifiers
TraceId string `json:"traceId"`
HTTPResponse secUtils.ResponseInfo `json:"httpResponse"`
HTTPRequest interface{} `json:"httpRequest"`
IsIASTRequest bool `json:"isIASTRequest"`
}

type FuzzFailBean struct {
ApplicationIdentifiers
FuzzHeader string `json:"fuzzHeader"`
Expand Down
38 changes: 24 additions & 14 deletions security_intercept/intercept.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,26 +328,35 @@ func TraceIncommingRequest(url, host string, hdrMap map[string][]string, method
infoReq.Request.URI = getRequestUri(url)
infoReq.TraceId = traceId

if reqtype == "gRPC" {
if reqtype == "gRPC" {
infoReq.Request.IsGRPC = true
}

secConfig.Secure.AssociateInboundRequest(infoReq)
}

func associateResponseBody(body string) {
r := secConfig.Secure.GetRequest()
if r != nil {
r.ResponseBody = r.ResponseBody + body
secConfig.Secure.CalculateOutboundApiId()
if secConfig.GlobalInfo.ReportHttpResponseBody() {
r := secConfig.Secure.GetRequest()
if r != nil {
if l := len(r.Response.Body); len(body) <= secConfig.HttpResponseBodyLimit-l {
r.Response.Body = r.Response.Body + body
} else if secConfig.HttpResponseBodyLimit-l > 1 {
end := secConfig.HttpResponseBodyLimit - l
r.Response.Body = r.Response.Body + body[:end-1]
}
secConfig.Secure.CalculateOutboundApiId()
}
}

}

func associateResponseHeader(header http.Header) {
r := secConfig.Secure.GetRequest()
if r != nil {
r.ResponseHeader = header
r.ResponseContentType = header.Get("content-type")
r.Response.Headers = ToOneValueMap(header)
r.Response.HeadersMap = header
r.Response.ContentType = header.Get("content-type")
}
}

Expand Down Expand Up @@ -452,8 +461,9 @@ func traceResponseOperations() {

r := secConfig.Secure.GetRequest()
if r != nil {
checkSecureCookies(r.ResponseHeader)
checkSecureCookies(r.Response.HeadersMap)
xssCheck(r)
eventGeneration.SendResponseEvent(r)
}
}

Expand Down Expand Up @@ -484,24 +494,24 @@ func checkSecureCookies(responseHeader http.Header) {
}

func xssCheck(r *secUtils.Info_req) {
if !IsRxssDisabled() && r.ResponseBody != "" {
if !IsRxssDisabled() && r.Response.Body != "" {

contentType := r.ResponseContentType
contentType := r.Response.ContentType
if !secUtils.IsContentTypeSupported(contentType) {
SendLogMessage(SKIP_RXSS_EVENT+contentType, "XssCheck", "SEVERE")
logger.Debugln(SKIP_RXSS_EVENT, contentType)
return
}

// Double check befor rxss event validation becouse in some case we don't have contentType in response header.
cType := http.DetectContentType([]byte(r.ResponseBody))
cType := http.DetectContentType([]byte(r.Response.Body))
if !secUtils.IsContentTypeSupported(cType) {
SendLogMessage(SKIP_RXSS_EVENT+cType, "XssCheck", "SEVERE")
logger.Debugln(SKIP_RXSS_EVENT, cType)
return
}
if r.ResponseContentType == "" {
r.ResponseContentType = cType
if r.Response.ContentType == "" {
r.Response.ContentType = cType
}

out := secUtils.CheckForReflectedXSS(r)
Expand All @@ -512,7 +522,7 @@ func xssCheck(r *secUtils.Info_req) {
} else {
var arg []string
arg = append(arg, out)
arg = append(arg, r.ResponseBody)
arg = append(arg, r.Response.Body)
secConfig.Secure.SendEvent("REFLECTED_XSS", "REFLECTED_XSS", arg)
}
}
Expand Down

0 comments on commit 473c89c

Please sign in to comment.