Essere in grado di utilizzare le matrici in $_GET
in questo modo non rappresenta di per sé una vulnerabilità di sicurezza. Il vettore DoS mi sembra trascurabile, sebbene possa essere amplificato dal codice che lo utilizza.
Tuttavia , gli esempi forniti mancavano della parte più importante di questa funzione (dal punto di vista di un attaccante): non solo è possibile passare array regolari in GET
e POST
parametri in questo modo, ma anche array associativi . In effetti, PHP non distingue tra i due:
PHP arrays can contain integer and string keys at the same time as PHP does not distinguish between indexed and associative arrays.
– PHP: Arrays - Manual
Questo significa che se un cliente fornisce POST
parametri come questo:
<input type="text" name="pass[pass1]" value="Password 1">
<input type="text" name="pass[pass2]" value="Password 2">
$_POST
/ $_GET
sarà simile a questo:
$_POST = array(
...
'pass' => array(
'pass1' => 'Password 1',
'pass2' => 'Password 2',
),
...
);
Ma se il server si aspettava che fosse un array normale anziché uno associativo, potrebbe portare a una vulnerabilità di sicurezza:
//Simplified example, bug is possible with parameterized queries as well
//Expects ?pass[]=password1&pass[]=password2
$query = 'INSERT INTO users (index, password) ';
$parts = array();
foreach($_GET['user'] AS $index=>$value){
parts[]=" VALUES ({$index}, ".$pdo->real_escape_string($value).')';
}
$query .= implode(", ", $parts);
$pdo->exec($query);//
$query
con l'input previsto:
INSERT INTO USERS (index, password) VALUES(0, 'password1'), VALUES(1, 'password2')
$query
con ?pass[0,'');DROP DATABASE DATABASE();--]=foo
:
INSERT INTO USERS (index, password) VALUES(0,'');DROP DATABASE DATABASE();--, 'foo')
Ineffetti,questoèesattamentelostessoerrorechehaportatoaldifettodisicurezzachiamato"Drupalgeddon" - e ha ricevuto quel nome per una buona ragione.
A vulnerability in this API allows an attacker to send specially crafted requests resulting in arbitrary SQL execution. Depending on the content of the requests this can lead to privilege escalation, arbitrary PHP execution, or other attacks. – SA-CORE-2014-005 - Drupal core - SQL injection
Automated attacks began compromising Drupal 7 websites that were not patched or updated to Drupal 7.32 within hours of the announcement of SA-CORE-2014-005 - Drupal core - SQL injection. You should proceed under the assumption that every Drupal 7 website was compromised unless updated or patched before Oct 15th, 11pm UTC, that is 7 hours after the announcement. – Drupal Core - Highly Critical - Public Service announcement - PSA-2014-003
Era anche la vulnerabilità che molto probabilmente ha portato alla divulgazione del Panama Papers (probabilmente dovrebbe aver installato quegli aggiornamenti di sicurezza ...).
La vulnerabilità di Drupal è stata risolta aggiornando il codice per passare l'array ricevuto a array_values()
, che restituisce un array indicizzato contenente solo valori dell'array ricevuto, eliminando quindi eventuali chiavi dannose.
Il codice di esempio potrebbe essere corretto allo stesso modo:
Prima:
foreach($_GET['user'] AS $index=>$value){
Dopo
foreach(array_values($_GET['user']) AS $index=>$value){
Ulteriori informazioni su Drupalgeddon, incluso un exploit di lavoro: Drupal 7: Drupalgeddon Exploit
Tieni presente che questa roba funziona allo stesso modo, indipendentemente dal fatto che tu stia lavorando con $_GET
o $_POST
. Non sono sicuro di $_REQUEST
e $_COOKIE
.