Без описания |
Поиск в теме | Версия для печати |
Furax |
Отправлено: 12 Марта, 2008 - 23:43:11
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
Systemnik
(int) приводит строку из GET-переменной к целочисленному типу.
Если написать так:CODE:$sql = @mysql_query("SELECT * FROM x_name WHERE `$11` = $_GET[page] LIMIT 1") То я могу передать в переменной page что угодно сразу на выполнение в базу данных. Например, передав в этой переменной текстCODE:1; DELETE FROM x_name WHERE 1; SELECT * FROM x_name WHERE `$11` = 1 Я могу фактически удалить все данные из таблицы x_name. Разумеется, можно поправить любые пароли, хранящиеся в базе, добавить или удалить таблицы и т. д. Это была бы грандиозная дыра в безопасности.
(int) сначала приводит строку к целочисленному типу (для строки, в которой содержится что-то, отличное от числа, возвращает 0). Таким образом, я уже не могу выполнить в твоей БД никакого кода, кроме того, который ты формируешь сам.
Точки - это сложение строк в PHP - я мог бы, разумеется, написать так:CODE:$page = (int)$_GET['page'];
$sql = @mysql_query("SELECT * FROM x_name WHERE `$11` = $page LIMIT 1"); Результат был бы тот же. Но я поленился писать в две строки, объединив всё в одну. Разумеется, при сложении со строкой целое ((int)$_GET['page']) преобразуется обратно в строковое представление, но эта строка уже не будет содержать ничего, кроме цифр. |
|
|
Furax |
Отправлено: 13 Марта, 2008 - 06:58:25
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
SystemnikCODE:$sql = @mysql_query("SELECT * FROM site_stranichki WHERE `id` = " . (int)$_GET['page'] . " LIMIT 1");
if (mysql_num_rows($sql))
{
$strings = mysql_fetch_row($sql);
echo($strings[1]);
} else {
echo("Данной страницы не существует.");
}
По второму вопросу - нужно просто проверить значение переменной. Например:CODE:if (!preg_match('/^\w+$/', $_GET['page']) die('Hack detected!'); (Отредактировано автором: 13 Марта, 2008 - 08:05:05) |
|
|
Furax |
Отправлено: 13 Марта, 2008 - 08:03:24
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
Systemnik
die - это не оператор, а функция. Она завершает работу скрипта, выведя свой аргумент.
Использовать можно. Потестировав, конечно. По идее, пример не должен пропускать ничего, кроме строки, состоящей из цифр, латинских букв, символа "_" и, возможно, "-" (не помню точно). |
|
|
Furax |
Отправлено: 14 Марта, 2008 - 07:02:40
|
Бледнотик
Покинул форум
Сообщений всего: 1472
Дата рег-ции: Март 2007
Откуда: Иркутск, Сибирь, СССР
Карма 32
|
Systemnik
А теперь посмотрим, в какой последовательности ты выполняешь действия.
В 12 строке ты отправляешь в базу данных на выполнение введённый пользователем код, а только в 13 интересуешься, а не введено ли там что-то не то. Поздно пить боржоми - почки отвалились!
В 16 строке ты получаешь данные из базы, а только в 17 начинаешь выяснять, а была ли вообще выбрана хоть одна строка.
Если ты хочешь допускать разные спецсимволы в идентификаторах, то проще всего перевести строку целиком в безопасный вид. То есть, чтобы, например, выбрать строки, метки которых выглядят как It's x\2+y\2, нужно заключить всю строку в одинарные кавычки и отбить обратными слэшами все "плохие" символы, чтобы база данных получила запрос такого вида:CODE:SELECT * FROM `table` WHERE `mark` = 'It\'s x\\2+y\\2' Отбивает слэшами "плохие" символы функция addSlashes(), а кавычки придётся добавить вручную. После этого можно смело совать строку в базу данных - ничего плохого она уже не сделает.
Кроме того, у тебя ошибка в 12 строке: вторая двойная кавычка завершила строковый литерал, поэтому для добавления к первой части строки содержимого GET-переменной нужно поставить точку (конкатенация строк):CODE:"SELECT * FROM site_stranichki WHERE `id` = " . $_GET['page'] . " LIMIT 1" Можно также написать и вот так:CODE:"SELECT * FROM site_stranichki WHERE `id` = $_GET[page] LIMIT 1" Обрати внимание на отсутствие кавычек вокруг слова page - поскольку оно и так упоминается в строковом литерале, необходимость в кавычках отпадает. Если же ты хотел просто поставить кавычки вокруг содержимого GET-переменной, то используй одинарные, чтобы они не перекрывались с теми, что формируют всю строку:CODE:"SELECT * FROM site_stranichki WHERE `id` = '$_GET[page]' LIMIT 1"
Посему отредактированный код будет выглядеть вот так:CODE:// Информация для досутпа к бд MySQL
$dbserver = "localhost"; // Имя сервера
$dbuser = "$$$"; // Имя пользователя
$dbpasswd = "$$$"; // Пароль
$dbname = "$$$"; // Имя базы данных
// Основые запросы для начала работы с бд
@mysql_connect($dbserver,$dbuser,$dbpasswd);
@mysql_select_db($dbname);
if (!isSet($_GET['page'])) //Если пользователь пришёл просто на index.php
$page = 'default'; //Метка по умолчанию
else
$page = addSlashes($_GET['page']); //Отбили слэшами "плохие" символы
// Работа с генерацией страницы засчет базы данных
//Обрати внимание на кавычки вокруг $page
$sql = @mysql_query("SELECT * FROM site_stranichki WHERE `id` = '$page' LIMIT 1");
if (mysql_num_rows($sql))
{
$strings = @mysql_fetch_row($sql);
echo($strings[1]);
} else {
echo("Данной страницы не существует.");
}
?> |
|
|
|
Поиск в теме | Версия для печати |
Страниц (6): « 1 [2] 3 4 5 6 » |
Сейчас эту тему просматривают: 3 (гостей: 3, зарегистрированных: 0, скрытых: 0) |
« PHP/Perl » |
Все гости форума могут просматривать этот раздел. Только администраторы и модераторы могут создавать новые темы в этом разделе. Только администраторы и модераторы могут отвечать на сообщения в этом разделе.
|
|
|