2015-10-18 4 views
-1

Этот код был взят из другого сообщения в Notice: Undefined offset: 0 in, где было указано, что существует уязвимость SQL-инъекции. Что относительно этого кода уязвим, как его можно использовать и как его можно сделать безопасным?Как насчет этого кода вводит уязвимость SQL-инъекции?

<?php 
include("config.php"); 

function getAllVotes($id) 
{ 
    $votes = array(); 
    $q = "SELECT * FROM entries WHERE id = $id"; 
    $r = mysql_query($q); 
    if(mysql_num_rows($r)==1)//id found in the table 
    { 
     $row = mysql_fetch_assoc($r); 
     $votes[0] = $row['votes_up']; 
     $votes[1] = $row['votes_down']; 
    } 
    return $votes; 
} 

function getEffectiveVotes($id) 
{ 
     $votes = getAllVotes($id); 
     $effectiveVote = $votes[0] - $votes[1]; //ERROR THROWN HERE 
     return $effectiveVote; 
} 

$id = $_POST['id']; 
$action = $_POST['action']; 

//get the current votes 
$cur_votes = getAllVotes($id); 

//ok, now update the votes 

if($action=='vote_up') //voting up 
{ 

    $votes_up = $cur_votes[0]+1;  //AND ERROR THROWN HERE 


    $q = "UPDATE threads SET votes_up = $votes_up WHERE id = $id"; 
} 
elseif($action=='vote_down') 
{ 
    $votes_down = $cur_votes[1]+1; 
    $q = "UPDATE threads SET votes_down = $votes_down WHERE id = $id"; 
} 

$r = mysql_query($q); 
if($r) 
{ 
    $effectiveVote = getEffectiveVotes($id); 
    echo $effectiveVote." votes"; 
} 
elseif(!$r) //voting failed 
{ 
    echo "Failed!"; 
} 
?> 
+0

это: 'WHERE ID = $ id'. Что делать, если я должен был передать «$ id = 17; DROP TABLE entries»? Вы можете узнать больше о sql injection [здесь] (http://bobby-tables.com/). Вы можете избежать этого, используя [подготовленные заявления.] (Https://dev.mysql.com/doc/refman/5.0/en/sql-syntax-prepared-statements.html). Существуют и другие методы, такие как кастинг $ id на целое число, если вы знаете, что оно всегда должно быть целым числом. –

+1

См. [Подвиги мамы] (http://imgs.xkcd.com/comics/exploits_of_a_mom.png) – user3791372

+0

Хорошо сделанный @devlincarnate. Я забыл название «подготовленные заявления» в своем ответе. Кроме того, для обеспечения альтернативного решения (литья). – andrewgu

ответ

0

код не использует mysqli или PDO безопасно выполнить оператор SQL. Оба mysqli и PDO отправляют оператор и определяемые пользователем переменные на сервер отдельно, где они интерпретируются и действуют. Вместо этого код позволяет людям добавлять в свой собственный код SQL (SQL-инъекцию) в оператор через переменную $_POST['id'].


Например, если бы я POST следующее как id, вы потеряете свой стол:

avalidid; DROP TABLE entries 
Смежные вопросы