Friday, March 8, 2024

Allowing arbitrary custom scripting in SharePoint Online, or not? – that is the question! (aka Stealing your data since 2001!)

…and the answer is, as it always has been, NO!



Disclaimer: the opinions of this post are mine entirely, and nothing to do with my work at Microsoft. I have not changed opinion on this matter in the past many many years.

Sparked by the recent message center post MC714186 – Remove Custom Script setting in OneDrive and SharePoint web, I figured I’d write out my stance and my full support of the planned change.

Summary: The Custom Script setting in OneDrive and SharePoint web will be removed in March 2024. A new PowerShell command, "DelayDenyAddAndCustomizePagesEnforcement", has been introduced to delay the change to custom script set on the Tenant until mid-November 2024. The NoScriptSite setting will be configured to True for all existing SharePoint sites and OneDrive sites except for specific site templates. Existing scripts in OneDrive and SharePoint sites will remain unaffected. Administrators can permit the execution of custom scripts on specific SharePoint sites using the Set-SPOSite command.

In the above summary I want to point out that “existing scripts will remain unaffected” means classic page injections. Not SPFx solutions on with the setting requiresCustomScript=true.

The challenge

SharePoint by design is a JavaScript application and has always allowed for extensibility in the UX. In modern ways extensibility is achieved via the SharePoint Framework (SPFx), which you should use, and that is ok. Because by virtue of how SPFx is built any script or logic in a SPFx solution is governed and controlled by design.

To explain what I mean. By arbitrary code I mean someone can insert and freely modify JavaScript that runs in a SharePoint site or page without anyone noticing. One example being a bad actor put script on a page which when a person visit the page then transfers all the persons OneDrive files to evil.corp in the background without the person ever knowing. And this has been possible with SharePoint in classic experiences since always, and also with 3p modern webparts when allowing script to run, or by bypassing settings for a site.

When writing code in a SPFx solution, it is no longer arbitrary. Someone wrote it, built it, and then handed the package over to a person with SharePoint admin role rights to install it (or by an admin role proxy if a site has it’s own app catalog). How diligent the process is for code review and installation is up to each organization, but at least the setup allows for a governed process to help control what is installed into a tenants SharePoint Online experience.

Arbitrary script on the other hand would be JavaScript added to SharePoint sites or pages by any regular user with edit rights or a site administrator. Every Team or Group creator is a site administrator of the associated site, and this is not very controlled in my opinion. With classic SharePoint, script can be injected or allowed via the Script Editor web part, via search display templates, and via something called custom actions. When Modern sites were introduced many years ago, allowing these features were by default turned by setting the “Allow and Customize Pages” permission to false. The feature is more commonly renamed in e.g. PnP PowerShell to NoScriptSite. Documentation on turning this on or off can be found at https://learn.microsoft.com/en-us/sharepoint/allow-or-prevent-custom-script.

Back to the message center post and what changes

  • In March, the SharePoint admin UX setting to allow custom script on OneDrive sites or self-service sites is going away, and is being replaced by a PowerShell cmdlet function Set-SPOTenant DelayDenyAddAndCustomizePagesEnforcement which you can use until mid-November 2024.
  • All new and existing sites will be set to block custom scripts unless they were created with any of these web templates: BLANKINTERNETCONTAINER#0, CMSPUBLISHING#0, BLANKINTERNET#0. GROUP#0, APPCATALOG#0, CSPCONTAINER#0.
  • From mid-November 2024, custom script is disabled for your sites every 24 hours. You can manually re-enable it with for example Set-SPOSite <SiteURL> –DenyAddAndCustomizePages. This means you need to set up a scheduled job every day to re-enable it where needed for SPFx solutions relying on this feature, unless you migrate your ungoverned script solutions to governed ones using SPFx.

Should you be worried?

If you are still on classic pages, then disregard as you are a lost cause anyways. It’s 2024 people! Modern is no longer modern. It is the new classic.

Hopefully most customers have moved over to using SharePoint Framework for any custom JavaScript solution running in SharePoint Online by now. However, the elephant in the room is my infamous Modern Script Editor Web Part- https://github.com/pnp/sp-dev-fx-webparts/blob/main/samples/react-script-editor/README.md. If built without changes then someone has changed the site settings to allow arbitrary script to run for the web part to work. When this is then flipped off every 24 hours by the service, the web part will stop running (which is good!).

Instead of working the web part will render ugly white space instead.

image
Alternatively you rebuild the web part bypassing the custom script check saying it does not rely on custom script (boooooo on you, and bad governance practice).

It is no secret what my take is on usage of this web part. The sample modern script web part should NEVER be used, and I will argue to my death that there are no good scenarios for it. Sure, it’s quicker to use compared to always creating new SPFx extensions or web parts, but is this ease of use more important than security? My answer is still a big NO! Sure, you may reduce the attack vector by using site scoped app catalogs, and maybe you have the utter most control for who can edit pages in those sites. But is this a long term risk you are willing to take?

Why not just build your scenario solutions in a governed way thus blocking someone from changing the code? If you have access to someone building the Modern Script Editor web part, then you also have access to someone who can do it the right way.

What now?

My hope is that people do not run a script every 24h to allow custom script, or that they cheat on building SPFx web parts to bypass scripting. Instead everyone should embrace this opportunity to get their solutions cleaned up – if they haven’t already.

Happy coding governed solution, and preventing your files from being stolen!