Back to Checks
azure

Function app has FTP and FTPS deployments disabled

app_function_ftps_deployment_disabled
Service: appSeverity: medium
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:microsoft.web/sites

Azure Function apps are evaluated for the ftps_state setting that controls FTP/FTPS deployment endpoints. Values AllAllowed or FtpsOnly indicate deployment over FTP/FTPS is enabled, while Disabled indicates both endpoints are turned off.

Risk

Enabled FTP/FTPS deployment undermines confidentiality and integrity. FTP exposes credentials in cleartext; FTPS still presents a public basic-auth endpoint susceptible to brute force and credential reuse. Compromise enables unauthorized code pushes, leading to RCE, data leakage, and service disruption.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks app_function_ftps_deployment_disabled

Recommendation

Disable FTP and FTPS deployment on Function apps (ftps_state: Disabled). Adopt defense in depth: deploy via CI/CD with packaged artifacts (zip or containers), enforce least privilege publishing access, and limit exposure of build and deployment endpoints. If unavoidable, use FTPS-only with TLS 1.2 and rotate credentials promptly.

Remediation

CLI

az webapp config set --resource-group <resource-group> --name <app-name> --ftps-state Disabled

Terraform

# Disable FTP and FTPS on a Function App
resource "azurerm_linux_function_app" "<example_resource_name>" {
  name                       = "<example_resource_name>"
  resource_group_name        = "<example_resource_name>"
  location                   = "<example_location>"
  service_plan_id            = "<example_resource_id>"
  storage_account_name       = "<example_resource_name>"
  storage_account_access_key = "<example_secret_value>"
  functions_extension_version = "~4"

  site_config {
    ftps_state = "Disabled" # CRITICAL: Disables both FTP and FTPS deployments
  }
}

NativeIaC

// Disable FTP and FTPS on an existing Function App
resource functionApp 'Microsoft.Web/sites@2022-09-01' existing = {
  name: '<example_resource_name>'
}

resource webConfig 'Microsoft.Web/sites/config@2022-09-01' = {
  name: 'web'
  parent: functionApp
  properties: {
    ftpsState: 'Disabled' // CRITICAL: Disables both FTP and FTPS deployments
  }
}

Other

1In the Azure portal, go to your Function App
2Select Configuration > General settings
3Under Platform settings, set FTP state to Disabled
4Click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.app.app_client import app_client


class app_function_ftps_deployment_disabled(Check):
    def execute(self) -> Check_Report_Azure:
        findings = []

        for (
            subscription_id,
            functions,
        ) in app_client.functions.items():
            subscription_name = app_client.subscriptions.get(
                subscription_id, subscription_id
            )
            for function in functions.values():
                report = Check_Report_Azure(metadata=self.metadata(), resource=function)
                report.subscription = subscription_id
                report.status = "FAIL"
                report.status_extended = f"Function {function.name} from subscription {subscription_name} ({subscription_id}) has {'FTP' if function.ftps_state == 'AllAllowed' else 'FTPS' if function.ftps_state == 'FtpsOnly' else 'FTP or FTPS'} deployment enabled."
                if function.ftps_state == "Disabled":
                    report.status = "PASS"
                    report.status_extended = f"Function {function.name} from subscription {subscription_name} ({subscription_id}) has FTP and FTPS deployment disabled."

                findings.append(report)

        return findings