Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support replacer job #273

Merged
merged 3 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions config/config-template-zap-long.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,19 @@ scanners:
# Use https://www.zaproxy.org/docs/alerts/ to match rule with its ID
disabledRules: "2,10015,10024,10027,10054,10096,10109,10112"

#replacer: # replacer replaces strings in requests and responses during active scan
# parameters:
# deleteAllRules: True # Boolean, if true then will delete all existing replacer rules, default false
# rules: # list of rules
# - description: # String, the name of the rule
# url: # String, a regex which will be used to match URLs, if empty then it will match all
# matchType: # String, one of req_header, req_header_str, req_body_str, resp_header, resp_header_str, resp_body_str
# matchString: # String, will be used to identify what should be replaced
# matchRegex: # Boolean, if set then the matchString will be treated as a regex, default false
# replacementString: # String, the new string that will replace the specified selection
# tokenProcessing: # Boolean, when enabled the replacementString may contain a single token
# initiators: # A list of integers representing the initiators (see the help)

activeScan:
# The list of parameters: https://www.zaproxy.org/docs/desktop/addons/ajax-spider/automation/
#maxRuleDurationInMins: max scan time for each Rule (default: unlimited)
Expand Down
24 changes: 24 additions & 0 deletions scanners/zap/zap.py
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ def _setup_zap_automation(self):
self._setup_api()
self._setup_graphql()
self._setup_import_urls()
self._setup_replacer()
self._setup_active_scan()
self._setup_passive_wait()
self._setup_report()
Expand Down Expand Up @@ -618,6 +619,29 @@ def _setup_passive_wait(self):
}
self.automation_config["jobs"].append(waitfor)

def _setup_replacer(self):
"""Adds the replacer to the job list"""

if self.my_conf("replacer", default=False) is False:
jeremychoi marked this conversation as resolved.
Show resolved Hide resolved
return

rules = self.my_conf("replacer.rules")
if rules:
if not isinstance(rules, list):
raise ValueError("replacer.rules must be a list")

# replacer schema
replacer = {
"name": "replacer",
"type": "replacer",
"parameters": {
"deleteAllRules": self.my_conf("replacer.parameters.deleteAllRules", default=True),
},
"rules": rules,
}

self.automation_config["jobs"].append(replacer)

def _setup_active_scan(self):
"""Adds an active scan job list, if there is one"""

Expand Down
45 changes: 45 additions & 0 deletions tests/scanners/zap/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,51 @@ def test_setup_include_urls(test_config):
assert "def" in find_context(test_zap.automation_config)["includePaths"]


def test_setup_replacer(test_config):
# test if deleteAllRules is set to True by default when it is not set
test_zap = ZapNone(config=test_config)
test_zap.setup()

for item in test_zap.automation_config["jobs"]:
if item["type"] == "replacer":
jeremychoi marked this conversation as resolved.
Show resolved Hide resolved
assert item["parameters"]["deleteAllRules"] is True

# test deleteAllRules option False
test_config.set("scanners.zap.replacer.parameters.deleteAllRules", False)
test_zap = ZapNone(config=test_config)
test_zap.setup()

for item in test_zap.automation_config["jobs"]:
if item["type"] == "replacer":
assert item["parameters"]["deleteAllRules"] is False

# test rules
test_rule1 = {
"description": "test_rule1", # String, the name of the rule
"url": ".*", # String, a regex which will be used to match URLs, if empty then it will match all
"matchType": "req_body_str", # String, one of req_header, req_header_str, req_body_str, resp_header, resp_header_str, resp_body_str
"matchString": "John Doe,", # String, will be used to identify what should be replaced
"matchRegex": "false", # Boolean, if set then the matchString will be treated as a regex, default false
jeremychoi marked this conversation as resolved.
Show resolved Hide resolved
"replacementString": "JeremyC",
}
test_rule2 = {
"description": "test_rule2", # String, the name of the rule
"matchType": "req_header", # String, one of req_header, req_header_str, req_body_str, resp_header, resp_header_str, resp_body_str
"matchString": "Cookie", # String, will be used to identify what should be replaced
"matchRegex": "false", # Boolean, if set then the matchString will be treated as a regex, default false
"replacementString": "session=abc123",
}

test_config.set("scanners.zap.replacer.rules", [test_rule1, test_rule2])
test_zap = ZapNone(config=test_config)
test_zap.setup()

for item in test_zap.automation_config["jobs"]:
if item["type"] == "replacer":
assert item["rules"][0] is test_rule1
assert item["rules"][1] is test_rule2


@patch("scanners.zap.zap.validate_active_scan_policy")
def test_setup_active_scan(mock_validate_active_scan_policy, test_config):
test_config.set("scanners.zap.activeScan.maxRuleDurationInMins", 10)
Expand Down
Loading