Azure misconfigurations are not exotic. They're the same handful of mistakes, repeated across thousands of tenants, that turn into incidents because no one ever ran a third-party check. Here are the five we surface in nearly every Red Shield assessment — and exactly how to fix them.
1. Storage accounts with public blob access
The default for blob containers is "private" but the historical default was "public," and storage accounts created years ago often retain it. Combine that with a forgotten container name in source control and you have an open S3-style bucket waiting to be indexed.
Fix: set allowBlobPublicAccess to false at the storage account level. Apply Azure Policy to enforce it tenant-wide. Audit existing containers with az storage container list --query "[?properties.publicAccess!='None']".
2. NSGs allowing 0.0.0.0/0 on management ports
RDP (3389), SSH (22), WinRM (5985), and database ports (1433, 3306, 5432) exposed to the world. Almost always inherited from a "we'll lock this down later" decision that never happened.
Fix: Just-In-Time (JIT) VM access via Microsoft Defender for Cloud, or — better — Azure Bastion for management. Add an NSG rule explicitly denying these ports from the internet. Audit weekly.
3. Service principals with overly broad roles
Application service principals with Contributor or Owner at the subscription scope. Often created during a CI/CD setup, never scoped down. One stolen client secret = full subscription compromise.
Fix: apply least privilege at the resource group or resource scope. Use Workload Identity Federation instead of long-lived secrets. Rotate any client secret older than 90 days. Audit with az role assignment list --all --query "[?principalType=='ServicePrincipal']".
4. Conditional Access gaps for legacy auth
Legacy authentication protocols (POP3, IMAP, SMTP-Auth, MAPI) bypass MFA entirely. Every tenant should have these blocked, but we still find them open in around half of assessments.
Fix: create a Conditional Access policy blocking legacy authentication for all users. Microsoft has been deprecating these protocols, but you should not wait for that timeline. Verify with sign-in logs filtered to ClientAppUsed in (Other clients, ...).
5. Diagnostic settings disabled or short-retention
The single greatest impediment to investigating an incident is missing logs. Yet most Azure resources ship with no diagnostic settings configured. Activity Log defaults to 90 days. Resource-level logs default to nothing at all.
Fix: deploy Azure Policy to enforce diagnostic settings on every resource type that supports them, with a destination of either Log Analytics or a long-term storage account. At minimum capture Activity Log, AAD Sign-Ins, AAD Audit Logs, and resource provider logs for storage, key vault, and SQL.
Why these five keep recurring
Three reasons. First, Azure ships with reasonable defaults today, but every tenant carries forward decisions made under older defaults. Second, no one is paid to find these — security teams are stretched, and engineering teams have a bias toward "ship it." Third, point-in-time audits miss them because they reappear with the next configuration change.
The fix isn't doing it once. The fix is continuous validation that it stays done.
Red Shield runs these checks (and ~200 others across Azure, AWS, GCP, M365, and Google Workspace) on a continuous cadence so that drift gets caught the day it happens — not the next time someone opens a PDF.