Skip to content

Commit e94ff34

Browse files
Merge pull request #38 from coreruleset/feat/var-operation-enums
feat: var operations to enums
2 parents 2dd8295 + aa25134 commit e94ff34

File tree

4 files changed

+67
-19
lines changed

4 files changed

+67
-19
lines changed

listener_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func mustNewActionWithParam[T types.ActionType](action T, param string) types.Ac
2727
return newAction
2828
}
2929

30-
func mustNewSetvarAction(collection types.CollectionName, operation string, vars []types.VarAssignment) types.Action {
30+
func mustNewSetvarAction(collection types.CollectionName, operation types.VarOperation, vars []types.VarAssignment) types.Action {
3131
newAction, err := types.NewSetvarAction(collection, operation, vars)
3232
if err != nil {
3333
panic(err)
@@ -169,7 +169,7 @@ SecAction \
169169
DisruptiveAction: mustNewActionOnly(types.Pass),
170170
NonDisruptiveActions: []types.Action{
171171
mustNewActionOnly(types.NoLog),
172-
mustNewSetvarAction(types.TX, "=", []types.VarAssignment{
172+
mustNewSetvarAction(types.TX, types.Assign, []types.VarAssignment{
173173
{Variable: "blocking_inbound_anomaly_score", Value: "0"},
174174
{Variable: "detection_inbound_anomaly_score", Value: "0"},
175175
{Variable: "inbound_anomaly_score_pl1", Value: "0"},
@@ -296,7 +296,7 @@ SecRule REQUEST_LINE "@rx (?i)^(?:get /[^#\?]*(?:\?[^\s\v#]*)?(?:#[^\s\v]*)?|(?:
296296
DisruptiveAction: mustNewActionOnly(types.Block),
297297
NonDisruptiveActions: []types.Action{
298298
mustNewActionWithParam(types.LogData, "%{request_line}"),
299-
mustNewSetvarAction(types.TX, "=+", []types.VarAssignment{{Variable: "inbound_anomaly_score_pl1", Value: "%{tx.warning_anomaly_score}"}}),
299+
mustNewSetvarAction(types.TX, types.Increment, []types.VarAssignment{{Variable: "inbound_anomaly_score_pl1", Value: "%{tx.warning_anomaly_score}"}}),
300300
},
301301
},
302302
},

types/actions.go

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,44 @@ type VarAssignment struct {
116116
Value string `yaml:"value"`
117117
}
118118

119+
type VarOperation int
120+
121+
const (
122+
UnknownOp VarOperation = iota
123+
Assign
124+
Increment
125+
Decrement
126+
)
127+
128+
func (v VarOperation) String() string {
129+
switch v {
130+
case Assign:
131+
return "="
132+
case Increment:
133+
return "=+"
134+
case Decrement:
135+
return "=-"
136+
default:
137+
return "unknown"
138+
}
139+
}
140+
141+
func stringToVarOperation(s string) VarOperation {
142+
switch s {
143+
case "=":
144+
return Assign
145+
case "=+":
146+
return Increment
147+
case "=-":
148+
return Decrement
149+
default:
150+
return UnknownOp
151+
}
152+
}
153+
119154
type SetvarAction struct {
120155
Collection CollectionName `yaml:"collection,omitempty"`
121-
Operation string `yaml:"operation,omitempty"`
156+
Operation VarOperation `yaml:"operation,omitempty"`
122157
Assignments []VarAssignment `yaml:"assignments,omitempty"`
123158
}
124159

@@ -136,7 +171,7 @@ func (a SetvarAction) ToString() string {
136171
var result []string
137172
// Reconstruct the setvar actions
138173
for _, asg := range a.Assignments {
139-
result = append(result, SetVar.String()+":"+a.Collection.String()+"."+asg.Variable+a.Operation+asg.Value)
174+
result = append(result, SetVar.String()+":"+a.Collection.String()+"."+asg.Variable+a.Operation.String()+asg.Value)
140175
}
141176
return strings.Join(result, ", ")
142177
}
@@ -154,7 +189,7 @@ func (a SetvarAction) GetAllParams() []string {
154189
var result []string
155190
// Get all the variables
156191
for _, asg := range a.Assignments {
157-
res := SetVar.String() + ":" + a.Collection.String() + "." + asg.Variable + a.Operation + asg.Value
192+
res := SetVar.String() + ":" + a.Collection.String() + "." + asg.Variable + a.Operation.String() + asg.Value
158193
result = append(result, res)
159194
}
160195
return result
@@ -168,10 +203,10 @@ func (s VarAssignment) MarshalYAML() (interface{}, error) {
168203
}
169204

170205
func (s SetvarAction) MarshalYAML() (interface{}, error) {
171-
if s.Collection == UNKNOWN_COLLECTION || s.Operation == "" || len(s.Assignments) == 0 {
206+
if s.Collection == UNKNOWN_COLLECTION || s.Operation == UnknownOp || len(s.Assignments) == 0 {
172207
return nil, fmt.Errorf("invalid setvar action: missing collection name, operation, or assignments")
173208
}
174-
if s.Collection == TX && s.Operation == "=" {
209+
if s.Collection == TX && s.Operation == Assign {
175210
// Default case
176211
res := map[string][]VarAssignment{}
177212
res["setvar"] = s.Assignments
@@ -190,7 +225,7 @@ func (s SetvarAction) MarshalYAML() (interface{}, error) {
190225
Assignments []VarAssignment
191226
}{
192227
Collection: s.Collection,
193-
Operation: s.Operation,
228+
Operation: s.Operation.String(),
194229
Assignments: s.Assignments,
195230
}
196231
return res, nil
@@ -218,10 +253,13 @@ func NewActionWithParam[T ActionType](action T, param string) (ActionWithParam,
218253
}
219254

220255
// NewSetvarAction creates a new SetvarAction with the given collection name, operation, and variable assignments
221-
func NewSetvarAction(collection CollectionName, operation string, vars []VarAssignment) (SetvarAction, error) {
256+
func NewSetvarAction(collection CollectionName, operation VarOperation, vars []VarAssignment) (SetvarAction, error) {
222257
if collection != GLOBAL && collection != IP && collection != RESOURCE && collection != SESSION && collection != TX && collection != USER {
223258
return SetvarAction{}, fmt.Errorf("invalid setvar action: invalid collection name '%s'", collection)
224259
}
260+
if operation == UnknownOp {
261+
return SetvarAction{}, fmt.Errorf("invalid setvar action: invalid operation '%s'", operation)
262+
}
225263
return SetvarAction{Collection: collection, Operation: operation, Assignments: vars}, nil
226264
}
227265

@@ -529,12 +567,18 @@ func (s *SeclangActions) AddNonDisruptiveActionWithParam(action NonDisruptiveAct
529567
// AddSetvarAction adds a setvar action to the NonDisruptiveActions list
530568
func (s *SeclangActions) AddSetvarAction(collection, variable, operation, value string) error {
531569
colName := stringToCollectionName(strings.ToUpper(collection))
570+
571+
op := stringToVarOperation(operation)
572+
if op == UnknownOp {
573+
return fmt.Errorf("invalid setvar action: invalid operation '%s'", operation)
574+
}
575+
532576
// Check if there is already a setvar action in the last position
533577
if len(s.NonDisruptiveActions) > 0 {
534578
lastAction := s.NonDisruptiveActions[len(s.NonDisruptiveActions)-1]
535-
if lastAction.GetKey() != SetVar.String() || lastAction.(SetvarAction).Collection != colName || lastAction.(SetvarAction).Operation != operation {
579+
if lastAction.GetKey() != SetVar.String() || lastAction.(SetvarAction).Collection != colName || lastAction.(SetvarAction).Operation != op {
536580
// If the last action is not setvar, we need to create a new one
537-
newAction, err := NewSetvarAction(colName, operation, []VarAssignment{{Variable: variable, Value: value}})
581+
newAction, err := NewSetvarAction(colName, op, []VarAssignment{{Variable: variable, Value: value}})
538582
if err != nil {
539583
return err
540584
}
@@ -553,7 +597,7 @@ func (s *SeclangActions) AddSetvarAction(collection, variable, operation, value
553597
}
554598
} else {
555599
// If there are no actions yet, we need to create a new setvar action
556-
newAction, err := NewSetvarAction(colName, operation, []VarAssignment{{Variable: variable, Value: value}})
600+
newAction, err := NewSetvarAction(colName, op, []VarAssignment{{Variable: variable, Value: value}})
557601
if err != nil {
558602
return err
559603
}

types/actions_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func mustNewActionWithParam[T ActionType](action T, param string) Action {
2424
return newAction
2525
}
2626

27-
func mustNewSetvarAction(collection CollectionName, operation string, vars []VarAssignment) Action {
27+
func mustNewSetvarAction(collection CollectionName, operation VarOperation, vars []VarAssignment) Action {
2828
newAction, err := NewSetvarAction(collection, operation, vars)
2929
if err != nil {
3030
panic(err)
@@ -52,7 +52,7 @@ flow:
5252
NonDisruptiveActions: []Action{
5353
mustNewActionOnly(Capture),
5454
mustNewActionWithParam(LogData, "Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}"),
55-
mustNewSetvarAction(TX, "=", []VarAssignment{{Variable: "rfi_parameter_%{MATCHED_VAR_NAME}", Value: ".%{tx.1}"}}),
55+
mustNewSetvarAction(TX, Assign, []VarAssignment{{Variable: "rfi_parameter_%{MATCHED_VAR_NAME}", Value: ".%{tx.1}"}}),
5656
},
5757
FlowActions: []Action{
5858
mustNewActionOnly(Chain),
@@ -90,7 +90,7 @@ non-disruptive:
9090
DisruptiveAction: mustNewActionOnly(Pass),
9191
NonDisruptiveActions: []Action{
9292
mustNewActionOnly(NoLog),
93-
mustNewSetvarAction(TX, "=", []VarAssignment{
93+
mustNewSetvarAction(TX, Assign, []VarAssignment{
9494
{Variable: "blocking_inbound_anomaly_score", Value: "0"},
9595
{Variable: "detection_inbound_anomaly_score", Value: "0"},
9696
{Variable: "inbound_anomaly_score_pl1", Value: "0"},
@@ -130,7 +130,7 @@ non-disruptive:
130130
DisruptiveAction: mustNewActionOnly(Pass),
131131
NonDisruptiveActions: []Action{
132132
mustNewActionOnly(NoLog),
133-
mustNewSetvarAction(TX, "=+", []VarAssignment{{Variable: "paramcounter_%{MATCHED_VAR_NAME}", Value: "1"}}),
133+
mustNewSetvarAction(TX, Increment, []VarAssignment{{Variable: "paramcounter_%{MATCHED_VAR_NAME}", Value: "1"}}),
134134
},
135135
},
136136
},

types/condition_directives.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,11 @@ func (s *SeclangActions) UnmarshalYAML(value *yaml.Node) error {
240240
if cName == UNKNOWN_COLLECTION {
241241
return fmt.Errorf("Collection name %s is not valid", cName)
242242
}
243-
newAct, err := NewSetvarAction(cName, op.(string), parsedAssigns)
243+
vOp := stringToVarOperation(op.(string))
244+
if vOp == UnknownOp {
245+
return fmt.Errorf("invalid setvar action: invalid operation '%s'", op)
246+
}
247+
newAct, err := NewSetvarAction(cName, vOp, parsedAssigns)
244248
if err != nil {
245249
return err
246250
}
@@ -260,7 +264,7 @@ func (s *SeclangActions) UnmarshalYAML(value *yaml.Node) error {
260264
}
261265
}
262266
}
263-
newAct, err := NewSetvarAction(TX, "=", parsedAssigns)
267+
newAct, err := NewSetvarAction(TX, Assign, parsedAssigns)
264268
if err != nil {
265269
return err
266270
}

0 commit comments

Comments
 (0)