It’s time for Microsoft to step up their AppSource Security Game

With AppSource maturing and we’re passing 1700 apps for Business Central, it’s time to think about app security. How does a customer see what tables, events and resources an app will be using? How does a customer stay in control of their data and system? In this video, I’m showing a prototype of how one aspect of how to improve app security.

https://youtu.be/DgMsLLBRN0E

In this thought-provoking video, Erik demonstrates a critical gap in Business Central’s app security model. Using a proof-of-concept “threat protection” app, he shows how an innocent-looking AppSource extension—like an exchange rate updater—could silently modify vendor bank accounts, potentially redirecting payments to malicious actors. Erik makes a compelling case for why Microsoft needs to implement app manifests, permission declarations, and runtime security prompts similar to what we see on mobile platforms.

The Problem: Implicit Trust in a Growing Ecosystem

We all experience app security on our phones every day. You install a weather app and it asks for access to your contacts, phone numbers, and files—and you rightly question why a weather app needs any of that. That’s app security in action.

But in Business Central, no such mechanism exists. When you have a platform like AppSource with hundreds of publishers, you as the consumer don’t necessarily know or trust every single one. And unlike a fart sound app on your phone, Business Central contains sensitive financial data—customer ledger entries, vendor bank accounts, posted documents—information that certain parties would find very interesting to tamper with.

A Frightening Demo: The “Innocent” Exchange Rate App

Erik walks through a scenario that should concern every Business Central administrator. He searches AppSource for “exchange rates” and finds a free app called “Automatic Exchange Rates” published by an unknown developer. He installs it, navigates to Currencies, and clicks “Get from openrates.io” to fetch exchange rates.

The app works—exchange rates are updated. But behind the scenes, it also silently modifies a vendor bank account number, changing it to an attacker-controlled value. The next time the company runs a payment batch and generates an EFT file, they could unknowingly send money to the wrong account.

How would you ever know this happened? Currently, there’s no mechanism in Business Central to alert you that an exchange rate app is writing to the Vendor Bank Account table—something it has absolutely no business doing.

The Proof of Concept: Runtime Permission Prompts

To demonstrate what app security could look like, Erik built a prototype app called “BC Threat Protection.” When the exchange rate app attempts to modify the Vendor Bank Account table, a dialog appears:

“Automatic Exchange Rates is requesting permission to modify data in the Vendor Bank Account table. Do you trust [publisher]?”

The user is presented with three options—just like on a mobile device:

  • Always Allow – Grant permanent access
  • Allow this session – Grant temporary access for the current session only
  • Don’t Allow – Block the operation entirely

When access is denied, the operation fails with a security violation message, and the malicious modification never occurs.

Three Asks for Microsoft

1. Verify Who Signed the App, Not Just That It’s Signed

Currently, Microsoft verifies that an app submitted to AppSource is digitally signed, but they don’t verify who signed it. If someone compromises a publisher’s Microsoft account, they could upload a new version of the app signed with a completely different certificate, and Microsoft would accept it because it’s “signed.”

Erik argues that Microsoft should tie the publisher identity to the signing certificate. If Erik as a publisher uses a specific certificate, Microsoft should reject any update signed with a different one. This is a straightforward validation that would prevent a significant attack vector.

2. Introduce an App Manifest with Declared Capabilities

Erik draws a parallel to Universal Windows Platform (UWP) applications, which have a manifest file declaring exactly what capabilities the app needs—internet access, user account information, Bluetooth, contacts, and so on. If a capability isn’t in the manifest, the app simply cannot access it.

He proposes a similar system for Business Central apps. An app manifest would declare:

  • Which tables the app needs read/write access to
  • Whether the app sends emails
  • Whether it runs background sessions
  • What external services it connects to
  • Any other sensitive operations it performs

This way, before installing an app, an administrator could review what it declares and ask: “Why does an exchange rate updater need write access to Customer Ledger Entries?” Something similar existed in a limited form with pre-version 18 permissions, but a proper manifest system would be far more robust.

3. Runtime Monitoring and Consent Prompts

Even with manifests, apps get updated. An app that was perfectly benign at version 1.0 could become malicious at version 2.0—either through a compromised developer account or a supply chain attack. Runtime monitoring would catch scenarios where an app suddenly starts accessing resources it never touched before, prompting the user for explicit consent.

The SolarWinds Parallel

