[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: запретить ввод посторонних переменных
mxwuser
Как сделать так, чтобы юзер не мог вводить посторонние ГЕТ переменные, а обробатывались только те, что задуманы автором? Тоесть чтобы просто не реагировала программа на левые переменные?



Спустя 5 минут, 55 секунд (2.11.2010 - 00:14) aH6y написал(а):
mxwuser
Обрабатывай только те, которые тебе нужны.

Спустя 31 минута, 15 секунд (2.11.2010 - 00:45) inpost написал(а):
mxwuser
phpforum.ru/index.php?inpost=noob
Можешь запустить! Видишь, что что-то произошло? Ответ: НЕТ! Потому что эта гет.переменная не используется скриптом. Пользователь может её хоть 100 раз отправить, всё равно ничего не будет. Как бы ты не старался, переменная в любом случае будет отправлена в скрипт.

Спустя 1 час, 25 минут, 40 секунд (2.11.2010 - 02:11) ИНСИ написал(а):
mxwuser можно сделать так, но это лишнее будет, просто отвечаю что можно сделать в твоем варианте:

1. Сделать массив, который будет содержать именна переменных, которые разрешены.
2. Пройтись циклом все переменные, которые присылаются в этот файл и проверить, разрешена ли присланная переменная в первом массиве.
4. Если нет лишних переменных, то пусть скрипт выполняет по плану..... если же есть лишняя переменная, то сразу alert('Ты, отправляешь лишнюю переменную, а значит ты хакер!!!');

P.S. alert - это js.

Спустя 6 минут, 16 секунд (2.11.2010 - 02:17) ИНСИ написал(а):
должно получиться, что-то в этом роде:
	$error = false;
$arr = array('name','email'); // массив, с разрешенными переменными
while(list($name) = each($_GET)) {
if(!in_array($name,$arr)) $error = true;
}

if($error == true) {
echo 'Error!';
} else {
// далее скрипт
}

Спустя 2 минуты, 56 секунд (2.11.2010 - 02:20) inpost написал(а):
welbox2
скрипт всё равно их получит =(

Спустя 6 часов, 8 минут, 59 секунд (2.11.2010 - 08:29) twin написал(а):
mxwuser
Цитата
Тоесть чтобы просто не реагировала программа на левые переменные?
С этого места поподробнее. Как именно она реагирует?

Спустя 3 часа, 12 минут, 4 секунды (2.11.2010 - 11:41) ИНСИ написал(а):
inpost я и не говорю что можно как-то запретить посылку лишних переменных. Я просто привел пример, если есть левые переменные, чтобы скрипт перестал дальше обрабатывать.

И я считаю это не нужным, просто для примера привел.
mxwuser самое главное, как можно лучше обрабатывать переменные.

Спустя 9 часов, 6 минут, 51 секунда (2.11.2010 - 20:48) mxwuser написал(а):
Вообщем, в той статейке было написано, что если записать в переменную не число, а некотыре строки, включая URL на сторонние файлы(там было про текстовые документы лежащие на других хостингах), то можно сильно на портачить. А каким образом тогда можно сделать, чтобы необходимые мне гет переменные, к примеру там ID, обробатывались только в определенном виде, например, числовом?

Спустя 19 минут, 2 секунды (2.11.2010 - 21:07) ИНСИ написал(а):
mxwuser

1. Если число: int(), intval;
2. stripslashes(); mysql_real_escape_string(); htmlspecialchars();

Спустя 9 минут, 39 секунд (2.11.2010 - 21:17) mxwuser написал(а):
Это все нужно сделать при на инициализации гет переменных типа:

if(isset($_GET['page'])) {
$page = $_GET['page'];
$page = (int)$page;
}

Так должно быть?

И как лучше с не числовыми переменными поступать. Твин в своей статье писал htmlspecialchars(); , а в каких случаях другие два юзать, и как это должно выглядеть?

Спустя 11 минут, 27 секунд (2.11.2010 - 21:28) ИНСИ написал(а):
mxwuser я защищаю так:

1. Для чисел: $_GET['id'] = intval($_GET['id']);
2. Для текста: $_GET['text'] = mysql_real_escape_sting(stripslashes($_GET['text']));


htmlspecialchars() - почитай тут

Спустя 4 минуты, 13 секунд (2.11.2010 - 21:33) ИНСИ написал(а):
вот еще ОЧЕНЬ классная функция:
function var_filter($value) {
if(is_array($value)) { $value = array_map('var_filter', $value); }
else {
$value = trim($value);
if(get_magic_quotes_gpc()) $value = stripslashes($value);
}
return $value;
}
$_GET = var_filter($_GET);



Спустя 26 минут (2.11.2010 - 21:59) mxwuser написал(а):
Благодарю. А она подходит и для чисел и для строковых переменных?

Спустя 21 минута, 30 секунд (2.11.2010 - 22:20) ИНСИ написал(а):
mxwuser функция для строковых переменных. После функции, обязательно используй mysql_real_escape_string

Спустя 6 минут, 21 секунда (2.11.2010 - 22:26) mxwuser написал(а):
welbox2, извини, я совсем ламер еще, эта функция работает сразу для всех гет переменных, или на каждую потом отдельно прописывать, например
$_GET['id'] = var_filter($_GET['id']);

Тоесть все полностью должно выглядеть так?:

if(isset($_GET['id'])) {
$_GET['id'] = var_filter($_GET['id']);
$id = $_GET['id'];
$id = mysql_real_escape_string($id);
}

Спустя 11 минут, 5 секунд (2.11.2010 - 22:38) ИНСИ написал(а):
mxwuser можешь сделать так:

function var_filter($value) {
if(is_array($value)) { $value = array_map('var_filter', $value); }
else {
$value = trim($value);
if(get_magic_quotes_gpc()) $value = stripslashes($value);
}
return $value;
}

while(list($i) = each($_GET)) {
$_GET[$i] = var_filter($_GET[$i]);
$_GET[$i] = mysql_real_escape_string(trim($_GET[$i]));
}


так применится ко всем $_GET переменным. Получается БД защищена.

Спустя 8 минут, 56 секунд (2.11.2010 - 22:46) ИНСИ написал(а):
можно, вот этот кусок:
while(list($i) = each($_GET)) {
$_GET[$i] = var_filter($_GET[$i]);
$_GET[$i] = mysql_real_escape_string(trim($_GET[$i]));
}


заменить на:
	while(list($i) = each($_GET)) { // обходим циклом все присланные переменные
if(is_numeric($_GET[$i])) { $_GET[$i] = intval($_GET[$i]); } // Если переменная является числом, то обрабатываем c intval
else { // иначе
$_GET[$i] = var_filter($_GET[$i]); // вызываем функцию и избавляемся от всякой ерунды
$_GET[$i] = mysql_real_escape_string(trim($_GET[$i])); // еще раз избавляемся от всякой ерунды
}
}

Спустя 2 минуты, 7 секунд (2.11.2010 - 22:49) mxwuser написал(а):
Тоесть, если я вставлю в свою свою прогу этот код, то каждую стровокую гет переменную, после этого останется из гет в обычную переменную превратить, и уже над ними колдовать не нужно?

Спустя 6 минут, 25 секунд (2.11.2010 - 22:55) ИНСИ написал(а):
mxwuser после этой проверки, больше можно ничего не делать, хотя может есть еще какие-то варианты ...

А зачем тебе превращать в обычные переменные? Просто используй далее эти же гет переменные. Не усложняй себе работу smile.gif


Спустя 6 минут, 55 секунд (2.11.2010 - 23:02) DmitryOpalev написал(а):
По-моему, вы (зря паритесь что-ли)... даже объяснить не могу rolleyes.gif
Если переменная нигде не используется, то она создастся и умрет! Все biggrin.gif

Спустя 13 минут, 15 секунд (2.11.2010 - 23:15) ИНСИ написал(а):
DmitryOpalev уже речь идет просто об обработке присланных переменных.

Спустя 36 минут, 47 секунд (2.11.2010 - 23:52) twin написал(а):
welbox2
У меня матов уже не осталось.
Ну если ты сам до конца не разобрался, зачем других то учишь?
Для чего это:
while(list($i) = each($_GET)) { // обходим циклом все присланные переменные
if(is_numeric($_GET[$i])) { $_GET[$i] = intval($_GET[$i]); } // Если переменная является числом, то обрабатываем c intval
else { // иначе
$_GET[$i] = var_filter($_GET[$i]); // вызываем функцию и избавляемся от всякой ерунды
$_GET[$i] = mysql_real_escape_string(trim($_GET[$i])); // еще раз избавляемся от всякой ерунды
}
}

Скрипт массив $_GET только в SQL использует?
НИКОГДА не обрабатывайте внешние данные на входе. Сколько раз говорить то. mad.gif

Спустя 8 минут (3.11.2010 - 00:00) ИНСИ написал(а):
twin в данном случае, пользователю надо ввести данные в БД, поэтому и все проверяем. А матом не стоит, в любом случае!

Спустя 5 минут, 55 секунд (3.11.2010 - 00:06) twin написал(а):
Если надо ввести данные в БД, то надо их и вводить в БД.
Но никак не портить суперглобальный массив $_GET

Спустя 28 минут, 14 секунд (3.11.2010 - 00:34) ИНСИ написал(а):
Цитата
Но никак не портить суперглобальный массив $_GET

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

mxwuser тогда вот исправленный вариант:
	while(list($i) = each($_GET)) { // обходим циклом все присланные переменные
if(is_numeric($_GET[$i])) { $$i = intval($_GET[$i]); } // Если переменная является числом, то обрабатываем c intval
else { // иначе
$value = var_filter($_GET[$i]); // вызываем функцию и избавляемся от всякой ерунды
$$i = mysql_real_escape_string(trim($value)); // еще раз избавляемся от всякой ерунды
}
}

теперь, для каждой гет переменной, создается обычная переменная, с названием этой ГЕТ-ПЕРЕМЕННОЙ.

То есть, если я послал $_GET['name'] = 'welbox2';, то в скрипте после обработок, я должен использовать не $_GET['name'], a просто переменную $name;

Спустя 1 час, 27 минут, 34 секунды (3.11.2010 - 02:02) mxwuser написал(а):
[b]$$i = intval($_GET[$i]); }[/b]

А почему 2 "доллара"? Ошибка, или я чего-то не знаю? (=

Спустя 23 минуты, 31 секунда (3.11.2010 - 02:25) ИНСИ написал(а):
mxwuser это не ошибка smile.gif smile.gif

Спустя 1 час, 7 минут, 22 секунды (3.11.2010 - 03:33) twin написал(а):
Зто не ошибка. Но пользоваться этим - моветон. Есть функция extract() для таких целей.
И вообще все эти изобретения, когда пытаются обработать данные одним махрм, до добра не доводят.
Все пытаются это делать, наивно полагая, что до них то никто не додумался.

Вот и тут - куча ошибок, которые не видны на первый взгляд, но обязательно когда-нибудь вылезут.

Обрабатывать данные нужно по месту применения. Если запрос - то в запросе. А не устраивать подобных каруселей.

Спустя 13 минут, 22 секунды (3.11.2010 - 03:46) kirik написал(а):
welbox2
О!) Нашел баг в подсветке)

