Surendra Sharma

Surendra Sharma

Search This Blog

Sunday, August 4, 2024

Installing Content Hub Connector in Sitecore PaaS instance

Sitecore Connect for content hub used to integrate Sitecore Content Hub to Sitecore XP or XM.

DAM stands for Digital Asset Management & DAM Module is used to interact with assets created in Content Hub inside Sitecore XP/XM. We can upload, search and insert assets from DAM directly from within Sitecore Content Editor or Experience Editor.

The Sitecore Connect for Sitecore Content Hub (DAM) Installation in Sitecore XP/XM PaaS can 
be done via PowerShell Script.

You can deploy Sitecore Connect for Content Hub (SCCH) in an existing Azure PaaS 
Environment.

To deploy in an existing PaaS environment, you must have an existing Sitecore XM or XP Azure 
PaaS Environment and Microsoft Web Deploy installed.

Prepare an installation folder

To prepare an installation folder:

1. Create a local folder in your file system, for example, C:\Temp\SCCHInstallation.

2. Download the Sitecore Connect for Content Hub WDP Package from the Sitecore 
download page and store it in the local folder you created.

3. In the local folder, create a new file and name it Deploy.ps1.

4. Open the new file with an editor such as notepad or VS Code and paste the following 
script inside:

`[CmdletBinding(DefaultParameterSetName = "no-arguments")]
param(
[Parameter(HelpMessage = "Name of the resource group in Azure to target.")]
[string]$ResourceGroupName,[Parameter(HelpMessage = "Name of the web app in Azure to target.")]
[string]$WebAppName,
[Parameter(HelpMessage = "Path to the WDP to deploy to the target.")]
[string]$WdpPackagePath,
[Parameter(HelpMessage = "Content Hub Client Id.")]
[string]$CHClientId,
[Parameter(HelpMessage = "Content Hub Client Secret.")]
[string]$CHClientSecret,
[Parameter(HelpMessage = "Content Hub Username.")]
[string]$CHUserName,
[Parameter(HelpMessage = "Content Hub Password.")]
[string]$CHPassword,
[Parameter(HelpMessage = "Content Hub URI.")]
[string]$CHUri,
[Parameter(HelpMessage = "Content Hub Azure Service Bus connection string path in.")]
[string]$CHServiceBusEntityPathIn,
[Parameter(HelpMessage = "Content Hub Subscription name. (must be unique per Sitecore CM
deployment)")]
[string]$CHServiceBusSubscription,
[Parameter(HelpMessage = "Content Hub Azure Service Bus connection string path out.")]
[string]$CHServiceBusEntityPathOut,
[Parameter(HelpMessage = "Content Hub Search Page Uri.")]
[string]$CHSearchPage,
[Parameter(HelpMessage = "Content Hub External Redirect Key.")]
[string]$CHExternalRedirectKey = "Sitecore",
[Parameter(HelpMessage = "Path to MSDeploy.")]
[string]$MsDeployPath = "C:\Program Files\IIS\Microsoft Web Deploy V3\msdeploy.exe",
[Parameter(HelpMessage = "Skips Azure Login when True.")]
[switch]$SkipAzureLogin = $False,
[Parameter(HelpMessage = "Amount of retry attempts. 6 by default which with default retryinterval would
come down to 1 minute.")]


Parameter(HelpMessage = "Amount of retry attempts. 6 by default which with default 
retryinterval would come down to 1 minute.")]
[int]$RetryAttempts = 6,
[Parameter(HelpMessage = "Amount of time to wait between retries in milliseconds. 10000 by 
default which is 10 seconds which adds up to 1 minute with default retry attempts.")]
[int]$RetryInterval = 10000
)
Add-Type -AssemblyName "System.IO.Compression.FileSystem"
function PreparePath($path) {
if(-Not (Test-Path $path)) {
$result = New-Item -Path $path -Type Directory -Force
} else {
$result = Resolve-Path $path
}
return $result
}
function UnzipFolder($zipfile, $folder, dst) { 
[IO.Compression.ZipFile]::OpenRead(zipfile).Entries | Where-Object {
(.FullName−like".FullName−like"folder/*") -and ($.Length -gt 0)
} | ForEach-Object {
parent=Split−Path(parent=Split−Path(.FullName -replace $folder, '')
$parent = PreparePath (Join-Path $dst $parent)
$file = Join-Path $parent .Name[IO.Compression.ZipFileExtensions]::ExtractToFile(.
Name[IO.Compression.ZipFileExtensions]::ExtractToFile(_, $file, $true)
}
}
function DownloadWebsiteFile($filePath, $downloadFolderName) {
$basePath = Split-Path ".$downloadFolderName$filePath"
$fileName = Split-Path $filePath -Leaf
if(-Not (Test-Path ".$downloadFolderName$filePath")) {
New-Item -Path $basePath -Type Directory -Force
}
outFilePath=Join−Path(Resolve−Path"outFilePath=Join−Path(Resolve−Path"basePath") fileNam
eInvoke−WebRequest−Uri"https://fileNameInvoke−WebRequest−Uri"https://WebAppName.sc
m.azurewebsites.net/api/vfs/site/wwwroot/$filePath " -Headers @{"Authorization"=("Basic {0}" -
f $base64AuthInfo)} -Method GET -OutFile $outFilePath
}
function UploadWebsiteFile($filePath, uploadFilePath) { Invoke-WebRequest -Uri 
"https://WebAppName.scm.azurewebsites.net/api/vfs/site/wwwroot/$filePath " -Headers 

@{"Authorization"=("Basic {0}" -f $base64AuthInfo);"If-Match"="*"} -Method PUT -InFile 
$uploadFilePath
}
function ApplyTransform($filePath, xdtFilePath) { Write-Verbose "Applying XDT transformation 
'xdtFilePath' on '$filePath'..."
$target = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
$target.PreserveWhitespace = $true
$target.Load($filePath);
$transformation = New-Object Microsoft.Web.XmlTransform.XmlTransformation($xdtFilePath);
if ($transformation.Apply($target) -eq $false)
{
 throw "XDT transformation failed."
}
$target.Save($filePath);
}
if(-Not (Test-Path MsDeployPath)) { Write-Host "MS Deploy was not found at 
`"MsDeployPath`"!" -ForegroundColor Red
return
}
if(-Not $SkipAzureLogin) {
Write-Host "Logging into Azure..." -ForegroundColor Green
& az login
}
Write-Host "Fetching Publish Profile..." -ForegroundColor Green
$publishProfile = az webapp deployment list-publishing-profiles --resource-group 
$ResourceGroupName --name WebAppName --query "[?publishMethod=='MSDeploy']" | 
ConvertFrom-Json userName = publishProfile.userNamepublishProfile.userNamepassword 
= publishProfile.userPWDpublishProfile.userPWDbase64AuthInfo = 
[Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $userName, 
$password)))
Write-Host "Preparing configuration..." -ForegroundColor Green
$xdtsPath = (PreparePath ".\xdts")
UnzipFolder $WdpPackagePath "Content/Website/App_Data/Transforms/scch/xdts" $xdtsPath
Get-ChildItem $xdtsPath -File -Include "*.xdt" -Recurse | ForEach-Object {
$targetWebsiteFile = .FullName.Replace(".FullName.Replace("xdtsPath", "").Replace("", "/").Replace(".xdt", "")
DownloadWebsiteFile targetWebsiteFile "Configuration" } configurationPath = (PreparePath 
".\Configuration")
currentDateTime=(Get−Date).ToString("dd−MM−yyyy−hh−mm−ss")currentDateTime=(Get−Date)
.ToString("dd−MM−yyyy−hh−mm−ss")backupPath = (PreparePath ".\Backup-$currentDateTime")
robocopy $configurationPath $backupPath /s
Write-Host "Preparing transformations..." -ForegroundColor Green
nupkgPath=Join−Path(Resolve−Path".")"microsoft.web.xdt.3.1.0.nupkg"nupkgPath=Join−Path(R
esolve−Path".")"microsoft.web.xdt.3.1.0.nupkg"xdtDllBinPath = PreparePath ".\bin"
Invoke-WebRequest -Uri "https://www.nuget.org/api/v2/package/Microsoft.Web.Xdt/3.1.0 " -
OutFile $nupkgPath
UnzipFolder $nupkgPath "lib/netstandard2.0" $xdtDllBinPath
Add-Type -Path (Resolve-Path ".\bin\Microsoft.Web.XmlTransform.dll")
Write-Host "Fill ConnectionStrings..." -ForegroundColor Green
$connectionStringsXdtPath = Join-Path $xdtsPath "App_Config\ConnectionStrings.config.xdt"
((Get-Content -Path $connectionStringsXdtPath -Raw).Replace("{client_id}", 
$CHClientId).Replace("{client_secret}", $CHClientSecret).Replace("{username}", 
$CHUserName).Replace("{password}", $CHPassword).Replace("{uri}", $CHUri).Replace("{Azure 
Service Bus connection string with incoming topic}", 
$CHServiceBusEntityPathIn).Replace("{Subscription name}", 
$CHServiceBusSubscription).Replace("{Azure Service Bus connection string with outcoming 
topic}", $CHServiceBusEntityPathOut).Replace("{Content Hub search page URI}", 
$CHSearchPage).Replace("{External redirect key}", $CHExternalRedirectKey)) | Set-Content -
Path $connectionStringsXdtPath
Write-Host "Running transformations..." -ForegroundColor Green
Get-ChildItem $xdtsPath -File -Include "*.xdt" -Recurse | ForEach-Object {
$targetFilePath = .FullName.Replace(.FullName.Replace(xdtsPath, 
$configurationPath).Replace(".xdt", "")
if (-not(Test-Path targetFilePath -PathType Leaf)) { Write-Verbose "No matching file 
'targetFilePath' for transformation '((.FullName)'. Skipping..."
} else {
ApplyTransform $targetFilePath $.FullName
}
}
Write-Host "Starting MSDeploy..." -ForegroundColor Green
verb="−verb:sync"verb="−verb:sync"source = "-source:package="$WdpPackagePath""
dest="−dest:auto,ComputerName=‘"https://dest="−dest:auto,ComputerName=‘"https://WebA
ppName.scm.azurewebsites.net/msdeploy.axd?site= WebAppName‘",UserName=‘"WebAppNa
me‘",UserName=‘"userName",Password="password‘",AuthType=‘"Basic‘""password‘",AuthType
=‘"Basic‘""iisWebAppParam = "-setParam:name="IIS Web Application 
Name",value="$WebAppName""
coreParam="−setParam:name=‘"CoreAdminConnectionString‘",value=‘"Encrypt=True;TrustServ
erCertificate=False;DataSource=sitecore−xm−sql.database.windows.net,1433;InitialCatalog=s
itecore−xm−core−db;UserId=sqladmin;Password=Sitecore101;‘""coreParam="−setParam:nam
e=‘"CoreAdminConnectionString‘",value=‘"Encrypt=True;TrustServerCertificate=False;DataSour
ce=sitecore−xm−sql.database.windows.net,1433;InitialCatalog=sitecore−xm−core−db;UserId=sqladmin;Password=Sitecore101;‘""masterParam = "-setParam:name="Master Admin 
Connection String",value="Encrypt=True;TrustServerCertificate=False;Data Source=sitecore￾xm-sql.database.windows.net,1433;Initial Catalog=sitecore-xm-master-db;User 
Id=sqladmin;Password=Sitecore101;""
skipDbFullSql="−skip:objectName=dbFullSql"skipDbFullSql="−skip:objectName=dbFullSql"ski
pDbDacFx = "-skip:objectName=dbDacFx"
doNotDeleteRule="−enableRule:DoNotDeleteRule"doNotDeleteRule="−enableRule:DoNotDele
teRule"appOfflineRule = "-enableRule:AppOffline"
retryAttemptsParam="−retryAttempts:retryAttemptsParam="−retryAttempts:RetryAttempts"
retryIntervalParam="−retryInterval:retryIntervalParam="−retryInterval:RetryInterval"
verboseParam = "-verbose" Invoke-Expression "& 'MsDeployPath' --% $verb $source $dest 
$iisWebAppParam $coreParam $masterParam $skipDbFullSql $skipDbDacFx 
$doNotDeleteRule $appOfflineRule $retryAttemptsParam $retryIntervalParam $verboseParam"
Write-Host "Uploading configuration..." -ForegroundColor Green
Get-ChildItem $configurationPath -File -Recurse | ForEach-Object {
$targetWebsiteFile = .FullName.Replace(".FullName.Replace("configurationPath", 
"").Replace("", "/")
UploadWebsiteFile $targetWebsiteFile $_.FullName
}
`


Update the connection strings for the Core and Master admin parameters.

Get ADO.NET connection information (optional - SQL Database only)


• Navigate to the database blade in the Azure portal and, under Settings, select Connection 
strings.

• Review the complete ADO.NET connection string.

Copy the ADO.NET connection string if you intend to use it.

To successfully run the script and install and configure the connector, you must prepare the 
following parameters:

ResourceGroupName - the resource group name in Azure you want to install to.

WebAppName - the name of the Web App in Azure you want to install to.

CHClientId and CHClientSecret - a Content Hub OAuth Client ID and Client Secret. (See 
Create an OAuth client for how to create these).

CHUserName and CHPassword - a Content Hub username and password that is used as the 
identification of Sitecore to access Content Hub.

CHUri - the URI to your Content Hub instance, for example, https://mysandbox.stylelabs.io/ .

CHServiceBusEntityPathIn and CHServiceBusEntityPathOut - to find these connection strings, in Content Hub, create a new action of the type M Azure Service Bus. Make a note of the connection strings in Hub out for CHServiceBusEntityPathIn and Hub in for 
CHServiceBusEntityPathOut. For example:

Congratulation




CHServiceBusSubscription - the name of your Sitecore subscription.

CHSearchPage - the URI to the Search Page you want to use to select DAM Assets, for 
example, https://mysandbox.stylelabs.io/en-us/sitecore-dam-connect/approved-assets .

Run below commands in PowerShell admin mode

cd "C:\Temp\SCCHInstallation"

az account set –subscription “<subscription name or id>”

.\Deploy.ps1 -ResourceGroupName "<MyResourceGroup>" -WebAppName "<MyWebApp>" -
WdpPackagePath "C:\Temp\SCCHInstallation\Sitecore.Connector.ContentHub.WDP.5.0.0-
r00328.4145.scwdp.zip" -CHClientId "<ClientId>" -CHClientSecret "<ClientSecret>" -
CHUserName "<UserName>" -CHPassword "<Password>" -CHUri 
"https://mysandbox.stylelabs.io/" -CHServiceBusEntityPathIn "<Hub out connectionstring>" -
CHServiceBusSubscription "<MySitecoreSubscription>" -CHServiceBusEntityPathOut "<Hub in 
connectionstring>" -CHSearchPage "https://mysandbox.stylelabs.io/en-us/sitecore-dam￾connect/approved-assets"

Note:-
You must run this command against both your CM and your CD Azure PaaS Web Applications.

If you use the DAM functionality in SCCH, to allow the connector to select assets from Content Hub, add all hostnames to the Content-Security-Policy tag.

In the root folder (by default, wwwroot), open the web.config file. Make sure the URL of the 
Content Hub instance (for example, content-hub-url.stylelabs.com ), other delivery hostnames 
(for example, content-hub-url-delivery.stylelabs.cloud), and generated public links (for 
example, content-hub-url.stylelabs.com:8686 ) are added as sources to the Content-Security-Policy tag.

For example:

<add name="Content-Security-Policy" value="default-src 'self' 'unsafe-inline' 'unsafe-eval' 
https://apps.sitecore.net; img-src 'self' data: https://s.gravatar.com 
https://*.wp.com/cdn.auth0.com/avatars https://ids-p-001.sitecorecontenthub.cloud/ 
https://ids-p-001.sitecorecontenthub.cloud/; style-src 'self' 'unsafe-inline' 
https://fonts.googleapis.com; font-src 'self' 'unsafe-inline' https://fonts.gstatic.com; upgrade￾insecure-requests; block-all-mixed-content; child-src 'self' https://ids-p￾001.sitecorecontenthub.cloud/ https://ids-p-001.sitecorecontenthub.cloud/; connect-src 'self' 
https://ids-p-001.sitecorecontenthub.cloud/ https://ids-p-001.sitecorecontenthub.cloud/; 
media-src https://ids-p-001.sitecorecontenthub.cloud/ https://ids-p￾001.sitecorecontenthub.cloud/;" />

Note

In Content Hub, you can configure different delivery hostnames for public links by using the 
AssetExtensionDataConfigurationSetting setting.

If you have configured different hostnames, you must add all the hostnames as sources. You do 
this in the Content-Security-Policy parameter, in the img-src, child-src and connect-src 
properties.

Content Hub Configuration


To allow a Sitecore instance to access content hub, you must add a CORS configuration entry 
with your Sitecore CM instance URL.

Navigate to: Manage -> Settings -> PortalConfiguration -> CORSConfiguration

Enter your CM instance URL (e.g. http://sc92.dev.local ) and click Save.

You must configure the CORS for Sitecore Digital Asset Management (DAM) to allow incoming 
traffic from the Sitecore instance.

To configure the CORS:
• On the Sitecore DAM main menu, click Manage.
• Click Settings.
• On the Settings page, click PortalConfiguration, then click CORSConfiguration.
• Click Add, and add the URL for your Sitecore instance, for example, https://www.sitecore.instance.com .

CORS Congratulation



• Save the changes.

Enable CMP or DAM


By default, installing Sitecore Connect for Content Hub (SCCH) disables both Sitecore Digital Asset Management (DAM) and Sitecore Content Management Platform (CMP). You must re￾enable CMP or DAM if you require the functionality they provide.

To enable CMP or DAM:


On your Content Management server, open the web.config file. The default location is 
wwwroot/web.config

Enable DAM or CMP functionality:


• To enable DAM, change the configuration as follows: <add key="damEnabled:define" 
value="yes"/>

• To enable CMP, change the configuration as follows: <add key="cmpEnabled:define" 
value="yes"/>

Save the file, and refresh your browser window.

The Insert from Sitecore DAM icon is now available in the Rich Text Editor for fields that use the Rich Text Default profile. If you want to access DAM assets in profiles other than Rich Text Default:

• In the Core database, navigate to /sitecore/system/Settings/Html Editor Profiles/Rich Text Default/Toolbar 1.

• Copy the Insert from Sitecore DAM item.

CORE DB item


• Navigate to the Rich Text Editor profile you intend to use, and paste the Insert from Sitecore 
DAM item.

Sunday, July 21, 2024

Security in Sitecore: An Expert Guide

 

Introduction


In the ever-evolving digital landscape, securing web applications is of paramount importance. Sitecore, a powerful and flexible digital experience platform, offers a comprehensive set of tools and features to ensure the security of your website and data. This article aims to provide an in-depth understanding of security in Sitecore, covering best practices, configurations, and advanced strategies to protect your Sitecore environment.


The Importance of Security in Sitecore


Security is crucial in protecting sensitive data, maintaining the integrity of your website, and ensuring compliance with regulatory requirements. Security breaches can lead to data loss, financial loss, and damage to your organization's reputation. Sitecore provides robust security features to safeguard your content, user data, and application, making it an essential aspect of your overall digital strategy.


Database security recommendations


It focusses on protecting your data both at rest and in motion.

To secure data transmission between an instance of SQL Server and a client application (data in motion or transit), use Transport Layer Security (TLS) to encrypt the connection.

To secure physical files, such as data and log files (data at rest), use Transparent Data Encryption (TDE). TDE is configured on the SQL Server side and does not require any specific Sitecore configuration settings. TDE is enabled by default for newly deployed Azure SQL databases, but it is not enabled by default for on-premises deployments.

Important: TDE does not encrypt the communication channel or the data itself, meaning that anyone with database access can still read sensitive data.

For encrypting sensitive data at rest, use the Always Encrypted feature. This feature ensures a separation between those who own and process the data and those who manage it but must not access sensitive information. Only the client application can decrypt and utilize sensitive data.

Always Encrypted configures encryption for individual database columns containing sensitive data, so not all columns may be encrypted.

Note: Not all Sitecore databases support the Always Encrypted configuration. Supported Sitecore databases include the xDB Collection database and the Sitecore Cortex Processing database.


Control User Access to Web Resources


You can configure access privileges for web resources using the <location> tag in the Web.config file. The following example denies access to the /sitecore path for all users except for admin and webmaster:


<location path="sitecore">

<system.web>

<authorization>

<deny users="*"/>

<allow users="admin, webmaster"/>

</authorization>

</system.web>

</location>


You can also configure the Web.config file to use Windows ASP.NET groups and users. 

Note: By default, only Core roles use the <location> tag, and each Core role is configured differently. We recommend auditing your location tags as part of your security review process.


Update the Administrator Password


Prior to deploying your Sitecore installation, it is essential to change the administrator password to a strong, secure password. This helps prevent unauthorized users from accessing the admin account using the default password.


Create a New Administrator Account

For additional security, Sitecore recommends creating a new administrator account with a unique name and disabling the default administrator account. This provides an extra layer of protection.


Update the Hash Algorithm for Password Encryption


By default, Sitecore uses the Microsoft ASP.NET membership provider for user management.

When setting up a new website, it is crucial to replace the default weak hash algorithm (SHA1) used for encrypting user passwords with a stronger one. 

Steps to Change the Hash Algorithm:

  1. Log in as an administrator:

    • Ensure you are logged in as an administrator while the SHA1 configuration is still active in both Sitecore XP and the Identity Server.

  2. Modify the configuration files:

    • Ensure both Sitecore and the Identity Server use the same hash algorithm setting.

  3. Update the web.config file:

    • In the <membership> node, set the hashAlgorithmType to a stronger algorithm. We recommend using SHA512.

  4. Update Sitecore Identity Server:

    • If you are using Sitecore Identity, you must also change the algorithm in the Identity Server configuration. Specify the algorithm in the PasswordHashAlgorithm node to SHA512 in the \sitecore\Sitecore.Plugin.IdentityServer\Config\identityServer.xml file.

  5. Restart the Identity Server:

    • Restart the Sitecore Identity app service.

  6. Change the admin password:

    • Use the User Manager application to update the admin password so that it is hashed with the new algorithm.

Note: After changing the hash algorithm, you cannot manually type a new admin password to change it. Instead, click "Generate" to create a new hashed admin password.

  1. Update other user passwords:

    • Ensure all user passwords are updated to be hashed with the new algorithm.



Enabling and Disabling Administrative Tools


Sitecore administrative tools can be helpful for troubleshooting issues in a production environment, but for security reasons, you must:

  • Always disable them as part of the deployment process.

  • Always disable them when they are not in use.

  • Never enable them on the Content Delivery and xDB Processing roles. It's safe to delete the administrative tools folder on these roles.

  • Only enable them on Content Management roles that are not exposed to the internet.

Administrative tools are ASPX files with .aspx extensions, located in the <webroot>\sitecore\admin\ folder and its subfolders.

Disabling an Administrative Tool

To disable an administrative tool:

  1. Navigate to the administrative tools folder.

  2. Click on the tool you want to disable.

  3. Add .disabled to the tool's filename. For example, rename cache.aspx to cache.aspx.disabled.

Admin Files
Admin files



Disabling Client RSS Feeds


If your Sitecore installation contains sensitive information that you want to protect, you can disable the Sitecore client RSS feeds.

RSS technology allows users to follow an RSS link directly to the item specified in the feed's URL. Most RSS readers do not support authentication, meaning users subscribed to Sitecore client RSS feeds can access the specified items directly without identifying themselves through the Sitecore security system. However, the Sitecore security system verifies user authorization when they attempt any actions associated with the client feed.

If an unauthorized user gains access to the URL of a client RSS feed:

  • They can follow the link and view all the content in the client feed, even if their security permissions do not grant access to the item.

  • They cannot perform any actions on the content.

  • They cannot view any other content.

  • They cannot gain access to the username or password of the original feed owner.

  • They cannot modify the link to access other content.

Important: Sitecore users should not share client RSS feeds.

To disable Sitecore client RSS feeds:

  1. Open the web.config file.

  2. Locate the <httpHandlers> section (it may be called <Handlers> depending on your IIS pool).

  3. Remove the following handler:


<add verb="*" path="sitecore_feed.ashx" type="Sitecore.Shell.Feeds.FeedRequestHandler, Sitecore.Kernel"/>


Removing this handler disables all client feeds available within Sitecore. Any public RSS feeds you have created will still be accessible to website visitors.


Disabling SQL Server Access from XSLT


Sitecore includes an xslExtension helper for use with SQL Server. It is strongly recommended to disable this helper if:

  • You do not need it.

  • You are not using Sitecore XSLT renderings.

To disable the xslExtension helper:

  1. In the App_Config/Include folder, create a patch file. Name the file with a .config extension.

  2. Insert the following code into the patch file:


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">

<sitecore>

<xslExtensions>

<extension type="Sitecore.Xml.Xsl.SqlHelper, Sitecore.Kernel">

<patch:delete/>

</extension>

</xslExtensions>

</sitecore>

</configuration>



Enhance Login Security


You can enhance the security of the Sitecore login page by taking the following steps:

  1. Enable SSL: Make the login page accessible only through SSL.

  2. Turn off autocomplete for usernames: Prevent Sitecore from automatically completing usernames during login. This is especially useful if content authors log in from shared or public computers.

  3. Disable the "Remember me" checkbox: Remove the option for users to save their login credentials on the login page.

Steps to Implement:

  1. Turn off autocomplete for usernames:

    • Open the sitecore.config file.

    • Set the Login.DisableAutoComplete setting to true. This disables autocomplete on the Sitecore login forms located at /sitecore/login/default.aspx and /sitecore/admin/login.aspx.

  2. Disable the "Remember me" checkbox on the login page:

    • On the Sitecore Identity Server role, open the sitecore/Sitecore.Plugin.IdentityServer/Config/identityServer.xml file.

    • Set the AllowRememberLogin setting to false. This also ignores any existing "Remember me" cookies, requiring all users to log in again.

  3. Disable the "Remember Last Logged In User Name" setting:

    • Open the sitecore.config file.

    • Set the Login.RememberLastLoggedInUserName setting to false. This prevents the browser from remembering the username of the last logged-in user.

Implementing these measures will significantly improve the security of your Sitecore login process.


Restrict Access to XML, XSLT, and MRT Files


To enhance the security of your Sitecore installation, you should limit access to XML, XSLT, and MRT files. This involves editing the web.config file with general Sitecore settings and disabling the web.config file with EXM settings.

Steps to Limit Access:

  1. Open the web.config file with general Sitecore settings:

    • This file is located in the top-level folder of your installation or in the Website folder.

  2. Add the following lines in the <system.webServer><handlers> section:


<system.webServer>

<handlers>

<add path="*.xml" verb="*" type="System.Web.HttpForbiddenHandler" name="xml (integrated)" preCondition="integratedMode"/>

<add path="*.xslt" verb="*" type="System.Web.HttpForbiddenHandler" name="xslt (integrated)" preCondition="integratedMode"/>

<add path="*.config.xml" verb="*" type="System.Web.HttpForbiddenHandler" name="config.xml (integrated)" preCondition="integratedMode"/>

<add path="*.mrt" verb="*" type="System.Web.HttpForbiddenHandler" name="mrt (integrated)" preCondition="integratedMode"/>

</handlers>

</system.webServer>


This configuration restricts access to all XML, XSLT, and MRT files.

  1. Disable the web.config file with EXM settings:

    • This file is located in the \sitecore modules\Shell\EmailCampaign\ folder.

Allow Unrestricted Access to a Specific File Path

After restricting general access, you might need to allow access to specific files.

  1. Open the web.config file with general Sitecore settings.

  2. Add the following line before the handlers that limit access:


<add path="sitemap.xml" verb="GET" type="System.Web.StaticFileHandler" name="xml allow" />

Replace sitemap.xml with the specific file to allow unrestricted access to.


Restrict Access to PhantomJS


By default, PhantomJS is not disabled on Content Delivery, xDB Processing, and xDB Reporting roles. It is used by Sitecore for content testing and generating thumbnails. To enhance security, you should move PhantomJS outside the webroot folder, limit its permissions, and disable it on roles where it is not needed.

Steps to Secure PhantomJS:

  1. Move PhantomJS Outside the Webroot Folder:

    • By default, PhantomJS is located in the <webroot>\$(dataFolder)\tools\phantomjs\ folder. The $(dataFolder) variable defaults to App_Data, placing PhantomJS in <webroot>\App_Data\tools\phantomjs\.

    • This location can potentially expose the phantomjs.exe program file if Sitecore security settings are not properly configured.

  2. Update Configuration Settings:

    • Sitecore references PhantomJS for content testing through the ContentTesting.PhantomJS.ExecutablePath setting in the <webroot>\App_Config\Sitecore\ContentTesting\Sitecore.ContentTesting.config patch file.

    • For thumbnail generation, Sitecore uses the following settings:

      • PhantomJsExePath references the phantomjs.exe file.

      • PhantomJsRenderScriptPath references the render.js file.

Example Configuration to Move PhantomJS:

  1. Move the PhantomJS Folder:

    • Move the <webroot>\App_Data\tools\phantomjs\ folder to a new location, such as C:\phantomjs1\. Optionally, you can define separate folders for content testing and thumbnails (e.g., phantomjs1 for content testing, phantomjs2 for thumbnails).

  2. Create a Patch File:

    • In the <webroot>\App_Config\Include\ folder, create a patch file named MovePhantomJSFolder.config.


  1. Insert the Following Configuration:


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:security="http://www.sitecore.net/xmlconfig/security/">

<sitecore>

<settings>

<setting name="ContentTesting.PhantomJS.ExecutablePath" value="C:\phantomjs1\phantomjs.exe" />

<setting name="PhantomJsExePath" value="C:\phantomjs2\phantomjs.exe" />

<setting name="PhantomJsRenderScriptPath" value="C:\phantomjs2\render.js" />

</settings>

</sitecore>

</configuration>


  1. Move Contents from the App_Data Folder:

    • Transfer the contents from the App_Data folder to the new data folder (e.g., D:\SC\Data).

  2. Important Considerations:

    • The App_Data folder is defined by default in the dataFolder variable in the Sitecore.config file.

    • When creating a new location for PhantomJS.exe (e.g., C:\PhantomJs), ensure only the files originally found inside the <webroot>\App_Data\tools\phantomjs folder are moved to the new location.

By following these steps, you can secure your Sitecore installation by limiting access to PhantomJS and reducing potential vulnerabilities.


Protect Media Requests


The media request protection feature in Sitecore restricts media URLs with dynamic image-scaling parameters, ensuring that only valid server-generated requests are processed. This helps optimize server resource usage and disk space by avoiding unnecessary processing of invalid requests.

To enhance the security and functionality of media request protection, you can patch the Sitecore.Media.RequestProtection.config file.

Steps to Optimize Media Request Protection:

  1. Create a Patch File:

    • In the App_Config\Include\ folder, create a new patch file named MediaRequestProtectionSecret.config (or another name of your choice).

  2. Insert the Configuration Code:

    • Add the following code to the patch file:


<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">

<sitecore>

<settings>

<setting

  name="Media.RequestProtection.SharedSecret" value="YourRandomGeneratedString"/>

</settings>

</sitecore>

</configuration>


  1. Save the Patch File:

    • Save the newly created patch file to apply the changes.

Important Note:

  • Consistency in Multi-Server Environments:

    • In a multi-server setup, the same Media.RequestProtection.SharedSecret value must be used across all servers. This ensures that dynamic image scaling works correctly, regardless of which server generates the image URL and which server handles the request.

By implementing these changes, you can strengthen the protection of media requests and ensure efficient and secure handling of dynamic image-scaling requests in your Sitecore environment.


Remove Header Information from Responses


Enhancing security and saving bandwidth can be achieved by removing header information from responses sent by your website. These headers often reveal details about your website's framework that are unnecessary to disclose.

Remove the X-Aspnet-Version HTTP Header

The X-Aspnet-Version header reveals the version of ASP.NET being used, which can be useful for potential attackers. By removing this header, you not only save a small amount of bandwidth but also obscure this information.

To remove the X-Aspnet-Version HTTP header, add the following configuration to your web.config file:

<system.web>

<httpRuntime enableVersionHeader="false" />

</system.web>


Remove the X-Powered-By HTTP Header

The X-Powered-By header indicates which version of ASP.NET is being used. Removing this header helps prevent the exposure of this information.

To remove the X-Powered-By HTTP header, include the following code in your web.config file:


<system.webServer>

<httpProtocol>

<customHeaders>

<remove name="X-Powered-By" />

</customHeaders>

</httpProtocol>

</system.webServer>


Implementing these changes will contribute to your website's security by obscuring the details of your framework and saving a minimal amount of bandwidth.


Restrict Access to the Client


Disable Forms Authentication

To ensure Sitecore does not handle any authentication requests, you can disable Forms authentication.

To disable Forms authentication:

  1. Open the <webroot>\Web.config file.

  2. Locate the <authentication> node.

  3. Modify the mode attribute from Forms to None.


<authentication mode="None" />


Deny Access to the Copyrights Folder

The sitecore/Copyrights/ folder on the CD server contains license text files for third-party components used by Sitecore. To prevent unauthorized access to this folder, configure Sitecore to deny access.

To deny access to the folder:

  1. Add the following setting to the <handlers> section of the web.config file on your CD server:

<add name="StopSitecoreCopyrightsDirectoryBrowsing" path="sitecore/Copyrights/*" resourceType="Directory" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />


These measures will enhance security by restricting unauthorized access and ensuring that authentication requests are handled appropriately.


Disable the Upload Watcher


To ensure that files can only be uploaded to Sitecore through the Media Library and to maintain control over file uploads, you should disable the Upload Watcher. This will prevent automatic uploads of files placed in the upload folder to the Media Library.

To disable the Upload Watcher:

  1. Open the web.config file.

  2. Locate the <system.webServer><modules> section.

  3. Remove the following line:


<add type="Sitecore.Resources.Media.UploadWatcher,Sitecore.Kernel" name="SitecoreUploadWatcher" />


By disabling the Upload Watcher, you restrict file uploads to the Sitecore client interface, ensuring better management and security of uploaded files.


Secure Telerik Controls


Sitecore utilizes certain Telerik UI controls, which are only employed in a Content Management environment. To minimize security risks:

  1. In Non-Content Management Environments:

    • Open the web.config file.

    • Remove the following nodes:

<add name="Telerik_Web_UI_DialogHandler_aspx" verb="*" preCondition="integratedMode" path="Telerik.Web.UI.DialogHandler.aspx" type="Telerik.Web.UI.DialogHandler" />

<add name="Telerik_Web_UI_SpellCheckHandler_axd" verb="*" preCondition="integratedMode" path="Telerik.Web.UI.SpellCheckHandler.axd" type="Telerik.Web.UI.SpellCheckHandler" />

<add name="Telerik_Web_UI_WebResource_axd" verb="*" preCondition="integratedMode" path="Telerik.Web.UI.WebResource.axd" type="Telerik.Web.UI.WebResource" />


  1. In Content Management Environments:

    • Configure the encryption keys for the Telerik upload control by modifying the web.config file.

    • In the <appSettings> section, add nodes for the Telerik configuration encryption keys:

<appSettings>

<add key="Telerik.AsyncUpload.ConfigurationEncryptionKey" value="YOUR_ENCRYPTION_KEY_HERE" />

<add key="Telerik.Upload.ConfigurationHashKey" value="YOUR_ENCRYPTION_KEY_HERE" />

<add key="Telerik.Web.UI.DialogParametersEncryptionKey" value="YOUR_ENCRYPTION_KEY_HERE" />

</appSettings>

  • Replace YOUR_ENCRYPTION_KEY_HERE with a secure string of random characters and numbers. The key should be at least 32 characters long, with a maximum length of 256 characters.


Separate Content Management and Content Delivery Servers


To enhance security as part of a defense-in-depth strategy, it's crucial to minimize the exposure of your deployment.

Sitecore advises deploying distinct servers for Content Management (internal use only) and Content Delivery (public-facing) in a production environment. Your Content Management server should not be accessible from the internet.

If it is necessary to expose your Content Management server to the internet, you should:

  • Use HTTPS to encrypt communications with the Content Management server.

  • Implement IP Filtering to restrict access to a whitelist of approved clients.


Enforce a Strong Password Policy


Sitecore utilizes the Microsoft ASP.NET Membership Provider for user management by default. It is advisable to customize the password policy to align with your organization's security requirements.

In the web.config file, within the <membership> section, you can configure the following properties to enforce a robust password policy:

  • minRequiredPasswordLength

  • minRequiredNonAlphanumericCharacters

  • maxInvalidPasswordAttempts

  • passwordAttemptWindow

  • passwordStrengthRegularExpression


Protect Connection String Passwords from Unauthorized Access


Sitecore stores connection string passwords in the App_Config\ConnectionStrings.config file. To prevent unauthorized access to these passwords, it is advisable to encrypt this file.

For securing connection strings in PaaS deployments using Kudu:

  1. Navigate to App Service, then Development Tools, and click on Advanced Tools.

Advanced Tools

  1. Open Kudu.

  2. Click on Debug console, select Powershell, and navigate to site/wwwroot/App_config. Open the ConnectionStrings.config file.

Kudu

  1. In the ConnectionStrings.config file, remove the values for the database connection strings and save the changes. For instance, remove the values for core, master, security, and web.

Connection Strings

  1. Go back to App Service and navigate to Settings, then Configuration. In the Connection strings section, click New connection string. Add the connection strings for all the databases you need and click OK.

Connection Strings

  1. Click Save to apply the changes.


Updates and Disaster Recovery


We recommend using the latest version of Microsoft Windows supported by Sitecore and ensuring that your system remains updated with the latest security patches. Utilize the Windows Update/Automatic Update service to keep your systems current.

Additionally, we advise developing a comprehensive disaster recovery plan that includes:

  • A strategy for obtaining new or temporary equipment.

  • Procedures for restoring backups.

  • Regular testing of the recovery plan.


Conclusion


Securing your Sitecore environment requires a comprehensive approach that encompasses application security, data protection, and infrastructure security. By following the best practices and strategies outlined in this article, you can ensure that your Sitecore deployment is secure and resilient against potential threats.

By following the detailed guidelines and implementing the solutions provided in this article, you will be well-equipped to secure your Sitecore environment and protect your digital assets from potential threats.