Dot Peekser Logo

#Sitecore#Cumulative hotfix#Sitecore 10.2.1 rev. 009116 PRE

Sitecore Cumulative hotfix 009116 PRE in docker

by Tobias Demski on

Sitecore recently published a new cumulative hotfix which should be applied to all Sitecore roles due to a new security issue.
⁠KB Article: Security Bulletin SC2023-001-568150
⁠Sitecore recommends to install a cumulative hotfix instead of patching just the security hole.

As we have a customer running Sitecore in version 10.2.0 docker managed cloud environment we had to configure our docker setup / deployment to work with pre releases.

Relevant links:

The second link is a good starting point to configure your Dockerfile for each role.
⁠In short, you need an option to provide a pre-release through arguments in a Dockerfile and copy the related files from the image to your custom image.

Example configuration for the cm/cd role

[yml]: Dockerfile
# escape=`

ARG BASE_IMAGE
ARG TOOLING_IMAGE
ARG SOLUTION_IMAGE
ARG DELTA_ASSET_IMAGE


FROM ${TOOLING_IMAGE} as tooling
FROM ${SOLUTION_IMAGE} as solution
FROM ${DELTA_ASSET_IMAGE} as deltaAssetImage
FROM ${BASE_IMAGE}

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

ARG ENVIRONMENT_NAME

WORKDIR C:\\

# Copy development tools and entrypoint
COPY --from=tooling C:\tools .\tools
# Copy solution transforms
COPY --from=solution \artifacts\transforms\ .\transforms\solution\
# Copy role transforms
COPY .\transforms\ .\transforms\role\

# Copy cumulative hotfix data
COPY --from=deltaAssetImage \platform\cm .\

WORKDIR C:\inetpub\wwwroot
COPY --from=solution c:\artifacts\website .

#apply cumulative hotfix files
COPY [".\\hotfix\\10.2.1 rev. 009116 PRE\\", ".\\"]

# Apply role web.config transform
RUN C:\tools\scripts\Invoke-XdtTransform.ps1 -Path C:\inetpub\wwwroot\Web.config -XdtPath C:\transforms\role\Web.config.xdt

# Apply cumulative hotfix transform file
RUN C:\tools\scripts\Invoke-XdtTransform.ps1 -Path C:\inetpub\wwwroot\Web.config -XdtPath C:\transforms\role\Web.config.Sitecore.Hotfix.009116-PRE.xdt


# Install IISRewrite Module
RUN Invoke-WebRequest http://download.microsoft.com/download/D/D/E/DDE57C26-C62C-4C59-A1BB-31D58B36ADA2/rewrite_amd64_en-US.msi -OutFile c:/inetpub/rewrite_amd64_en-US.msi ; `
 powershell -Command Start-Process c:/inetpub/rewrite_amd64_en-US.msi -ArgumentList "/qn" -Wait

# Perform solution transforms
#RUN C:\tools\scripts\Invoke-XdtTransform.ps1 -Path .\ -XdtPath C:\transforms\solution\DockerExamples.Website

# Perform role transforms
#RUN C:\tools\scripts\Invoke-XdtTransform.ps1 -Path .\ -XdtPath C:\transforms\role

Based on the existing Dockerfile we extended the file with line 28 to import all required files from the cumulative hotfix image. Line 34 copy all required files from the Instructions.md.
Line 40 should only applied to the Dockerfile for the CD role and this removes the sitecore_xaml.ashx from the handler.

The required files are placed next to the Dockerfile which we named hotfix and the version number.
The structure of the folder is based on the location where the files needs to be applied. The Web.config.Sitecore.Hotfix.009116-PRE.xdt is placed in the transforms folder (lies next to the Dockerfile).

File Structure
- Repo
  - docker
    - cm
      - Dockerfile
      - transforms
        - Web.config.Sitecore.Hotfix.009116-PRE.xdt
      - hotfix
        - 10.2.1 rev. 009116 PRE
          - App_Config
            - Include
              - Hotfix
                - Sitecore.Hotfix.009116-PRE.config
            - Sitecore
              - ContentSearch
                - Sitecore.ContentSearch.Solr.EnableConnectionLeaseTimeout.config

Here is a working config file which contains all settings from the Instructions.md file.

[xml]: Sitecore.Hotfix.009116-PRE.config
<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>
      <!--  RENDERING - SITE RESOLVING MATCH DATABASE
          Affects how links are rendered when Rendering.SiteResolving is enabled.
          If true, the link provider will check if the target item database name matches a site database attribute.
          This ensures that the correct site is resolved when sites have different databases but the same rootPath and language.
      -->
      <setting name="Rendering.SiteResolvingMatchDatabase" value="true"/>

      <!-- RESTRICT DELETE BY INDEX NAME If enabled, the delete command removes only documents in the solr core/collection which are associated with the current index. The value must be set to true, if multiple indexes are stored in a single Solr core/collection. Default vaue: true -->
      <setting name="ContentSearch.Solr.RestrictDeleteByIndexName" value="true"/>

      <!-- USE SOFT COMMITS If enabled, soft commits are used. The auto-commit must be enabled and configured in solr before enabling this setting. Default vaue: false -->
      <setting name="ContentSearch.Solr.UseSoftCommits" value="false"/>

      <!-- CONTENT SEARCH - INDEXING READACCESS WITH PRIORITY TO ENABLE FIX FOR 493002 This setting specifies whether or not to indexing readaccess permission with proprity and search with prioriry. When enabled it will have extra priority to the readaccess permission when indexing e.g. User > Entity > Descendents. Default value: false -->
      <setting name="ContentSearch.Enable-493002" value="false"/>

      <!-- VERSION INSTALL MODE FOR NEW ITEMS Sets the default installation mode for the versions of new items when installing a Sitecore package. Merge - merge versions by version number Append - append version if version with same revision number is not exists Default value: Append -->
      <setting name="VersionInstallModeForNewItems" value="Append"/>
    </settings>

    <customHandlers role:require="ContentDelivery">
      <handler trigger="-/xaml/" handler="sitecore_xaml.ashx">
        <patch:delete/>
      </handler>
      <handler trigger="~/xaml/" handler="sitecore_xaml.ashx">
        <patch:delete/>
      </handler>
    </customHandlers>
  </sitecore>
