VYPR
High severityNVD Advisory· Published Aug 26, 2021· Updated Aug 3, 2024

Authentication bypass in Octobercms

CVE-2021-29487

Description

octobercms in a CMS platform based on the Laravel PHP Framework. In affected versions of the october/system package an attacker can exploit this vulnerability to bypass authentication and takeover of and user account on an October CMS server. The vulnerability is exploitable by unauthenticated users via a specially crafted request. This only affects frontend users and the attacker must obtain a Laravel secret key for cookie encryption and signing in order to exploit this vulnerability. The issue has been patched in Build 472 and v1.1.5.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
october/systemPackagist
< 1.0.4721.0.472
october/systemPackagist
>= 1.1.1, < 1.1.51.1.5

Affected products

1

Patches

2
5bd1a28140b8

Use int casting

https://github.com/octobercms/librarySamuel GeorgesApr 7, 2021via ghsa
2 files changed · +8 8
  • src/Auth/Models/Role.php+4 4 modified
    @@ -84,7 +84,7 @@ public function hasAccess($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but starts with it.
    -                    if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && $value === 1) {
    +                    if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && (int) $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -102,7 +102,7 @@ public function hasAccess($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but ends with it.
    -                    if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && $value === 1) {
    +                    if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && (int) $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -121,14 +121,14 @@ public function hasAccess($permissions, $all = true)
     
                             // We will make sure that the merged permission does not
                             // exactly match our permission, but starts with it.
    -                        if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && $value === 1) {
    +                        if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && (int) $value === 1) {
                                 $matched = true;
                                 break;
                             }
                         }
                         // Otherwise, we'll fallback to standard permissions checking where
                         // we match that permissions explicitly exist.
    -                    elseif ($permission === $rolePermission && $rolePermissions[$permission] === 1) {
    +                    elseif ($permission === $rolePermission && (int) $rolePermissions[$permission] === 1) {
                             $matched = true;
                             break;
                         }
    
  • src/Auth/Models/User.php+4 4 modified
    @@ -481,7 +481,7 @@ public function hasPermission($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but starts with it.
    -                    if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && $value === 1) {
    +                    if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && (int) $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -496,7 +496,7 @@ public function hasPermission($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but ends with it.
    -                    if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && $value === 1) {
    +                    if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && (int) $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -515,15 +515,15 @@ public function hasPermission($permissions, $all = true)
     
                             // We will make sure that the merged permission does not
                             // exactly match our permission, but starts with it.
    -                        if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && $value === 1) {
    +                        if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && (int) $value === 1) {
                                 $matched = true;
                                 break;
                             }
                         }
     
                         // Otherwise, we'll fallback to standard permissions checking where
                         // we match that permissions explicitly exist.
    -                    elseif ($permission === $mergedPermission && $mergedPermissions[$permission] === 1) {
    +                    elseif ($permission === $mergedPermission && (int) $mergedPermissions[$permission] === 1) {
                             $matched = true;
                             break;
                         }
    
016a297b1bec

Backport code audit from 1.2

https://github.com/octobercms/librarySamuel GeorgesApr 1, 2021via ghsa
4 files changed · +13 13
  • src/Auth/Manager.php+1 1 modified
    @@ -241,7 +241,7 @@ public function findUserByCredentials(array $credentials)
             foreach ($hashedCredentials as $credential => $value) {
                 if (!$user->checkHashValue($credential, $value)) {
                     // Incorrect password
    -                if ($credential == 'password') {
    +                if ($credential === 'password') {
                         throw new AuthException(sprintf(
                             'A user was found to match all plain text credentials however hashed credential "%s" did not match.',
                             $credential
    
  • src/Auth/Models/Role.php+4 4 modified
    @@ -84,7 +84,7 @@ public function hasAccess($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but starts with it.
    -                    if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && $value == 1) {
    +                    if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -102,7 +102,7 @@ public function hasAccess($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but ends with it.
    -                    if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && $value == 1) {
    +                    if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -121,14 +121,14 @@ public function hasAccess($permissions, $all = true)
     
                             // We will make sure that the merged permission does not
                             // exactly match our permission, but starts with it.
    -                        if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && $value == 1) {
    +                        if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && $value === 1) {
                                 $matched = true;
                                 break;
                             }
                         }
                         // Otherwise, we'll fallback to standard permissions checking where
                         // we match that permissions explicitly exist.
    -                    elseif ($permission == $rolePermission && $rolePermissions[$permission] == 1) {
    +                    elseif ($permission === $rolePermission && $rolePermissions[$permission] === 1) {
                             $matched = true;
                             break;
                         }
    
  • src/Auth/Models/Throttle.php+1 1 modified
    @@ -99,7 +99,7 @@ public function clearLoginAttempts()
             // anything either as clearing login attempts
             // makes us unsuspended. We need to manually
             // call unsuspend() in order to unsuspend.
    -        if ($this->getLoginAttempts() == 0 or $this->is_suspended) {
    +        if ($this->getLoginAttempts() === 0 or $this->is_suspended) {
                 return;
             }
     
    
  • src/Auth/Models/User.php+7 7 modified
    @@ -190,7 +190,7 @@ public function checkPersistCode($persistCode)
                 return false;
             }
     
    -        return $persistCode == $this->persist_code;
    +        return $persistCode === $this->persist_code;
         }
     
         //
    @@ -278,7 +278,7 @@ public function checkResetPasswordCode($resetCode)
                 return false;
             }
     
    -        return ($this->reset_password_code == $resetCode);
    +        return ($this->reset_password_code === $resetCode);
         }
     
         /**
    @@ -386,7 +386,7 @@ public function removeGroup($group)
         public function inGroup($group)
         {
             foreach ($this->getGroups() as $_group) {
    -            if ($_group->getKey() == $group->getKey()) {
    +            if ($_group->getKey() === $group->getKey()) {
                     return true;
                 }
             }
    @@ -481,7 +481,7 @@ public function hasPermission($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but starts with it.
    -                    if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && $value == 1) {
    +                    if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -496,7 +496,7 @@ public function hasPermission($permissions, $all = true)
     
                         // We will make sure that the merged permission does not
                         // exactly match our permission, but ends with it.
    -                    if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && $value == 1) {
    +                    if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && $value === 1) {
                             $matched = true;
                             break;
                         }
    @@ -515,15 +515,15 @@ public function hasPermission($permissions, $all = true)
     
                             // We will make sure that the merged permission does not
                             // exactly match our permission, but starts with it.
    -                        if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && $value == 1) {
    +                        if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && $value === 1) {
                                 $matched = true;
                                 break;
                             }
                         }
     
                         // Otherwise, we'll fallback to standard permissions checking where
                         // we match that permissions explicitly exist.
    -                    elseif ($permission == $mergedPermission && $mergedPermissions[$permission] == 1) {
    +                    elseif ($permission === $mergedPermission && $mergedPermissions[$permission] === 1) {
                             $matched = true;
                             break;
                         }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.