aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2021-09-25 02:31:30 +0700
committerShulhan <ms@kilabit.info>2021-09-25 02:31:30 +0700
commit66975f1b439dcbb185b9b7c2d6ca382606cc23d2 (patch)
tree6f4dcc60150dc9f85093258075699a3a12090d15
parent8b2b38de2e55d5c1ab7bed5bd19ce315ae8908d5 (diff)
downloadgorankusu-66975f1b439dcbb185b9b7c2d6ca382606cc23d2.tar.xz
all: prevent leaking Target and HttpTarget headers and variables
In case two or more users access the Trunks web and set the target variables, the last user that run any HttpTarget will set the Target variables or HttpTarget headers/variables. The next user that open the Trunks web will see the values of headers and variables from the latest run. This changes fix this issue by generating new RunRequest using request original target
-rw-r--r--example/example.go2
-rw-r--r--run_request.go108
-rw-r--r--trunks.go23
3 files changed, 65 insertions, 68 deletions
diff --git a/example/example.go b/example/example.go
index abf6c0e..3bf7395 100644
--- a/example/example.go
+++ b/example/example.go
@@ -259,7 +259,7 @@ func (ex *Example) registerTargets() (err error) {
},
Params: trunks.KeyFormInput{
"Param1": trunks.FormInput{
- Label: "X-FreeForm",
+ Label: "Param1",
Hint: "Parameter with number.",
Kind: trunks.FormInputKindNumber,
Value: "123",
diff --git a/run_request.go b/run_request.go
index bbb4f2d..174781d 100644
--- a/run_request.go
+++ b/run_request.go
@@ -12,79 +12,93 @@ import (
vegeta "github.com/tsenart/vegeta/v12/lib"
)
+//
+// RunRequest define the request to run HTTP or WebSocket target.
+//
type RunRequest struct {
- Locker sync.Mutex
- Target *Target
- HttpTarget *HttpTarget
- WebSocketTarget *WebSocketTarget
+ Locker sync.Mutex `json:"-"`
+ Target Target
+ HttpTarget HttpTarget
+ WebSocketTarget WebSocketTarget
result *AttackResult
}
-func (rr *RunRequest) String() string {
- return fmt.Sprintf("Target:%v HttpTarget:%v\n", rr.Target, rr.HttpTarget)
-}
-
//
-// mergeHttpTarget merge the request parameter into original target and HTTP
-// target.
+// generateRunRequest merge the run request with original target and HTTP
+// target into new RunRequest.
//
-func (rr *RunRequest) mergeHttpTarget(env *Environment, origTarget *Target, origHttpTarget *HttpTarget) {
- if rr.Target.Opts.Duration > 0 && rr.Target.Opts.Duration <= env.MaxAttackDuration {
- origTarget.Opts.Duration = rr.Target.Opts.Duration
+func generateRunRequest(
+ env *Environment,
+ req *RunRequest,
+ origTarget *Target,
+ origHttpTarget *HttpTarget,
+) (outrr *RunRequest) {
+ if req.Target.Opts.Duration > 0 && req.Target.Opts.Duration <= env.MaxAttackDuration {
+ origTarget.Opts.Duration = req.Target.Opts.Duration
}
-
- if rr.Target.Opts.RatePerSecond > 0 && rr.Target.Opts.RatePerSecond <= env.MaxAttackRate {
- origTarget.Opts.RatePerSecond = rr.Target.Opts.RatePerSecond
+ if req.Target.Opts.RatePerSecond > 0 && req.Target.Opts.RatePerSecond <= env.MaxAttackRate {
+ origTarget.Opts.RatePerSecond = req.Target.Opts.RatePerSecond
origTarget.Opts.ratePerSecond = vegeta.Rate{
- Freq: rr.Target.Opts.RatePerSecond,
+ Freq: req.Target.Opts.RatePerSecond,
Per: time.Second,
}
}
+ if req.Target.Opts.Timeout > 0 && req.Target.Opts.Timeout <= DefaultAttackTimeout {
+ origTarget.Opts.Timeout = req.Target.Opts.Timeout
+ }
+ if origHttpTarget.IsCustomizable {
+ origHttpTarget.Method = req.HttpTarget.Method
+ origHttpTarget.Path = req.HttpTarget.Path
+ origHttpTarget.RequestType = req.HttpTarget.RequestType
+ }
- if rr.Target.Opts.Timeout > 0 && rr.Target.Opts.Timeout <= DefaultAttackTimeout {
- origTarget.Opts.Timeout = rr.Target.Opts.Timeout
+ outrr = &RunRequest{
+ Target: *origTarget,
+ HttpTarget: *origHttpTarget,
}
- origTarget.Vars = rr.Target.Vars
- rr.Target = origTarget
+ outrr.Target.Vars = req.Target.Vars
+ outrr.HttpTarget.Headers = req.HttpTarget.Headers
+ outrr.HttpTarget.Params = req.HttpTarget.Params
- if origHttpTarget.IsCustomizable {
- origHttpTarget.Method = rr.HttpTarget.Method
- origHttpTarget.Path = rr.HttpTarget.Path
- origHttpTarget.RequestType = rr.HttpTarget.RequestType
- }
- origHttpTarget.Headers = rr.HttpTarget.Headers
- origHttpTarget.Params = rr.HttpTarget.Params
- rr.HttpTarget = origHttpTarget
+ return outrr
}
//
-// mergeWebSocketTarget merge the request parameter into original target and
-// WebSocket target.
+// generateWebSocketTarget merge the run request with original target and
+// WebSocket target into new RunRequest
//
-func (rr *RunRequest) mergeWebSocketTarget(env *Environment,
- origTarget *Target, origWebSocketTarget *WebSocketTarget,
-) {
- if rr.Target.Opts.Duration > 0 && rr.Target.Opts.Duration <= env.MaxAttackDuration {
- origTarget.Opts.Duration = rr.Target.Opts.Duration
+func generateWebSocketTarget(
+ env *Environment,
+ req *RunRequest,
+ origTarget *Target,
+ origWebSocketTarget *WebSocketTarget,
+) (outrr *RunRequest) {
+ if req.Target.Opts.Duration > 0 && req.Target.Opts.Duration <= env.MaxAttackDuration {
+ origTarget.Opts.Duration = req.Target.Opts.Duration
}
-
- if rr.Target.Opts.RatePerSecond > 0 && rr.Target.Opts.RatePerSecond <= env.MaxAttackRate {
- origTarget.Opts.RatePerSecond = rr.Target.Opts.RatePerSecond
+ if req.Target.Opts.RatePerSecond > 0 && req.Target.Opts.RatePerSecond <= env.MaxAttackRate {
+ origTarget.Opts.RatePerSecond = req.Target.Opts.RatePerSecond
origTarget.Opts.ratePerSecond = vegeta.Rate{
- Freq: rr.Target.Opts.RatePerSecond,
+ Freq: req.Target.Opts.RatePerSecond,
Per: time.Second,
}
}
+ if req.Target.Opts.Timeout > 0 && req.Target.Opts.Timeout <= DefaultAttackTimeout {
+ origTarget.Opts.Timeout = req.Target.Opts.Timeout
+ }
- if rr.Target.Opts.Timeout > 0 && rr.Target.Opts.Timeout <= DefaultAttackTimeout {
- origTarget.Opts.Timeout = rr.Target.Opts.Timeout
+ outrr = &RunRequest{
+ Target: *origTarget,
+ WebSocketTarget: *origWebSocketTarget,
}
+ outrr.Target.Vars = req.Target.Vars
+ outrr.WebSocketTarget.Headers = req.WebSocketTarget.Headers
+ outrr.WebSocketTarget.Params = req.WebSocketTarget.Params
- origTarget.Vars = rr.Target.Vars
- rr.Target = origTarget
+ return outrr
+}
- origWebSocketTarget.Headers = rr.WebSocketTarget.Headers
- origWebSocketTarget.Params = rr.WebSocketTarget.Params
- rr.WebSocketTarget = origWebSocketTarget
+func (rr *RunRequest) String() string {
+ return fmt.Sprintf("Target:%v HttpTarget:%v\n", rr.Target, rr.HttpTarget)
}
diff --git a/trunks.go b/trunks.go
index 44d6400..2972b54 100644
--- a/trunks.go
+++ b/trunks.go
@@ -272,9 +272,6 @@ func (trunks *Trunks) apiTargetAttack(epr *libhttp.EndpointRequest) (resbody []b
if err != nil {
return nil, errInternal(err)
}
- if req.Target == nil {
- return nil, errInvalidTarget("")
- }
origTarget := trunks.getTargetByID(req.Target.ID)
if origTarget == nil {
@@ -290,7 +287,7 @@ func (trunks *Trunks) apiTargetAttack(epr *libhttp.EndpointRequest) (resbody []b
return nil, errAttackNotAllowed()
}
- req.mergeHttpTarget(trunks.Env, origTarget, origHttpTarget)
+ req = generateRunRequest(trunks.Env, req, origTarget, origHttpTarget)
req.result, err = newAttackResult(trunks.Env, req)
if err != nil {
@@ -386,19 +383,12 @@ func (trunks *Trunks) apiTargetRunHttp(epr *libhttp.EndpointRequest) ([]byte, er
if err != nil {
return nil, errInternal(err)
}
- if req.Target == nil {
- return nil, errInvalidTarget("")
- }
origTarget := trunks.getTargetByID(req.Target.ID)
if origTarget == nil {
return nil, errInvalidTarget(req.Target.ID)
}
- if req.HttpTarget == nil {
- return nil, errInvalidHttpTarget("")
- }
-
origHttpTarget := origTarget.getHttpTargetByID(req.HttpTarget.ID)
if origHttpTarget == nil {
return nil, errInvalidHttpTarget(req.HttpTarget.ID)
@@ -411,7 +401,7 @@ func (trunks *Trunks) apiTargetRunHttp(epr *libhttp.EndpointRequest) ([]byte, er
req.Target.Name = origTarget.Name
res, err = trunks.runHttpTarget(req)
} else {
- req.mergeHttpTarget(trunks.Env, origTarget, origHttpTarget)
+ req := generateRunRequest(trunks.Env, req, origTarget, origHttpTarget)
res, err = req.HttpTarget.Run(req)
}
if err != nil {
@@ -431,25 +421,18 @@ func (trunks *Trunks) apiTargetRunWebSocket(epr *libhttp.EndpointRequest) ([]byt
if err != nil {
return nil, errInternal(err)
}
- if req.Target == nil {
- return nil, errInvalidTarget("")
- }
origTarget := trunks.getTargetByID(req.Target.ID)
if origTarget == nil {
return nil, errInvalidTarget(req.Target.ID)
}
- if req.WebSocketTarget == nil {
- return nil, errInvalidWebSocketTarget("")
- }
-
origWsTarget := origTarget.getWebSocketTargetByID(req.WebSocketTarget.ID)
if origWsTarget == nil {
return nil, errInvalidWebSocketTarget(req.WebSocketTarget.ID)
}
- req.mergeWebSocketTarget(trunks.Env, origTarget, origWsTarget)
+ req = generateWebSocketTarget(trunks.Env, req, origTarget, origWsTarget)
res, err := req.WebSocketTarget.Run(req)
if err != nil {