Skip to content
Back to Resources

ControlPlane AI Security Team Responsibly Discloses Entra ID Security Issue at the Planning Inspectorate

Planning Inspectorate: Entra ID Security Issue
  • Publications
  • Security
  • Public Sector

Summary

ControlPlane's AI security research team identified a critical credential exposure affecting the Planning Inspectorate, an executive agency of the United Kingdom’s Ministry of Housing, Communities and Local Government (MHCLG). A complete Microsoft Entra ID application credential was committed to a GitHub repository. Although removed from the branch, the commit was orphaned via a force push and remained retrievable via GitHub's raw object CDN for 18 months.

The Planning Inspectorate’s monitoring immediately alerted its cyber team to the researcher’s activity, and the team was already responding to the incident when ControlPlane made contact. Once reported, the Planning Inspectorate confirmed the finding and revoked the secret in Entra ID within approximately 20 minutes. Severity was assessed as Critical, CVSS 10.0 (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N), classified under CWE-798 (Use of Hard-coded Credentials).

Background

The Planning Inspectorate's Open Data Workspace (ODW) project automates the ingestion of operational and corporate data into an Azure Synapse Analytics data lake. To import monthly human resources extracts from SharePoint, an automated pipeline notebook was configured to authenticate against Microsoft Graph using an Entra ID service principal. As service principals operate unattended without an interactive user or multi-factor authentication, the permissions assigned to the application registration define the absolute boundary of its access.

The finding

The credentials were committed in plain text within an exported Synapse notebook file. The file contained all three values required to request an access token via an OAuth 2.0 client_credentials grant: client ID, tenant ID, and a valid 40-character client secret. Removing the file from the branch left an HTTP 404 at HEAD, but GitHub continues to serve orphaned commits indefinitely via its raw content CDN. This behaviour is demonstrable and ongoing: a public reference repository (opens in a new tab) creates orphaned commits via eight separate routes and verifies weekly that GitHub still serves every one of them.

A single-token request confirmed that the credential was active. Further inspection of the issued token revealed unscoped, tenant-wide application permissions with admin consent: Sites.ReadWrite.All and Files.ReadWrite.All. This granted access to all SharePoint site collections in the tenant, including potentially sensitive sites and libraries, as well as private employee OneDrive accounts. This highlighted that the scope was wider than necessary for the original integration.

ControlPlane validated both read and write authorisation non-destructively, by reading column headers and row counts. To prove write authorisation without modifying or reading the real, live data, a folder-creation probe was issued using an existing name with a fail-on-conflict directive; receiving an HTTP 409 Conflict confirmed that write authorisation was granted and halted only by the collision, with zero bytes written or altered.

Root cause

The exposure stemmed from three compounding flaws: committing credentials to source control; assigning broad, tenant-wide application permissions to an integration that only required access to a single file in a single SharePoint library; and failing to limit the token with an expiry date.

Finally, removing a sensitive file from a Git repository with “force push” is not remediation. A secret committed to a repository must be revoked at the identity provider, not merely deleted from HEAD.

Potential impact

An attacker in possession of the credential held unconstrained, tenant-wide read and write access across the organisation's entire Microsoft 365 estate.

Beyond exfiltrating sensitive casework and employee data, the write authorisation also extended to Preservation Hold Libraries, which safeguard evidence under legal hold for statutory planning inquiries and appeals.

Coordinated disclosure and remediation

The Planning Inspectorate responded decisively to the report submitted through HackerOne under the Government Cyber Coordination Centre (GC3). Within approximately 20 minutes of submission, the agency revoked the application secret in Entra ID, permanently terminating the exposure, followed by a very positive collaborative stakeholder technical briefing later that afternoon with our researcher. The Planning Inspectorate also reviewed all of its other repositories to ensure this type of issue isn’t repeated, and has since restored all of them to public accessibility.

Disclosure timeline (dates and times):

  • 2026-08-26 05:45:44: ControlPlane’s automated secret scanner identifies and validates the token endpoint; flags the credential as live
  • 2026-08-26 10:20 to 11:20: Manual verification: permissions inspected, blast radius enumerated, write verified non-destructively
  • 2026-08-26 12:10:05: Coordinated vulnerability report submitted via HackerOne (GC3)
  • 2026-08-26 13:15:39: Mitigated: Planning Inspectorate confirms they’ve deleted the client secret in Entra ID (revoked approximately 20 minutes after the report; confirmed to the researcher at 65 minutes, once service resilience was confirmed)
  • 2026-08-26 16:30:00: Technical briefing with the ControlPlane researcher; Planning Inspectorate stakeholders had already been on incident calls
  • 2026-08-28 14:14:40: Report formally triaged on HackerOne

Responsible testing and data handling

Testing followed the GC3 Vulnerability Disclosure Policy (opens in a new tab), which anyone who finds a vulnerability in a public sector service can use. Within that policy, ControlPlane took a minimum-necessary approach: verification was non-destructive, read-only metadata and row-1 column headers, and used intentional conflict probes to verify write permissions with zero state changes. A full forensic activity log (including single-source IP addresses, user agents, timestamps, and exact API calls) was provided to the agency for log exclusion, and all tokens were purged immediately.

The broader lesson

Four practices prevent this class of flaw:

  • Workload or on-behalf-of identity instead of static credentials.Zero-trust credentials, including SPIFFE/SPIRE (opens in a new tab), exist that avoid hard-coded tokens and passwords by limiting their duration, scope, origin, and other properties.
  • Commit removal is not secret revocation. A secret committed to a Git repository remains permanently reachable via orphaned commit hashes on GitHub; revoking the credential at the provider is the only effective remediation. Tools like GitGuardian (opens in a new tab), GitHub Advanced Security (opens in a new tab), TruffleHog (opens in a new tab), etc., can run pre-commit to prevent secrets from reaching the remote repository, but not all of them detect secrets in orphaned commits. A reference repository (opens in a new tab)demonstrates this in practice.
  • Scope service principals to the minimum necessary resource and calling location. Never assign tenant-wide .All permissions. In Microsoft Graph, use Sites.Selected to restrict application access strictly to designated site collections and restrict access by IP.
  • Log retention limits dictate post-incident certainty. When an exposed credential falls outside the retention window of cloud audit logs, determining whether it was exploited becomes impossible.

About this work

ControlPlane is an AI-native cybersecurity consultancy specialising in cloud native security, secure software supply chains, and the assurance regimes that regulated organisations depend on. We help teams design and secure platforms and non-human identities without sacrificing usability. If you are building cloud services that must remain both open and safe, we would be happy to talk.

View all

Speak to an expert

Engage with world-leading AI and cloud security specialists