Спустя 6 часов, 46 минут, 23 секунды (3.11.2010 - 10:32) ИНСИ написал(а):
kirik я не только этот баг нашел ...Часто, когда я нажимаю на редактировать своего сообщения, то мне выводится спан классы и много другой ерунды... я уже писал про это, но никто не откликнулся из администрации...

twin не все такие эксперты как ты, но делать хоть это, лучше чем ничего. Люди когда интересуются, учатся - рано или поздно сами смогут все понять и потом правильно писать код.

Спустя 1 час, 26 минут, 27 секунд (3.11.2010 - 11:59) twin написал(а):
welbox2
Цитата
Люди когда интересуются, учатся - рано или поздно сами смогут все понять и потом правильно писать код.

На самом деле это не совсем так. Делать что-то, лишь бы работало, да и причем методом тыка, это не тот путь, по которому должен развиваться профессиональный программист.
Это долго, неэфективно, зачастую опасно.

Читать, читать, читать, потом только пробовать. Изучать предмет не изнутри сначала, а снаружи.

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


Спустя 14 минут, 11 секунд (3.11.2010 - 12:13) ИНСИ написал(а):
twin я у кого только не спрашиваю, все говорят по разному. Все вы эксперты, по моему наблюдению, привыкли работать каждый по своему. Допустим, меня обучал Sylex. Именно он говорил что так надо делать.

