Intereting Posts

Примеры уязвимого кода PHP?

Хорошо, поэтому я и друг делают мини-презентацию по безопасности PHP (я вообще не занимаюсь PHP), и он попросил меня найти несколько примеров уязвимого кода PHP (который подвержен SQL-инъекциям и всем другим типам атак ). Мне было интересно, есть ли какие-либо сайты с хорошими и плохими фрагментами кода, показывающими, как вы должны и не должны кодировать?

В основном я помещу их на наш сайт, и он попытается взломать его, тогда мы покажем «правильный» веб-сайт, и он попытается снова его взломать.

SQL-инъекция проста:

$var = $_POST['var']; mysql_query("SELECT * FROM sometable WHERE id = $var"); 

Это легко решить:

 $var = mysql_real_escape_string($_POST['var']); 

Другим распространенным является XSS (межсайтовый скриптинг) :

 $var = $_POST['var']; echo "<div>$var</div>\n"; 

позволяет вам вводить Javascript, который запускается с вашего сайта. Существует несколько способов борьбы с этим, например:

 $var = strip_tags($_POST['var']); 

а также

 $var = filter_var($_POST['var'], FILTER_SANITIZE_STRING); 

Ошибочная ошибка начинающего пользователя – это забудьте прекратить выполнение скрипта после перенаправления.

 <?php if ($_SESSION['user_logged_in'] !== true) { header('Location: /login.php'); } omg_important_private_functionality_here(); 

Решение:

 if ($_SESSION['user_logged_in'] !== true) { header('Location: /login.php'); exit(); } 

Это может быть пропущено при тестировании в обычном браузере, поскольку браузеры обычно следуют за заголовком « Location без отображения какого-либо вывода сценария.

О, мальчик, у тебя не будет примеров. Просто учебник Google PHP, и каждый из них имеет достаточно отверстий для заполнения Альберт-Холла.

Результат 1, w3schools. Каков их первый пример для включения пользовательского ввода?

 Welcome <?php echo $_POST["fname"]; ?>!<br /> 

Bzzt. HTML-инъекция, повторяющаяся во всех частях кода примера. Каков их первый запрос к базе данных?

 $sql="INSERT INTO Persons (FirstName, LastName, Age) VALUES ('$_POST[firstname]','$_POST[lastname]','$_POST[age]')"; 

Bzzt. SQL-инъекция, вы теряете. Следующий.

Результат 2, официальный учебник по PHP. Каков первый пример вывода переменной?

 echo $_SERVER['HTTP_USER_AGENT']; 

Bzzt. HTML-инъекция. Не является легкодоступной, но все же плохой практикой такого рода, которая повторяется в учебных материалах php.net.

Результат 3, tizag.com. Каков первый пример эхо ввода пользователя?

 echo "You ordered ". $quantity . " " . $item . ".<br />"; 

Bzzt.

Результат 4, freewebmasterhelp.com. Слишком простой, чтобы включать много, но все же управляет:

 print "Hello $name"; // Welcome to the user 

Bzzt.

Результат 5, learnphp-tutorial.com.

 <title><?= $greeting ?> World!</title> 

Bz …

Я мог бы продолжить.

Неудивительно, что общее качество кода PHP в дикой природе настолько катастрофично, когда этот горестный мусор – это то, что изучают кодеры?

Бобби Столы

alt text

Bobby Tables – это страница, посвященная тому, как скрипт может быть уязвим с помощью SQL-инъекции . Это не уникально для PHP, однако SQL-инъекция является причиной многих уязвимостей веб-страниц.

Возможно, вы захотите включить в свою презентацию.

Я видел такой код, как это написано в прошлом:

 foreach ($_REQUEST as $var => $val) { $$var = $val; } 

Это способ имитации параметра maligned register_globals . Это означает, что вы можете получить доступ к своим переменным следующим образом:

 $myPostedVar 

а не ужасно сложнее:

 $_POST['myPostedVar'] 

Риск безопасности появляется в таких ситуациях:

 $hasAdminAccess = get_user_access(); foreach ($_REQUEST as $var => $val) { $$var = $val; } if ($hasAdminAccess) { ... } 

Поскольку все, что вам нужно сделать, это добавить ?hasAdminAccess=1 к URL-адресу, и вы находитесь.

Еще один пример сценария входа в систему с поддержкой SQL-инъекций. Это, к сожалению, очень распространено среди новых программистов.

 $username = $_POST["username"]; $password = $_POST["password"]; $query = "SELECT username, password FROM users WHERE (username = '{$username}') AND (password = '{$password}')"; 

Сегодня DailyWTF :

 if(strstr($username, '**')) { $admin = 1; $username = str_replace('**', '', $username); $_SESSION['admin'] = 1; } else { $admin = 0; } 

Атака ответа на ответ HTTP

Если веб-приложение хранит входные данные из HTTP-запроса в cookie, скажем,

 <?php setcookie("author",$_GET["authorName"]); ?> 

Он очень подвержен атаке расщепления ответа HTTP, если вход не проверен правильно для символов «\ r \ n».

Если злоумышленник отправляет вредоносную строку, например «AuthorName \ r \ nHTTP / 1.1 200 OK \ r \ n ..», ответ HTTP будет разделен на два ответа следующей формы:

HTTP / 1.1 200 OK

Set-cookie: author = AuthorName

HTTP / 1.1 200 OK …

Очевидно, что второй ответ полностью контролируется злоумышленником и может быть сконструирован с любым содержимым заголовка и тела

Нападения в заголовке заголовка электронной почты представляют собой гораздо большую боль в шее, чем вы могли бы подозревать (если только вам не приходилось иметь дело с ними).

Это очень плохо:

 $to = 'contact@domain.com'; $subject = $_POST["subject"]; $message = $_POST["message"]; $headers = "From: ".$_POST["from"]; mail($to,$subject,$message,$headers); 

