Information Exposure Affecting sylius/sylius package, versions <1.10.11>=1.11.0, <1.11.2


Severity

Recommended
0.0
medium
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

EPSS
1.25% (67th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-PHP-SYLIUSSYLIUS-2423400
  • published15 Mar 2022
  • disclosed15 Mar 2022
  • creditUnknown

Introduced: 15 Mar 2022

CVE-2022-24743  (opens in a new tab)
CWE-613  (opens in a new tab)

How to fix?

Upgrade sylius/sylius to version 1.10.11, 1.11.2 or higher.

Overview

sylius/sylius is a platform for PHP, based on Symfony framework.

Affected versions of this package are vulnerable to Information Exposure due to the password token not being set to null after a password is changed. The same token could be used several times, which could result in leak of the existing token and unauthorized password change.

Workaround

  1. Overwrite the Sylius\Bundle\ApiBundle\CommandHandler\ResetPasswordHandler class with this code:
<?php
declare(strict_types=1);

namespace App\CommandHandler\Account;

use Sylius\Bundle\ApiBundle\Command\Account\ResetPassword; use Sylius\Component\Core\Model\ShopUserInterface; use Sylius\Component\Resource\Metadata\MetadataInterface; use Sylius\Component\User\Repository\UserRepositoryInterface; use Sylius\Component\User\Security\PasswordUpdaterInterface; use Symfony\Component\Messenger\Handler\MessageHandlerInterface; use Webmozart\Assert\Assert;

final class ResetPasswordHandler implements MessageHandlerInterface { private UserRepositoryInterface $userRepository; private MetadataInterface $metadata; private PasswordUpdaterInterface $passwordUpdater;

public function __construct(
    UserRepositoryInterface $userRepository,
    MetadataInterface $metadata,
    PasswordUpdaterInterface $passwordUpdater
) {
    $this-&gt;userRepository = $userRepository;
    $this-&gt;metadata = $metadata;
    $this-&gt;passwordUpdater = $passwordUpdater;
}

public function __invoke(ResetPassword $command): void
{
    /** @var ShopUserInterface|null $user */
    $user = $this-&gt;userRepository-&gt;findOneBy([&#39;passwordResetToken&#39; =&gt; $command-&gt;resetPasswordToken]);

    Assert::notNull($user, &#39;No user found with reset token: &#39; . $command-&gt;resetPasswordToken);

    $resetting = $this-&gt;metadata-&gt;getParameter(&#39;resetting&#39;);
    $lifetime = new \DateInterval($resetting[&#39;token&#39;][&#39;ttl&#39;]);

    if (!$user-&gt;isPasswordRequestNonExpired($lifetime)) {
        throw new \InvalidArgumentException(&#39;Password reset token has expired&#39;);
    }

    if ($command-&gt;resetPasswordToken !== $user-&gt;getPasswordResetToken()) {
        throw new \InvalidArgumentException(&#39;Password reset token does not match.&#39;);
    }

    $user-&gt;setPlainPassword($command-&gt;newPassword);

    $this-&gt;passwordUpdater-&gt;updatePassword($user);
    $user-&gt;setPasswordResetToken(null);
}

}

  1. Register it in a container.

CVSS Base Scores

version 3.1