Skip to content

Commit c070c76

Browse files
committed
Add more input validation in ServerController.
1 parent bbbd6be commit c070c76

File tree

2 files changed

+79
-6
lines changed

2 files changed

+79
-6
lines changed

solid/lib/Controller/ServerController.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ public function authorize() {
156156
// return $result->addHeader('Access-Control-Allow-Origin', '*');
157157
}
158158

159+
if (! isset($_GET['client_id'])) {
160+
return new JSONResponse('Bad request, missing client_id', 400);
161+
}
162+
159163
if (isset($_GET['request'])) {
160164
$jwtConfig = Configuration::forSymmetricSigner(new Sha256(), InMemory::plainText($this->config->getPrivateKey()));
161165
try {
@@ -323,7 +327,9 @@ public function session() {
323327
*/
324328
public function token() {
325329
$request = \Laminas\Diactoros\ServerRequestFactory::fromGlobals($_SERVER, $_GET, $_POST, $_COOKIE, $_FILES);
326-
$grantType = $request->getParsedBody()['grant_type'];
330+
331+
$grantType = $request->getParsedBody()['grant_type'] ?? null;
332+
327333
switch ($grantType) {
328334
case "authorization_code":
329335
$code = $request->getParsedBody()['code'];
@@ -342,9 +348,9 @@ public function token() {
342348
break;
343349
}
344350

345-
$clientId = $request->getParsedBody()['client_id'];
351+
$clientId = $request->getParsedBody()['client_id'] ?? null;
346352

347-
$httpDpop = $request->getServerParams()['HTTP_DPOP'];
353+
$httpDpop = $request->getServerParams()['HTTP_DPOP'] ?? null;
348354

349355
$response = new \Laminas\Diactoros\Response();
350356
$server = new \Pdsinterop\Solid\Auth\Server($this->authServerFactory, $this->authServerConfig, $response);
@@ -361,7 +367,7 @@ public function token() {
361367
);
362368
}
363369

364-
return $this->respond($response); // ->addHeader('Access-Control-Allow-Origin', '*');
370+
return $this->respond($response);
365371
}
366372

367373
/**
@@ -389,8 +395,13 @@ public function logout() {
389395
* @NoCSRFRequired
390396
*/
391397
public function register() {
392-
$clientData = file_get_contents('php://input');
393-
$clientData = json_decode($clientData, true);
398+
$postData = file_get_contents('php://input');
399+
$clientData = json_decode($postData, true);
400+
401+
if (! isset($clientData)) {
402+
return new JSONResponse("Missing client data", Http::STATUS_BAD_REQUEST);
403+
}
404+
394405
if (! isset($clientData['redirect_uris'])) {
395406
return new JSONResponse("Missing redirect URIs", Http::STATUS_BAD_REQUEST);
396407
}

solid/tests/Unit/Controller/ServerControllerTest.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,33 @@ public function testAuthorizeWithoutUser()
119119
$this->assertEquals($expected, $actual);
120120
}
121121

122+
/**
123+
* @testdox ServerController should return a 400 when asked to authorize with a user but without client_id
124+
*
125+
* @covers ::authorize
126+
*/
127+
public function testAuthorizeWithoutClientId()
128+
{
129+
$parameters = $this->createMockConstructorParameters();
130+
131+
$this->mockUserManager->method('userExists')->willReturn(true);
132+
133+
$controller = new ServerController(...array_values($parameters));
134+
135+
$actual = $controller->authorize();
136+
$expected = new JSONResponse('Bad request, missing client_id', Http::STATUS_BAD_REQUEST);
137+
138+
$this->assertEquals($expected, $actual);
139+
}
140+
122141
/**
123142
* @testdox ServerController should return a 400 when asked to authorize with a user but without valid token
124143
*
125144
* @covers ::authorize
126145
*/
127146
public function testAuthorizeWithoutValidToken()
128147
{
148+
$_GET['client_id'] = self::MOCK_CLIENT_ID;
129149
$_GET['response_type'] = 'mock-response-type';
130150

131151
$parameters = $this->createMockConstructorParameters();
@@ -277,12 +297,33 @@ public function testAuthorize()
277297
*
278298
* @covers ::register
279299
*/
300+
public function testRegisterWithoutClientData()
301+
{
302+
$parameters = $this->createMockConstructorParameters();
303+
304+
$controller = new ServerController(...array_values($parameters));
305+
306+
$actual = $controller->register();
307+
308+
$this->assertEquals(
309+
new JSONResponse('Missing client data', Http::STATUS_BAD_REQUEST),
310+
$actual
311+
);
312+
}
313+
314+
/**
315+
* @testdox ServerController should return a 400 when asked to register without redirect URIs
316+
*
317+
* @covers ::register
318+
*/
280319
public function testRegisterWithoutRedirectUris()
281320
{
282321
$parameters = $this->createMockConstructorParameters();
283322

284323
$controller = new ServerController(...$parameters);
285324

325+
self::$clientData = json_encode([]);
326+
286327
$actual = $controller->register();
287328

288329
$this->assertEquals(
@@ -335,6 +376,26 @@ public function testRegisterWithRedirectUris()
335376
$this->assertEquals($expected, $actual);
336377
}
337378

379+
public function testTokenWithoutPostBody()
380+
{
381+
$parameters = $this->createMockConstructorParameters();
382+
383+
$controller = new ServerController(...$parameters);
384+
385+
$tokenResponse = $controller->token();
386+
387+
$expected = $this->createExpectedResponse(Http::STATUS_BAD_REQUEST, 'Bad Request');
388+
389+
$actual = [
390+
'data' => $tokenResponse->getData(),
391+
'headers' => $tokenResponse->getHeaders(),
392+
'status' => $tokenResponse->getStatus(),
393+
];
394+
unset($actual['headers']['X-Request-Id']);
395+
396+
$this->assertEquals($expected, $actual);
397+
}
398+
338399
/**
339400
* @testdox ServerController should consume Post, Server, and Session variables when generating a token
340401
*
@@ -344,6 +405,7 @@ public function testToken()
344405
{
345406
$_POST['client_id'] = self::MOCK_CLIENT_ID;
346407
$_POST['code'] = '';
408+
$_POST['grant_type'] = 'authorization_code';
347409
$_SERVER['HTTP_DPOP'] = 'mock dpop';
348410
$_SESSION['nonce'] = 'mock nonce';
349411

0 commit comments

Comments
 (0)