1
0

TwigConfigTest.php 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Tests\Integration\App;
  4. use App\Tests\Integration\Support\AppTestCase;
  5. use Slim\Views\Twig;
  6. use Twig\Extension\EscaperExtension;
  7. /**
  8. * SEC_REVIEW F63 — pin Twig's autoescape strategy to `'html'`. The
  9. * current Twig major defaults to `'html'`, but the SEC_REVIEW asked
  10. * us not to rely on the default in case a future major bump or a
  11. * Slim-twig wrapper change silently flips it.
  12. */
  13. final class TwigConfigTest extends AppTestCase
  14. {
  15. protected function setUp(): void
  16. {
  17. $this->bootApp();
  18. }
  19. public function testAutoescapeStrategyIsExplicitlyHtml(): void
  20. {
  21. /** @var Twig $twig */
  22. $twig = $this->container->get(Twig::class);
  23. $escaper = $twig->getEnvironment()->getExtension(EscaperExtension::class);
  24. // `getDefaultStrategy` takes the template name; for the
  25. // pinned `'html'` policy it returns the strategy regardless
  26. // of name.
  27. self::assertSame('html', $escaper->getDefaultStrategy('any.twig'));
  28. self::assertSame('html', $escaper->getDefaultStrategy('pages/login.twig'));
  29. }
  30. public function testRenderedTemplateAutoescapesUserInput(): void
  31. {
  32. // Defence-in-depth: render a string with a script tag through
  33. // `{{ value }}` and confirm the output is HTML-escaped. The
  34. // unit test above pins the configured strategy; this one
  35. // proves the pipeline actually applies it.
  36. /** @var Twig $twig */
  37. $twig = $this->container->get(Twig::class);
  38. $env = $twig->getEnvironment();
  39. $env->setLoader(new \Twig\Loader\ArrayLoader([
  40. 'inline.twig' => 'value=[{{ value }}]',
  41. ]));
  42. $rendered = $env->render('inline.twig', ['value' => '<script>alert(1)</script>']);
  43. self::assertSame(
  44. 'value=[&lt;script&gt;alert(1)&lt;/script&gt;]',
  45. $rendered,
  46. );
  47. }
  48. }