Вывод страниц по запросу вида ?go=index. Взгляд с безопасности!

Baller

Новичок
index.php?goto=index Запрос к MySQL с условием пользователя.

Наверно не у меня одного есть задача сделать навигацию на сайте, в таком случае что бы не было накладок при изменение переменных.

Мой скрипт контента должен делать так:
Брать переменную с ?goto=index, сравнивать с базой если есть читать и выдавать как страницу.
Что же выходит если он не находит, он выводит что переменные пустые для вывода.
Так же как и это не хочется что бы была возможность управлять запросами прямо из ГЕТ переменной.

Вот код который есть. - Принимаю любые конструктивные пожелания, если есть вариант переделать всё тоже ок.

PHP:
if (isset ($_GET['page'])){
	$goto = $_GET['page'];}
else {
	$goto = "index";
}
#Есть модуль подключение.
#В этой части делаю менюшку тех страниц которые есть.
$DB = new mysql_db();
$DB->sql_connect();
$DB->query("SELECT short_call,title_page FROM content");

$menyu = "";
while ($row = $DB->fetch_row()){
    $linkhref = stripslashes($row['short_call']);
    $linktitle = stripslashes($row['title_page']);

    $menyu .= " <a href=?page=$linkhref>$linktitle</a><br>";
}

$DB->sql_free();
#Вот началась самая уязвимая зона скрипта
#Можно конечно "раздеть запрос тегом типа
#$goto = mysql_escape_string ('$goto');
#Остаётся другая проблема, если $goto кто то изменил. Выводит ошибки.
$DB->query("SELECT * FROM content WHERE short_call = '$goto'");
while ($row = $DB->fetch_row_obj())
{
    $contenta = "$row->short_call";
    $contenta2 = "$row->title_page";
    $contenta3 = "$row->content_code";
    $contenta4 = "$row->date";
    $contenta3 = htmlspecialchars_decode($contenta3);
}
$DB->sql_free();
$DB->sql_close();
# тут уже идёт вывод содержания.
register_globals off
php 5
Apache 2.2
СПАСИБО
 

Андрейка

Senior pomidor developer
Можно конечно "раздеть запрос тегом типа
#$goto = mysql_escape_string ('$goto')

не можно, а нужно... какие еще вопросы?
 

jonjonson

Охренеть
Если goto не определено, то страница сайта поумолчанию.
Если значение из goto не определено в базе данных, то ошибка http 404 (страница не найдена).
Если идиот меняет значения goto на не существующие, чем это будет отличаться от остальных попыток набрать в браузере не верный URL? И секьюрити тут не причём.
 

Фанат

oncle terrible
Команда форума
мда, выглядит страшновато.
зачем делать htmlspecialchars_decode перед выводом на экран - непонятно.
равно как и stripslashes
опять непонятно - почему в первом случае получаем row, а во втором - obj. в чем разница?
какие-то одинаковые с лица $contenta. Ты сам-то в них не путаешься?
не проще обращаться к полученным данным по именам?

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

то есть, весь вопрос в одном операторе if.

-~{}~ 17.06.07 10:23:

и класс для работы с БД довольно странный.
почему-то работа с ним ничем не отличается от работы с обычным API - ровно те же самые коннект, квери и вайл.
какой смысл в таком классе?
Не по урокам ли идиота Крепина он писался?
 

AmdY

Пью пиво
Команда форума
"$row->short_call" - а кавычки зачем?
$contenta, $contenta1 ... - лучше делать
PHP:
$contenta = array(
1=>$row->short_call,
2=>$row->title_page,
3=>htmlspecialchars_decode($row->content_code) // если это так нужно
);
а while вообще не нужен
 

jonjonson

Охренеть
Автор оригинала: *****
а суть самой проблемы, как я понял, сводится, всго лишь, к проверке существования в базе нужной записи, и, если такой нет - выводить сообщение о том, что страница не найдена.
что является более осмысленным действием, чем выводить индекс.
В данном случае индекс является главной страницей, когда GET параметр page явно не определён (например при обращении к сайту первый раз по имени домена). И автор кода в этом прав. А вот далее, если страница определена в GET параметре, но её значение отсутсвует в БД, то проверка этого действительно нужна и дальнейший вывод 404 Page not found...
 

