Skip to content

Commit dfce158

Browse files
authored
Merge pull request #1024 from soyuka/security/json-error-normalizer
Do not expose sensitive informations (json format)
2 parents 5f68df2 + 1a6362e commit dfce158

File tree

4 files changed

+95
-8
lines changed

4 files changed

+95
-8
lines changed

src/Hydra/Serializer/ErrorNormalizer.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace ApiPlatform\Core\Hydra\Serializer;
1313

1414
use ApiPlatform\Core\Api\UrlGeneratorInterface;
15+
use ApiPlatform\Core\Problem\Serializer\ErrorNormalizerTrait;
1516
use Symfony\Component\Debug\Exception\FlattenException;
16-
use Symfony\Component\HttpFoundation\Response;
1717
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
1818

1919
/**
@@ -26,6 +26,8 @@ final class ErrorNormalizer implements NormalizerInterface
2626
{
2727
const FORMAT = 'jsonld';
2828

29+
use ErrorNormalizerTrait;
30+
2931
private $urlGenerator;
3032
private $debug;
3133

@@ -40,16 +42,12 @@ public function __construct(UrlGeneratorInterface $urlGenerator, bool $debug = f
4042
*/
4143
public function normalize($object, $format = null, array $context = [])
4244
{
43-
$message = $object->getMessage();
4445
if ($this->debug) {
4546
$trace = $object->getTrace();
46-
} elseif ($object instanceof FlattenException) {
47-
$statusCode = $context['statusCode'] ?? $object->getStatusCode();
48-
if ($statusCode >= 500 && $statusCode < 600) {
49-
$message = Response::$statusTexts[$statusCode];
50-
}
5147
}
5248

49+
$message = $this->getErrorMessage($object, $context, $this->debug);
50+
5351
$data = [
5452
'@context' => $this->urlGenerator->generate('api_jsonld_context', ['shortName' => 'Error']),
5553
'@type' => 'hydra:Error',

src/Problem/Serializer/ErrorNormalizer.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ final class ErrorNormalizer implements NormalizerInterface
2525
{
2626
const FORMAT = 'jsonproblem';
2727

28+
use ErrorNormalizerTrait;
29+
2830
private $debug;
2931

3032
public function __construct(bool $debug = false)
@@ -37,11 +39,12 @@ public function __construct(bool $debug = false)
3739
*/
3840
public function normalize($object, $format = null, array $context = [])
3941
{
40-
$message = $object->getMessage();
4142
if ($this->debug) {
4243
$trace = $object->getTrace();
4344
}
4445

46+
$message = $this->getErrorMessage($object, $context, $this->debug);
47+
4548
$data = [
4649
'type' => $context['type'] ?? 'https://tools.ietf.org/html/rfc2616#section-10',
4750
'title' => $context['title'] ?? 'An error occurred',
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace ApiPlatform\Core\Problem\Serializer;
13+
14+
use Symfony\Component\Debug\Exception\FlattenException;
15+
use Symfony\Component\HttpFoundation\Response;
16+
17+
trait ErrorNormalizerTrait
18+
{
19+
private function getErrorMessage($object, array $context, bool $debug = false): string
20+
{
21+
$message = $object->getMessage();
22+
23+
if ($debug) {
24+
return $message;
25+
} elseif ($object instanceof FlattenException) {
26+
$statusCode = $context['statusCode'] ?? $object->getStatusCode();
27+
if ($statusCode >= 500 && $statusCode < 600) {
28+
$message = Response::$statusTexts[$statusCode];
29+
}
30+
}
31+
32+
return $message;
33+
}
34+
}

tests/Problem/Serializer/ErrorNormalizerTest.php

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use ApiPlatform\Core\Problem\Serializer\ErrorNormalizer;
1515
use Symfony\Component\Debug\Exception\FlattenException;
16+
use Symfony\Component\HttpFoundation\Response;
1617

1718
/**
1819
* @author Kévin Dunglas <[email protected]>
@@ -53,4 +54,55 @@ public function testNormalize()
5354
$normalizer->normalize(new \Exception('Hello'), null, ['type' => 'https://dunglas.fr', 'title' => 'Hi'])
5455
);
5556
}
57+
58+
/**
59+
* @dataProvider providerStatusCode
60+
*
61+
* @param $status http status code of the Exception
62+
* @param $originalMessage original message of the Exception
63+
* @param $debug simulates kernel debug variable
64+
*/
65+
public function testErrorServerNormalize($status, $originalMessage, $debug)
66+
{
67+
$normalizer = new ErrorNormalizer($debug);
68+
$exception = FlattenException::create(new \Exception($originalMessage), $status);
69+
70+
$expected = [
71+
'type' => 'https://tools.ietf.org/html/rfc2616#section-10',
72+
'title' => 'An error occurred',
73+
'detail' => ($debug || $status < 500) ? $originalMessage : Response::$statusTexts[$status],
74+
];
75+
76+
if ($debug) {
77+
$expected['trace'] = $exception->getTrace();
78+
}
79+
80+
$this->assertEquals($expected, $normalizer->normalize($exception, null, ['statusCode' => $status]));
81+
}
82+
83+
public function providerStatusCode()
84+
{
85+
return [
86+
[Response::HTTP_INTERNAL_SERVER_ERROR, 'Sensitive SQL error displayed', false],
87+
[Response::HTTP_GATEWAY_TIMEOUT, 'Sensitive server error displayed', false],
88+
[Response::HTTP_BAD_REQUEST, 'Bad Request Message', false],
89+
[Response::HTTP_INTERNAL_SERVER_ERROR, 'Sensitive SQL error displayed', true],
90+
[Response::HTTP_GATEWAY_TIMEOUT, 'Sensitive server error displayed', true],
91+
[Response::HTTP_BAD_REQUEST, 'Bad Request Message', true],
92+
];
93+
}
94+
95+
public function testErrorServerNormalizeContextStatus()
96+
{
97+
$normalizer = new ErrorNormalizer(false);
98+
$exception = FlattenException::create(new \Exception(''), 500);
99+
100+
$expected = [
101+
'type' => 'https://tools.ietf.org/html/rfc2616#section-10',
102+
'title' => 'An error occurred',
103+
'detail' => Response::$statusTexts[502],
104+
];
105+
106+
$this->assertEquals($expected, $normalizer->normalize($exception, null, ['statusCode' => 502]));
107+
}
56108
}

0 commit comments

Comments
 (0)