Repository: microsoft/CSS-Exchange
File: Security/src/CVE-2023-23397/CVE-2023-23397.ps1 (PowerShell)

Code before:
        }

        #Use newly created app to query graphAPI
        [string]$ClientID = $aadApplication.AppId

        Write-Host "Application created with required permissions. Client ID: $ClientID" -ForegroundColor Green
    }

    ## function to check if a given token is expired and renew it
    function CheckTokenExpiry {
        param (
            $applicationInfo,
            [ref]$ewsService,
            [ref]$token,
            [string]$Environment,
            $EWSOnlineURL,
            $EWSOnlineScope,
            $AzureADEndpoint
        )

        if ($Environment -eq "Onprem") {
            return
        }

        # if token is going to expire in next 5 min then refresh it
        if ($null -eq $script:tokenLastRefreshTime -or $script:tokenLastRefreshTime.AddMinutes(55) -lt (Get-Date)) {
            $createOAuthTokenParams = @{
                TenantID        = $applicationInfo.TenantID
                ClientID        = $applicationInfo.ClientID
                AppSecret       = $applicationInfo.AppSecret
                AzureADEndpoint = $AzureADEndpoint
                Scope           = $EWSOnlineScope
            }

            $token.Value = CreateOAUTHToken @createOAuthTokenParams
            $ewsService.Value = EWSAuth -Environment $Environment -token $token.Value -EWSOnlineURL $EWSOnlineURL
        }
    }

    ## function to get our named search folder
    function GetSearchFolder {
        param($ewsService, $userMailbox)

        $searchFoldersId = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root, $userMailbox)
        $searchFoldersFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($ewsService, $searchFoldersId)
        $searchFoldersView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1)
        $searchFoldersFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, $searchFolderName)
        $results = $searchFoldersFolder.FindFolders($searchFoldersFilter, $searchFoldersView)
        return $results
    }


Review comment (suggestion):
Just noticed that we must acquire a new `JWT` via `New-JsonWebToken` too as the previous one is only valid for 1 hour.

Code after:
        }

        #Use newly created app to query graphAPI
        [string]$ClientID = $aadApplication.AppId

        Write-Host "Application created with required permissions. Client ID: $ClientID" -ForegroundColor Green
    }

    ## function to check if a given token is expired and renew it
    function CheckTokenExpiry {
        param (
            $applicationInfo,
            [ref]$ewsService,
            [ref]$token,
            [string]$Environment,
            $EWSOnlineURL,
            $EWSOnlineScope,
            $AzureADEndpoint
        )

        if ($Environment -eq "Onprem") {
            return
        }

        # if token is going to expire in next 5 min then refresh it
        if ($null -eq $script:tokenLastRefreshTime -or $script:tokenLastRefreshTime.AddMinutes(55) -lt (Get-Date)) {
            $createOAuthTokenParams = @{
                TenantID                     = $applicationInfo.TenantID
                ClientID                     = $applicationInfo.ClientID
                AzureADEndpoint              = $AzureADEndpoint
                UseCertificateToAuthenticate = (-not([System.String]::IsNullOrEmpty($applicationInfo.CertificateThumbprint)))
                Scope                        = $EWSOnlineScope
            }

            # Check if we use an app secret or certificate by using regex to match Json Web Token (JWT)
            if ($applicationInfo.AppSecret -match "^([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_=]+)\.([a-zA-Z0-9_\-\+\/=]*)") {
                $jwtParams = @{
                    CertificateThumbprint = $applicationInfo.CertificateThumbprint
                    CertificateStore      = "CurrentUser"
                    Issuer                = $applicationInfo.ClientID
                    Audience              = ("{0}{1}/oauth2/v2.0/token" -f $AzureADEndpoint, $applicationInfo.TenantID)
                    Subject               = $applicationInfo.ClientID
                }
                $jwt = Get-NewJsonWebToken @jwtParams

                if ($null -eq $jwt) {
                    Write-Host "Unable to sign a new Json Web Token by using certificate: $($applicationInfo.CertificateThumbprint)" -ForegroundColor Red
                    exit
                }

                $createOAuthTokenParams.Add("AppSecret", $jwt)