mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
[CVE-2022-38148] Validate SortColumn exists
This commit is contained in:
parent
55b23d0c9f
commit
4308a93cc8
@ -11,6 +11,7 @@ use SilverStripe\ORM\DataObject;
|
|||||||
use SilverStripe\View\ArrayData;
|
use SilverStripe\View\ArrayData;
|
||||||
use SilverStripe\View\SSViewer;
|
use SilverStripe\View\SSViewer;
|
||||||
use LogicException;
|
use LogicException;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GridFieldSortableHeader adds column headers to a {@link GridField} that can
|
* GridFieldSortableHeader adds column headers to a {@link GridField} that can
|
||||||
@ -271,6 +272,16 @@ class GridFieldSortableHeader implements GridField_HTMLProvider, GridField_DataM
|
|||||||
return $dataList;
|
return $dataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent SQL Injection by validating that SortColumn exists
|
||||||
|
/** @var GridFieldDataColumns $columns */
|
||||||
|
$columns = $gridField->getConfig()->getComponentByType(GridFieldDataColumns::class);
|
||||||
|
$fields = $columns->getDisplayFields($gridField);
|
||||||
|
if (!array_key_exists($state->SortColumn, $fields) &&
|
||||||
|
!in_array($state->SortColumn, $this->getFieldSorting())
|
||||||
|
) {
|
||||||
|
throw new LogicException('Invalid SortColumn: ' . $state->SortColumn);
|
||||||
|
}
|
||||||
|
|
||||||
return $dataList->sort($state->SortColumn, $state->SortDirection('asc'));
|
return $dataList->sort($state->SortColumn, $state->SortDirection('asc'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,17 +71,18 @@ class GridFieldSortableHeaderTest extends SapphireTest
|
|||||||
$list = Team::get()->filter([ 'ClassName' => Team::class ]);
|
$list = Team::get()->filter([ 'ClassName' => Team::class ]);
|
||||||
$config = new GridFieldConfig_RecordEditor();
|
$config = new GridFieldConfig_RecordEditor();
|
||||||
$gridField = new GridField('testfield', 'testfield', $list, $config);
|
$gridField = new GridField('testfield', 'testfield', $list, $config);
|
||||||
|
$component = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
|
||||||
|
|
||||||
// Test normal sorting
|
// Test normal sorting
|
||||||
|
$component->setFieldSorting(['Name' => 'City']);
|
||||||
$state = $gridField->State->GridFieldSortableHeader;
|
$state = $gridField->State->GridFieldSortableHeader;
|
||||||
$state->SortColumn = 'City';
|
$state->SortColumn = 'City';
|
||||||
$state->SortDirection = 'asc';
|
$state->SortDirection = 'asc';
|
||||||
|
|
||||||
$compontent = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
|
$listA = $component->getManipulatedData($gridField, $list);
|
||||||
$listA = $compontent->getManipulatedData($gridField, $list);
|
|
||||||
|
|
||||||
$state->SortDirection = 'desc';
|
$state->SortDirection = 'desc';
|
||||||
$listB = $compontent->getManipulatedData($gridField, $list);
|
$listB = $component->getManipulatedData($gridField, $list);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['Auckland', 'Cologne', 'Melbourne', 'Wellington'],
|
['Auckland', 'Cologne', 'Melbourne', 'Wellington'],
|
||||||
@ -93,12 +94,13 @@ class GridFieldSortableHeaderTest extends SapphireTest
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Test one relation 'deep'
|
// Test one relation 'deep'
|
||||||
|
$component->setFieldSorting(['Name' => 'Cheerleader.Name']);
|
||||||
$state->SortColumn = 'Cheerleader.Name';
|
$state->SortColumn = 'Cheerleader.Name';
|
||||||
$state->SortDirection = 'asc';
|
$state->SortDirection = 'asc';
|
||||||
$relationListA = $compontent->getManipulatedData($gridField, $list);
|
$relationListA = $component->getManipulatedData($gridField, $list);
|
||||||
|
|
||||||
$state->SortDirection = 'desc';
|
$state->SortDirection = 'desc';
|
||||||
$relationListB = $compontent->getManipulatedData($gridField, $list);
|
$relationListB = $component->getManipulatedData($gridField, $list);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['Wellington', 'Melbourne', 'Cologne', 'Auckland'],
|
['Wellington', 'Melbourne', 'Cologne', 'Auckland'],
|
||||||
@ -110,12 +112,13 @@ class GridFieldSortableHeaderTest extends SapphireTest
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Test two relations 'deep'
|
// Test two relations 'deep'
|
||||||
|
$component->setFieldSorting(['Name' => 'Cheerleader.Hat.Colour']);
|
||||||
$state->SortColumn = 'Cheerleader.Hat.Colour';
|
$state->SortColumn = 'Cheerleader.Hat.Colour';
|
||||||
$state->SortDirection = 'asc';
|
$state->SortDirection = 'asc';
|
||||||
$relationListC = $compontent->getManipulatedData($gridField, $list);
|
$relationListC = $component->getManipulatedData($gridField, $list);
|
||||||
|
|
||||||
$state->SortDirection = 'desc';
|
$state->SortDirection = 'desc';
|
||||||
$relationListD = $compontent->getManipulatedData($gridField, $list);
|
$relationListD = $component->getManipulatedData($gridField, $list);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
['Cologne', 'Auckland', 'Wellington', 'Melbourne'],
|
['Cologne', 'Auckland', 'Wellington', 'Melbourne'],
|
||||||
@ -139,6 +142,7 @@ class GridFieldSortableHeaderTest extends SapphireTest
|
|||||||
$component = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
|
$component = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
|
||||||
|
|
||||||
// Test that inherited dataobjects will work correctly
|
// Test that inherited dataobjects will work correctly
|
||||||
|
$component->setFieldSorting(['Name' => 'Cheerleader.Hat.Colour']);
|
||||||
$state->SortColumn = 'Cheerleader.Hat.Colour';
|
$state->SortColumn = 'Cheerleader.Hat.Colour';
|
||||||
$state->SortDirection = 'asc';
|
$state->SortDirection = 'asc';
|
||||||
$relationListA = $component->getManipulatedData($gridField, $list);
|
$relationListA = $component->getManipulatedData($gridField, $list);
|
||||||
@ -179,6 +183,7 @@ class GridFieldSortableHeaderTest extends SapphireTest
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Test subclasses of tables
|
// Test subclasses of tables
|
||||||
|
$component->setFieldSorting(['Name' => 'CheerleadersMom.Hat.Colour']);
|
||||||
$state->SortColumn = 'CheerleadersMom.Hat.Colour';
|
$state->SortColumn = 'CheerleadersMom.Hat.Colour';
|
||||||
$state->SortDirection = 'asc';
|
$state->SortDirection = 'asc';
|
||||||
$relationListB = $component->getManipulatedData($gridField, $list);
|
$relationListB = $component->getManipulatedData($gridField, $list);
|
||||||
@ -229,4 +234,21 @@ class GridFieldSortableHeaderTest extends SapphireTest
|
|||||||
$relationListBdesc->column('City')
|
$relationListBdesc->column('City')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testSortColumnValidation()
|
||||||
|
{
|
||||||
|
$this->expectException(\LogicException::class);
|
||||||
|
$this->expectExceptionMessage('Invalid SortColumn: INVALID');
|
||||||
|
|
||||||
|
$list = Team::get()->filter([ 'ClassName' => Team::class ]);
|
||||||
|
$config = new GridFieldConfig_RecordEditor();
|
||||||
|
$gridField = new GridField('testfield', 'testfield', $list, $config);
|
||||||
|
$component = $gridField->getConfig()->getComponentByType(GridFieldSortableHeader::class);
|
||||||
|
|
||||||
|
$state = $gridField->State->GridFieldSortableHeader;
|
||||||
|
$state->SortColumn = 'INVALID';
|
||||||
|
$state->SortDirection = 'asc';
|
||||||
|
|
||||||
|
$component->getManipulatedData($gridField, $list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user