Фильтрация входящих данных с помощь php
Один из самых главных плюсов PHP является его простота в использовании. К сожалению, большинство программистов во время разработки приложений забывают принимать меры безопасности или у них отсутствует опыт написания необходимых функций. В PHP есть немало функций служащие для обеспечения безопасности приложений. Я покажу примеры уязвимостей вызванных неправильной фильтрации входящих данных и расскажу как от них избавиться.
Входящие данные – данные полученные от пользователя, например путем форм.
Пример #1
Вы никогда не должны подгружать на страницу файл, путь к которому получен путем передачи данных методом $_GET.
<code><?php include( $_GET [ 'filename' ]); ?>
Пример #2
Вы никогда не должны заносить в базу данных значения полученные от пользователя методом $_GET или $_POST, без каких либо фильтраций.
<code><?php
mysql_query ( "INSERT INTO table (field_one, field_two) VALUES ( { $_POST [ 'var1' ]} , { $_POST [ 'var2' ]} )" ;
?>
Представление про SQL Injection
Предположим у нас есть файл news.php, в который мы будем передавать уникальное значение ID которое присваивается каждой новости, для получения данных.
news.php
<?php
include("config/db.php"); //подключаемся к базе данных
$id = $_GET['id']; //получаем id при помощи метода $_GET
$sql = "SELECT * FROM news WHERE id='$id'"; //формируем MySQL запрос
mysql_query($sql); //выполняем MySQL запрос на получение данных
?>
Соответственно, если переменная $_GET['id'] будет равна — 1, то мы выполним следующий запрос:
SELECT * FROM news WHERE id='1'
В SQL языке есть оператор UNION, который объединяет два или более SELECT запроса.
Пример использования оператора UNION:
SELECT column_name(s) FROM table_name1 UNION SELECT column_name(s) FROM table_name2
Предположим что в базе данных в которой мы храним информацию относительно новостей портала, мы еще держим таблицу с логинами и паролями наших пользователей, которая содержит ячейки “login“, “password” и “admin” (определяем права администрирования пользователям, если значение 1 значит администратор, в противном случае обычный пользователь).
Теперь давай-те представим, что пользователь подделает адрес в браузере, и вместо:
http://example.com/news.php?id=1
он напишет:
http://example.com/news.php?id=1′ UNION SELECT login,password FROM users WHERE admin=’1′
И в таком случае, целиком SQL запрос будет выглядеть следующим образом:
SELECT * FROM news WHERE id='1' UNION SELECT login,password FROM users WHERE admin='1'
Это приводит к тому, что помимо самой информации относительно новости с ID — 1, мы еще получаем логин и пароль администратора.
Осуществление фильтрации данных.
Пример #1 (проверка целости чисел)
В пример приведенным выше, избавиться от уязвимости можно было-бы при помощи функции filter_var с параметром FILTER_VALIDATE_INT (только целые числа).
Пример использования:
<?php
include("config/db.php");
if(!filter_var($_GET['id'], FILTER_VALIDATE_INT )) {
$id = $_GET['id'];
} else {
exit("Ошибочный запрос!");
}
}$sql = "SELECT * FROM news WHERE id='$id'";
mysql_query($sql);
?>
Пример #2 (проверка почтового адреса)
Предположим в переменной $_POST['email'] у нас имеется предполагаемый почтовый адрес. Проверить так ли это можно так-же с помощью функции filter_var с параметром FILTER_VALIDATE_EMAIL.
Пример использования:
<?php
if(!filter_var($_POST['email'],FILTER_VALIDATE_EMAIL)) {
exit("Проверьте правильность ввода E-mai.");
} else {
$email = $_POST['email'];
}
?>
Проверку входящих данных можно так-же осуществлять в последствии использования функции preg_match, которая осуществляет проверку на соответствие заданному регулярному выражению (маске). Про использование этой функции я напишу позднее. Советую лучше ознакомиться поближе с рассмотренной мною функцией (filter_var), так как она употребляет меньше памяти и удобна в использовании.
RSS
полезно знать как для меня (новичка). спасибо
интересненько
Мне кажется чего-то не хватает, хотя может и ошибаюсь.