У меня есть вся наша переписка, вот кусок:
Цитата
все что нужно помнить, это просто - ЧТО ВСЕ ПЕРЕМЕННЫЕ, КОТОРЫЕ ТЫ ИСПОЛЬЗУЕШЬ В ЗАПРОСЕ ДОЛЖНЫ СТРОГО ОБРАБОТАТЬСЯ ФУНКЦИЕЙ mysql_real_escape_string (и только ей!!!!!!!!), а если это число - то (int) или intval()

Цитата
таким образом, чтобы в БД делать безопасные запросы нужно:

1. стереть слэши, если включена опция magic_quotes_gpc - используем var_filter
2. перед вставкой в запрос экранировать данные функцией mysql_real_escape_string или intval
ВСЕ, ТОГДА ТВОЯ БД ЗАЩИЩЕНА !


Исходя из того, чему меня научили, я так и работаю. Ты все время меня подправляешь, Я НЕ ПРОТИВ! Я буду благодарен, за справедливую критику. Но часто, ты просто говоришь, что я делаю неправильно, а выход из ситуации не предлагаешь.

Спустя 48 минут, 13 секунд (3.11.2010 - 13:01) twin написал(а):
Все он говорит верно. Ошибка твоя не в том, как ты обрабатываешь данные. Ошибка где ты их обрабатываешь.