Фанат

oncle terrible
Команда форума
а кто с этим спорит-то?
ситуация, когда GET параметр page явно не определён, у него нормально обрабатывается.
 

jonjonson

Охренеть
что является более осмысленным действием, чем выводить индекс
Смутило вот это, хотя автор кода не наставил на таком решении :)

А вообще у автора проблема в другом. У него судя по циклу вывода контента страница определена, если для неё определён хоть один айтем контента.

Причём все эти айтемы затирают друг друга в цикле :)
 

Baller

Новичок
Да я считаю что выводить ошибку 404 надо, но при этом кто в первые заходит у него не определена переменная ему ошибку видеть не надо.
Волнует меня а безопасно ли прямо таки на прямую из гет переменную тащить в MySQL запрос?


Ясли я ясно понял последнее обсуждение, то первый запрос к базе строит менюшку, а второй уже выводит на страничку саму страницу.

to *****
Стоит декод потому что, на странице админа он делает так:
$short = strip_tags($short);
$title = strip_tags($title);
$cont = htmlspecialchars($cont, ENT_QUOTES);
$date = strip_tags($date);

А насчёт класса, нет он не из книги ни какой.
Сейчас скину ссылку в мануале по пхп кто то выложил я и взял, только дополнил ещё. http://www.php.net/manual/en/ref.mysql.php#74437

-~{}~ 17.06.07 19:39:

Была идея наверно верная, если там идёт первый запрос запрашивая имена(которые потом сравниваються) то почему бы их не засунуть в массив что бы потом и проверить на существование!
К сожалению я не очень с массивами.

-~{}~ 17.06.07 19:55:

to>AmdY
Интересное предложение, но оно не работает.
Попытался устранить ошибки выводит.
PHP:
$DB->query("SELECT * FROM content WHERE short_call = '$goto'");
#while ($row = $DB->fetch_row_obj())
#{
$contenta = array(
$contenta['1']=>$row->short_call,
$contenta['2']=>$row->title_page,
$contenta['3']=>htmlspecialchars_decode($row->content_code),
$contenta['4']=>$row->date
);#}
echo "$contenta[1],$contenta[2],$contenta[3],$contenta[4]";
А вот результат:
http://denis.clubfiat.ru/screen_error_array.jpg
 

Baller

Новичок
Да $row не даёт, а с синтаксисом разобрался. Сейчас над классом голову ломаю
 

phprus

Moderator
Команда форума
Baller
Не надо ломать голову. Тебе просто надо найти в своем коде то место, в котором у тебя $row присваивается значение $DB->fetch_row_obj() и убедиться что этот код закоментирован.
 

Baller

Новичок
Работает, надо было просто нормально спросить.

-~{}~ 17.06.07 20:45:

если спросить как объект не работает.
Fatal error: Cannot use object of type stdClass as array in C:\server\www\Valya\DLEW-content\index.php on line 30

А если mysql_fetch_array, то всё как по масло и по моему быстрее.

-~{}~ 17.06.07 20:45:

Быстрее чем предыдущий вариант.

-~{}~ 17.06.07 23:17:

Стал тестировать скорость.....
Вот результаты.
Без массива 0.029,0.0137,0.0137,0.0068,0.0065,0.0151
С массивом 0.0096,0.0105,0.009,0.0111,0.0121,0.023

И кто же "Быстрее", работает лучше и безопаснее?
 

Фанат

oncle terrible
Команда форума
кто в первые заходит у него не определена переменная ему ошибку видеть не надо.
У тебя он её и не увидит. И с самого начала не должен был какие проблемы-то? Речь не о них.
Волнует меня а безопасно ли прямо таки на прямую из гет переменную тащить в MySQL запрос?
тебе сказали уже - если обезопасить переменную с помощью mysql_real_escape_string, то безопасно.
Тебе все по два раза надо объяснять?
Ну тогда на, читай: PHP FAQ: \"Кавычки \". Cоставление запросов mysql, слеши, экранирование кавычек.
Надеюсь, больше вопросов по безопасности не возникнет.

