Защита при странициране от SQL Injection

Theif

Registered
Имам примерен код за странициране:
И ако може да му се сложат защити от SQL Injection защото така като гледам при примерена инжекция:
obqvi.php?str=-1 и по натам не я зная как се прави може да се направят бели...
Давам +1 който ми помогне най-ефективно.

Код:
<?
function secure($var) { 
return addslashes(htmlspecialchars($var)); 
} 
$str = secure($_GET['str']);
$pp = "13";
$table = "obqvi";
$total = mysql_result(mysql_query("SELECT COUNT(id) FROM $table"),0);
if (!isset($str)) {
$page = 1;
}
else {
$page = $str;
}
$limitvalue = $page * $pp - ($pp);

$redove = mysql_query("SELECT * FROM obqvi");
$max = mysql_numrows($redove);
$total = ceil($max/$pp);
$query = "SELECT * FROM obqvi order by id desc LIMIT $limitvalue, $pp"; 
$result = mysql_query($query); 
while ($r = mysql_fetch_array($result))
echo "
obqvi.php?id=".$r[id]."
</tr>
";
echo '<br>
<table border="0" cellpadding="0" cellspacing="0" width="100&" align="center">
<tbody align="center"><tr>
<td class="pagination" nowrap="nowrap" valign="top" width="490">
';
if ($page > 1) {
   $prev = ($page - 1);
   echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$prev.'"><font face="Trebuchet MS">пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ</font></a> ';
}


if (!$page or ($page > $total)) {
   $page="1";
}