Вот смотри.
1. Способ не удачный даже потому, что переменных не видно явно. То что они находятся в текущей таблице, не добавляет читабельности коду.

2. Если вдруг придется в базу записать данные, полученные не из $_GET, а из той же базы, то во первых они останутся необработанными (ибо мы понадеемся на твой универсальный костыль), либо будут обработанны неверно, если мы все же их через него попытаемся пропустить.

3. Литеральные константы (строки) перед внесением в запрос нужно обрамить апострофами. А числовые - нет. Твоя "универсальная" обработка не делает различий. А это значит мы должны либо определить тип вручную (тогда смысл костыля теряется), либо обрамлять всё. Тогда портится семантика SQL.

Я много раз писал (не сам придумал), что обработка должна производится непосредственно там, где она необходима.

Магические кавычки убить на входе, так как это ошибка разработчиков и её нужно исправить.
Экранирование и приведение типов при формировании запросов.
Обработку вывода на выводе, ни как не раньше.

Чтобы понять, что это единственно верный путь, нужно было решить задачу. Её нельзя решить иначе. А не пытаться нагородить заборов из граблей.

Спустя 1 час, 32 минуты, 48 секунд (3.11.2010 - 14:34) mxwuser написал(а):
Я тут все перечитал, и меня вообще, переклинило.
У меня такая задача была. Есть страница, ее контент зависит от значения переменной $_GET['page']. Эта переменная является числовой. В связи с этим, как я понял, она должна обрабатываться только один раз, функцей intval, которая возьмет из значения моей переменной только челое число в десятичной системе, без каких либо посторонних знаков. Страница у меня простая(типа тренировочная, чтобы понять как и что для начала), переменная GET всего одна, правильно ли будет сделать так, если сразу после подключения к БД, второй строкой на странице, выполнить следующее:
if (isset($_GET['page'])) {$_GET['page'] = intval($page); }

А если же $page, будет иметь текстовое значение, то должно будет обрабатываться следующим образом:
if(isset($_GET['page'])) = {$_GET['page'] = mysql_real_escape_string(stripslashes($page)); }
Где stripslashes преобразует кавычки и слеши, используемые для каких либо действий в PHP, а mysq_real_escape_string, преобразует символы используемые для записи в БДмускул. Я правильно основу понял?
Далее 2 вопроса.
Первый: В каких случаях необходимо использовать функцию htmlspecialchars();?
Второй: Если моя страница не предусматривает записи данных в БД, а только их вывод, можно ла как-то дополнительно обезопасить страницу, путем, например, запрета записи данных в MYSQL, пользователю через который подключается к mysql страница?

Спустя 4 минуты, 1 секунда (3.11.2010 - 14:38) aH6y написал(а):
mxwuser
Тогда уж так правильно будет:
if (isset($_GET['page'])) $page = intval($_GET['page']);

Если будет иметь текстовое значение, то ты проверяй на пустоту, обрезай пробелы и убирай кавычки. А mysql_real_escape_string можно использовать только в строке запроса, например так:
mysql_query("INSERT INTO `table` VALUES ('".mysql_real_escape_string($page)."')");

