Governance & Security

From the field archive · Learned in 2020

Passing an Enterprise Security Scan With Dynamics 365 and Portals

When a customer's security team runs an automated scan against a SaaS app, the findings report lands on everyone's desk at once. Here's how I helped customers work through those reports in 2020, and what the platform gives you today.

Kaustubh Giri··8 min read

Hero image for Passing an Enterprise Security Scan With Dynamics 365 and Portals

In late 2020, a large automaker's application security team ran dynamic application security testing (DAST) against their Dynamics 365 apps and customer portal. The report came back with findings rated critical and high, an internal SLA to close them, and a pilot for a new app on hold until someone could explain what the findings meant. I spent a good part of the following months helping their teams and ours sort through that report.

If you run Dynamics 365 or Power Pages in a regulated enterprise, you'll go through this at some point. The scan tools are designed for applications you build and host yourself. When you point them at a SaaS platform, the findings mix three very different things together, and the first job is to separate them. In this post I go through how I approach that, the categories of findings I saw most, and the controls that exist today. I'm only describing general categories and publicly documented controls here, not the details of any specific finding.

What's changed since 2020

Power Pages (formerly Dynamics 365 portals) now has a Security workspace with a built-in security scan, a Web Application Firewall powered by Azure Front Door, and settings to manage HTTP headers, including content security policy (CSP). Model-driven apps have an environment-level CSP setting in the Power Platform admin center, with report-only mode and a strict mode. Dataverse documents its supported TLS 1.3 and 1.2 cipher suites, and older TLS versions and cipher suites have been deprecated. Microsoft no longer requires you to notify it before penetration testing your own Microsoft cloud resources, but you must follow the published Microsoft Cloud Unified Penetration Testing Rules of Engagement.

01Triage first: whose finding is it?

Every DAST report against a SaaS app contains a mix of findings. Before anyone starts fixing anything, sort each finding into one of three buckets:

BucketWhat it meansWho acts
Your configuration or codeCustom scripts, web templates, portal pages, table permissions, settings you controlYour team, right away
Platform behaviorSomething in the service itself, the same for every customerMicrosoft, through a support case, or MSRC for a suspected vulnerability
Expected behavior or false positiveThe scanner flagged something that's documented, by design, or not exploitable in contextYour security team, with documented evidence

This is the shared responsibility model applied to a findings report. The takeaway: a single spreadsheet with one owner and three columns will save you weeks of back-and-forth.

From the field

The automaker's security team escalated a finding in an area the business used heavily, and the first suggestion was to disable the feature. I pushed back on that. Disabling a tool people rely on every day creates a different business risk. Instead, I asked for a meeting to understand exactly why they rated it high risk, and whether the context changed the severity. In parallel, we moved users to the modern experience, where the platform's current protections apply. That combination closed the issue without taking anything away from users.

02The categories I saw most

Across several customers, the same categories came up again and again. Here's how I'd handle each one today.

CategoryWhat to checkControl that helps
Weak TLS or cipher suitesWhich endpoint was scanned, and whether it's the platform, a custom domain, or your own server that integrates with DataverseDataverse's published TLS 1.3/1.2 cipher list. Your own servers must support at least one listed cipher.
Cross-site scripting (XSS)Where untrusted input is rendered: your portal templates, custom scripts, or downstream appsOutput encoding in your code, CSP, and the Power Pages WAF managed rules
Clickjacking or framingWhether pages can be embedded by other sitesCSP frame-ancestors for model-driven apps and Power Pages
Sensitive data in responsesWhat your pages and APIs actually return to the browserTable and column permissions, and minimal data in custom templates
File uploadWhich file types are accepted and whether they're scannedBlocked file extensions in Dataverse, and malware scanning where you store attachments
Missing security headersWhich headers your site sendsPower Pages HTTP header site settings and the Security workspace
Know the limits

For TLS findings, read Microsoft's server cipher suites article before you escalate. It lists what Dataverse supports, which older protocols and suites are deprecated, and what your on-premises servers need when they connect to Dataverse, for example for email sync or outbound calls.

03Input sanitization: platform vs. your code

One finding category caused more debate than any other. Testers entered script tags into a text field, saved the record, and flagged it as stored XSS. In our testing, the model-driven app didn't run the script. It stored the text and displayed it as text. The real risk was somewhere else: another application that later read that value and rendered it as HTML without encoding it.

The customer asked for a platform option to sanitize or escape such content when it's saved, at the field level, so each team could choose which fields allow markup. I thought that was a reasonable ask and submitted it as a product idea on their behalf. But I was also clear with them about what they could control right away:

  • Treat every value from Dataverse as untrusted in any app that renders it. Encode output for the context (HTML, attribute, JavaScript, URL).
  • Validate input where the business rule is known, for example with column formats, business rules, or a plug-in that rejects markup in fields that should never contain it.
  • Review custom portal templates and scripts for places where content is inserted into the page as raw HTML.
  • Use CSP to limit what scripts can run, starting in report-only mode.

