From 877aaf7cb6768eb9c40081fc078202ebe2566ad1 Mon Sep 17 00:00:00 2001 From: David Greminger Date: Mon, 27 Jan 2020 12:45:21 +0100 Subject: [PATCH] Fix possible null value access in BackupCodeManager (see #1246) Description ----------- Fixes #1243 Commits ------- 3ded076e Fix possible null value 60836e49 Also check for null on json_decode --- src/Security/TwoFactor/BackupCodeManager.php | 12 ++++++- .../TwoFactor/BackupCodeManagerTest.php | 32 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Security/TwoFactor/BackupCodeManager.php b/src/Security/TwoFactor/BackupCodeManager.php index db2759857e..f4e2b2275d 100644 --- a/src/Security/TwoFactor/BackupCodeManager.php +++ b/src/Security/TwoFactor/BackupCodeManager.php @@ -23,7 +23,17 @@ public function isBackupCode($user, string $code): bool return false; } - return \in_array($code, json_decode($user->backupCodes, true), true); + if (null === $user->backupCodes) { + return false; + } + + $backupCodes = json_decode($user->backupCodes, true); + + if (null === $backupCodes) { + return false; + } + + return \in_array($code, $backupCodes, true); } public function invalidateBackupCode($user, string $code): void diff --git a/tests/Security/TwoFactor/BackupCodeManagerTest.php b/tests/Security/TwoFactor/BackupCodeManagerTest.php index 97523ead7e..9b5cd24e6f 100644 --- a/tests/Security/TwoFactor/BackupCodeManagerTest.php +++ b/tests/Security/TwoFactor/BackupCodeManagerTest.php @@ -31,6 +31,38 @@ public function testDoesNotHandleNonContaoUsers(): void $backupCodeManager->invalidateBackupCode($user, '123456'); } + public function testHandlesNullValue(): void + { + /** @var FrontendUser&MockObject $frontendUser */ + $frontendUser = $this->mockClassWithProperties(FrontendUser::class, []); + $frontendUser->backupCodes = null; + + /** @var BackendUser&MockObject $backendUser */ + $backendUser = $this->mockClassWithProperties(BackendUser::class); + $backendUser->backupCodes = null; + + $backupCodeManager = new BackupCodeManager(); + + $this->assertFalse($backupCodeManager->isBackupCode($frontendUser, '123456')); + $this->assertFalse($backupCodeManager->isBackupCode($backendUser, '234567')); + } + + public function testHandlesInvalidJson(): void + { + /** @var FrontendUser&MockObject $frontendUser */ + $frontendUser = $this->mockClassWithProperties(FrontendUser::class, []); + $frontendUser->backupCodes = 'foobar'; + + /** @var BackendUser&MockObject $backendUser */ + $backendUser = $this->mockClassWithProperties(BackendUser::class); + $backendUser->backupCodes = 'foobar'; + + $backupCodeManager = new BackupCodeManager(); + + $this->assertFalse($backupCodeManager->isBackupCode($frontendUser, '123456')); + $this->assertFalse($backupCodeManager->isBackupCode($backendUser, '234567')); + } + public function testHandlesContaoUsers(): void { $backupCodes = json_encode(['123456', '234567']);