PHP2Shell and the portal that calls Dynamics 365.
The vulnerable component is PHP on a server you or your partner operate. Patch now. Remove the stored secret. Move the portal onto a platform Microsoft maintains.
Finance and Operations, Dataverse and Business Central online are Microsoft-hosted services. The flaw is in PHP on a server you or your partner operate. A portal that calls them often holds a long-lived credential.
PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 5.4 to 8.1 have no upstream fix.
Unauthenticated remote code execution in a default configuration.
The host that calls Dynamics 365. The product Microsoft hosts is a separate system.
Two flaws in PHP.
Both were patched after the details leaked, and after exploitation had already begun. The count below is of PHP on the internet. It is not a count of Dynamics 365 customers.
- 17 OctAmazon honeypots log an exploit attempt, four days before disclosure.
- 20 OctDetails leak. PHP announces an emergency release.
- 21 OctPHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 ship. Affected: PHP 5.4 through 8.5.11.
- 22 OctCloudflare reports attempts rising from tens of thousands to millions.
- 23 OctPHP flags a third issue, CVE-2026-115560. It needs an unusual configuration.
- 25 OctPalo Alto Unit 42 counts over 22.6 million potentially exposed PHP instances.
Triggered by out-of-memory handling. Code execution in a default configuration.
A PHP worker can reuse stale state from a freed request. Code execution in a default configuration.
Both are CVSS v4.0 9.2, as described by Datadog, Unit 42 and Google Cloud. Sources for the timeline and the instance count: the PHP project, Amazon, Cloudflare, Datadog, Google Cloud and Palo Alto Unit 42. Software Dynamics has not independently counted those hosts.
The flaw sits in PHP on a server you or your partner operate. That server is the customer, vendor or partner portal, the web shop or booking site, or the middleware script that calls Dynamics 365 through OData, a custom service, or the Dataverse Web API. If that host runs a PHP version below the fixed releases, anyone on the internet can attempt to run code on it.
The damage equals the identity.
Code execution on the portal lets an attacker act as the portal. This table is analysis of typical integration designs. It is not a record of a published incident. Adjust it to the architecture you actually run.
| What sits on the PHP host | What an attacker gains |
|---|---|
| Entra ID app registration client secret or certificate | Token requests as the service principal, from anywhere, until the secret is rotated. |
| Cached OAuth access tokens | Short-lived Dynamics 365 access, typically about an hour, without the secret. |
| .env, config.php or web.config | Database credentials, SMTP credentials, and payment gateway keys. |
| The portal database | Customer and vendor records, order history, and password hashes. |
| A network position | A trusted route to Dynamics 365, to integration databases, or to an on-premises gateway. |
The worst case is a wide role. An integration identity with System Administrator in Dataverse, or a wide security role in Finance and Operations, turns one request to the portal into read and write access to customers, vendors, pricing and open orders. Read the table against three facts: the identity (the Entra application and the user it maps to), the role (the tables, entities and actions it may touch) and the secret (the file, vault or certificate that holds the credential tonight).
Patch, hunt, rotate.
Treat a portal that was on the internet and unpatched on 17 October as exposed until the logs say otherwise.
-
1
Patch the runtimeMove to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. On Linux, confirm the distribution package carries the fix. A backport can keep the old version number. PHP 5.4 to 8.1 have no upstream fix: upgrade those hosts or take them off the internet.
-
2
Read the logsCheck web and process logs for PHP workers spawning shells or child processes, and for unusually long filenames in POST bodies.
-
3
Rotate the credentialRotate the Entra ID client secret or certificate the portal uses, then database and gateway keys. Revoke sessions where you can.
-
4
Hunt in the tenantReview service principal sign-ins for new IP addresses or odd hours. Review Dynamics 365 audit logs for bulk reads, exports or writes by the integration user.
-
5
Shrink the identityGive the integration its own service principal and a minimal security role. Restrict it by Conditional Access or IP where licensing allows. Prefer a certificate in Key Vault over a secret in a config file.
-
6
Narrow the pathAdd web-application-firewall rules for the published signatures. Limit outbound traffic from the PHP host. Disable session upload progress, which mitigates CVE-2026-115560.
Who owns which action. The infrastructure owner patches the host and confirms the package. The identity owner rotates the Entra credential. The Dynamics 365 administrator reads the audit log and cuts the security role. Name one person for each, today.
A stolen file should be useless.
Key Vault alone does not stop code running inside the portal from using what the portal can use. Pair the vault with a small role, and with a front door that exposes only the operations the portal needs.
| Pattern | What it stops | What remains |
|---|---|---|
| Secret in a config file. The client secret sits in .env or config.php. Common today. | Nothing. | Full theft, and reuse from anywhere. |
| Secret in Azure Key Vault, read at runtime with a managed identity. Access by Azure RBAC, rotation on a schedule. | Secrets leaking through file reads and backups. Rotation becomes routine. | A compromised portal can still read the secret while it runs. |
| Certificate, private key held in Key Vault. The portal asks Key Vault to sign the client assertion. The key is not exported. | Exfiltrating a credential that can be reused later. | The attacker can sign requests only while the portal is compromised. |
| Managed identity with a federated credential. The app registration trusts the host. No secret exists. | Credential theft, on an Azure-hosted portal. | The attacker can still request tokens from the compromised host. |
An application user with a custom security role, limited to the tables the portal needs. Never System Administrator.
Register the Entra application and map it to a service user. The role covers only the required data entities and actions.
Conditional Access for the workload identity, where licensing allows it. Alert on sign-ins from a new location.
Azure API Management, or an Azure Functions facade, between the portal and Dynamics 365. Only the operations the portal needs, with rate limits and logging.
Do these in this order. Rotate the secret that sits in a file. Then cut the role. Then put a front door in front of Dynamics 365. A vault, without the smaller role and the front door, still leaves a portal that can ask for a token.
Every host that touches Dynamics 365.
Capture eight facts for each portal and each script, then put the host in one tier: the PHP version and framework, the hosting location, who owns it and patches it, which Dynamics 365 identity it uses, the roles on that identity, where the secret lives, which data it reads or writes, and when it was last patched or tested.
| Tier | Profile | Action window |
|---|---|---|
| Tier 1 | On the internet. Writes to Dynamics 365, or uses a broad role. Secret in a config file. | Patch and rotate now. A front door and a smaller role within 30 days. |
| Tier 2 | On the internet. Read-only, or a narrow role. | Patch now. Move the secret to Key Vault within 60 days. |
| Tier 3 | Internal only, or it touches little data. | Patch in the normal cycle. Fold it into the migration backlog. |
| Tier 4 | Nobody owns it, it is unpatched, or nobody can say what it is for. | Isolate or retire. Do not carry it forward. |
How to weight a host. Give extra weight to a PHP version with no upstream fix, and to a portal that handles payment, pricing or customer master data. A public vendor portal on PHP 8.1, with a client secret in config.php and a System Administrator application user, is Tier 1. An internal read-only price list on a fixed PHP 8.3 build is Tier 3. Retiring a portal that nobody can justify is the cheapest reduction available.
Most PHP portals repeat Power Platform.
Every line of PHP is code you must patch yourself. Match each portal to the lowest-maintenance option that meets the need.
| Option | Best for | Trade-off |
|---|---|---|
| Power Pages | External customers, partners and vendors. Forms, lists, order or case status, document upload. | No server-side PHP. Custom logic moves to Dataverse plug-ins, Power Automate or Azure Functions. Data must be in Dataverse, so Finance and Operations data needs virtual tables, dual-write or an integration. Licensing is capacity-based: check it before you commit. |
| Model-driven apps | Internal staff, and licensed partner users, working with Dynamics 365 records. | The full Dynamics 365 security model, and the audit log. Not for anonymous users, and not for high-volume external users. |
| Azure Functions or Logic Apps, behind API Management | Headless business-to-business integrations, and bespoke logic the portal must keep. | You own the code, on a Microsoft-managed runtime, with a managed identity, patched by the platform. It needs an API design and monitoring. |
| Harden, and keep PHP | A complex application that cannot move yet. | You keep the patching burden. Use it only with a front door, Key Vault, a firewall and a written patch commitment. A bridge, not a destination. |
A practical rule. If a portal mostly shows and edits records, move it to Power Pages or a model-driven app. If it contains real business logic or integrations, extract that logic into a governed API layer first, then retire the PHP front end. If it cannot move this quarter, harden it, name the owner, and write the date it will be retired.
Shrink what holds a trusted identity.
PHP2Shell will not be the last critical flaw in a runtime you operate. The durable fix is less custom, internet-facing code holding a Dynamics 365 identity, and an identity that is cheap to rotate and hard to misuse.
- Days 0 to 3 · ContainPatch, hunt, rotate, and disable session upload progress.
- Days 3 to 30 · StabiliseFinish the inventory. Move secrets into Key Vault. Cut integration roles to the minimum. Turn on Entra sign-in alerts and Dynamics 365 audit alerts.
- Days 30 to 90 · RedesignPut API Management or Azure Functions in front of Dynamics 365. Retire every Tier 4 portal. Pilot the highest-risk external portal on Power Pages.
- Days 90 to 180 · MigrateMove the remaining portals, by tier, to Power Pages, a model-driven app, or the API layer. Any PHP that remains sits on a written patch commitment.
Häufig gestellte Fragen
Is Dynamics 365 itself vulnerable to PHP2Shell?
No. Finance and Operations, Dataverse and Business Central online are Microsoft-hosted services. The flaws are in PHP on a server you or your partner operate, such as a customer, vendor or partner portal, a web shop, or a script that calls Dynamics 365.
Which PHP versions fix the PHP2Shell flaws?
PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released on 21 October 2026. PHP 5.4 to 8.1 have no upstream fix and should be upgraded or taken off the internet. On Linux, confirm the distribution package carries the fix, because a backport can keep the old version number.
What should we do first?
Patch the PHP host, then rotate the Entra ID client secret or certificate that the portal uses, then the database and gateway keys. After that, cut the integration identity to a minimal security role and review service principal sign-ins and Dynamics 365 audit logs.
Where should a PHP portal for Dynamics 365 move to?
A portal that mostly shows and edits records fits Power Pages or a model-driven app. A portal with real business logic needs that logic extracted into a governed API layer, such as Azure API Management or Azure Functions, before the PHP front end is retired. PHP that stays is a bridge with a written patch commitment.