feat(azure-app): extract Web App resource metadata in automated way (#6529)

This commit is contained in:
Rubén De la Torre Vico
2025-01-15 14:48:36 +01:00
committed by GitHub
parent fdac58d031
commit 0db46cdc81
41 changed files with 249 additions and 194 deletions
+4 -2
View File
@@ -669,8 +669,9 @@ class Test_app_ensure_http_is_redirected_to_https:
# Create the custom App object to be tested
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(),
client_cert_mode="Ignore",
@@ -716,8 +717,9 @@ class Test_app_ensure_http_is_redirected_to_https:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(),
client_cert_mode="Ignore",
@@ -10,18 +10,17 @@ class app_client_certificates_on(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
report = Check_Report_Azure(self.metadata())
report.status = "PASS"
for app in apps.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status_extended = f"Clients are required to present a certificate for app '{app_name}' in subscription '{subscription_name}'."
report.status = "PASS"
report.status_extended = f"Clients are required to present a certificate for app '{app.name}' in subscription '{subscription_name}'."
if app.client_cert_mode != "Required":
report.status = "FAIL"
report.status_extended = f"Clients are not required to present a certificate for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"Clients are not required to present a certificate for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,18 +10,17 @@ class app_ensure_auth_is_set_up(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
report = Check_Report_Azure(self.metadata())
report.status = "PASS"
for app in apps.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status_extended = f"Authentication is set up for app '{app_name}' in subscription '{subscription_name}'."
report.status = "PASS"
report.status_extended = f"Authentication is set up for app '{app.name}' in subscription '{subscription_name}'."
if not app.auth_enabled:
report.status = "FAIL"
report.status_extended = f"Authentication is not set up for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"Authentication is not set up for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,18 +10,17 @@ class app_ensure_http_is_redirected_to_https(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
report = Check_Report_Azure(self.metadata())
report.status = "PASS"
for app in apps.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status_extended = f"HTTP is redirected to HTTPS for app '{app_name}' in subscription '{subscription_name}'."
report.status = "PASS"
report.status_extended = f"HTTP is redirected to HTTPS for app '{app.name}' in subscription '{subscription_name}'."
if not app.https_only:
report.status = "FAIL"
report.status_extended = f"HTTP is not redirected to HTTPS for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"HTTP is not redirected to HTTPS for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,30 +10,29 @@ class app_ensure_java_version_is_latest(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
for app in apps.values():
linux_framework = getattr(app.configurations, "linux_fx_version", "")
windows_framework_version = getattr(
app.configurations, "java_version", None
)
if "java" in linux_framework.lower() or windows_framework_version:
report = Check_Report_Azure(self.metadata())
report.status = "FAIL"
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status = "FAIL"
java_latest_version = app_client.audit_config.get(
"java_latest_version", "17"
)
report.status_extended = f"Java version is set to '{f'java{windows_framework_version}' if windows_framework_version else linux_framework}', but should be set to 'java {java_latest_version}' for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"Java version is set to '{f'java{windows_framework_version}' if windows_framework_version else linux_framework}', but should be set to 'java {java_latest_version}' for app '{app.name}' in subscription '{subscription_name}'."
if (
f"java{java_latest_version}" in linux_framework
or java_latest_version == windows_framework_version
):
report.status = "PASS"
report.status_extended = f"Java version is set to 'java {java_latest_version}' for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"Java version is set to 'java {java_latest_version}' for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,24 +10,23 @@ class app_ensure_php_version_is_latest(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
for app in apps.values():
framework = getattr(app.configurations, "linux_fx_version", "")
if "php" in framework.lower() or getattr(
app.configurations, "php_version", ""
):
report = Check_Report_Azure(self.metadata())
report.status = "FAIL"
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status = "FAIL"
php_latest_version = app_client.audit_config.get(
"php_latest_version", "8.2"
)
report.status_extended = f"PHP version is set to '{framework}', the latest version that you could use is the '{php_latest_version}' version, for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"PHP version is set to '{framework}', the latest version that you could use is the '{php_latest_version}' version, for app '{app.name}' in subscription '{subscription_name}'."
if (
php_latest_version in framework
@@ -35,7 +34,7 @@ class app_ensure_php_version_is_latest(Check):
== php_latest_version
):
report.status = "PASS"
report.status_extended = f"PHP version is set to '{php_latest_version}' for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"PHP version is set to '{php_latest_version}' for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,22 +10,21 @@ class app_ensure_python_version_is_latest(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
for app in apps.values():
framework = getattr(app.configurations, "linux_fx_version", "")
if "python" in framework.lower() or getattr(
app.configurations, "python_version", ""
):
report = Check_Report_Azure(self.metadata())
report.status = "FAIL"
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status = "FAIL"
python_latest_version = app_client.audit_config.get(
"python_latest_version", "3.12"
)
report.status_extended = f"Python version is '{framework}', the latest version that you could use is the '{python_latest_version}' version, for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"Python version is '{framework}', the latest version that you could use is the '{python_latest_version}' version, for app '{app.name}' in subscription '{subscription_name}'."
if (
python_latest_version in framework
@@ -33,7 +32,7 @@ class app_ensure_python_version_is_latest(Check):
== python_latest_version
):
report.status = "PASS"
report.status_extended = f"Python version is set to '{python_latest_version}' for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"Python version is set to '{python_latest_version}' for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,20 +10,19 @@ class app_ensure_using_http20(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
report = Check_Report_Azure(self.metadata())
report.status = "FAIL"
for app in apps.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status_extended = f"HTTP/2.0 is not enabled for app '{app_name}' in subscription '{subscription_name}'."
report.status = "FAIL"
report.status_extended = f"HTTP/2.0 is not enabled for app '{app.name}' in subscription '{subscription_name}'."
if app.configurations and getattr(
app.configurations, "http20_enabled", False
):
report.status = "PASS"
report.status_extended = f"HTTP/2.0 is enabled for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"HTTP/2.0 is enabled for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,22 +10,20 @@ class app_ftp_deployment_disabled(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
report = Check_Report_Azure(self.metadata())
report.status = "FAIL"
for app in apps.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status_extended = f"FTP is enabled for app '{app_name}' in subscription '{subscription_name}'."
report.status = "FAIL"
report.status_extended = f"FTP is enabled for app '{app.name}' in subscription '{subscription_name}'."
if (
app.configurations
and getattr(app.configurations, "ftps_state", "AllAllowed")
!= "AllAllowed"
):
report.status = "PASS"
report.status_extended = f"FTP is disabled for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"FTP is disabled for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,16 +10,15 @@ class app_function_access_keys_configured(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
report = Check_Report_Azure(self.metadata())
for function in functions.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "FAIL"
report.status_extended = (
f"Function {function.name} does not have function keys configured."
)
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
if len(function.function_keys) > 0:
report.status = "PASS"
@@ -13,16 +13,15 @@ class app_function_application_insights_enabled(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
report = Check_Report_Azure(self.metadata())
for function in functions.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "FAIL"
report.status_extended = (
f"Function {function.name} is not using Application Insights."
)
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
if function.enviroment_variables.get(
"APPINSIGHTS_INSTRUMENTATIONKEY", ""
@@ -10,15 +10,13 @@ class app_function_ftps_deployment_disabled(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
report = Check_Report_Azure(self.metadata())
for function in functions.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "FAIL"
report.status_extended = f"Function {function.name} has {'FTP' if function.ftps_state == 'AllAllowed' else 'FTPS' if function.ftps_state == 'FtpsOnly' else 'FTP or FTPS'} deployment enabled"
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
if function.ftps_state == "Disabled":
report.status = "PASS"
report.status_extended = (
@@ -10,14 +10,13 @@ class app_function_identity_is_configured(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
report = Check_Report_Azure(self.metadata())
for function in functions.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "FAIL"
report.status_extended = f"Function {function.name} does not have a managed identity enabled."
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
if function.identity:
report.status = "PASS"
@@ -17,15 +17,14 @@ class app_function_identity_without_admin_privileges(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
for function in functions.values():
if function.identity:
report = Check_Report_Azure(self.metadata())
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "PASS"
report.status_extended = f"Function {function.name} has a managed identity enabled but without admin privileges."
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
admin_roles_assigned = []
@@ -10,16 +10,15 @@ class app_function_latest_runtime_version(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
report = Check_Report_Azure(self.metadata())
for function in functions.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "PASS"
report.status_extended = (
f"Function {function.name} is using the latest runtime."
)
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
if (
function.enviroment_variables.get("FUNCTIONS_EXTENSION_VERSION", "")
@@ -10,16 +10,15 @@ class app_function_not_publicly_accessible(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
report = Check_Report_Azure(self.metadata())
for function in functions.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "FAIL"
report.status_extended = (
f"Function {function.name} is publicly accessible."
)
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
if not function.public_access:
report.status = "PASS"
@@ -10,14 +10,13 @@ class app_function_vnet_integration_enabled(Check):
subscription_name,
functions,
) in app_client.functions.items():
for function_id, function in functions.items():
report = Check_Report_Azure(self.metadata())
for function in functions.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=function
)
report.subscription = subscription_name
report.status = "FAIL"
report.status_extended = f"Function {function.name} does not have virtual network integration enabled."
report.subscription = subscription_name
report.resource_name = function.name
report.resource_id = function_id
report.location = function.location
if function.vnet_subnet_id:
report.status = "PASS"
@@ -7,22 +7,22 @@ class app_http_logs_enabled(Check):
findings = []
for subscription_name, apps in app_client.apps.items():
for app_name, app in apps.items():
for app in apps.values():
if "functionapp" not in app.kind:
report = Check_Report_Azure(self.metadata())
report.status = "FAIL"
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.status = "FAIL"
if not app.monitor_diagnostic_settings:
report.status_extended = f"App {app_name} does not have a diagnostic setting in subscription {subscription_name}."
report.status_extended = f"App {app.name} does not have a diagnostic setting in subscription {subscription_name}."
else:
for diagnostic_setting in app.monitor_diagnostic_settings:
report.status_extended = f"App {app_name} does not have HTTP Logs enabled in diagnostic setting {diagnostic_setting.name} in subscription {subscription_name}"
report.status_extended = f"App {app.name} does not have HTTP Logs enabled in diagnostic setting {diagnostic_setting.name} in subscription {subscription_name}"
for log in diagnostic_setting.logs:
if log.category == "AppServiceHTTPLogs" and log.enabled:
report.status = "PASS"
report.status_extended = f"App {app_name} has HTTP Logs enabled in diagnostic setting {diagnostic_setting.name} in subscription {subscription_name}"
report.status_extended = f"App {app.name} has HTTP Logs enabled in diagnostic setting {diagnostic_setting.name} in subscription {subscription_name}"
break
findings.append(report)
@@ -10,20 +10,19 @@ class app_minimum_tls_version_12(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
report = Check_Report_Azure(self.metadata())
report.status = "FAIL"
for app in apps.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status_extended = f"Minimum TLS version is not set to 1.2 for app '{app_name}' in subscription '{subscription_name}'."
report.status = "FAIL"
report.status_extended = f"Minimum TLS version is not set to 1.2 for app '{app.name}' in subscription '{subscription_name}'."
if app.configurations and getattr(
app.configurations, "min_tls_version", ""
) in ["1.2", "1.3"]:
report.status = "PASS"
report.status_extended = f"Minimum TLS version is set to {app.configurations.min_tls_version} for app '{app_name}' in subscription '{subscription_name}'."
report.status_extended = f"Minimum TLS version is set to {app.configurations.min_tls_version} for app '{app.name}' in subscription '{subscription_name}'."
findings.append(report)
@@ -10,18 +10,17 @@ class app_register_with_identity(Check):
subscription_name,
apps,
) in app_client.apps.items():
for app_name, app in apps.items():
report = Check_Report_Azure(self.metadata())
report.status = "PASS"
for app in apps.values():
report = Check_Report_Azure(
metadata=self.metadata(), resource_metadata=app
)
report.subscription = subscription_name
report.resource_name = app_name
report.resource_id = app.resource_id
report.location = app.location
report.status_extended = f"App '{app_name}' in subscription '{subscription_name}' has an identity configured."
report.status = "PASS"
report.status_extended = f"App '{app.name}' in subscription '{subscription_name}' has an identity configured."
if not app.identity:
report.status = "FAIL"
report.status_extended = f"App '{app_name}' in subscription '{subscription_name}' does not have an identity configured."
report.status_extended = f"App '{app.name}' in subscription '{subscription_name}' does not have an identity configured."
findings.append(report)
@@ -39,8 +39,9 @@ class App(AzureService):
apps[subscription_name].update(
{
app.name: WebApp(
app.id: WebApp(
resource_id=app.id,
name=app.name,
auth_enabled=(
getattr(platform_auth, "enabled", False)
if platform_auth
@@ -97,6 +98,7 @@ class App(AzureService):
functions[subscription_name].update(
{
function.id: FunctionApp(
id=function.id,
name=function.name,
location=function.location,
kind=function.kind,
@@ -172,6 +174,7 @@ class App(AzureService):
@dataclass
class WebApp:
resource_id: str
name: str
configurations: SiteConfigResource
identity: ManagedServiceIdentity
location: str
@@ -184,6 +187,7 @@ class WebApp:
@dataclass
class FunctionApp:
id: str
name: str
location: str
kind: str
@@ -64,8 +64,9 @@ class Test_app_client_certificates_on:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Required",
@@ -106,8 +107,9 @@ class Test_app_client_certificates_on:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -64,8 +64,9 @@ class Test_app_ensure_auth_is_set_up:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(),
client_cert_mode="Ignore",
@@ -106,8 +107,9 @@ class Test_app_ensure_auth_is_set_up:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=False,
configurations=mock.MagicMock(),
client_cert_mode="Ignore",
@@ -64,8 +64,9 @@ class Test_app_ensure_http_is_redirected_to_https:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(),
client_cert_mode="Ignore",
@@ -106,8 +107,9 @@ class Test_app_ensure_http_is_redirected_to_https:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(),
client_cert_mode="Ignore",
@@ -64,8 +64,9 @@ class Test_app_ensure_java_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -99,8 +100,9 @@ class Test_app_ensure_java_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(
linux_fx_version="Tomcat|9.0-java17", java_version=None
@@ -145,8 +147,9 @@ class Test_app_ensure_java_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(
linux_fx_version="Tomcat|9.0-java11", java_version=None
@@ -191,8 +194,9 @@ class Test_app_ensure_java_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(
linux_fx_version="", java_version="17"
@@ -236,8 +240,9 @@ class Test_app_ensure_java_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(
linux_fx_version="", java_version="11"
@@ -282,8 +287,9 @@ class Test_app_ensure_java_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(
linux_fx_version="php|8.0", java_version=None
@@ -64,8 +64,9 @@ class Test_app_ensure_php_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -99,8 +100,9 @@ class Test_app_ensure_php_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(linux_fx_version="php|8.0"),
client_cert_mode="Ignore",
@@ -143,8 +145,9 @@ class Test_app_ensure_php_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(linux_fx_version="php|8.2"),
client_cert_mode="Ignore",
@@ -63,8 +63,9 @@ class Test_app_ensure_python_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -98,8 +99,9 @@ class Test_app_ensure_python_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(linux_fx_version="python|3.12"),
client_cert_mode="Ignore",
@@ -142,8 +144,9 @@ class Test_app_ensure_python_version_is_latest:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(linux_fx_version="python|3.10"),
client_cert_mode="Ignore",
@@ -64,8 +64,9 @@ class Test_app_ensure_using_http20:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -106,8 +107,9 @@ class Test_app_ensure_using_http20:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(http20_enabled=True),
client_cert_mode="Ignore",
@@ -148,8 +150,9 @@ class Test_app_ensure_using_http20:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(http20_enabled=False),
client_cert_mode="Ignore",
@@ -64,8 +64,9 @@ class Test_app_ftp_deployment_disabled:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -106,8 +107,9 @@ class Test_app_ftp_deployment_disabled:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(ftps_state="AllAllowed"),
client_cert_mode="Ignore",
@@ -148,8 +150,9 @@ class Test_app_ftp_deployment_disabled:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(ftps_state="Disabled"),
client_cert_mode="Ignore",
@@ -68,6 +68,7 @@ class Test_app_function_access_keys_configured:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -116,6 +117,7 @@ class Test_app_function_access_keys_configured:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -75,6 +75,7 @@ class Test_app_function_application_insights_enabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -139,6 +140,7 @@ class Test_app_function_application_insights_enabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -203,6 +205,7 @@ class Test_app_function_application_insights_enabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -267,6 +270,7 @@ class Test_app_function_application_insights_enabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -68,6 +68,7 @@ class Test_app_function_ftps_deployment_disabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -114,6 +115,7 @@ class Test_app_function_ftps_deployment_disabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -160,6 +162,7 @@ class Test_app_function_ftps_deployment_disabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -68,6 +68,7 @@ class Test_app_function_identity_is_configured:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -114,6 +115,7 @@ class Test_app_function_identity_is_configured:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -69,6 +69,7 @@ class Test_app_function_identity_without_admin_privileges:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -114,6 +115,7 @@ class Test_app_function_identity_without_admin_privileges:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -190,6 +192,7 @@ class Test_app_function_identity_without_admin_privileges:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -68,6 +68,7 @@ class Test_app_function_latest_runtime_version:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -113,6 +114,7 @@ class Test_app_function_latest_runtime_version:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -68,6 +68,7 @@ class Test_app_function_not_publicly_accessible:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -114,6 +115,7 @@ class Test_app_function_not_publicly_accessible:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -68,6 +68,7 @@ class Test_app_function_vnet_integration_enabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -113,6 +114,7 @@ class Test_app_function_vnet_integration_enabled:
app_client.functions = {
AZURE_SUBSCRIPTION_ID: {
function_id: FunctionApp(
id=function_id,
name="function1",
location="West Europe",
kind="functionapp,linux",
@@ -63,8 +63,9 @@ class Test_app_http_logs_enabled:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app1": WebApp(
"resource_id": WebApp(
resource_id="resource_id",
name="app1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -107,8 +108,9 @@ class Test_app_http_logs_enabled:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
"resource_id1": WebApp(
resource_id="resource_id1",
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -151,8 +153,9 @@ class Test_app_http_logs_enabled:
),
],
),
"app_id-2": WebApp(
"resource_id2": WebApp(
resource_id="resource_id2",
name="app_id-2",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -64,8 +64,9 @@ class Test_app_minimum_tls_version_12:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -106,8 +107,9 @@ class Test_app_minimum_tls_version_12:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=mock.MagicMock(min_tls_version="1.2"),
client_cert_mode="Ignore",
@@ -148,8 +150,9 @@ class Test_app_minimum_tls_version_12:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=False,
configurations=mock.MagicMock(min_tls_version="1.0"),
client_cert_mode="Ignore",
@@ -190,8 +193,9 @@ class Test_app_minimum_tls_version_12:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=False,
configurations=mock.MagicMock(min_tls_version="1.3"),
client_cert_mode="Ignore",
@@ -64,8 +64,9 @@ class Test_app_register_with_identity:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -106,8 +107,9 @@ class Test_app_register_with_identity:
app_client.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
resource_id: WebApp(
resource_id=resource_id,
name="app_id-1",
auth_enabled=True,
configurations=None,
client_cert_mode="Ignore",
@@ -12,7 +12,7 @@ from tests.providers.azure.azure_fixtures import (
# def mock_app_get_apps(_):
# return {
# AZURE_SUBSCRIPTION_ID: {
# "app_id-1": WebApp(
# "/subscriptions/resource_id": WebApp(
# resource_id="/subscriptions/resource_id",
# configurations=SiteConfigResource(),
# identity=ManagedServiceIdentity(type="SystemAssigned"),
@@ -64,12 +64,15 @@ from tests.providers.azure.azure_fixtures import (
# )
class Test_App_Service:
def test_app_service_(self):
with patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
), patch(
"prowler.providers.azure.services.monitor.monitor_service.Monitor",
new=MagicMock(),
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_azure_provider(),
),
patch(
"prowler.providers.azure.services.monitor.monitor_service.Monitor",
new=MagicMock(),
),
):
from prowler.providers.azure.services.app.app_service import WebApp
from prowler.providers.azure.services.monitor.monitor_service import (
@@ -79,8 +82,9 @@ class Test_App_Service:
app_service = MagicMock()
app_service.apps = {
AZURE_SUBSCRIPTION_ID: {
"app_id-1": WebApp(
"/subscriptions/resource_id": WebApp(
resource_id="/subscriptions/resource_id",
name="app_id-1",
configurations=SiteConfigResource(),
identity=ManagedServiceIdentity(type="SystemAssigned"),
auth_enabled=True,
@@ -130,56 +134,68 @@ class Test_App_Service:
# )
assert len(app_service.apps) == 1
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"].resource_id
app_service.apps[AZURE_SUBSCRIPTION_ID][
"/subscriptions/resource_id"
].resource_id
== "/subscriptions/resource_id"
)
assert app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"].auth_enabled
assert app_service.apps[AZURE_SUBSCRIPTION_ID][
"/subscriptions/resource_id"
].auth_enabled
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"].client_cert_mode
app_service.apps[AZURE_SUBSCRIPTION_ID][
"/subscriptions/resource_id"
].client_cert_mode
== "Required"
)
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"].location
app_service.apps[AZURE_SUBSCRIPTION_ID][
"/subscriptions/resource_id"
].location
== "West Europe"
)
assert app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"].https_only
assert app_service.apps[AZURE_SUBSCRIPTION_ID][
"/subscriptions/resource_id"
].https_only
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"].identity.type
app_service.apps[AZURE_SUBSCRIPTION_ID][
"/subscriptions/resource_id"
].identity.type
== "SystemAssigned"
)
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID][
"app_id-1"
"/subscriptions/resource_id"
].configurations.__class__.__name__
== "SiteConfigResource"
)
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"]
app_service.apps[AZURE_SUBSCRIPTION_ID]["/subscriptions/resource_id"]
.monitor_diagnostic_settings[0]
.id
== "id2/id2"
)
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"]
app_service.apps[AZURE_SUBSCRIPTION_ID]["/subscriptions/resource_id"]
.monitor_diagnostic_settings[0]
.logs[0]
.category
== "AppServiceHTTPLogs"
)
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"]
app_service.apps[AZURE_SUBSCRIPTION_ID]["/subscriptions/resource_id"]
.monitor_diagnostic_settings[0]
.storage_account_name
== "storage_account_name2"
)
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"]
app_service.apps[AZURE_SUBSCRIPTION_ID]["/subscriptions/resource_id"]
.monitor_diagnostic_settings[0]
.storage_account_id
== "storage_account_id2"
)
assert (
app_service.apps[AZURE_SUBSCRIPTION_ID]["app_id-1"]
app_service.apps[AZURE_SUBSCRIPTION_ID]["/subscriptions/resource_id"]
.monitor_diagnostic_settings[0]
.name
== "name_diagnostic_setting2"