The takeaway: the platform storing text as entered is expected. Whether that becomes XSS depends on how your code displays it.

04Re-testing without blocking the business

A few weeks into the effort, a pilot for a new model-driven app was put on hold. The concern was that it hadn't gone through its own security scan. I explained that the new app changed the user interface, not the underlying platform. The open findings were already being worked on with the right people, and the new app didn't introduce new risk to the base framework. The pilot went ahead.

Here's how I approach re-testing:

  1. Scope each new scan to what changed: new custom code, new portal pages, new integrations, new authentication.
  2. Keep a record of closed findings with the evidence for each, so the same item isn't re-opened with every scan.
  3. Run scans against a test environment or site that matches production.
  4. Follow the rules of engagement. They prohibit denial-of-service testing and require you to stop and report through MSRC if you find a vulnerability in Microsoft's services.

05Power Pages security today

Most of what we had to work around in 2020 for portals is now built in.

Security scan

AvailableDesign studio → Security workspace

Runs a deep scan of your site and produces a summary report of failed checks, with guidance for fixing each alert. By default it scans anonymous pages only. You can include authenticated pages by providing test credentials. You get an email when the scan finishes and can download the report as a PDF.

How I recommend using it
  1. Run it before every major release and before the enterprise DAST scan, not after.
  2. Include authenticated pages, using a dedicated test account.
  3. Fix your own findings first, then share the report with your security team as evidence.

Web Application Firewall

AvailablePower Platform admin center → site → Performance & protection

Powered by Azure Front Door, in prevention mode. The managed rule set covers cross-site scripting, local and remote file inclusion, session fixation, and protocol attacks. Custom rules let you allow, block, or rate-limit by geography, IP address, or request URI.

Things to know
  • It's for production sites. Trial sites aren't supported.
  • It isn't available in every region. Check the current list.
  • When WAF is on, use WAF custom rules for IP filtering instead of the site-level IP restrictions.

HTTP headers and content security policy

AvailableSecurity workspace → Advanced settings, or site settings

Configure CSP, CORS, cookies, and other headers. Power Pages supports nonce-based protection for inline scripts. Newer sites get a default CSP, while older sites might not have one enabled. Check current docs for the exact default and the migration steps. Microsoft recommends testing in report-only mode first.

For model-driven apps, the matching control is the environment-level CSP setting in the admin center. Microsoft's suggested rollout is to enforce it in a dev or test environment, turn on report-only mode in production, and enforce in production once no violations are reported. The same privacy and security settings page also has options like IP-based cookie binding and the IP firewall. The governance toolbox post covers the admin center's Security page and security score.

From the field

One customer's scan flagged that their CRM pages could be embedded by other sites. The control they needed was content security policy, specifically the frame-ancestors directive, which limits who can host the app in a frame. Back then, an admin had to change it through organization settings rather than a simple toggle. Today it's a toggle and a list of allowed origins in the admin center. Whatever the tooling, test it first, because legitimate embeddings like Teams, Outlook, or Power BI need their origins added.

06Reporting a real platform issue

Sometimes a finding really is in the platform. When that happens, I recommend this path:

  • Confirm you can reproduce it in a clean environment without your customizations.
  • Stop testing beyond a proof of concept. The rules of engagement prohibit going further.
  • Report it to the Microsoft Security Response Center (MSRC), following coordinated vulnerability disclosure.
  • Don't share details publicly or in unrelated tickets while it's being investigated.
  • Track it in your findings spreadsheet as "reported to vendor," with the date, so your auditors can see it's being handled.

Where I'd start

Before the next enterprise scan, run the Power Pages security scan yourself and fix what it finds. Turn on the WAF for production sites. Roll out CSP in report-only mode for both your sites and your model-driven apps. Check that your integration servers support Dataverse's current cipher suites. Then, when the DAST report arrives, sort every finding into "ours," "platform," or "expected" before anyone starts fixing anything.

Happy to go deeper on any of this.

— K.G

→ Related: Environment Strategy and DLP

Sources

  • Microsoft Learn: Power Pages security; Overview of the Security workspace; Run security scan
  • Microsoft Learn: Web Application Firewall (WAF) for Power Pages; Configure Web Application Firewall for Power Pages
  • Microsoft Learn: Advanced settings (Power Pages); Manage your site's Content Security Policy; Set up HTTP headers in Power Pages
  • Microsoft Learn: Content security policy (Power Platform); Manage privacy and security settings
  • Microsoft Learn: Server cipher suites and TLS requirements
  • Microsoft Learn: Penetration testing (Azure security fundamentals)
  • Microsoft Security Response Center: Microsoft Security Testing Rules of Engagement
Kaustubh Giri

Kaustubh Giri · Sr Solution Engineer at Microsoft. 22 years in tech, 18 at Microsoft, helping enterprises build and govern AI agents on Copilot Studio and Power Platform.