
Riferimento CVE-2023-45503
In Macrob7 Macs Framework Content Management System (CMS) versioni 1.1.4f e precedenti, la gestione non sicura dell'input utente porta a 16 vulnerabilità di SQL injection. La capacità di eseguire query SQL arbitrarie può portare alla divulgazione di dati privati, inclusi gli hash delle password degli utenti, e alla possibilità di modificare le credenziali e il livello di privilegio di altri utenti. L'impatto può includere escalation dei privilegi e potenziale esecuzione remota di codice (RCE).
Un foglio di calcolo che descrive ogni endpoint interessato, parametro vulnerabile e funzioni vulnerabili è disponibile a questo link.
Classificazione CWE: CWE-89: Neutralizzazione impropria di elementi speciali usati in un comando SQL ('SQL Injection')
Segnalato da: Ally Petitt
Prodotto interessato: Macrob7 Macs CMS
Versioni interessate: 1.1.4f e precedenti
In 16 casi che ho individuato, l'input utente veniva ricevuto senza una corretta sanificazione o parametrizzazione. Ad esempio, nella funzionalità "Forgot Password" (password dimenticata) di questo CMS, viene richiesto un indirizzo email.
Application/plugins/CMS/controllers/CMS.php:224
public function forgotPasswordProcess()
{
$this->loadModels();
$emailAddress = Post::getByKey('emailAddress');
$user = $this->usersModel->getUserByEmailAddress($emailAddress);
L'indirizzo email viene quindi passato al metodo getUserByEmailAddress(), che passa l'email a selectSingle(), un metodo che non protegge adeguatamente dalle query SQL iniettate.
Application/plugins/CMS/models/Users_Model.php:41
public function getUserByEmailAddress($emailAddress)
{
return $this->selectSingle( $this->getCMSTableNameUsers(), array('EmailAddress'=>$emailAddress));
}
Quindi, selectSingle() chiama select() con l'input utente passato.
Application/core/DB.php:200
public function selectSingle($tableName, array $where = array(), array $fields = array('*'))
{
$return = $this->select($tableName, $where, $fields);
$single = NULL;
if( count($return) > 0 )
$single = $return[0];
return $single;
}
La vulnerabile funzione select() concatena i parametri che le vengono passati in una query SQL che viene successivamente eseguita.
Application/core/DB.php:186
public function select($tableName, array $where = array(), array $fields = array('*'))
{
$fieldsString = $this->generatePair($fields, ',');
$whereString = $this->generateKeyValuePair($where, '=', 'AND');
$sql = 'SELECT '.$fieldsString.' FROM '.$tableName;
if($whereString !='')
$whereString = ' WHERE '.$whereString;
$sql = $sql.' '.$whereString.';';
return $this->execute($sql)->fetchAll($this->returnType, $this->className);
}
A causa della mancanza di sanificazione, validazione e parametrizzazione dell'input, questa funzione rimane vulnerabile agli attacchi di SQL injection.
Purtroppo, la mancanza di manutenzione di questo CMS significa che non è disponibile un aggiornamento corretto. I singoli utenti possono modificare il codice per utilizzare query SQL parametrizzate anziché affidarsi alla concatenazione per passare l'input utente al database. Le istruzioni preparate (prepared statements) sono un esempio di mitigazione che può ottenere questo risultato.