|
21 | 21 | use Slim\Tests\TestCase; |
22 | 22 | use stdClass; |
23 | 23 |
|
| 24 | +use function htmlspecialchars; |
24 | 25 | use function json_decode; |
25 | 26 | use function json_encode; |
26 | 27 | use function simplexml_load_string; |
27 | 28 |
|
| 29 | +use const ENT_QUOTES; |
| 30 | +use const ENT_SUBSTITUTE; |
| 31 | + |
28 | 32 | class AbstractErrorRendererTest extends TestCase |
29 | 33 | { |
30 | 34 | public function testHTMLErrorRendererDisplaysErrorDetails() |
@@ -94,6 +98,45 @@ public function testHTMLErrorRendererRenderHttpException() |
94 | 98 | $this->assertStringContainsString($exceptionDescription, $output, 'Should contain http exception description'); |
95 | 99 | } |
96 | 100 |
|
| 101 | + public function testHTMLErrorRendererEscapesHttpException() |
| 102 | + { |
| 103 | + $exceptionTitle = '<script>alert(1)</script>'; |
| 104 | + $exceptionDescription = "<script>alert('xss')</script>"; |
| 105 | + |
| 106 | + $httpExceptionProphecy = $this->prophesize(HttpException::class); |
| 107 | + |
| 108 | + $httpExceptionProphecy |
| 109 | + ->getTitle() |
| 110 | + ->willReturn($exceptionTitle) |
| 111 | + ->shouldBeCalledOnce(); |
| 112 | + |
| 113 | + $httpExceptionProphecy |
| 114 | + ->getDescription() |
| 115 | + ->willReturn($exceptionDescription) |
| 116 | + ->shouldBeCalledOnce(); |
| 117 | + |
| 118 | + $renderer = new HtmlErrorRenderer(); |
| 119 | + $output = $renderer->__invoke($httpExceptionProphecy->reveal(), false); |
| 120 | + |
| 121 | + $this->assertStringNotContainsString($exceptionTitle, $output, 'Title must not be rendered unescaped'); |
| 122 | + $this->assertStringContainsString( |
| 123 | + htmlspecialchars($exceptionTitle, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), |
| 124 | + $output, |
| 125 | + 'Title must be HTML-escaped' |
| 126 | + ); |
| 127 | + |
| 128 | + $this->assertStringNotContainsString( |
| 129 | + $exceptionDescription, |
| 130 | + $output, |
| 131 | + 'Description must not be rendered unescaped' |
| 132 | + ); |
| 133 | + $this->assertStringContainsString( |
| 134 | + htmlspecialchars($exceptionDescription, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), |
| 135 | + $output, |
| 136 | + 'Description must be HTML-escaped' |
| 137 | + ); |
| 138 | + } |
| 139 | + |
97 | 140 | public function testJSONErrorRendererDisplaysErrorDetails() |
98 | 141 | { |
99 | 142 | $exception = new Exception('Oops..'); |
|
0 commit comments