Skip to content

Commit e431e86

Browse files
committed
Fixing issue found by Felix Wilhelm(flxm) where users could send potentially dangerous or corrupted serialized objects to SecurityComponent, potentially allowing manipulation of file map caches. Test case added.
1 parent eb76ab9 commit e431e86

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

Diff for: cake/libs/controller/components/security.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,15 @@ function _validatePost(&$controller) {
618618
}
619619
unset($check['_Token']);
620620

621+
$locked = str_rot13($locked);
622+
if (preg_match('/(\A|;|{|})O\:[0-9]+/', $locked)) {
623+
return false;
624+
}
625+
621626
$lockedFields = array();
622627
$fields = Set::flatten($check);
623628
$fieldList = array_keys($fields);
624-
$locked = unserialize(str_rot13($locked));
629+
$locked = unserialize($locked);
625630
$multi = array();
626631

627632
foreach ($fieldList as $i => $key) {

Diff for: cake/tests/cases/libs/controller/components/security.test.php

+24
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,30 @@ function testValidatePostFormHacking() {
608608
$result = $this->Controller->Security->validatePost($this->Controller);
609609
$this->assertFalse($result, 'validatePost passed when key was missing. %s');
610610
}
611+
612+
/**
613+
* Test that objects can't be passed into the serialized string. This was a vector for RFI and LFI
614+
* attacks. Thanks to Felix Wilhelm
615+
*
616+
* @return void
617+
*/
618+
function testValidatePostObjectDeserialize() {
619+
$this->Controller->Security->startup($this->Controller);
620+
$key = $this->Controller->params['_Token']['key'];
621+
$fields = 'a5475372b40f6e3ccbf9f8af191f20e1642fd877';
622+
623+
// a corrupted serialized object, so we can see if it ever gets to deserialize
624+
$attack = 'O:3:"App":1:{s:5:"__map";a:1:{s:3:"foo";s:7:"Hacked!";s:1:"fail"}}';
625+
$fields .= urlencode(':' . str_rot13($attack));
626+
627+
$this->Controller->data = array(
628+
'Model' => array('username' => 'mark', 'password' => 'foo', 'valid' => '0'),
629+
'_Token' => compact('key', 'fields')
630+
);
631+
$result = $this->Controller->Security->validatePost($this->Controller);
632+
$this->assertFalse($result, 'validatePost passed when key was missing. %s');
633+
}
634+
611635
/**
612636
* Tests validation of checkbox arrays
613637
*

0 commit comments

Comments
 (0)