Add original http request to hooks (#2740)

This commit is contained in:
AlteredCoder 2024-01-16 10:33:44 +01:00 committed by GitHub
parent 24b5e8f100
commit a65223aa5b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 2 deletions

View file

@ -1,6 +1,7 @@
package appsec package appsec
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -43,6 +44,7 @@ type ParsedRequest struct {
IsOutBand bool `json:"-"` IsOutBand bool `json:"-"`
AppsecEngine string `json:"appsec_engine,omitempty"` AppsecEngine string `json:"appsec_engine,omitempty"`
RemoteAddrNormalized string `json:"normalized_remote_addr,omitempty"` RemoteAddrNormalized string `json:"normalized_remote_addr,omitempty"`
HTTPRequest *http.Request `json:"-"`
} }
type ReqDumpFilter struct { type ReqDumpFilter struct {
@ -274,13 +276,16 @@ func NewParsedRequestFromRequest(r *http.Request, logger *logrus.Entry) (ParsedR
if contentLength < 0 { if contentLength < 0 {
contentLength = 0 contentLength = 0
} }
body := make([]byte, contentLength)
body := make([]byte, contentLength)
if r.Body != nil { if r.Body != nil {
_, err = io.ReadFull(r.Body, body) _, err = io.ReadFull(r.Body, body)
if err != nil { if err != nil {
return ParsedRequest{}, fmt.Errorf("unable to read body: %s", err) return ParsedRequest{}, fmt.Errorf("unable to read body: %s", err)
} }
r.Body.Close()
// reset the original body back as it's been read, i'm not sure its needed?
r.Body = io.NopCloser(bytes.NewBuffer(body))
} }
clientIP := r.Header.Get(IPHeaderName) clientIP := r.Header.Get(IPHeaderName)
@ -292,10 +297,12 @@ func NewParsedRequestFromRequest(r *http.Request, logger *logrus.Entry) (ParsedR
if clientURI == "" { if clientURI == "" {
return ParsedRequest{}, fmt.Errorf("missing '%s' header", URIHeaderName) return ParsedRequest{}, fmt.Errorf("missing '%s' header", URIHeaderName)
} }
clientMethod := r.Header.Get(VerbHeaderName) clientMethod := r.Header.Get(VerbHeaderName)
if clientMethod == "" { if clientMethod == "" {
return ParsedRequest{}, fmt.Errorf("missing '%s' header", VerbHeaderName) return ParsedRequest{}, fmt.Errorf("missing '%s' header", VerbHeaderName)
} }
clientHost := r.Header.Get(HostHeaderName) clientHost := r.Header.Get(HostHeaderName)
if clientHost == "" { //this might be empty if clientHost == "" { //this might be empty
logger.Debugf("missing '%s' header", HostHeaderName) logger.Debugf("missing '%s' header", HostHeaderName)
@ -307,6 +314,13 @@ func NewParsedRequestFromRequest(r *http.Request, logger *logrus.Entry) (ParsedR
delete(r.Header, URIHeaderName) delete(r.Header, URIHeaderName)
delete(r.Header, VerbHeaderName) delete(r.Header, VerbHeaderName)
originalHTTPRequest := r.Clone(r.Context())
originalHTTPRequest.Body = io.NopCloser(bytes.NewBuffer(body))
originalHTTPRequest.RemoteAddr = clientIP
originalHTTPRequest.RequestURI = clientURI
originalHTTPRequest.Method = clientMethod
originalHTTPRequest.Host = clientHost
parsedURL, err := url.Parse(clientURI) parsedURL, err := url.Parse(clientURI)
if err != nil { if err != nil {
return ParsedRequest{}, fmt.Errorf("unable to parse url '%s': %s", clientURI, err) return ParsedRequest{}, fmt.Errorf("unable to parse url '%s': %s", clientURI, err)
@ -343,5 +357,6 @@ func NewParsedRequestFromRequest(r *http.Request, logger *logrus.Entry) (ParsedR
TransferEncoding: r.TransferEncoding, TransferEncoding: r.TransferEncoding,
ResponseChannel: make(chan AppsecTempResponse), ResponseChannel: make(chan AppsecTempResponse),
RemoteAddrNormalized: remoteAddrNormalized, RemoteAddrNormalized: remoteAddrNormalized,
HTTPRequest: originalHTTPRequest,
}, nil }, nil
} }

View file

@ -22,6 +22,7 @@ func GetPreEvalEnv(w *AppsecRuntimeConfig, request *ParsedRequest) map[string]in
return map[string]interface{}{ return map[string]interface{}{
"IsInBand": request.IsInBand, "IsInBand": request.IsInBand,
"IsOutBand": request.IsOutBand, "IsOutBand": request.IsOutBand,
"req": request.HTTPRequest,
"RemoveInBandRuleByID": w.RemoveInbandRuleByID, "RemoveInBandRuleByID": w.RemoveInbandRuleByID,
"RemoveInBandRuleByName": w.RemoveInbandRuleByName, "RemoveInBandRuleByName": w.RemoveInbandRuleByName,
"RemoveInBandRuleByTag": w.RemoveInbandRuleByTag, "RemoveInBandRuleByTag": w.RemoveInbandRuleByTag,
@ -39,13 +40,14 @@ func GetPostEvalEnv(w *AppsecRuntimeConfig, request *ParsedRequest) map[string]i
"IsInBand": request.IsInBand, "IsInBand": request.IsInBand,
"IsOutBand": request.IsOutBand, "IsOutBand": request.IsOutBand,
"DumpRequest": request.DumpRequest, "DumpRequest": request.DumpRequest,
"req": request.HTTPRequest,
} }
} }
func GetOnMatchEnv(w *AppsecRuntimeConfig, request *ParsedRequest, evt types.Event) map[string]interface{} { func GetOnMatchEnv(w *AppsecRuntimeConfig, request *ParsedRequest, evt types.Event) map[string]interface{} {
return map[string]interface{}{ return map[string]interface{}{
"evt": evt, "evt": evt,
"req": request, "req": request.HTTPRequest,
"IsInBand": request.IsInBand, "IsInBand": request.IsInBand,
"IsOutBand": request.IsOutBand, "IsOutBand": request.IsOutBand,
"SetRemediation": w.SetAction, "SetRemediation": w.SetAction,