mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
206 lines
7.5 KiB
Python
206 lines
7.5 KiB
Python
from unittest import mock
|
|
|
|
from prowler.providers.vercel.services.project.project_service import VercelProject
|
|
from prowler.providers.vercel.services.security.security_service import Security
|
|
from tests.providers.vercel.vercel_fixtures import PROJECT_ID, PROJECT_NAME, TEAM_ID
|
|
|
|
|
|
class TestSecurityService:
|
|
def test_fetch_firewall_config_reads_active_version_and_normalizes_response(self):
|
|
project = VercelProject(
|
|
id=PROJECT_ID,
|
|
name=PROJECT_NAME,
|
|
team_id=TEAM_ID,
|
|
billing_plan="pro",
|
|
)
|
|
service = Security.__new__(Security)
|
|
service.firewall_configs = {}
|
|
|
|
service._get = mock.MagicMock(
|
|
return_value={
|
|
"active": {
|
|
"firewallEnabled": True,
|
|
"managedRules": {
|
|
"owasp": {"active": True, "action": "deny"},
|
|
"ai_bots": {"active": False, "action": "deny"},
|
|
},
|
|
"rules": [
|
|
{
|
|
"id": "rule-custom",
|
|
"name": "Block admin access",
|
|
"active": True,
|
|
"conditionGroup": [
|
|
{
|
|
"conditions": [
|
|
{
|
|
"type": "path",
|
|
"op": "pre",
|
|
"value": "/admin",
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"action": {
|
|
"mitigate": {
|
|
"action": "deny",
|
|
}
|
|
},
|
|
},
|
|
{
|
|
"id": "rule-rate-limit",
|
|
"name": "Rate limit login",
|
|
"active": True,
|
|
"conditionGroup": [
|
|
{
|
|
"conditions": [
|
|
{
|
|
"type": "path",
|
|
"op": "eq",
|
|
"value": "/login",
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"action": {
|
|
"mitigate": {
|
|
"action": "deny",
|
|
"rateLimit": {
|
|
"algo": "fixed_window",
|
|
"window": 60,
|
|
"limit": 10,
|
|
},
|
|
}
|
|
},
|
|
},
|
|
],
|
|
"ips": [
|
|
{
|
|
"id": "ip-rule",
|
|
"ip": "203.0.113.7",
|
|
"action": "deny",
|
|
}
|
|
],
|
|
},
|
|
"draft": None,
|
|
"versions": [1],
|
|
}
|
|
)
|
|
|
|
service._fetch_firewall_config(project)
|
|
|
|
service._get.assert_called_once_with(
|
|
"/v1/security/firewall/config/active",
|
|
params={"projectId": PROJECT_ID, "teamId": TEAM_ID},
|
|
)
|
|
|
|
config = service.firewall_configs[PROJECT_ID]
|
|
assert config.billing_plan == "pro"
|
|
assert config.firewall_enabled is True
|
|
assert config.managed_rulesets == {"owasp": {"active": True, "action": "deny"}}
|
|
assert [rule["id"] for rule in config.custom_rules] == ["rule-custom"]
|
|
assert [rule["id"] for rule in config.rate_limiting_rules] == [
|
|
"rule-rate-limit"
|
|
]
|
|
assert [rule["id"] for rule in config.ip_blocking_rules] == ["ip-rule"]
|
|
|
|
def test_fetch_firewall_config_parses_crs_managed_rulesets(self):
|
|
project = VercelProject(
|
|
id=PROJECT_ID,
|
|
name=PROJECT_NAME,
|
|
team_id=TEAM_ID,
|
|
firewall_config_version="1",
|
|
)
|
|
service = Security.__new__(Security)
|
|
service.firewall_configs = {}
|
|
|
|
service._get = mock.MagicMock(
|
|
return_value={
|
|
"id": "waf_test",
|
|
"version": 1,
|
|
"firewallEnabled": True,
|
|
"crs": {
|
|
"gen": {"active": True, "action": "log"},
|
|
"xss": {"active": True, "action": "deny"},
|
|
"php": {"active": False, "action": "log"},
|
|
},
|
|
"rules": [],
|
|
"ips": [],
|
|
}
|
|
)
|
|
|
|
service._fetch_firewall_config(project)
|
|
|
|
config = service.firewall_configs[PROJECT_ID]
|
|
assert config.firewall_enabled is True
|
|
assert config.managed_rulesets == {
|
|
"gen": {"active": True, "action": "log"},
|
|
"xss": {"active": True, "action": "deny"},
|
|
}
|
|
|
|
def test_fetch_firewall_config_falls_back_to_wrapper_when_active_missing(self):
|
|
project = VercelProject(id=PROJECT_ID, name=PROJECT_NAME, team_id=TEAM_ID)
|
|
service = Security.__new__(Security)
|
|
service.firewall_configs = {}
|
|
|
|
service._get = mock.MagicMock(
|
|
side_effect=[
|
|
Exception("404 active config not found"),
|
|
{"active": None, "draft": None, "versions": []},
|
|
]
|
|
)
|
|
|
|
service._fetch_firewall_config(project)
|
|
|
|
assert service._get.call_args_list == [
|
|
mock.call(
|
|
"/v1/security/firewall/config/active",
|
|
params={"projectId": PROJECT_ID, "teamId": TEAM_ID},
|
|
),
|
|
mock.call(
|
|
"/v1/security/firewall/config",
|
|
params={"projectId": PROJECT_ID, "teamId": TEAM_ID},
|
|
),
|
|
]
|
|
|
|
config = service.firewall_configs[PROJECT_ID]
|
|
assert config.firewall_enabled is False
|
|
assert config.managed_rulesets == {}
|
|
assert config.custom_rules == []
|
|
assert config.rate_limiting_rules == []
|
|
assert config.ip_blocking_rules == []
|
|
|
|
def test_fetch_firewall_config_uses_project_security_metadata_when_config_empty(
|
|
self,
|
|
):
|
|
project = VercelProject(
|
|
id=PROJECT_ID,
|
|
name=PROJECT_NAME,
|
|
team_id=TEAM_ID,
|
|
firewall_enabled=True,
|
|
firewall_config_version="42",
|
|
managed_rules={
|
|
"owasp": {"active": True, "action": "log"},
|
|
"ai_bots": {"active": False, "action": "deny"},
|
|
},
|
|
)
|
|
service = Security.__new__(Security)
|
|
service.firewall_configs = {}
|
|
|
|
service._get = mock.MagicMock(
|
|
return_value={"active": None, "draft": None, "versions": []}
|
|
)
|
|
|
|
service._fetch_firewall_config(project)
|
|
|
|
service._get.assert_called_once_with(
|
|
"/v1/security/firewall/config/42",
|
|
params={"projectId": PROJECT_ID, "teamId": TEAM_ID},
|
|
)
|
|
|
|
config = service.firewall_configs[PROJECT_ID]
|
|
assert config.firewall_enabled is True
|
|
assert config.managed_rulesets == {"owasp": {"active": True, "action": "log"}}
|
|
assert config.custom_rules == []
|
|
assert config.rate_limiting_rules == []
|
|
assert config.ip_blocking_rules == []
|