API CHANGE Disallow methods/actions in RequestHandler->checkAccessAction() which are implemented on parent classes (e.g. ViewableData and Object), unless access is controlled through $allowed_actions. This limits information exposure from getters used in template contexts. (from r102003)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@112053 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sam Minnee 2010-10-13 01:24:15 +00:00
parent d99c2c7ee4
commit 740e49061f
2 changed files with 22 additions and 4 deletions

View File

@ -233,6 +233,7 @@ class RequestHandler extends ViewableData {
* It will interrogate {@link self::$allowed_actions} to determine this.
*/
function checkAccessAction($action) {
$actionOrigCasing = $action;
$action = strtolower($action);
$allowedActions = $this->allowedActions();
@ -262,13 +263,25 @@ class RequestHandler extends ViewableData {
// If we get here an the action is 'index', then it hasn't been specified, which means that
// it should be allowed.
if($action == 'index') return true;
if($action == 'index' || empty($action)) return true;
if($allowedActions === null || !$this->uninherited('allowed_actions')) {
// If no allowed_actions are provided, then we should only let through actions that aren't handled by magic methods
// we test this by calling the unmagic method_exists and comparing it to the magic $this->hasMethod(). This will
// still let through actions that are handled by templates.
return method_exists($this, $action) || !$this->hasMethod($action);
// we test this by calling the unmagic method_exists.
if(method_exists($this, $action)) {
// Disallow any methods which aren't defined on RequestHandler or subclasses
// (e.g. ViewableData->getSecurityID())
$r = new ReflectionClass(get_class($this));
if($r->hasMethod($actionOrigCasing)) {
$m = $r->getMethod($actionOrigCasing);
return ($m && is_subclass_of($m->class, 'RequestHandler'));
} else {
throw new Exception("method_exists() true but ReflectionClass can't find method - PHP is b0kred");
}
} else if(!$this->hasMethod($action)){
// Return true so that a template can handle this action
return true;
}
}
return false;

View File

@ -122,6 +122,11 @@ class RequestHandlingTest extends SapphireTest {
$this->assertEquals('This page does not exist.', $response->getBody());
}
function testMethodsOnParentClassesOfRequestHandlerDeclined() {
$response = Director::test('testGoodBase1/getSecurityID');
$this->assertEquals(403, $response->getStatusCode());
}
}
/**