Erik draws a sobering parallel to the SolarWinds hack. In that attack, hackers gained access to SolarWinds’ source control repository and injected malicious code. The company’s build pipeline compiled and digitally signed the compromised software, and customers received an update that looked perfectly legitimate from every angle—but contained a backdoor.

The same pattern could theoretically affect Business Central apps. The source code provided with the video illustrates this perfectly—a simple, seemingly harmless extension:

pageextension 50129 CustomerListExt extends "Customer List"
{
    trigger OnOpenPage();
    begin
        // SUPER SECRET CODE!!!
        Message('App published: Hello world');
    end;
}

This looks innocent enough—just a message on the Customer List. But notice the app.json configuration:

{
  "id": "b742993f-ac74-46aa-8bab-a4e133d9cd25",
  "name": "BadActor",
  "publisher": "Partner from Hell",
  "version": "1.0.0.0",
  "brief": "",
  "description": "",
  "privacyStatement": "",
  "EULA": "",
  "help": "",
  "url": "",
  "logo": "",
  "dependencies": [],
  "screenshots": [],
  "platform": "1.0.0.0",
  "application": "22.0.0.0",
  "idRanges": [
    {
      "from": 50100,
      "to": 50149
    }
  ],
  "resourceExposurePolicy": {
    "allowDebugging": false,
    "allowDownloadingSource": false,
    "includeSourceInSymbolFile": false
  },
  "runtime": "11.0",
  "features": [
    "NoImplicitWith"
  ]
}

Note the resourceExposurePolicy: debugging is disabled, source download is disabled, and source isn’t included in symbols. A bad actor deliberately makes their code opaque. There’s no way for an administrator to inspect what this app actually does before or after installation. The name “BadActor” and publisher “Partner from Hell” are obviously tongue-in-cheek, but the point is clear—the app.json reveals nothing about what tables or resources the extension touches.

Supply Chain Risks: Build Pipelines and Tooling

Erik extends the concern beyond individual apps to the entire supply chain. Consider the widely-used community tools:

  • AL-Go for GitHub (maintained by Freddy Kristiansen/Microsoft)
  • BcContainerHelper (PowerShell module for building and testing)
  • Waldo’s AL extensions and pipeline tools

These tools manipulate source code, compile apps, and interact with repositories. If any of these were compromised—whether through a direct hack or a malicious pull request—code could be injected into apps during the build process without ever appearing in source control. The compiled, signed app would contain the malicious code, but the repository would look clean.

How the Prototype Works (Bonus Material)

Erik’s proof-of-concept BC Threat Protection app works by subscribing to database triggers: OnDatabaseModify, OnDatabaseInsert, and OnDatabaseDelete. Whenever one of these fires, it calls a Verify function.

The app maintains a dictionary of “sensitive tables”—GL entries, customer/vendor ledger entries, bank account information, posted documents—and checks whether the triggering operation targets one of these tables. If it does, the app needs to determine which app is making the call.

This is where the real hack comes in. Since there’s no built-in AL function to get the calling app from the call stack, Erik uses a creative (and admittedly ugly) workaround: he calls a try function that deliberately throws an error, then uses GetLastErrorCallStack to capture the full call stack. By parsing the call stack string—knowing his own position in it—he can walk up to find the originating app name and publisher.

Permission decisions are stored in isolated storage so that no other app can subscribe to events on the threat protection app to extract information about what’s been allowed or denied.

Erik is candid about the limitations: the try function approach is painfully slow and wholly impractical for production use. But the key insight is that Microsoft already has all of this information internally. The platform knows which app is executing code, which tables are being modified, and which publisher owns the app. Adding runtime security checks would be a relatively minor enhancement for Microsoft—they wouldn’t need the call stack hack because they already have the context.

Conclusion

Erik’s message is clear and delivered constructively: the AppSource ecosystem has matured beyond its infancy. With thousands of companies running Business Central and relying on third-party apps, the platform needs security mechanisms that match the sensitivity of the data it handles. The three key improvements he proposes—certificate identity verification, app manifests with declared capabilities, and runtime permission monitoring—would bring Business Central’s app security model in line with what we already expect from mobile platforms. The alternative is waiting for the headline: “Company loses millions after installing malicious Business Central app from AppSource.” By then, it will be too late to ask why the platform didn’t have these protections in the first place.