Спустя 8 минут, 20 секунд (3.11.2010 - 14:46) mxwuser написал(а):
Ну я ошибся там с местами, да (= А как же тогда строковую переменную обрабатывать, можете функции озвучить? (-=

Спустя 6 минут, 5 секунд (3.11.2010 - 14:52) aH6y написал(а):
mxwuser
if (isset($_GET['page'])) $page = trim(stripslashes($_GET['page']));

В самом запросе пишем так:
mysql_query("INSERT INTO `table` VALUES ('".mysql_real_escape_string($page)."')");

Спустя 4 минуты, 21 секунда (3.11.2010 - 14:57) twin написал(а):
aH6y
А попробуй такой текст записать:
Цитата
Бэкслэш (\) - символ, применяемый для экранирования и обознчения непечатных символоd (\r, \n, \t, \d, \s и так далее).
при выключенных магических кавычках.

Спустя 11 минут, 35 секунд (3.11.2010 - 15:08) mxwuser написал(а):
ААА... Твин, ну уже 3 раз в тему говоришь загадками, и непонятно потом что правильно, а что нет(

Спустя 1 минута, 17 секунд (3.11.2010 - 15:10) mxwuser написал(а):
Далее 2 вопроса.
Первый: В каких случаях необходимо использовать функцию htmlspecialchars();?
Второй: Если моя страница не предусматривает записи данных в БД, а только их вывод, можно ла как-то дополнительно обезопасить страницу, путем, например, запрета записи данных в MYSQL, пользователю через который подключается к mysql страница?

Спустя 5 минут, 57 секунд (3.11.2010 - 15:16) twin написал(а):
Никаких загадок. Нужно просто попробовать и разобраться почему так.
А на все вопросы я давно ответил здесь.

Спустя 9 минут, 44 секунды (3.11.2010 - 15:25) mxwuser написал(а):
Ну так как тогда правильно обработать строковую переменную? Я внимательно прочитал вашу статью не один раз, но именно об обработке гет переменных ничего не нашел. Можете меня носом ткнуть туда где это есть в той статье?

Спустя 17 минут, 35 секунд (3.11.2010 - 15:43) aH6y написал(а):
twin
Попробывал. Всё так и сохранилось, как я написал:
Цитата
Бэкслэш (\) - символ, применяемый для экранирования и обознчения непечатных символоd (\r, \n, \t, \d, \s и так далее).

С включёнными кавычками:
Цитата
Бэкслэш (\\) - символ, применяемый для экранирования и обознчения непечатных символоd (\\r, \\n, \\t, \\d, \\s и так далее).


mxwuser
Разницы get и post нету. Обрабатывай аналогично.

Спустя 6 минут, 8 секунд (3.11.2010 - 15:49) mxwuser написал(а):
Так я и ПОСТ не нашел...

Спустя 2 минуты, 46 секунд (3.11.2010 - 15:52) mxwuser написал(а):
if (isset($_GET['page'])) $page = trim(stripslashes($_GET['page']));
- Анбу, эта твоя строчка правильная? (=

Спустя 35 секунд (3.11.2010 - 15:52) aH6y написал(а):
mxwuser
Первый и второй пункты:воть

Да, но при работе с бд следует прменять еще и mysql_real_escape_string

Спустя 2 минуты, 6 секунд (3.11.2010 - 15:54) mxwuser написал(а):
Про SQL иньекции я понял все, а вот с той строчкой что ты дал, там обрабатвается переменные строковые, в первом же пункте не идет никакое не "не обрезание", не прочее колдавство...

Спустя 4 минуты, 15 секунд (3.11.2010 - 15:59) aH6y написал(а):
mxwuser
Читайте документацию.
stripslashes - убирает экранизацию.
addslashes - добавляет экранизацию.

Спустя 4 минуты, 38 секунд (3.11.2010 - 16:03) mxwuser написал(а):
Да я читал уже все. Мне 2 стрнаницу, всего лишь навсего, нужно было узнать правильно ли сформулировал код обработки или нет. В любом случае всем спасибо, Тебе, Твину, и Веллбоксу, что мне нужно было, я узнал (=

Спустя 2 часа, 27 минут, 6 секунд (3.11.2010 - 18:30) twin написал(а):
Поройся тут в решениях. Там много интересного.

Спустя 2 часа, 4 минуты, 15 секунд (3.11.2010 - 20:35) ИНСИ написал(а):
twin большое спасибо, что объяснил где именно моя ошибка. Я понял.

Спасибо. Тогда правильно ли будет, если посоветую для mxwuser следующее:

1. Забудь все, о чем мы ранее говорили и коды, которые были сделаны.
2. Когда отправляешь в скрипт: $_GET['name'] или $_GET['id'] и их необходимо записать в БД, делаем так:

function var_filter($value) {
if(is_array($value)) { $value = array_map('var_filter', $value); }
else {
$value = trim($value);
if(get_magic_quotes_gpc()) $value = stripslashes($value);
}
return $value;
}

mysql_query("
INSERT
INTO `users`(`name`,`id`)
VALUES('"
.mysql_real_escape_string(var_filter($_GET['name']))."',".intval($_GET['id']).")
"
);


получается числовую переменную, мы обрабатываем через intval, а строковое, через функцию и mysql_real_escape_string. И самое главное, обрабатываем уже прямо в запросе, для того чтобы не гадить глобальную переменную.

twin так правильно?

Спустя 23 минуты, 4 секунды (3.11.2010 - 20:58) twin написал(а):
Воооот. smile.gif
Еще совет один - intval() дольше писать и работает медленнее, чем (int)

Спустя 1 час, 35 минут, 6 секунд (3.11.2010 - 22:33) inpost написал(а):
Лично на сервере, где мои сайты валяются, intval работает в 2,5 раза медленее.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.