if ($total < 10) {
   for($i=1 ; $i<=$total ; $i++) {
      if ( ($page)==$i ) {
         echo '<b>'.$i.'</b> ';
      }
      else {
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
}
else {
   for($i=1 ; $i<=3 ; $i++) {
      if ( ($page)==$i ) {
         echo '<b>'.$i.'</b> ';
      }
      else {
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
   
   if ($page <= 3) {
      if ($page == 3) echo '<a href="http://web-tourist.net/forum/obqvi.php?str=4">4</a> ';
      echo "... ";
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
   }
    if ($page == 5) $parva.= '<a href="http://web-tourist.net/forum/?id='.$_GET['id'].'&page=4\" class="button">4</a> ';
   
   if ( ($page == 4) or ($page == 5) ) {
      for ($i=$page; $i<=$page+1; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
      echo '... ';
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
   }
   
   if ( ($page > 5) and ($page < ($total - 4)) ) {
      echo '... ';
      for ($i=$page-1; $i<=$page+1; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
      echo '... ';
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/?str='.$i.'">'.$i.'</a> ';
   }
   
   if ( $page > ($total - 5) ) {
      echo '... ';
      for ($i=$total-5; $i<=$total; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
}

if ($page < $total) {
   $next = ($page + 1);
   echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$next.'"><font face="Trebuchet MS">пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ </font></a> ';
}

echo '</td>
</tr>
</tbody></table>';
?>
 
Нали str ти е винаги число... Защо просто не провериш дали във него има само цифри
Код:
 <?
function integer($variable) {
	if ((int)$variable){
    return true;
    }else{
    return false;
    }
}
$str = $_GET['str'];
	if (!integer($str)){
    echo 'Грешка!';!';
    exit();
    }
$pp = "13";
$table = "obqvi";
$total = mysql_result(mysql_query("SELECT COUNT(id) FROM $table"),0);
if (!isset($str)) {
$page = 1;
}
else {
$page = $str;
}
$limitvalue = $page * $pp - ($pp);

$redove = mysql_query("SELECT * FROM obqvi");
$max = mysql_numrows($redove);
$total = ceil($max/$pp);
$query = "SELECT * FROM obqvi order by id desc LIMIT $limitvalue, $pp";
$result = mysql_query($query);
while ($r = mysql_fetch_array($result))
echo "
obqvi.php?id=".$r[id]."
</tr>
";
echo '<br>
<table border="0" cellpadding="0" cellspacing="0" width="100&" align="center">
<tbody align="center"><tr>
<td class="pagination" nowrap="nowrap" valign="top" width="490">
';
if ($page > 1) {
   $prev = ($page - 1);
   echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$prev.'"><font face="Trebuchet MS">????????????????????????</font></a> ';
}


if (!$page or ($page > $total)) {
   $page="1";
}

if ($total < 10) {
   for($i=1 ; $i<=$total ; $i++) {
      if ( ($page)==$i ) {
         echo '<b>'.$i.'</b> ';
      }
      else {
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
}
else {
   for($i=1 ; $i<=3 ; $i++) {
      if ( ($page)==$i ) {
         echo '<b>'.$i.'</b> ';
      }
      else {
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }

   if ($page <= 3) {
      if ($page == 3) echo '<a href="http://web-tourist.net/forum/obqvi.php?str=4">4</a> ';
      echo "... ";
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
   }
    if ($page == 5) $parva.= '<a href="http://web-tourist.net/forum/?id='.$_GET['id'].'&page=4\" class="button">4</a> ';

   if ( ($page == 4) or ($page == 5) ) {
      for ($i=$page; $i<=$page+1; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
      echo '... ';
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
   }

   if ( ($page > 5) and ($page < ($total - 4)) ) {
      echo '... ';
      for ($i=$page-1; $i<=$page+1; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
      echo '... ';
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/?str='.$i.'">'.$i.'</a> ';
   }

   if ( $page > ($total - 5) ) {
      echo '... ';
      for ($i=$total-5; $i<=$total; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
}

if ($page < $total) {
   $next = ($page + 1);
   echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$next.'"><font face="Trebuchet MS">???????????????????????? </font></a> ';
}

echo '</td>
</tr>
</tbody></table>';
?>
 
trevata каза:
Нали str ти е винаги число... Защо просто не провериш дали във него има само цифри
int не проверява, дали низа се състои само от цифри, а дали низа започва с цифра/число и ако започва, взема само цифрата/числото и се освобождава от всички други символи нататък. Пример:
Код:
print (int)1sdw.r";   //Връща 1
print (int)2.3efw;     //Връща 2
print (int)324,3fe;    //Връща 324
print (int)-32.43fe;   //Връща -32
print (int)"23;              //Връща грешка
print (int)as23.4;         //Връща грешка
print (int)34fdsfe,3"'   //Връща 34
И понеже ако се зададе отрицателно число на страницата, int няма да върне грешка, а ще изпълни кода. Отрицателните числа в случая са проблем, също както и нулата, следователно, кода ти не е на 100% ефективен срещу inject-а. Нямаш нужда от такива функции, if и else ще свършат чудесна работа без функцията.
Код:
<?
$str = (int)$_GET['str'];
if($str > 0){
$pp = "13";
$table = "obqvi";
$total = mysql_result(mysql_query("SELECT COUNT(id) FROM $table"),0);
if (!isset($str)) {
$page = 1;
}
else {
$page = $str;
}
$limitvalue = $page * $pp - ($pp);

$redove = mysql_query("SELECT * FROM obqvi");
$max = mysql_numrows($redove);
$total = ceil($max/$pp);
$query = "SELECT * FROM obqvi order by id desc LIMIT $limitvalue, $pp";
$result = mysql_query($query);
while ($r = mysql_fetch_array($result))
echo "
obqvi.php?id=".$r[id]."
</tr>
";
echo '<br>
<table border="0" cellpadding="0" cellspacing="0" width="100&" align="center">
<tbody align="center"><tr>
<td class="pagination" nowrap="nowrap" valign="top" width="490">
';
if ($page > 1) {
   $prev = ($page - 1);
   echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$prev.'"><font face="Trebuchet MS">пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ</font></a> ';
}


if (!$page or ($page > $total)) {
   $page="1";
}

if ($total < 10) {
   for($i=1 ; $i<=$total ; $i++) {
      if ( ($page)==$i ) {
         echo '<b>'.$i.'</b> ';
      }
      else {
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
}
else {
   for($i=1 ; $i<=3 ; $i++) {
      if ( ($page)==$i ) {
         echo '<b>'.$i.'</b> ';
      }
      else {
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
   
   if ($page <= 3) {
      if ($page == 3) echo '<a href="http://web-tourist.net/forum/obqvi.php?str=4">4</a> ';
      echo "... ";
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
   }
    if ($page == 5) $parva.= '<a href="http://web-tourist.net/forum/?id='.$_GET['id'].'&page=4" class="button">4</a> ';
   
   if ( ($page == 4) or ($page == 5) ) {
      for ($i=$page; $i<=$page+1; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
      echo '... ';
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
   }
   
   if ( ($page > 5) and ($page < ($total - 4)) ) {
      echo '... ';
      for ($i=$page-1; $i<=$page+1; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
      echo '... ';
      for ($i=$total-2; $i<=$total; $i++)
         echo '<a href="http://web-tourist.net/forum/?str='.$i.'">'.$i.'</a> ';
   }
   
   if ( $page > ($total - 5) ) {
      echo '... ';
      for ($i=$total-5; $i<=$total; $i++) {
         if ($page == $i) echo '<b>'.$i.'</b> ';
         else echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$i.'">'.$i.'</a> ';
      }
   }
}

if ($page < $total) {
   $next = ($page + 1);
   echo '<a href="http://web-tourist.net/forum/obqvi.php?str='.$next.'"><font face="Trebuchet MS">пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ </font></a> ';
}

echo '</td>
</tr>
</tbody></table>';
}
else{
   echo "INJECT!!!";
}
?>
 
И за како да минава през intval или is_numeric, като int и допускането само на положителни числа са му напълно достатъчни? Дайте някакъв пример с какво ще ми атакувате кода и атаката ще мине?
 
Позволи ми да цитирам:
30th April, 15:36 jooorooo
не ми харесва
if ( (int)$tekst )
return $tekst;
ако задам 2jooorooo то ще го възприеме като int и ще игнорира jooorooo и остава само 2-ката, така стринга става на int и се губи информация.
 
А иначе в темата чел ли си за какво става дума? Точно това е целта, ако имаме 2fww3 да вземе само двойката и да изпълни заявката с нея. Каква информация ще се загуби при положение, че останалата информация ако не се загуби ще навреди на заявката? Защо трябва да изкарва сумати грешки ако някой се мъчи да инжектира нещо, като може да изпълни кода без да има инжекция, като хване само цифрата/числото.
Тоя код, който съм му дал е за конкретния случай със странирането, а не като цяло за метода $_GET['...'].
Страницата трябва да бъде положително, цяло число, ти някъде виждал ли си страница 12ad или 12.23, която да се ползва за select на данни с limit? Защо трябва да връща грешки от intval и is_numeric, а не да изпълни заявката само с 12? Ако страицата започва с нещо друго освен цифра(каквото и да е), int връща грешка, ако е по-малка от нула, моя код също връща грешка.
Edit: Дори и тук в web-tourist е направено така странирането.
 
Ето ти примерен код за защита:
Код:
<?php
$get = $_GET['get'];
if(!is_numeric("$get")){
die("Опит за SQL Инжекция");
}
?>
 

Back
Горе