(код скопирован из второй ссылки выше).

CSRF для победы.

 <?php $newEmail = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL); $pdoStatement = $pdoDb->prepare('UPDATE user SET email=:email WHERE ID=:id'); $pdoStatement->execute(array(':email'=>$newEmail, ':id'=>$_SESSION['userId'])); 

Вы чувствуете себя в безопасности с таким кодом. Все хорошо, что ваши пользователи могут изменять свои электронные письма, не вводя SQL из-за вашего кода. Но, представьте, что у вас есть это на вашем сайте http: // siteA / , подключен один из ваших пользователей. В том же браузере он переходит на http: // siteB / где какой-то AJAX выполняет эквивалент этого кода:

 <form method="post" action="http://site/updateMyAccount.php"> <p> <input name="email" value="badguy@siteB"/> <input type="submit"/> </p> </form> 

Ваш пользователь просто изменил свою электронную почту, не зная об этом. Если вы не думаете, что такая атака опасна, спросите об этом Google

Чтобы противостоять таким атакам, вы можете:

  • Проверьте своего пользователя REFERER (далеко не идеальный)
  • Реализуйте несколько токенов, которые у вас были для ваших форм, и проверьте их присутствие при возврате ваших данных.

Еще один – захват сеанса. Один из способов сделать это – это комбинирование. Если ваш сервер принимает не cookie-сессии, у вас могут быть URL-адреса, такие как http: // siteA /? PHPSESSID = blabla, что означает, что ваш идентификатор сеанса является blabla.

Злоумышленник может начать сеанс и отметить его идентификатор сеанса, а затем передать ссылку http: // siteA /? PHPSESSID = attackerSessionId другим пользователям вашего сайта. Когда эти пользователи следуют этой ссылке, они используют тот же сеанс, что и ваш злоумышленник: сеанс без регистрации. Поэтому они заходят в систему. Если веб-сайт ничего не делает, ваш злоумышленник и ваш пользователь по-прежнему используют один и тот же сеанс с одинаковыми правами. Плохо, если пользователь является администратором.

Чтобы смягчить это, вы должны использовать session_regenerate_id, когда ваши учетные данные пользователей меняются (вход в систему и выход, переход в раздел администрирования и т. Д.).

Просмотрите проект Open Web Application Security. У них есть объяснения и примеры множества различных видов атак. http://www.owasp.org/index.php/Category:Attack

НЕПРАВИЛЬНЫЙ способ делать шаблоны.

 <?php include("header.php"); include($_GET["source"]); //http://www.mysite.com/page.php?source=index.php include("footer.php"); ?> в <?php include("header.php"); include($_GET["source"]); //http://www.mysite.com/page.php?source=index.php include("footer.php"); ?> в <?php include("header.php"); include($_GET["source"]); //http://www.mysite.com/page.php?source=index.php include("footer.php"); ?> 

XSS-уязвимости легко показать. Просто создайте страницу, которая помещает значение переменной GET «q» где-то на странице, а затем нажимает следующий URL-адрес:

 http://mysite.com/vulnerable_page.php?q%3D%3Cscript%20type%3D%22javascript%22%3Ealert(document.cookie)%3B%3C%2Fscript%3E 

Это приведет к отображению файлов cookie пользователя в окне предупреждения.

Разрешить загрузку и не проверять расширение. Заметим:

Сайт A позволяет загружать изображения и отображать их.

Cracker guy загружает файл и обманывает вас, чтобы поверить в его файл изображения (через HTTP mimetypes). Этот файл имеет расширение PHP и содержит вредоносный код. Затем он пытается увидеть свой файл изображения и потому, что каждый PHP-файл, исполняемый PHP, выполняется, код запускается. Он может делать все, что может сделать пользователь Apache.

Основные (часто чувствительные к безопасности) операции работают не так, как ожидалось, вместо этого требуя, чтобы программист использовал вторую «настоящую» версию, чтобы получить неисполненные функциональные возможности.

Самым серьезным из них будет то, на что влияет фактический оператор: Оператор «==» не работает так, как можно было бы ожидать, вместо этого необходим оператор «===», чтобы получить истинное сравнение равенства.

Один из больших 3-х PHP-пакетов форума был затронут уязвимостью в коде «оставаться в системе». Файл cookie будет содержать идентификатор пользователя и хэш-код пароля. PHP-скрипт будет читать и очищать идентификатор, использовать его для запроса правильного хэша пользователя в базе данных, а затем сравнить его с файлом в cookie, чтобы узнать, должны ли они автоматически регистрироваться.

Однако сравнение было с ==, поэтому, изменяя файл cookie, злоумышленник использует хэш-значение «значение» логического значения: true, делая вывод о сравнении хеш-выражения бесполезным. Таким образом, злоумышленник может заменить любой идентификатор пользователя для входа без пароля.

Разрешить пользователям загружать файлы, должен ли этот API использоваться пользователями или нет. Например, если программа загружает некоторые файлы на сервер, и эта программа никогда не загрузит плохой файл, это нормально.

Но хакер мог проследить, что отправляется, и где. Он мог узнать, что он позволяет загружать файлы.

Оттуда он мог легко загрузить файл php. Как только это будет сделано, игра закончится. Теперь у него есть доступ ко всем вашим данным и может уничтожить или изменить все, что он хочет.

Другая распространенная ошибка – это наводнение. Вы должны ввести некоторые нормальные ограничения на свои данные. Не разрешайте пользователям вводить бессмысленные данные. Почему имя пользователя имеет длину 2 МБ? Такие вещи делают так просто, чтобы кто-то наполнил вашу базу данных или файловую систему и разбил систему из-за ошибок в пространстве.