Стоит декод потому что, на странице админа он делает так:
$cont = htmlspecialchars($cont, ENT_QUOTES);
ну и какой глубокий смысл делать сначала htmlspecialchars, а потом htmlspecialchars_decode? мощность процессора некуда девать?
Была идея наверно верная, если там идёт первый запрос запрашивая имена(которые потом сравниваються) то почему бы их не засунуть в массив что бы потом и проверить на существование!
К сожалению я не очень с массивами.
хорошая идея, если весь сайт состоит из всего лишь тех разделов, которые в меню, и эти разделы - простые тексты.
Но и смысла в затее немного - по базе тоде проверить не проблема.
Но для практики, в учебных целях, можешь попробовать сделать такую проверку.
Интересное предложение, но оно не работает.
ДУРАЦКОЕ предложение. Тебе нафиг не нужен там массив.
ты себе зачем-то придумал дурацкие $contenta с цифрами, а AmdY придумал для них дурацкий массив.
extract(), и обращайся к своим переменным по нормальным именам.

-~{}~ 18.06.07 10:05:

И кто же "Быстрее", работает лучше и безопаснее?
О.ДИ.НА.КО.ВО.

-~{}~ 18.06.07 10:35:

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

Baller

Новичок
***** Спасибо!
Очень доходчиво мне объяснил и ответил на все мои вопросы.


ну и какой глубокий смысл делать сначала htmlspecialchars, а потом htmlspecialchars_decode? мощность процессора некуда девать?
Действительно убрал кодирование и декод...
Странички создаваться (в админ панельки) стали в 2 раза быстрее.
Ну наверно и просмотр тоже стал побыстрее.

ДУРАЦКОЕ предложение. Тебе нафиг не нужен там массив.
ты себе зачем-то придумал дурацкие $contenta с цифрами, а AmdY придумал для них дурацкий массив.
extract(), и обращайся к своим переменным по нормальным именам.
Зато теперь в них разбираться стал :D


Ну я будучи слушая все советы переписал вывод страницы на массивы.
Вот что получилось, код ниже.
PHP:
<?
list( $msec , $sec )= explode ( chr ( 32 ), microtime ());
$headtime = $sec + $msec ;

include "head.php";
include "function.php";
if (empty ($_GET['page'])){	$goto = "index";} else {	$goto = $_GET['page'];}
$goto = mysql_escape_string ($goto); 

$DB = new mysql_db();
$DB->sql_connect();
$DB->query("SELECT short_call,title_page FROM content");
$menyu="";
while ($row = $DB->fetch_row())
{
    $linktitle = stripslashes($row['title_page']);
    $linkhref = stripslashes($row['short_call']);
    $menyu .= " <a href=\"?page="."$linkhref"."\">$linktitle</a><br>";
}


$DB->sql_free();

$DB->query("SELECT * FROM content WHERE short_call = '$goto'");
if ($row = $DB->fetch_row()){
$show = array(
"call" => $row['short_call'],
"title" => $row['title_page'],
"code" => $row['content_code'],
"date" => $row['date']);}

	else {
	$show = array(
	"call" => "",
	"title" => "Error",
	"code" => "<h1>Page cannot be found</h1><br>404",
	"date" => "");}



$DB->sql_free();
$DB->sql_close();

echo "<title>$show[title] - DLEW Content </title>";
echo "<table width=100%>
<tr><td width=160  valign=top bgcolor=c9c9c9>";
echo "$menyu";
print "</td><td align=center>";
echo "<h1>$show[title]</h1><br>$show[code]";
$today = date("Y-n-j");
echo "<p><div align=right>Since "."$show[date]"."</div>
<hr>";
echo "</td></tr></table>";

include "end.php";
list( $msec , $sec )= explode ( chr ( 32 ), microtime ());
echo "<center><h3>Generation time: " . round (( $sec + $msec )- $headtime , 4 ). "" ;
?>
И тут без массивов по всем советом ФaHаTа :)

