UrlRedirector.php 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin;
  4. use function __;
  5. use function is_scalar;
  6. use function preg_match;
  7. use function strlen;
  8. /**
  9. * URL redirector to avoid leaking Referer with some sensitive information.
  10. */
  11. final class UrlRedirector
  12. {
  13. /**
  14. * @psalm-return never
  15. */
  16. public static function redirect(): void
  17. {
  18. global $containerBuilder, $dbi;
  19. // Load database service because services.php is not available here
  20. $dbi = DatabaseInterface::load();
  21. $containerBuilder->set(DatabaseInterface::class, $dbi);
  22. // Only output the http headers
  23. $response = ResponseRenderer::getInstance();
  24. $response->getHeader()->sendHttpHeaders();
  25. $response->disable();
  26. if (
  27. ! isset($_GET['url']) || ! is_scalar($_GET['url']) || strlen((string) $_GET['url']) === 0
  28. || ! preg_match('/^https:\/\/[^\n\r]*$/', (string) $_GET['url'])
  29. || ! Core::isAllowedDomain((string) $_GET['url'])
  30. ) {
  31. Core::sendHeaderLocation('./');
  32. exit;
  33. }
  34. /**
  35. * JavaScript redirection is necessary. Because if header() is used then web browser sometimes does not change
  36. * the HTTP_REFERER field and so with old URL as Referer, token also goes to external site.
  37. *
  38. * @var Template $template
  39. */
  40. $template = $containerBuilder->get('template');
  41. echo $template->render('javascript/redirect', [
  42. 'url' => Sanitize::escapeJsString((string) $_GET['url']),
  43. ]);
  44. // Display redirecting msg on screen.
  45. // Do not display the value of $_GET['url'] to avoid showing injected content
  46. echo __('Taking you to the target site.');
  47. exit;
  48. }
  49. }