Vulnerability GHSA-4f5f-j737-pm58

Medium Risk
MEDIUM RISK
CVSS Score: 4.3
Score Range: 4.0–6.9
Medium severity vulnerabilities (CVSS 4.0–6.9). Important issues that meaningfully reduce security confidence.
3 days ago
September 24, 2026 at 02:57 PM UTC
REDAXO: Unwhitelisted ORDER BY Column in rex_list Allows Authenticated Column Enumeration
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1

Summary

REDAXO: Unwhitelisted ORDER BY Column in rex_list Allows Authenticated Column Enumeration

Details

Summary

The rex_list component reads the SQL sort column directly from the sort GET parameter without validating it against the set of columns declared sortable via setColumnSortable(). Although the value is wrapped in backticks via escapeIdentifier() (preventing classical SQL injection), this still allows any authenticated backend user to ORDER BY any column in the query's FROM tables, including unselected sensitive columns such as password from the rex_user table, and perform error-based column enumeration.

Details

File: redaxo/src/core/lib/list.php:976-982 — getSortColumn() returns the raw request parameter without whitelist check:

public function getSortColumn($default = null)
{
    if (rex_request('list', 'string') == $this->getName()) {
        return rex_request('sort', 'string', $default);  // NO validation against sortable columns
    }
    return $default;
}

File: redaxo/src/core/lib/list.php:899-911 — prepareQuery() uses it directly in the ORDER BY clause:

protected function prepareQuery($query, array $defaultSort = [])
{
    $sortColumn = $this->getSortColumn();
    if ('' != $sortColumn) {
        $sql = rex_sql::factory($this->db);
        $sortColumn = $sql->escapeIdentifier($sortColumn);  // backtick-wraps, but no whitelist
        if ($defaultSort || false === stripos($query, ' ORDER BY ')) {
            $query .= ' ORDER BY ' . $sortColumn . ' ' . $sortType;
        }
    }

The users list queries rex_user which contains password, previous_passwords, password_change_required — not in the SELECT. Specifying a non-existent column name produces a MySQL Unknown column exception whose message is propagated to the user, confirming or denying column existence.

PoC

Column enumeration (error-based):

GET /redaxo/index.php?page=users&list=<list_name>&sort=nonexistent_col&sorttype=asc

Response will contain: Unknown column 'nonexistent_col' in 'order clause'

Sort by password hash (data ordering leak):

GET /redaxo/index.php?page=users&list=<list_name>&sort=password&sorttype=asc

Users are silently reordered by their Argon2 password hash.

Impact

Authenticated backend users (non-admin) can enumerate database column names of internal tables via error messages and manipulate query ordering to include sensitive unselected columns. While this does not allow arbitrary SQL execution due to backtick escaping, it constitutes an information disclosure vulnerability enabling targeted further attacks.

Fix

Validate the sort request parameter against the whitelist of columns registered with setColumnSortable() before use in the query:

public function getSortColumn($default = null)
{
    if (rex_request('list', 'string') == $this->getName()) {
        $requested = rex_request('sort', 'string', $default);
        if ($requested !== null && $this->hasColumnOption($requested, REX_LIST_OPT_SORT)) {
            return $requested;
        }
    }
    return $default;
}

Related Vulnerabilities

Other vulnerabilities affecting the same packages

Medium Risk
4 days ago
REDAXO: Missing CSRF Protection on Package Update Action Allows Forced Addon Updates
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1 GHSA-m8r3-22v6-g877
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1 GHSA-m8r3-22v6-g877
Medium Risk
4 days ago
REDAXO: Stored XSS in Mediapool Sync Page via Unescaped Filesystem Filenames
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1 GHSA-w998-qmw9-mf4m
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1 GHSA-w998-qmw9-mf4m
Medium Risk
4 days ago
REDAXO: Stored XSS via Unescaped Media Manager Type Name in `mediaIsInUse()`
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1 GHSA-mf2p-wjp4-99pq
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 - 5.21.1 GHSA-mf2p-wjp4-99pq
High Risk
1 month ago
Redaxo has a Mediapool isAllowedExtension bypass via multi-segment filename that leads to authenticated RCE on Apache mod_php multi-extension handlers
5.18.2 - 5.20.2 and 5.21.0 GHSA-98pp-vccm-qm25
5.18.2 - 5.20.2 and 5.21.0 GHSA-98pp-vccm-qm25
Low Risk
5 months ago
REDAXO has reflected XSS backend packages API via function parameter (CSRF token required)
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 GHSA-xq4j-g85q-wf97
5.10.0 - 5.10.1 and 5.11.0 - 5.11.2 and 5.12.0 - 5.12.1 and 5.13.0 - 5.13.3 and 5.14.0 - 5.14.3 and 5.15.0 - 5.15.1 and 5.16.0 - 5.20.2 and 5.21.0 GHSA-xq4j-g85q-wf97
View all vulnerabilities for these packages

Impacted packages

Timeline

Published
3 days ago
September 24, 2026 at 02:57 PM UTC
Fixed (5.21.2)
3 months ago
June 29, 2026 at 09:41 AM UTC
Last Modified
3 days ago
September 24, 2026 at 03:00 PM UTC