cisagov / ScubaGear

Automation to assess the state of your M365 tenant against CISA's baselines
https://www.cisa.gov/resources-tools/services/secure-cloud-business-applications-scuba-project
Creative Commons Zero v1.0 Universal
1.61k stars 218 forks source link

Hands-on feasibility analysis calling M365 REST APIs directly without Powershell dependency modules #1359

Open tkol2022 opened 3 days ago

tkol2022 commented 3 days ago

šŸ’” Summary

This is a feasibility analysis via hands-on prototyping.

Ultimately ScubaGear is limited to whatever configuration fields the underlying Powershell modules offer. In some cases we have found that the fields we need are available in a back-end REST API even though we cannot get them via modules such as Sharepoint.Powershell. Therefore we investigated to see:

This work is an extension of previous work that was performed to call Sharepoint Online REST APIs directly without going through the PnP.Powershell or Sharepoint.Powershell modules that ScubaGear currently relies on. ScubaGear currently cannot get all of the configuration fields necessary to perform a full audit of the M365 tenant either because the underlying module does not include the fields (Sharepoint.Powershell) or we cannot use the latest version of the module (PnP.Powershell) because it requires Powershell 7.

Some of the previous related issues are:

958 which proved that calling the Sharepoint REST API directly can acquire numerous fields that are currently missing from ScubaGear.

957 which provides a proof of concept code branch that demonstrates how to call .NET MSAL authentication APIs to perform interactive user authentication and get a token that can be used to directly call Sharepoint REST APIs.

Lack of cmdlet support regarding interactive authentication to call Sharepoint REST APIs: The PnP.Powershell module offers an Invoke-PnPSPRestMethod cmdlet which can be used to make REST API calls directly to Sharepoint sites with a certificate without the need for custom MSAL authentication logic, but there is no equivalent in the Sharepoint.Powershell module for interactive authentication. We cannot use PnP.Powershell with interactive authentication since it requires either an existing PnP multi-tenant app that is overpermissioned or the user must create a custom app in their tenant which is not currently required for ScubaGear users with interactive authentication. We examined cmdlets outside of PnP.Powershell for interactive authentication such as Connect-MgGraph, but there does not seem to be a way to call Connect-MgGraph with Sharepoint as the target application for the token and subsequently call a Sharepoint REST API.

Precedence for direct REST API calls: There is precedence in ScubaGear for calling REST APIs directly. In Entra Id, earlier this year, ScubaGear was modified to directly call REST APIs instead of going through the MS Graph cmdlets due to performance problems with the cmdlets. We made these modifications for a subset of the Graph cmdlets that the Entra Id baseline was using. For Entra Id, we didn't need to worry about writing custom code to acquire authentication tokens and pass them to a Powershell function that makes REST API calls because that was handled by Connect-MgGraph (which handles the magic of getting the tokens) and Invoke-MgGraphRequest (which calls the REST API and uses the underlying token).

Note: If the Scuba team decided to implement a solution to directly call Sharepoint APIs then ScubaGear would no longer need the PnP.Powershell and Sharepoint.Powershell dependencies and there would be a single code path in the Sharepoint export provider.

Implementation notes

tkol2022 commented 3 days ago

Thank you

I wanted to thank the authors of the following blog post and GitHub repo for inspiration and code reference which was invaluable for the development of the source code associated with this issue.

tkol2022 commented 2 days ago

Prototype for directly calling Sharepoint REST APIs with the Microsoft MSAL library (certificate authentication)

This prototype relies on the Microsoft Authentication Library (MSAL) which is Microsoft's modern library that enables application developers to acquire tokens in order to call web APIs. Specifically the Powershell code relies on the Microsoft.Identity.Client Namespace for .NET. The assemblies are Microsoft.Identity.Client and Microsoft.IdentityModel.Abstractions.

Examine this branch for the source code and navigate to the Ted-MSAL folder for the files.

Installation

I took care of the installation by downloading recent versions of Microsoft.Identity.Client.dll and Microsoft.IdentityModel.Abstractions.dll and embedding them in the source code folder. I got them from the official Nuget repository. If ScubaGear were to use these assemblies we would need to write code in our setup routines to download the package and then load the version of the dll files that match the .NET version on the system ScubaGear is running on.

SharepointAPIWithCertificate.ps1 (demo script)

This script calls the .NET MSAL AcquireTokenForClient method to authenticate and acquire a token using client certificate authentication. You need to have an Entra Id registered application like the Scuba Functional Test Orchestrator created in the tenant and your client certificate configured as a credential in the application. Your client certificate must be in the cert:\CurrentUser\My section in the Windows certificate registry on the system you are running on. Once the authentication token is acquired, the script passes the token to an API call against a Sharepoint REST method. The script then outputs a JSON document to the console that contains the Sharepoint tenant configuration settings received from the REST API.

Permissions

The registered Entra Id application that you use must have the API permission shown in the screenshot below to be able to get data from Sharepoint Online. image

Example usage:

This example assumes you have a M365 tenant with the domain your365tenant.onmicrosoft.com

.\SharepointAPIWithCertificate.ps1 -ClientId ac391fde-1ff0-222f-be3d-03d9ba6cb987 -CertificateThumbprint 93fd41a761f434f12ee8ac3ff771347597435696 -TenantDomainPrefix your365tenant

SampleSharepointTenantConfig.json

This is a sample Sharepoint tenant configuration settings output file generated by the script above.

Snippet of example output JSON below. image