CVE-2021-29487 (PHP, published 2021-08-26T19:15Z)
Description: value: 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.
Severity: MEDIUM (CVSS v3 base score: 7.4)
Weakness: NVD-CWE-Other \u2014 Other
NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Repository: https://github.com/octobercms/library
Files changed:
src/Auth/Manager.php
src/Auth/Models/Role.php
src/Auth/Models/Throttle.php
src/Auth/Models/User.php
Commit message: Backport code audit from 1.2

Fixes issue with permissions checking


Vulnerable code:
                if ($credential == 'password') {
                    if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && $value == 1) {
                    if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && $value == 1) {
                        if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && $value == 1) {
                    elseif ($permission == $rolePermission && $rolePermissions[$permission] == 1) {
        if ($this->getLoginAttempts() == 0 or $this->is_suspended) {
        return $persistCode == $this->persist_code;
        return ($this->reset_password_code == $resetCode);
            if ($_group->getKey() == $group->getKey()) {
                    if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && $value == 1) {
                    if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && $value == 1) {
                        if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && $value == 1) {
                    elseif ($permission == $mergedPermission && $mergedPermissions[$permission] == 1) {

Fixed code:
                if ($credential === 'password') {
                    if ($checkPermission != $rolePermission && starts_with($rolePermission, $checkPermission) && $value === 1) {
                    if ($checkPermission != $rolePermission && ends_with($rolePermission, $checkPermission) && $value === 1) {
                        if ($checkGroupPermission != $permission && starts_with($permission, $checkGroupPermission) && $value === 1) {
                    elseif ($permission === $rolePermission && $rolePermissions[$permission] === 1) {
        if ($this->getLoginAttempts() === 0 or $this->is_suspended) {
        return $persistCode === $this->persist_code;
        return ($this->reset_password_code === $resetCode);
            if ($_group->getKey() === $group->getKey()) {
                    if ($checkPermission != $mergedPermission && starts_with($mergedPermission, $checkPermission) && $value === 1) {
                    if ($checkPermission != $mergedPermission && ends_with($mergedPermission, $checkPermission) && $value === 1) {
                        if ($checkMergedPermission != $permission && starts_with($permission, $checkMergedPermission) && $value === 1) {
                    elseif ($permission === $mergedPermission && $mergedPermissions[$permission] === 1) {