1
0

login.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?php
  2. require_once ($_SERVER['DOCUMENT_ROOT']."/inc/auth.utils.php");
  3. require_once ($_SERVER['DOCUMENT_ROOT']."/inc/languages/" . HTML_LANG . ".php");
  4. $error = '';
  5. function getSafeRedirectUrl(string $default = '/'): string {
  6. $url = filter_input(INPUT_GET, 'redirect_url', FILTER_SANITIZE_URL)
  7. ?? filter_input(INPUT_POST, 'redirect_url', FILTER_SANITIZE_URL)
  8. ?? $default;
  9. $decodedUrl = urldecode($url);
  10. // Проверяем:
  11. // 1. URL начинается с `/` (но не `//` или `http://`)
  12. // 2. Содержит только разрешённые символы (a-z, 0-9, -, _, /, ?, =, &, ., ~)
  13. if (!preg_match('/^\/(?!\/)[a-z0-9\-_\/?=&.~]*$/i', $decodedUrl)) {
  14. return $default;
  15. }
  16. // Проверяем:
  17. // 1. Начинается с /, не содержит //, ~, %00
  18. // 2. Разрешённые символы: a-z, 0-9, -, _, /, ?, =, &, .
  19. // 3. Допустимые форматы:
  20. // - /path/ (слэш на конце)
  21. // - /path (без слэша)
  22. // - /file.html (только .html)
  23. // - /script.php (только .php)
  24. // - Любой вариант с параметрами (?id=1)
  25. if (!preg_match(
  26. '/^\/' // Начинается с /
  27. . '(?!\/)' // Не //
  28. . '[a-z0-9\-_\/?=&.]*' // Разрешённые символы
  29. . '(?:\/' // Варианты окончаний:
  30. . '|\.(html|php)(?:\?[a-z0-9\-_=&]*)?' // .html/.php (+ параметры)
  31. . '|(?:\?[a-z0-9\-_=&]*)?' // Или параметры без расширения
  32. . ')$/i',
  33. $decodedUrl
  34. )) {
  35. return $default;
  36. }
  37. // Дополнительная защита: явно блокируем /config/, /vendor/ и т.д.
  38. if (preg_match('/(^|\/)(cfg|inc|log|sessions|tmp)(\/|$)/i', $decodedUrl)) {
  39. return $default;
  40. }
  41. return $url;
  42. }
  43. // Использование
  44. $redirect_url = getSafeRedirectUrl(DEFAULT_PAGE);
  45. if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['submit'])) {
  46. $login = trim($_POST['login']);
  47. $password = trim($_POST['password']);
  48. // validate if login is empty
  49. if (empty($login)) {
  50. $error .= '<p class="error">'.WEB_msg_login_hint.'.</p>';
  51. }
  52. // validate if password is empty
  53. if (empty($password)) {
  54. $error .= '<p class="error">'.WEB_msg_password_hint.'.</p>';
  55. }
  56. if (empty($error)) {
  57. if (login($db_link)) {
  58. $redirect_url = urldecode($redirect_url);
  59. header("Location: $redirect_url");
  60. }
  61. }
  62. }
  63. ?>
  64. <!DOCTYPE html>
  65. <html>
  66. <head>
  67. <title><?php echo WEB_site_title; ?> login</title>
  68. <link rel="stylesheet" type="text/css" href="/css/<?php echo HTML_STYLE.'.css'; ?>">
  69. <link rel="stylesheet" type="text/css" href="/login.css" >
  70. <meta http-equiv="content-type" content="application/xhtml+xml" />
  71. <meta charset="UTF-8" />
  72. </head>
  73. <body>
  74. <div class="login">
  75. <h1><?php echo WEB_msg_login; ?></h1>
  76. <form action="" method="post">
  77. <label for="username">
  78. <i class="fas fa-user"></i>
  79. </label>
  80. <input type="text" name="login" placeholder="<?php echo WEB_msg_username; ?>" id="login" required autofocus>
  81. <label for="password">
  82. <i class="fas fa-lock"></i>
  83. </label>
  84. <input type="password" name="password" placeholder="<?php echo WEB_msg_password; ?>" id="password" required>
  85. <input type="hidden" name="redirect_url" value="<?php print htmlspecialchars($redirect_url); ?>">
  86. <input type="submit" name="submit" value="<?php echo WEB_btn_login; ?>">
  87. </form>
  88. </div>
  89. </body>
  90. </html>