Skip to content

Conversation

@fzipi
Copy link
Member

@fzipi fzipi commented Feb 18, 2025

what

  • create a common core to easily add and test new checks
  • split checks from the main cli to individual files with common parameters
  • create helper classes to make things more pythonic
  • add documentation on how to add additional tests

why

  • create a standard format to make easier to add more checks
  • improve testability

@airween airween mentioned this pull request Feb 18, 2025
4 tasks
fzipi added 2 commits October 7, 2025 10:57
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
@fzipi fzipi force-pushed the refactor/split-linting-rules branch from 6919dc7 to c5b7eca Compare October 7, 2025 19:50
fzipi added 17 commits October 7, 2025 18:57
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
Signed-off-by: Felipe Zipitria <felipe.zipitria@owasp.org>
@fzipi fzipi changed the title chore: split checks into rules refactor: split checks into individual rules Oct 13, 2025
@fzipi fzipi added the refactor label Oct 13, 2025
@fzipi fzipi marked this pull request as ready for review October 13, 2025 00:35
@fzipi fzipi requested review from airween and theseion October 13, 2025 00:36
@fzipi
Copy link
Member Author

fzipi commented Oct 13, 2025

Finally got the time (and will) to finish this refactor.

Copy link
Contributor

@airween airween left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After my first review I have some comments.

if tags is None:
return

chained = False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chained is not used here. In the current code it used to get the rule ID, but you don't use that (eg. in message), so you should remove this, or use the rule ID in message, for eg.

from crs_linter.rule import Rule


class CrsTag(Rule):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the meantime, an addition was made to the original code: we have added a new function to check whether the rule has a tag for its filename. I think we need this here too. For details please check #27

"""check there is no ctl:auditLogParts action in any rules"""
for d in data:
if "actions" in d:
current_ruleid = 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you don't use the rule ID either so you should remove this line and below the block (or add rule ID to the message, for eg.).

from crs_linter.rule import Rule


class Deprecated(Rule):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this class have the same functionality like ctl_audit_log above? Why are both necessary?

if "actions" in d:
max_order = 0 # maximum position of read actions
if not chained:
current_rule_id = get_id(d["actions"])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you don't use variable current_rule_id, you should remove it or add it to message.

if a["act_name"] == "tag":
tags.append(a)
if a["act_name"] == "setvar":
if a["act_arg"][0:2].lower() == "tx":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In current (old) implementation I explained here why is this hack needs. I think that would be useful here too. (This is the parser's deficiency.)

for d in data:
# only SecRule counts
if d['type'] == "SecRule":
for a in d['actions']:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you don't need to iterate through all actions, just use your implemented get_id(). I think that would make the code a bit more clear. (But you will need the id in two formats: int and string)


val_act = []
val_act_arg = []
if "act_arg" in a and a["act_arg"] is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the explanation from current code would be useful here.

for v in d["variables"]:
if v["variable"].lower() == "tx":
if not v["counter"]:
rvar = v["variable_part"].lower()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here too from here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants