mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-05-06 08:47:18 +00:00
fix(cloudflare): guard validate_credentials against paginator infinite loops (#10771)
This commit is contained in:
@@ -13,6 +13,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
- Cloudflare account-scoped API tokens failing connection test in the App with `CloudflareUserTokenRequiredError` [(#10723)](https://github.com/prowler-cloud/prowler/pull/10723)
|
||||
- `prowler image --registry` failing with `ImageNoImagesProvidedError` due to registry arguments not being forwarded to `ImageProvider` in `init_global_provider` [(#10470)](https://github.com/prowler-cloud/prowler/pull/10470)
|
||||
- Google Workspace Calendar checks false FAIL on unconfigured settings with secure Google defaults [(#10726)](https://github.com/prowler-cloud/prowler/pull/10726)
|
||||
- Cloudflare `validate_credentials` can hang in an infinite pagination loop when the SDK repeats accounts, blocking connection tests [(#10771)](https://github.com/prowler-cloud/prowler/pull/10771)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -274,8 +274,12 @@ class CloudflareProvider(Provider):
|
||||
|
||||
for account in client.accounts.list():
|
||||
account_id = getattr(account, "id", None)
|
||||
# Prevent infinite loop - skip if we've seen this account
|
||||
# Prevent infinite loop on repeated pages from the SDK paginator
|
||||
if account_id in seen_account_ids:
|
||||
logger.warning(
|
||||
"Detected repeated Cloudflare account ID while listing accounts. "
|
||||
"Stopping pagination to avoid an infinite loop."
|
||||
)
|
||||
break
|
||||
seen_account_ids.add(account_id)
|
||||
|
||||
@@ -395,7 +399,20 @@ class CloudflareProvider(Provider):
|
||||
|
||||
# Fallback: try accounts.list()
|
||||
try:
|
||||
accounts = list(client.accounts.list())
|
||||
accounts: list = []
|
||||
seen_account_ids: set = set()
|
||||
for account in client.accounts.list():
|
||||
account_id = getattr(account, "id", None)
|
||||
# Prevent infinite loop on repeated pages from the SDK paginator
|
||||
if account_id in seen_account_ids:
|
||||
logger.warning(
|
||||
"Detected repeated Cloudflare account ID while validating credentials. "
|
||||
"Stopping pagination to avoid an infinite loop."
|
||||
)
|
||||
break
|
||||
seen_account_ids.add(account_id)
|
||||
accounts.append(account)
|
||||
|
||||
if not accounts:
|
||||
logger.error("CloudflareNoAccountsError: No accounts found")
|
||||
raise CloudflareNoAccountsError(
|
||||
|
||||
@@ -433,6 +433,29 @@ class TestCloudflareValidateCredentials:
|
||||
with pytest.raises(CloudflareNoAccountsError):
|
||||
CloudflareProvider.validate_credentials(session)
|
||||
|
||||
def test_validate_credentials_breaks_on_repeated_account_ids(self):
|
||||
"""Pagination must stop when the SDK repeats account IDs to avoid infinite loops."""
|
||||
|
||||
def repeating_accounts():
|
||||
account = MagicMock()
|
||||
account.id = ACCOUNT_ID
|
||||
while True:
|
||||
yield account
|
||||
|
||||
mock_client = MagicMock()
|
||||
mock_client.user.get.side_effect = Exception("Some other error")
|
||||
mock_client.accounts.list.return_value = repeating_accounts()
|
||||
|
||||
session = CloudflareSession(
|
||||
client=mock_client,
|
||||
api_token=API_TOKEN,
|
||||
api_key=None,
|
||||
api_email=None,
|
||||
)
|
||||
|
||||
# Must return without hanging; repeated IDs break the loop.
|
||||
CloudflareProvider.validate_credentials(session)
|
||||
|
||||
|
||||
class TestCloudflareTestConnection:
|
||||
"""Tests for test_connection method."""
|
||||
|
||||
Reference in New Issue
Block a user