mirror of
https://github.com/silverstripe/silverstripe-restfulserver
synced 2024-10-22 14:05:58 +02:00
Merge pull request #1 from silverstripe-security/pulls/2.0/sort-only-on-fields
[CVE-2019-12149] Fixed potential SQL injection vulnerability in RestfulServer
This commit is contained in:
commit
a3319831a8
@ -2,20 +2,20 @@
|
||||
|
||||
namespace SilverStripe\RestfulServer;
|
||||
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\Control\HTTPRequest;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\ORM\DataList;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
use SilverStripe\ORM\SS_List;
|
||||
use SilverStripe\ORM\ValidationException;
|
||||
use SilverStripe\ORM\ValidationResult;
|
||||
use SilverStripe\Security\Member;
|
||||
use SilverStripe\Security\Security;
|
||||
use SilverStripe\CMS\Model\SiteTree;
|
||||
use SilverStripe\Core\Injector\Injector;
|
||||
|
||||
/**
|
||||
* Generic RESTful server, which handles webservice access to arbitrary DataObjects.
|
||||
@ -205,23 +205,29 @@ class RestfulServer extends Controller
|
||||
* @todo Access checking
|
||||
*
|
||||
* @param string $className
|
||||
* @param Int $id
|
||||
* @param int $id
|
||||
* @param string $relation
|
||||
* @return string The serialized representation of the requested object(s) - usually XML or JSON.
|
||||
*/
|
||||
protected function getHandler($className, $id, $relationName)
|
||||
{
|
||||
$sort = '';
|
||||
$sort = ['ID' => 'ASC'];
|
||||
|
||||
if ($this->request->getVar('sort')) {
|
||||
$dir = $this->request->getVar('dir');
|
||||
$sort = array($this->request->getVar('sort') => ($dir ? $dir : 'ASC'));
|
||||
if ($sortQuery = $this->request->getVar('sort')) {
|
||||
/** @var DataObject $singleton */
|
||||
$singleton = singleton($className);
|
||||
// Only apply a sort filter if it is a valid field on the DataObject
|
||||
if ($singleton && $singleton->hasDatabaseField($sortQuery)) {
|
||||
$sort = [
|
||||
$sortQuery => $this->request->getVar('dir') === 'DESC' ? 'DESC' : 'ASC',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$limit = array(
|
||||
'start' => $this->request->getVar('start'),
|
||||
'limit' => $this->request->getVar('limit')
|
||||
);
|
||||
$limit = [
|
||||
'start' => (int) $this->request->getVar('start'),
|
||||
'limit' => (int) $this->request->getVar('limit'),
|
||||
];
|
||||
|
||||
$params = $this->request->getVars();
|
||||
|
||||
|
@ -49,7 +49,7 @@ class RestfulServerTest extends SapphireTest
|
||||
{
|
||||
parent::setUp();
|
||||
Director::config()->set('alternate_base_url', $this->baseURI);
|
||||
Security::setCurrentUser(null);
|
||||
$this->logOut();
|
||||
}
|
||||
|
||||
public function testApiAccess()
|
||||
@ -613,6 +613,49 @@ class RestfulServerTest extends SapphireTest
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetWithSortDescending()
|
||||
{
|
||||
$urlSafeClassname = $this->urlSafeClassname(RestfulServerTestAuthor::class);
|
||||
$url = "{$this->baseURI}/api/v1/{$urlSafeClassname}?sort=FirstName&dir=DESC&fields=FirstName";
|
||||
|
||||
$response = Director::test($url);
|
||||
$results = Convert::xml2array($response->getBody());
|
||||
|
||||
$this->assertSame('Author 4', $results[$urlSafeClassname][0]['FirstName']);
|
||||
$this->assertSame('Author 3', $results[$urlSafeClassname][1]['FirstName']);
|
||||
$this->assertSame('Author 2', $results[$urlSafeClassname][2]['FirstName']);
|
||||
$this->assertSame('Author 1', $results[$urlSafeClassname][3]['FirstName']);
|
||||
}
|
||||
|
||||
public function testGetWithSortAscending()
|
||||
{
|
||||
$urlSafeClassname = $this->urlSafeClassname(RestfulServerTestAuthor::class);
|
||||
$url = "{$this->baseURI}/api/v1/{$urlSafeClassname}?sort=FirstName&dir=ASC&fields=FirstName";
|
||||
|
||||
$response = Director::test($url);
|
||||
$results = Convert::xml2array($response->getBody());
|
||||
|
||||
$this->assertSame('Author 1', $results[$urlSafeClassname][0]['FirstName']);
|
||||
$this->assertSame('Author 2', $results[$urlSafeClassname][1]['FirstName']);
|
||||
$this->assertSame('Author 3', $results[$urlSafeClassname][2]['FirstName']);
|
||||
$this->assertSame('Author 4', $results[$urlSafeClassname][3]['FirstName']);
|
||||
}
|
||||
|
||||
public function testGetSortsByIdWhenInvalidSortColumnIsProvided()
|
||||
{
|
||||
$urlSafeClassname = $this->urlSafeClassname(RestfulServerTestAuthor::class);
|
||||
$url = "{$this->baseURI}/api/v1/{$urlSafeClassname}?sort=Surname&dir=DESC&fields=FirstName";
|
||||
|
||||
$response = Director::test($url);
|
||||
|
||||
$results = Convert::xml2array($response->getBody());
|
||||
|
||||
$this->assertSame('Author 1', $results[$urlSafeClassname][0]['FirstName']);
|
||||
$this->assertSame('Author 2', $results[$urlSafeClassname][1]['FirstName']);
|
||||
$this->assertSame('Author 3', $results[$urlSafeClassname][2]['FirstName']);
|
||||
$this->assertSame('Author 4', $results[$urlSafeClassname][3]['FirstName']);
|
||||
}
|
||||
|
||||
public function testApiAccessWithPOST()
|
||||
{
|
||||
$urlSafeClassname = $this->urlSafeClassname(RestfulServerTestAuthorRating::class);
|
||||
|
@ -46,7 +46,7 @@ SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestAuthor:
|
||||
author2:
|
||||
FirstName: Author 2
|
||||
author3:
|
||||
Firstname: Author 3
|
||||
FirstName: Author 3
|
||||
author4:
|
||||
FirstName: Author 4
|
||||
RelatedAuthors:
|
||||
|
@ -12,7 +12,7 @@ class RestfulServerTestAuthor extends DataObject implements TestOnly
|
||||
private static $table_name = 'RestfulServerTestAuthor';
|
||||
|
||||
private static $db = array(
|
||||
'Name' => 'Text',
|
||||
'FirstName' => 'Text',
|
||||
);
|
||||
|
||||
private static $many_many = array(
|
||||
|
Loading…
Reference in New Issue
Block a user