PHP:
<?
################ Count how long is it takes to compile. page
list( $msec , $sec )= explode ( chr ( 32 ), microtime ());
$headtime = $sec + $msec ;
################  Request need information
include "head.php";
include "function.php";
if (empty ($_GET['page'])){	$goto = "index";} else {	$goto = $_GET['page'];}
$goto = mysql_escape_string ($goto); 

################  Building Menu
$DB = new mysql_db();
$DB->sql_connect();
$DB->query("SELECT short_call,title_page FROM content");
$Menu="";
while ($row = $DB->fetch_row())
{
    $linktitle = stripslashes($row['title_page']);
    $linkhref = stripslashes($row['short_call']);
    $Menu .= " <a href=\"?page="."$linkhref"."\">$linktitle</a><br>";
}


$DB->sql_free();
################  Select info. to show

$DB->query("SELECT * FROM content WHERE short_call = '$goto'");
if ($row = $DB->fetch_row_obj()){
    $short = "$row->short_call";
    $title = "$row->title_page";
    $code = "$row->content_code";
    $date = "$row->date";

}
	else {
    $short = "";
    $title = "Error";
    $code = "<h1>Page cannot be found</h1><br>404";
    $date = "";
}



$DB->sql_free();
$DB->sql_close();
################  Show page
echo "<title>$title - DLEW Content </title>";
echo "<table width=100%>
<tr><td width=160  valign=top bgcolor=c9c9c9>";
echo "$Menu";
print "</td><td align=center>";
echo "<h1>$title</h1><br>$code";
$today = date("Y-n-j");
echo "<p><div align=right>Since "."$date"."</div>
<hr>";
echo "</td></tr></table>";

include "end.php";
list( $msec , $sec )= explode ( chr ( 32 ), microtime ());
echo "<center><h3>Generation time: " . round (( $sec + $msec )- $headtime , 4 ). "" ;
?>
 

Фанат

oncle terrible
Команда форума
Странички создаваться (в админ панельки) стали в 2 раза быстрее.
это тебе показалось
разумеется, ресурсы сервера я приплел исключительно в литературном плане.
никакого влияния на общую производительность скрипта эти две функции не оказывают.
речь шла только о бессмысленности делать такую парную операцию.
слушая все советы
ню-ню.
что делает stripslashes в этом коде?
переписал вывод страницы на массивы.
я только одного не могу понять.
смысл замены $row на $show от меня ускользает.
опять какая-то очень странная операция, когда вместо одного массива мы получаем другой - точно такой же.
чем нас первый не устроил - загадка!

а без массивов советом ФаНаТа был extract()
а не эта куча присвоений
 

AmdY

Пью пиво
Команда форума
PHP:
while ($row = $DB->fetch_row()) 
{ 
    $Menu .= '<a href="?page='. stripslashes($row['short_call']) 
                . ' ">' . stripslashes($row['title_page']) . '</a><br />'; 
}
------------
смени класс для работы с базой данных, переходи на шаблоны.
2фАнАт > extract() - это у тебя любовь со времён register global?
 

DeadLy

Новичок
$Menu .= " <a href=\"?page="."$linkhref"."\">$linktitle</a><br>";
нафига так делать? - бред
делай как AmdY предложил, только (тебе же ***** говорил - убери stripslashes)

PHP:
$Menu .= '<a href="?page='.$row['short_call'].'">'.$row['title_page'].'</a><br>';
 

Фанат

oncle terrible
Команда форума
AmdY
для тех, кто не понимает смысла написанного, extract - это замена блока присвоений
$short = "$row->short_call";
$title = "$row->title_page";
$code = "$row->content_code";
$date = "$row->date";
и про времена регистер глобалс я бы тебе не рекомендовал вообще заикаться в моем присутствии.
 

Baller

Новичок
Если уже речь пошла о выводе с стрипслэшами или без видно хорошо проблему не показывания в ссылках кавычки.
То есть если создать страницу в базе с short_name допустим "обо мне" Он не выведет ничего просто пустота.
 
Сверху