Фильтрация входящих данных с помощь 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), так как она употребляет меньше памяти и удобна в использовании.

3 комментариев

  1. teucremin пишет:

    полезно знать как для меня (новичка). спасибо

  2. SP1KE пишет:

    Мне кажется чего-то не хватает, хотя может и ошибаюсь. ;-)

Оставить комментарий