Защита от sql injection и xss атаки

vinsbg

Registered
Опитвам се да разбера колко незащитен е този код за подобни атаки и как мога да го защитя допълнително?
Код:
if(isset($_GET['joke_id'])&& is_numeric($_GET['joke_id'])){
                $joke_id = $_GET['joke_id'];
                $qry = "SELECT * FROM joke WHERE joke_cat = '$joke_id'";

                $result = mysqli_query($con, $qry) or die("Query failed: " . mysqli_errno($con));

                $line = mysqli_fetch_array($result, MYSQL_BOTH);
                if (!$line) echo '';
                $previd = -1;
                $currid = $line[0];
                if (isset($_GET['id']) && is_numeric($_GET['id'])) {
                    do {
                        $currid = $line[0];
                        if ($currid == (int)$_GET['id']) break;
                        $previd = $currid;
                        $line = mysqli_fetch_array($result, MYSQL_BOTH);
                    } while ($line);
                }

                if ($line) {
                    echo nl2br($line['text']) . "<br /><br />";
                    echo '<br /><br /><br />';

                }
                else echo '<p>Категорията е празна</p><br/>';

                if ($previd > -1)
                    echo '<a href="cat_vic.php?joke_id='.$joke_id.'&id='.$previd.'" class="prev_pic"><span>Предишен</span></a>';
                echo str_repeat(' ', 5);
                $line = mysqli_fetch_array($result, MYSQL_BOTH);

                if  ($line) echo '<a href="cat_vic.php?joke_id='.$joke_id.'&id='.$line[0].'" class="next_pic"><span>Следващ</span></a><br /><br />';
                echo "</div>";
            }
Доколкото разбирам тук уязвимите точки са: id, currid, joke_id
Или се бъркам? Как да ги защитя по-добре?
 
Този ред за какво ти е? Даже и else част нямаш...
Код:
if (!$line) echo '';
И има още едно нещо, за което не съм сигурен как стоят нещата: използваш mysqli функция с константата MYSQL_BOTH (а не MYSQLI_BOTH). Проверих в php.net и в описанието на mysqli_fetch_array пише следното:

php.net каза:
mixed mysqli_fetch_array ( mysqli_result $result [, int $resulttype = MYSQLI_BOTH ] )
Никъде не пише, че не трябва да се използва по твоя начин, но дори и да е правилно, то по това е стойността по подразбиране, така че можеш съвсем спокойно да я изпуснеш.
 
anonimen каза:
Мерси, тези ги оправих.

Код:
if (!$line) echo '';
Го ползвах преди известно време и после съм забравил да го изтрия.
 
Така като гледам имаш само ID да вземаш, ако е така просто ти трябва при първото _GET да му дадеш ctype_digit
и надолу не ти трябват повече проверки :)
Код:
if(isset($_GET['id']) && ctype_digit($_GET['id'])){
$id=$_GET['id'];
}
//edna mysql proverka za sashtestvuvashto id
$query=mysql_query(.... where id='$id');
if(mysql_num_rows($q) >0){
}
else{
echo "nesashstestvuvasht zapis";
exit;
}
//ostatuka ot koda
...
 
Благодаря!
А кое е по-добре да се използва в случая: is_numeric или ctype_digit ?
 
Благодаря!
А кое е по-добре да се използва в случая: is_numeric или ctype_digit или is_num ?
 
Видях още нещо - какво става ако заявката не върне резултат?
Виж тази част:
PHP:
if ($line) {
                    echo nl2br($line['text']) . "<br /><br />";
                    echo '<br /><br /><br />';

                }
else echo '<p>Категорията е празна</p><br/>';
Може $line да не е false, но ако заявката е върнала нула реда, какво става? Не е ли по-добре да го направиш така:
PHP:
if ($line && mysqli_num_rows($line)> 0) {
                    echo nl2br($line['text']) . "<br /><br />";
                    echo '<br /><br /><br />';

                }
                else echo '<p>Категорията е празна</p><br/>';

vinsbg каза:
Благодаря!
А кое е по-добре да се използва в случая: is_numeric или ctype_digit или is_num ?
http://tiffanybbrown.com/2006/07/27/php-quickie-is_numeric-versus-ctype_digit/
И тъй като в БД-то имаш само естествени числа, е по-добре да се използва ctype_digit. (според мен)
 
djman каза:
а може без проверки и $id = (int) $_GET['id'];
аз винаги ползвам ctype_digit не пропуска нищо
иначе int не го използвам защото дори да не е чисто число може да доведе до излишни разминавания :)
Код:
$te="1di9";
$test=(int)$te;
echo $test; // показва 1
 

Back
Горе