Bug Fixes and Resulting Recommendations

Objective

After completing this lesson, you will be able to identify fixed bugs and consequent recommendations

Possible infinite loop in Buy X Get Y Discount/Free promotions

An unexpected infinite loop issue may occur if you use two containers that contain identical products or categories to configure your promotion rule for Buy X Get X Discount/Free scenarios. For more information, see Containers Best Practice for Buy X Get X Discount/Free.

To avoid such infinite loop issues, a new constraint PromotionSourceRuleConditionConstraint was introduced to display a warning message in the Backoffice when two containers with identical products or categories are detected. For more information, see Configuring Containers with Identical Products or Categories Detection.

ResponseBody annotation now returns XML objects instead of JSON objects

In SAP Commerce Cloud 2211.27 or lower versions, methods annotated with @ResponseBody in a Spring MVC controller class returned JSON objects by default. Starting with version 2211.28, these methods return XML objects instead. This breaking change is due to the introduction of the library com.fasterxml.jackson.dataformat:jackson-dataformat-xml in the azurecloud extension and may cause the handing of the API response to fail. For more information, see 3527679

Additional Issues

To resolve issues with methods annotated with @ResponseBody in Spring MVC controller classes returning XML objects instead of JSON objects and RestTemplate classes failing to convert messages, the jackson-dataformat-xml library has been removed from SAP Commerce Cloud. The issues were noticed after the introduction of the Microsoft Azure Java Client 12.x libraries in the 2211.28 update release. Removing the jackson-dataformat-xml library was possible after upgrading to new versions of selected libraries. For a full list of library changes, see Library Changes. For more information on the introduction of Microsoft Azure Java Client 12.x, see Upgrading to Selected Microsoft Azure Java Client 12.x Libraries.

Using deprecated password encoder now throws an error

The issue regarding the deprecated PBKDF2 with HMAC-SHA1 salted hashing algorithm has been resolved. Any attempt to use this password encoder when the legacy.password.encoding.enabled flag is set to false throws an exception in the log as expected.

In addition, the value of the otp.customer.login.token.code.encoder property in the project.properties file has been set to the current default (Argon2). The property determines the hashing algorithm used to generate a One-Time Password token after user login, so the property should specify the safest algorithm to ensure the integrity and confidentiality of user sessions.

SSO Issues

New Behavior for SSO Password Encoding

To improve security, we've introduced a new behavior for password encoding used at Single Sign-On (SSO).

If SSO-specific password encoding is not explicitly set, it now falls back to the default encoding. The hard-coded bcrypt fallback has been removed, making the system more flexible and consistent with the Platform configuration.

SSO Issues for Newly-Created Users

Some customers might have experienced an issue of newly created users being unable to sign in to the storefront through Single Sign-On (SSO). This problem stemmed from inconsistencies in handling password encoding across different parts of the system and a technical issue of NullPointerException. More specifically, for core.plainTextEncoder, passwords were always re-encoded, preventing null values. For other encoders, the raw encoded password was returned, which could be null for new users.

To eliminate login failures, we’ve introduced the following modifications:

  • Updated the password comparison logic in the UserManager class to correctly compare a provided password (hashedPassword) against a stored password (encodedPasswordFromDB)
  • Modified the getEncodedPassword method to handle cases where a user's encoded password is null, falling back to a default encoding method where a new user might not have an encoded password set yet

These changes maintain compatibility with various password encoder types, including PlainTextPasswordEncoder and argon2PasswordEncoder.

Note

As an exception to our standard phased roll-out approach, the following changes have been implemented immediately for security and compliance reasons:

In bin/ext-platform-optional/samlsinglesignon/src/de/hybris/platform/samlsinglesignon/DefaultSSOService.java:

  • The constant MD5_PASS_ENCODING has been removed as it refers to the deprecated and insecure MD5 algorithm.
  • The constant BCRYPT_PASS_ENCODING has been marked as deprecated.

The solution doesn’t rely on legacy mode, taking into account the planned removal of old, insecure hashing strategies by Q3 2025.

For more information, see Improved Security of Password Handling.

Improved performance of guest user checkout

Some customers were experiencing performance degradation due to excessive Database Transaction Unit (DTU) usage in the database.

The problem was traced to a resource-intensive database query that was launched during the guest user checkout process, specifically when adding products to the cart. To eliminate the problem, we have optimized the following query, which was part of the registerGuestForAnonymousCheckout process in the ServiceLayer Direct mode for persistence:

SQL
12
SELECT TargetPK,max(RSequenceNumber) FROM pgrels WHERE TargetPK IN (?) GROUP BY TargetPK

