тока что хотел предложить htmlentities поставить strip_tags() htmlspecialchars() stripslashes() mysql_real_escape_string еще же эти можно да?
strip_tags() - однозначно нет. htmlspecialchars - да. stripslashes(), mysql_real_escape_string - вообе из другой оперы.
strip_tags удаляет теги, у нее есть баги. htmlspecialchars преобразует специальные символы в HTML сущности - тру защита от XSS. stripslashes удаляет экранирование символов, произведенное функцией addslashes() - вообще не в тему. mysql_real_escape_string() экранирует специальные символы в строке, используемой в SQL-запросе. Тру защита от инъ, но не XSS.
Фикс файла usersearch.php Найти: PHP: <td valign="middle" class=rowhead>Имя:</td> <td<?=$_GET['n']?$highlight:""?>><input name="n" type="text" value="<?=$_GET['n']?>" size=35></td> Заменить на: PHP: <td valign="middle" class=rowhead>Имя:</td> <td<?=$_GET['n']?$highlight:""?>><input name="n" type="text" value="<?=htmlspecialchars($_GET['n'])?>" size=35></td> Найти: PHP: $options = array("равен","выше","ниже","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['rt']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменяем на: PHP: $options = array("равен","выше","ниже","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['rt']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <input name="r" type="text" value="<?=$_GET['r']?>" size="5" maxlength="4"> <input name="r2" type="text" value="<?=$_GET['r2']?>" size="5" maxlength="4"></td> Заменить на: PHP: <input name="r" type="text" value="<?=htmlspecialchars($_GET['r'])?>" size="5" maxlength="4"> <input name="r2" type="text" value="<?=htmlspecialchars($_GET['r2'])?>" size="5" maxlength="4"></td> Найти: PHP: $options = array("(Любой)","Подтвержден","Не подтвержден"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['st']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: $options = array("(Любой)","Подтвержден","Не подтвержден"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['st']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <tr><td valign="middle" class=rowhead>Email:</td> <td<?=$_GET['em']?$highlight:""?>><input name="em" type="text" value="<?=$_GET['em']?>" size="35"></td> <td valign="middle" class=rowhead>IP:</td> <td<?=$_GET['ip']?$highlight:""?>><input name="ip" type="text" value="<?=$_GET['ip']?>" maxlength="17"></td> Заменить на: PHP: <tr><td valign="middle" class=rowhead>Email:</td> <td<?=$_GET['em']?$highlight:""?>><input name="em" type="text" value="<?=htmlspecialchars($_GET['em'])?>" size="35"></td> <td valign="middle" class=rowhead>IP:</td> <td<?=$_GET['ip']?$highlight:""?>><input name="ip" type="text" value="<?=htmlspecialchars($_GET['ip'])?>" maxlength="17"></td> Найти: PHP: $options = array("(Любой)","Нет","Да"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['as']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: $options = array("(Любой)","Нет","Да"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['as']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <td valign="middle" class=rowhead>Комментарий:</td> <td<?=$_GET['co']?$highlight:""?>><input name="co" type="text" value="<?=$_GET['co']?>" size="35"></td> <td valign="middle" class=rowhead>Маска:</td> <td<?=$_GET['ma']?$highlight:""?>><input name="ma" type="text" value="<?=$_GET['ma']?>" maxlength="17"></td> <td valign="middle" class=rowhead>Класс:</td> <td<?=($_GET['c'] && $_GET['c'] != 1)?$highlight:""?>><select name="c"><option value='1'>(Любой)</option> Заменить на: PHP: <td valign="middle" class=rowhead>Комментарий:</td> <td<?=$_GET['co']?$highlight:""?>><input name="co" type="text" value="<?=htmlspecialchars($_GET['co'])?>" size="35"></td> <td valign="middle" class=rowhead>Маска:</td> <td<?=$_GET['ma']?$highlight:""?>><input name="ma" type="text" value="<?=htmlspecialchars($_GET['ma'])?>" maxlength="17"></td> <td valign="middle" class=rowhead>Класс:</td> <td<?=((int)$_GET['c'] && (int)$_GET['c'] != 1)?$highlight:""?>><select name="c"><option value='1'>(Любой)</option> Найти: PHP: $class = $_GET['c']; if (!is_valid_id($class)) $class = ''; Заменить на: PHP: if (!is_valid_id($_GET['c'])) $class = ''; $class = (int) $_GET['c']; Найти: PHP: <td valign="middle" class=rowhead>Регистрация:</td> <td<?=$_GET['d']?$highlight:""?>><select name="dt"> <? $options = array("в","раньше","после","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['dt']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: <td valign="middle" class=rowhead>Регистрация:</td> <td<?=$_GET['d']?$highlight:""?>><select name="dt"> <? $options = array("в","раньше","после","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['dt']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <input name="d" type="text" value="<?=$_GET['d']?>" size="12" maxlength="10"> <input name="d2" type="text" value="<?=$_GET['d2']?>" size="12" maxlength="10"></td> Заменить на: PHP: <input name="d" type="text" value="<?=htmlspecialchars($_GET['d'])?>" size="12" maxlength="10"> <input name="d2" type="text" value="<?=htmlspecialchars($_GET['d2'])?>" size="12" maxlength="10"></td> Найти: PHP: <td valign="middle" class=rowhead>Раздал:</td> <td<?=$_GET['ul']?$highlight:""?>><select name="ult" id="ult"> <? $options = array("ровно","больше","меньше","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['ult']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: <td valign="middle" class=rowhead>Раздал:</td> <td<?=$_GET['ul']?$highlight:""?>><select name="ult" id="ult"> <? $options = array("ровно","больше","меньше","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['ult']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <input name="ul" type="text" id="ul" size="8" maxlength="7" value="<?=$_GET['ul']?>"> <input name="ul2" type="text" id="ul2" size="8" maxlength="7" value="<?=$_GET['ul2']?>"></td> Заменить на: PHP: <input name="ul" type="text" id="ul" size="8" maxlength="7" value="<?=htmlspecialchars($_GET['ul'])?>"> <input name="ul2" type="text" id="ul2" size="8" maxlength="7" value="<?=htmlspecialchars($_GET['ul2'])?>"></td> Найти: PHP: <td valign="middle" class="rowhead">Донор:</td> <td<?=$_GET['do']?$highlight:""?>><select name="do"> <? $options = array("(Любой)","Да","Нет"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['do']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: <td valign="middle" class="rowhead">Донор:</td> <td<?=$_GET['do']?$highlight:""?>><select name="do"> <? $options = array("(Любой)","Да","Нет"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['do']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <td valign="middle" class=rowhead>Последняя активность:</td> <td <?=$_GET['ls']?$highlight:""?>><select name="lst"> <? $options = array("в","раньше","после","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['lst']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: <td valign="middle" class=rowhead>Последняя активность:</td> <td <?=$_GET['ls']?$highlight:""?>><select name="lst"> <? $options = array("в","раньше","после","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['lst']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <input name="ls" type="text" value="<?=$_GET['ls']?>" size="12" maxlength="10"> <input name="ls2" type="text" value="<?=$_GET['ls2']?>" size="12" maxlength="10"></td> Заменить на: PHP: <input name="ls" type="text" value="<?=htmlspecialchars($_GET['ls'])?>" size="12" maxlength="10"> <input name="ls2" type="text" value="<?=htmlspecialchars($_GET['ls2'])?>" size="12" maxlength="10"></td> Найти: PHP: <td valign="middle" class=rowhead>Скачал:</td> <td<?=$_GET['dl']?$highlight:""?>><select name="dlt" id="dlt"> <? $options = array("ровно","больше","меньше","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['dlt']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: <td valign="middle" class=rowhead>Скачал:</td> <td<?=$_GET['dl']?$highlight:""?>><select name="dlt" id="dlt"> <? $options = array("ровно","больше","меньше","между"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['dlt']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: <input name="dl" type="text" id="dl" size="8" maxlength="7" value="<?=$_GET['dl']?>"> <input name="dl2" type="text" id="dl2" size="8" maxlength="7" value="<?=$_GET['dl2']?>"></td> Заменить на: PHP: <input name="dl" type="text" id="dl" size="8" maxlength="7" value="<?=htmlspecialchars($_GET['dl'])?>"> <input name="dl2" type="text" id="dl2" size="8" maxlength="7" value="<?=htmlspecialchars($_GET['dl2'])?>"></td> Найти: PHP: <td valign="middle" class=rowhead>Предупрежден:</td> <td<?=$_GET['w']?$highlight:""?>><select name="w"> <? $options = array("(Любой)","Да","Нет"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(($_GET['w']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Заменить на: PHP: <td valign="middle" class=rowhead>Предупрежден:</td> <td<?=$_GET['w']?$highlight:""?>><select name="w"> <? $options = array("(Любой)","Да","Нет"); for ($i = 0; $i < count($options); $i++){ echo "<option value=$i ".(((int)$_GET['w']=="$i")?"selected":"").">".$options[$i]."</option>\n"; Найти: PHP: // name $names = explode(' ',trim($_GET['n'])); Заменить на: PHP: // name $names = explode(' ',trim(htmlspecialchars($_GET['n']))); Найти: PHP: $q .= ($q ? "&" : "") . "n=".urlencode(trim($_GET['n'])); Заменить на: PHP: $q .= ($q ? "&" : "") . "n=".urlencode(trim(htmlspecialchars($_GET['n']))); Найти: PHP: // email $emaila = explode(' ', trim($_GET['em'])); Заменить на: PHP: // email $emaila = explode(' ', trim(htmlspecialchars($_GET['em']))); Найти: PHP: $q .= ($q ? "&" : "") . "em=".urlencode(trim($_GET['em'])); Заменить на: PHP: $q .= ($q ? "&" : "") . "em=".urlencode(trim(htmlspecialchars($_GET['em']))); Найти: PHP: //class // NB: the c parameter is passed as two units above the real one $class = $_GET['c'] - 2; Заменить на: PHP: //class // NB: the c parameter is passed as two units above the real one $class = (int) $_GET['c'] - 2; Найти: PHP: // IP $ip = trim($_GET['ip']); Заменить на: PHP: // IP $ip = trim(htmlspecialchars($_GET['ip'])); Найти: PHP: // ratio $ratio = trim($_GET['r']); Заменить на: PHP: // ratio $ratio = trim(htmlspecialchars($_GET['r'])); Найти: PHP: $where_is .= isset($where_is)?" AND ":""; $where_is .= " (u.uploaded/u.downloaded)"; $ratiotype = $_GET['rt']; Заменить на: PHP: $where_is .= isset($where_is)?" AND ":""; $where_is .= " (u.uploaded/u.downloaded)"; $ratiotype = (int) $_GET['rt']; Найти: PHP: $ratio2 = trim($_GET['r2']); if(!$ratio2) Заменить на: PHP: $ratio2 = trim(htmlspecialchars($_GET['r2'])); if(!$ratio2) Найти: PHP: // comment $comments = explode(' ',trim($_GET['co'])); Заменить на: PHP: // comment $comments = explode(' ',trim(htmlspecialchars($_GET['co']))); Найти: PHP: // uploaded $ul = trim($_GET['ul']); Заменить на: PHP: // uploaded $ul = trim((int)$_GET['ul']); Найти: PHP: $where_is .= isset($where_is)?" AND ":""; $where_is .= " u.uploaded "; $ultype = $_GET['ult']; Заменить на: PHP: $where_is .= isset($where_is)?" AND ":""; $where_is .= " u.uploaded "; $ultype = (int)$_GET['ult']; Найти: PHP: $ul2 = trim($_GET['ul2']); if(!$ul2) Заменить на: PHP: $ul2 = trim((int)$_GET['ul2']); if(!$ul2) Найти: PHP: // downloaded $dl = trim($_GET['dl']); Заменить на: PHP: // downloaded $dl = trim((int)$_GET['dl']); Найти: PHP: $dltype = $_GET['dlt']; $q .= ($q ? "&" : "") . "dlt=$dltype"; if ($dltype == "3") { $dl2 = trim($_GET['dl2']); if(!$dl2) Заменить на: PHP: $dltype = (int)$_GET['dlt']; $q .= ($q ? "&" : "") . "dlt=$dltype"; if ($dltype == "3") { $dl2 = trim((int)$_GET['dl2']); if(!$dl2) Найти: PHP: $datetype = $_GET['dt']; $q .= ($q ? "&" : "") . "dt=$datetype"; if ($datetype == "0") Заменить на: PHP: $datetype = (int)$_GET['dt']; $q .= ($q ? "&" : "") . "dt=$datetype"; if ($datetype == "0") Найти: PHP: $q .= ($q ? "&" : "") . "ls=$last"; $lasttype = $_GET['lst']; Заменить на: PHP: $q .= ($q ? "&" : "") . "ls=$last"; $lasttype = (int)$_GET['lst']; Найти: PHP: // status $status = $_GET['st']; Заменить на: PHP: // status $status = (int)$_GET['st']; Найти: PHP: // account status $accountstatus = $_GET['as']; Заменить на: PHP: // account status $accountstatus = (int)$_GET['as']; Найти: PHP: //donor $donor = $_GET['do']; Заменить на: PHP: //donor $donor = (int)$_GET['do']; Найти: PHP: //warned $warned = $_GET['w']; Заменить на: PHP: //warned $warned = (int)$_GET['w']; Найти: PHP: // disabled IP $disabled = $_GET['dip']; Заменить на: PHP: // disabled IP $disabled = htmlspecialchars($_GET['dip']); Найти: PHP: // active $active = $_GET['ac']; Заменить на: PHP: // active $active = (int)$_GET['ac']; PS: Выдрано из сборки Kinokpk. И ещё баг в usersearch.php, данные о количестве постов в комментариях съезжают влево, не вставая в ячейки таблицы! Найти: PHP: "|".($n_comments?"<a href=userhistory.php?action=viewcomments&id=".$user['id'].">$n_comments</a>":$n_comments). Заменить на: PHP: "<td><div align=center>".($n_comments?"<a href=userhistory.php?action=viewcomments&id=".$user['id'].">$n_comments</a>":$n_comments).
тут ты ошибаешься: Вот это: PHP: //class // NB: the c parameter is passed as two units above the real one $class = $_GET['c'] - 2; не надо менять на вот это: PHP: //class // NB: the c parameter is passed as two units above the real one $class = (int) $_GET['c'] - 2; Т.к. математические операции предотвращают XSS. Т.е. $a = 0 + $_GET['a'] - всегда будет числом. З.Ы. Ну это то что бросается в глаза. Уверен в твоих фиксах есть ещё избыточные и не совсем логичные. К примеру ты много где делаешь trim от числа, как тут: PHP: $dl2 = trim((int)$_GET['dl2']); Зачем? Тут либо ты ошибся, и разработчик ожидает в этом поле не число, то ли у разработчика руки кривые, но тогда trim можно вообще не переносить в фикс, т.к. (int) переведёт строку в число, даже если перед цифрами стоят пробелы. З.Ы.Ы. Вот если бы ты к каждому твоему фиксу показал пример использования XSS, то было бы понятно, что к чему
А не проще-ли usersearch.php выкинуть наф? + привязать юзерские сессии к ипам т.е ип и некая хрень известная только нам и будет солью для КУКИСОВ т.е фактически мы нифелируем почти весь эффект + ну да и заблочить внешние post что-б через xss не сделали iframe что шлет post на takeprofedit.php с изменением мыла (пароль нельзя сменить не зная старого)
Yuna, ты же разработчик ты и решай Я бы на твоём месте usersearch.php пофиксил, тем более, там не так уж и много фиксить. А привязать сессии к IP - мысль имхо здравая.
Qwazar Подскажите пожалуйста если не трудно как лучше сделать ... Мне кажется юна ищет лёгкий путь чтобы отделаться от usersearch.php
что то тема чуть тухнет без багов продолжим version : 2008 © TBDev RU v [3.0] [/color=green]XSS[/color] browse.php?search=&cat=%3E%3Cscript%3Ealert(/Hi/)%3C/script%3E news.php?action=edit&newsid=13&returnto=%3E%3Cscript%3Ealert(/Hi/)%3C/script%3E
думаю так счастье прийдет и на твой трекер как и пришло на мой вставь где-нибудь в "начале". foreach($_GET as $k=>$v) { $_GET[$k]=htmlspecialchars($v); } зы: конечно не идеальный вариант, но не "геморный", и достаточный для пользования на треке...
Ага, и все параметры-массиву прийдут жопой, ты попробуй попробуй например чек-боксы где-то проставить, скажем админка-блоки Лучше киньте ссылкой на решение array_walk_recursive только что-б еще массивы обрабатывало, а-то циклами гонять не хочу чго-то!
Ага, если быть уникалом и писать в текстбоксы спец символы, то немудрено что будет, я и писал что вариант не лучший, но быстрый. из usersearch: <input name="ac" value="1" type="checkbox"> попробуй сам если не понятен смысл своих строк, или не своих а спертых откудато! при установке передается цифра, или ее отсутствие в месте с параметром. зы: кто говорит об админка-блоках ? если нечего по теме сказать, то лучше помолчи или иди флуди на своем форуме.
Твой метод не катит (В общем случае). Данные на входе портить нельзя, нужно следить за тем что и куда ты выводишь.
где ты данные видел учетки или ящика или еще чего-то со спец символами? они все в основном идут в латинице и цифры, поэтому метод катит на 95%
Угу, в данном конкретно файле, этот вариант сработает, но неизвестно что там будет в будущем, т.е. как вариант добавят поле в котором забудут поставить "" и т.п. А предложенный тобой вариант создаст иллюзию безопасности. З.Ы. В качестве хотфикса конечно покатит, но разработчику я бы посоветовал разобраться с каждым передаваемым параметром основательно.
Во 1х: каждый символ " заменится на мнемонику хтмл "e;, поэтому дублировать его нет нужды, при выводе XSS не будет. Во 2х: я говорил и повторюсь работать не будет только с подобным спец. символами, т.к. при запросах к бд, в бд будет " а слаться на выборку будет "e; естественно совпадений не будет, на это я и оставил 5% не удобности данного метода. ЗЫ: уже 1.5 года в эксплуатации данный метод, хоть бы кто-то пожаловался что их не устраивает. ЗЫЫ: юна учи хтмл и пхп, чтоб не делать таких ошибок в скриптах, а лучше пиши свои и не юзай чужие.
Пример кода, на котором такой метод не сработает: PHP: <?php foreach($_GET as $k=>$v) { $_GET[$k]=htmlspecialchars($v); } echo "<table name=".$_GET['a']."><tr><td>test</td></tr></table>"; ?> Пример использования: Code: http://localhost/1.php.zzz?a=1%20onMouseOver=alert(/aaa/)