</configuration>

The Instructions.md contains a whole configuration which we have to apply in the App_Config/Sitecore/ContentSearch folder.

[xml]: Sitecore.ContentSearch.Solr.EnableConnectionLeaseTimeout.config
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"
               xmlns:role="http://www.sitecore.net/xmlconfig/role/"
               xmlns:search="http://www.sitecore.net/xmlconfig/search/">
  <sitecore role:require="Standalone or ContentManagement or ContentDelivery"
            search:require="solr">
    <contentSearch>
      <indexConfigurations>
        <solrHttpWebRequestFactory type="Sitecore.ContentSearch.SolrProvider.SolrNetIntegration.Requests.SolrHttpWebRequestAdaptingFactory, Sitecore.ContentSearch.SolrProvider">
          <param type="Sitecore.ContentSearch.Remote.Http.CompositeHttpWebRequestFactory, Sitecore.ContentSearch">
            <initializers hint="list:AddInitializer">
              <!-- Add ConnectionLeaseInitializer to enable setting the value of ConnectionLeaseTimeout in HttpWebRequest This is useful for disaster recovery scenarios when hosting multiple solr servers behind a DNS -->
              <connectionLeaseTimeout type="Sitecore.ContentSearch.SolrProvider.SolrNetIntegration.Requests.SolrHttpRequestInitializerFactory, Sitecore.ContentSearch.SolrProvider" factoryMethod="EnableConnectionLeaseTimeout"/>
            </initializers>
          </param>
        </solrHttpWebRequestFactory>
      </indexConfigurations>
    </contentSearch>
    <settings>
      <!-- CONNECTION LEASE TIMEOUT The timeout interval for the Solr server HttpWebRequest connection lease. A value of 00:00:00 means that the active HttpWebRequest will immediately be closed after it completes servicing the request. A value of 00:03:00 means that the active HttpWebRequest will be closed 3 minutes after it completes servicing the request. Default value: 00:03:00 -->
      <setting name="ContentSearch.Solr.HttpWebRequest.ConnectionLeaseTimeout"
               value="00:03:00"/>
    </settings>
  </sitecore>
</configuration>


A transform file for the CD role to remove the sitecore_xaml.ashx handler from the Web.config.

[xml]: Web.config.xdt
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">	
  <system.webServer>
    <handlers>
      <add path="sitecore_xaml.ashx" xdt:Transform="Remove" xdt:Locator="Match(path)" />
    </handlers>
  </system.webServer>
</configuration>

For the hotfix we created an additional compose file to provide the cumulative hotfix image for the build command.

[yml]: docker-compose.xp1.override.prerelease.yml
services:
  cd:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  cm:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  cortexprocessing:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  cortexprocessingworker:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  cortexreporting:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  id:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  prc:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  xdbautomation:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  xdbautomationrpt:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  xdbautomationworker:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  xdbcollection:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  xdbrefdata:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  xdbsearch:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}
  xdbsearchworker:
    build:
      args:
        DELTA_ASSET_IMAGE: ${SITECORE_PRE_DOCKER_REGISTRY}sitecore-xp1-assets:${SITECORE_PRE_VERSION}

After removing all old images / containers and executing docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.override.prerelease.yml up -d we created our new images with the hotfix and spun up our containers in detached mode (-d).

If we go now to the content editor under the license details we can see the new version.

Cloud deployment

As we already mentioned, our customer is in managed cloud docker. Therefor the base setup for a docker deployment is already in place.

In our Azure DevOps pipeline we adjusted the task for the docker build

- task: DockerCompose@0
  displayName: 'Build Images'
  inputs:
    containerregistrytype: 'Azure Container Registry'
    azureSubscription: '$(AZURE_SUBSCRIPTION)'
    azureContainerRegistry: '$(AZURE_CONTAINER_REGISTRY)'
    dockerComposeFile: 'docker-compose.xp1-azure.yml'
    additionalDockerComposeFiles: |
      docker-compose.xp1-azure-build.override.yml
      docker-compose.xp1-azure.override.prerelease.yml
    qualifyImageNames: false
    action: 'Build services'
    additionalImageTags: '$(Build.BuildNumber)-$(Build.SourceBranchName)'
    includeLatestTag: true
    arguments: '--parallel'

In our library we set the variable for SITECORE_PRE_DOCKER_REGISTRY to scr.sitecore.com/sxp-pre/ and for SITECORE_PRE_VERSION we set the value to 10.2.1.009116.387-10.0.17763.4131-1809

Thats it! - YAY!

Tobias Demski

I'm a Software Engineer with 10+ years of experience. Passionate about software development, and I like to get challenged by new stuff.