Действительно ли использование является существующим хэш-кодом от поля массива байтов, не достаточно хорошего? Также обратите внимание, что в Равняется методу, необходимо проверить, что массивы являются тем же размером прежде, чем сделать сравнивание.
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);
Разрешить людям загружать файлы, независимо от того, должен ли этот API использоваться пользователями или нет. Например, если программа загружает некоторые файлы на сервер, и эта программа никогда не загрузит плохой файл, это нормально.
Но хакер может отследить, что отправляется и куда. Он мог узнать, что это позволяет загружать файлы.
Оттуда он мог легко загрузить файл php. Как только это будет сделано, игра окончена. Теперь у него есть доступ ко всем вашим данным и он может уничтожить или изменить все, что захочет.
Другая распространенная ошибка - разрешить флуд. Вы должны установить разумные ограничения на свои данные. Не позволяйте пользователям вводить бессмысленные данные. Почему длина имени пользователя составляет 2 МБ? Подобные вещи позволяют кому-то легко переполнить вашу базу данных или файловую систему и привести к сбою системы из-за ошибок нехватки места.
Разрешение загрузки, но не проверка расширения. Обратите внимание:
Сайт A позволяет загружать и отображать изображения.
Взломщик загружает файл и обманом заставляет вас поверить, что это файл изображения (через HTTP-миметики). Этот файл имеет расширение PHP и содержит вредоносный код. Затем он пытается увидеть свой файл изображения, и поскольку каждый расширенный файл PHP выполняется PHP, выполняется код. Он может делать все, что может сделать пользователь apache.
Уязвимости 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 пользователя в окне предупреждения.
Базовые (часто чувствительные к безопасности) операции не работают должным образом, вместо этого от программиста требуется использовать вторую «настоящую» версию, чтобы получить исправную функциональность .
Самая серьезная из них - когда затрагивается фактический оператор: оператор «==» не работает так, как можно было бы ожидать, вместо этого оператор «===» необходим для получения истинного сравнения на равенство.
Один из трех больших пакетов форумов PHP был подвержен уязвимости в его коде «оставаться авторизованным». Файл cookie будет содержать идентификатор пользователя и хэш его пароля. Сценарий PHP будет читать и очищать идентификатор, использовать его для запроса правильного хэша пользователя в базе данных, а затем сравнивать его с хешем в файле cookie, чтобы увидеть, должны ли они автоматически входить в систему.
Однако сравнение было с ==, поэтому, изменяя cookie, злоумышленник использует "значение" хэша boolean: true, что делает оператор сравнения хэша бесполезным. Таким образом, злоумышленник может подставить любой идентификатор пользователя для входа в систему без пароля.
НЕПРАВИЛЬНЫЙ способ создания шаблонов.
<?php
include("header.php");
include($_GET["source"]); //http://www.mysite.com/page.php?source=index.php
include("footer.php");
?>
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.
Чтобы помочь против такого типа атак, вы можете:
Другой - захват сеанса. Один из способов сделать это - контрейлерство. Если ваш сервер принимает сеансы без файлов cookie, у вас могут быть URL-адреса типа http: // siteA /? PHPSESSID = blabla , что означает, что ваш идентификатор сеанса - blabla.
Злоумышленник может начать сеанс и отметить его сеанс ID, затем дайте ссылку http: // siteA /? PHPSESSID = attackerSessionId другим пользователям вашего сайта. Когда эти пользователи переходят по этой ссылке, они разделяют тот же сеанс, что и ваш злоумышленник: незарегистрированный сеанс. Итак, они входят в систему. Если веб-сайт ничего не делает, ваш злоумышленник и ваш пользователь по-прежнему используют один и тот же сеанс с одинаковыми правами. Плохо, если пользователь является администратором.
Чтобы смягчить это, вы должны использовать session_regenerate_id при изменении учетных данных ваших пользователей (вход и выход, переход в раздел администрирования и т. Д.).
Ознакомьтесь с проектом Open Web Application Security Project. У них есть объяснения и примеры множества различных атак. http://www.owasp.org/index.php/Category:Attack
Другой пример сценария входа в систему, уязвимого для sql-инъекций. К сожалению, это очень распространено среди начинающих программистов.
$username = $_POST["username"];
$password = $_POST["password"];
$query = "SELECT username, password
FROM users
WHERE (username = '{$username}')
AND (password = '{$password}')";
if(strstr($username, '**')) {
$admin = 1;
$username = str_replace('**', '', $username);
$_SESSION['admin'] = 1;
} else {
$admin = 0;
}
О мальчик, у тебя не будет недостатка в примерах. Просто погуглите учебник 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.
Очень распространенная ошибка новичков - забыть прервать выполнение скрипта после перенаправления.
<?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
, не отображая никаких выходных данных скрипта.
Я видел подобный код, написанный в прошлом:
foreach ($_REQUEST as $var => $val) {
$$var = $val;
}
Это способ имитировать злонамеренную опцию register_globals
. Это означает, что вы можете получить доступ к своим переменным таким образом:
$myPostedVar
, а не к ужасно более сложному:
$_POST['myPostedVar']
Риск безопасности возникает в таких ситуациях:
$hasAdminAccess = get_user_access();
foreach ($_REQUEST as $var => $val) {
$$var = $val;
}
if ($hasAdminAccess) { ... }
Поскольку все, что вам нужно сделать, это добавить ? hasAdminAccess = 1
к URL-адресу, и вы вошли.
Таблицы Бобби
Таблицы Бобби - это страница, посвященная подробному описанию способов, которыми скрипт может быть уязвим через SQL-инъекцию . Это характерно не только для PHP, однако SQL-инъекция является причиной многих уязвимостей веб-страниц.
Возможно, вы захотите кое-что включить в свою презентацию.
Заголовок электронной почты атаки путем инъекции - гораздо более серьезная боль в шее, чем вы могли подозревать (если только вам не приходилось иметь с ними дело).
Это очень плохо:
$to = 'contact@domain.com';
$subject = $_POST["subject"];
$message = $_POST["message"];
$headers = "From: ".$_POST["from"];
mail($to,$subject,$message,$headers);
(код скопирован из второй ссылки выше)
Атака с разделением 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 ОК ...
Очевидно, что второй ответ полностью контролируется злоумышленником и может быть построен вместо него с любым заголовком и содержанием тела