The fix consists in the change of loading of sequenceNumbers from eager to lazy, so they are now loaded only when required by specific relations, successfully mitigating the previous slowdowns.

Validating only active process definitions

Some customers might have experienced issues while trying to add a new transition as part of the DynamicProcessDefinition. Specifically, the system failed to recognize modifications to the OrderManualChecked action in the order management process during a system update. This prevented the manual fraud check step from being added to the order processing workflow handled by the customer support agent.

The root cause was traced to the system's attempt to validate both the old and new versions of the DynamicProcessDefinition simultaneously. Since the old definition didn't contain the newly added transition, it couldn’t be properly mapped, leading to a system exception.

Now only active process definitions are validated. This approach prevents unnecessary validation of inactive process definitions. The system can now properly recognize and apply modifications to active workflows, such as adding the manual fraud check step to the order processing workflow.

Note

Modifying bean definitions in the running system can cause breaking changes incompatible with existing processes.

To avoid such issues in production environments, we recommend that you introduce a new bean class, preferably a versioned one, in the*-spring.xml file. This approach creates a new entry in the DynamicProcessDefinition with the active flag set to true and a higher version number, while marking the previous entry as inactive (active=false).

By following this practice, you can proactively mitigate potential issues with process definitions and maintain better compatibility between versions.

Improved resiliency during server startup

Some customers might have experienced problems with server startup resilience in the face of temporary database connection issues.

If the database connection was dropped while the system was attempting to load essential database metadata (such as persistence information for non-abstract types), the server startup proceeded, and the Spring Context was loaded. However, the system did not attempt to reload the missing persistence metadata, nor did it fail the server startup after multiple attempts to recover. Consequently, while the server showed an alive status and was up and running, critical functionalities were impaired, as the essential persistence metadata was not loaded, leading to operational issues. Ultimately, even brief network issues prevented the system from recovering after failing to load persistence information, causing deployments to become indefinitely stalled and leading to potential extended downtime.

The system now includes intelligent retry logic and graceful error handling to make server startup resilient against temporary database connectivity issues. More specifically, we have introduced the following key improvements:

  • Automatic retry mechanism: When database connection issues occur specifically during the loading of persistence information within the startup process, the system automatically retries connecting and loading the required persistence information. By default, the retry duration is 120 seconds, but it's possible to configure the maximum waiting time through the persistence.loading.max.wait.duration property.
  • Graceful exception handling: If the database remains unavailable after the maximum wait time, the system returns a PersistenceInfoNotLoadedException and can either shut down cleanly or resort to legacy behavior, controlled by the persistence.loading.skip.exception.legacy.flag (with a default setting of false).
  • Controlled shutdown process: When persistence loading fails, the system prevents Spring Context creation and shuts down gracefully, avoiding stuck states.

This fix eliminates the problem of costly production outages caused by deployment failures and reduces deployment time and complexity by automatically handling temporary issues. At the same time, it offers configurable resilience settings for different operational requirements.

Removed multiple languages from CoddeMirror library

We have addressed a security vulnerability in CodeMirror 5.65.18 that affected the mode/markdown/markdown.js component. The vulnerability involves a regular expression denial-of-service (ReDoS) attack that could cause application freezing or significant performance degradation.

To mitigate this security risk, we have removed multiple language modes from the CodeMirror library in the hac extension, retaining only the following four essential modes:

  • clike
  • groovy
  • javascript
  • sql

All other language modes (including the vulnerable markdown mode) have been removed from the package.

For a complete list of over 100 removed language modes, consult the following page: What's new in Update Release 2211.45

If you want to use the hac extension with CodeMirror library modes other than the four retained modes listed above, add them back manually to the extension:

Option 1: Add Full CodeMirror via WebJars

Add the complete CodeMirror library to yourextension's external-dependencies.xml:

XML
123456
<dependency> <groupId>org.webjars.npm</groupId> <artifactId>codemirror</artifactId> <version>5.65.20</version> </dependency>

Caution

The full CodeMirror 5.65.20 version still contains the vulnerability in markdownmode. Use this option only if you do not use markdown mode or have implemented additional security measures.

Option 2: Add Specific Modes Manually

For better security, add only the specific modes you need:

  1. Place the required mode files in your hac/resources/static context.
  2. Update all references in your code to point to the new location of the added modes.

Example:

XML
12345
<!-- Before --> <script type="text/javascript" src="/webjars/codemirror/mode/yaml/yaml.js"></script> <!-- After --> <script type="text/javascript" src="/static/codemirror/mode/yaml/yaml.js"></script>