Summary:
Authenticated Time-Based Blind SQL Injection Vulnerabilities
Detailed Description:
Two independent authenticated SQL injection vulnerabilities were identified in
CMS Made Simple 2.2.22. Both vulnerabilities are exploitable through time-based
blind SQL injection techniques against MariaDB/MySQL-backed installations.
The first vulnerability, V-001, exists in the CMS Content Manager workflow and
is triggered through unsafe handling of a serialized, base64-encoded
user-controlled parameter. The decoded array is passed into a SQL IN (...)
clause without escaping, parameterization, or type validation.
The second vulnerability, V-002, exists in the Design Manager stylesheet bulk
operation workflow. User-controlled stylesheet identifiers are wrapped in single
quotes without escaping embedded quote characters, allowing an attacker to
escape the string context and inject SQL.
Although both vulnerabilities require authentication, they differ in required
permission levels. V-002 requires only the Manage Stylesheets permission, which
may be assigned to designer or editor-level users. Successful exploitation of
V-002 can allow extraction of sensitive database content, including
administrator password hashes. This creates a practical escalation path: a
lower-privileged authenticated user with Manage Stylesheets can extract
administrator credentials, authenticate as an administrator, and then exploit
V-001, which requires Manage All Content.
ID Component
Required Permission Vulnerability Type CVSS
V-001 CMSContentManager / LoadChildren Manage
All Content Unserialize to SQL Injection 8.8
V-002 DesignManager / CmsLayoutStylesheet::load_bulk() Manage Stylesheets SQL
Injection 8.1
Remediation for V-001
The application must not place user-controlled values directly into the SQL IN
(...) clause. Since the expected values are content IDs, all values should be
strictly validated and cast to integers before query construction.
Vulnerable pattern:
$expr = 'content_id IN ('.implode(',',$explicit_ids).')';
Recommended immediate fix:
$safe_ids = array_map('intval', $explicit_ids);
$expr = 'content_id IN ('.implode(',',$safe_ids).')';
Additional validation should reject invalid values rather than silently
converting arbitrary input to 0:
$safe_ids = array_filter($explicit_ids, static function ($id) {
return is_numeric($id) && (int)$id > 0;
});
$safe_ids = array_map('intval', $safe_ids);
if (empty($safe_ids)) {
throw new InvalidArgumentException('Invalid content ID list');
}
$expr = 'content_id IN ('.implode(',',$safe_ids).')';
Long-term recommended fix:
Avoid unserialize() on user-controlled input.
Replace serialized PHP data with JSON and strict schema validation.
Use prepared statements where possible.
Enforce server-side type validation before data reaches database query
construction.
Treat all decoded request data as untrusted, even if it is base64-encoded.
Remediation for V-002
The application must not wrap raw user-controlled strings in quotes manually.
Values should be escaped using the database abstraction layer or passed as bound
parameters.
Vulnerable pattern:
$idlist[] = "'".trim($val)."'";
Recommended escaping-based fix:
$db = cmsms()->GetDb();
$idlist[] = $db->qstr(trim($val));
Note: in many database abstraction layers, qstr() returns a fully quoted SQL
string literal. In that case, additional surrounding single quotes must not be
added.
Preferred long-term fix using parameterized queries:
$values = array_map('trim', $values);
$placeholders = implode(',', array_fill(0, count($values), '?'));
$query = 'SELECT *
FROM '.cms_db_prefix().'layout_stylesheets
WHERE name IN ('.$placeholders.')';
$result = $db->Execute($query, $values);
The vulnerabilities were validated in an isolated lab environment using
authenticated sessions and valid CSRF tokens. Both vulnerabilities require
access to the CMSMS administrative interface, but V-002 is especially
significant because it requires only the Manage Stylesheets permission, which
may be assigned to non-administrator users in real deployments.
The vulnerabilities should be remediated by applying strict input validation,
removing unsafe unserialization of request-derived data, and replacing dynamic
SQL concatenation with parameterized queries.