Перейти к контенту
  • 0

Неправильный бан


VAMPiRE69

Вопрос

В общем существует проблема с баном по IP. Существует она давно.

Проблема:

Если забанить адрес (например) 192.168.0.1, то автоматом будут забанены все адреса, где в последнем октете первой идет "1". Т.е.: 192.168.0.1, 192.168.0.11, 192.168.0.12, ..., 192.168.0.101, 192.168.0.102 и т.д.

Думается мне, что некорректно сделано сравнение (не жестко, а на вхождение). Вот нашел я тут место, где вроде бы имеет смысл поправить текст (хотя, к сожалению, это место не единственное):

if ($ibforums->vars['ban_ip'])
{
 $ips = explode( "|", $ibforums->vars['ban_ip'] );
 foreach ($ips as $ip)
 {
  $ip = preg_replace( "/\*/", '.*' , $ip );
  if (preg_match( "/$ip/", $ibforums->input['IP_ADDRESS'] ))
  {
   $std->Error( array( LEVEL => 1, MSG => 'you_are_banned' ) );
  }
 }
}

или корень проблемы кроется не в этом куске кода?

 

PS: Поиском пользовался, запросы типа "бан по ip" к результатам не привели...

PPS: Версия форума - "Invision Power Board(U) v1.2".

Ссылка на комментарий
Поделиться на других сайтах

Рекомендуемые сообщения

  • 0

сам себе ведь и ответил :D ну сделай жесткое сравнение ;)

if ($ibforums->vars['ban_ip'])
{
 $ips = explode( "|", $ibforums->vars['ban_ip'] );
 foreach ($ips as $ip)
 {
  $ip = preg_replace( "/\*/", '.*' , $ip );
  if (preg_match( "/^$ip\$/", $ibforums->input['IP_ADDRESS'] ))
  {
   $std->Error( array( LEVEL => 1, MSG => 'you_are_banned' ) );
  }
 }
}

Ссылка на комментарий
Поделиться на других сайтах

  • 0
кстати во всем этом механизме есть ещё один глюк: можно забанить звёздочкой только в последнем октете.
Ссылка на комментарий
Поделиться на других сайтах

  • 0

ну а ты попробуй

 

x.y.*.*

 

вместо x,y укажи свои первых два реальных октета. И заходи смело в форум :D

Ссылка на комментарий
Поделиться на других сайтах

  • 0
сам себе ведь и ответил :D ну сделай жесткое сравнение ;)

if ($ibforums->vars['ban_ip'])
{
 $ips = explode( "|", $ibforums->vars['ban_ip'] );
 foreach ($ips as $ip)
 {
  $ip = preg_replace( "/\*/", '.*' , $ip );
  if (preg_match( "/^$ip\$/", $ibforums->input['IP_ADDRESS'] ))
  {
   $std->Error( array( LEVEL => 1, MSG => 'you_are_banned' ) );
  }
 }
}

 

1. Это только одно из мест, которых явно больше. Найти все знаний не хватает.

2. Может кто предложит хороший вариант кода исправления хотя бы в этом месте?

Ссылка на комментарий
Поделиться на других сайтах

  • 0

Мне советовали: Добавь это. Только не забудь исправить путь к файлу.

В файл запишется пример регулярного выражения и ip, которые сравниваются ф-ей preg_match. Нужно понять неправильно ли они регулярное выражение составляют или виновата ф-я.

 

Код можно продержать в форуме буквально минуту, чтобы хотя бы 1 человек зашёл на него.

if ($ibforums->vars['ban_ip'])

{
$ips = explode( "|", $ibforums->vars['ban_ip'] );
foreach ($ips as $ip)
{
 $ip = preg_replace( "/\*/", '.*' , $ip );

$handle = fopen("/path/file.txt", "a");
fwrite($handle, "$ip - $ibforums->input['IP_ADDRESS']\n");
fclose($handle);

  if (preg_match( "/$ip/", $ibforums->input['IP_ADDRESS'] ))
 {
  $std->Error( array( LEVEL => 1, MSG => 'you_are_banned' ) );
 }
}
}

$ips - массив строк всех забаненых ip.

as $ip - строка с конкретным ip

preg_match - просто ищет вхождение

далее были варианты:

if ($ibforums->vars['ban_ip'])
{
$ips = explode( "|", $ibforums->vars['ban_ip'] );
foreach ($ips as $ip)
{
 $ip = preg_replace( "/\*/", '.*' , $ip );
 if (!strcmp(trim($ip), trim($ibforums->input['IP_ADDRESS'])))   //Здесь изменено
 {
  $std->Error( array( LEVEL => 1, MSG => 'you_are_banned' ) );
 }
}
}

preg_match работает следующим образом

1-й параметр (забаненый IP):

10.151.10.1

2-й параметр (мой ip)

10.151.10.125

preg_match ищет вхождения первого во втором, т.е я попадаю под раздачу в любом случае

 

10.151.10.125

10.151.10.15

10.151.10.1

 

По этому почему бы не сравнивать жестко? (==, strcmp)

Только я не уверен, что

foreach ($ips as $ip)
{
$ip = preg_replace( "/\*/", '.*' , $ip );

Выдает четкий IP адрес без всякого мусора.

 

или желательно что бы быстрее решить проблему сделать следующим образом:

if ($ibforums->vars['ban_ip'])
{
$ips = explode( "|", $ibforums->vars['ban_ip'] );
foreach ($ips as $ip)
{
 echo "<!--".$ip."-->\t";
 $ip = preg_replace( "/\*/", '.*' , $ip );
 if (preg_match( "/$ip/", $ibforums->input['IP_ADDRESS'] ))
 {
 echo "<!--".$ip."-->\n";
  $std->Error( array( LEVEL => 1, MSG => 'you_are_banned' ) );
 }
}
}

Ссылка на комментарий
Поделиться на других сайтах

  • 0

Тут вообщем-то всего-то надо знатока регулярных выражений.

Т.к. я к ним себя не отношу я сделал дёшево и сердито:

  $ips      = explode( "\n", $ips );

 foreach ($ips as $ip)
 {
	 if ( !$ip ) continue;
	 $new_ip    = array();
	 $ip   	 = explode(".", $ip);
	 foreach($ip as $ip_part)
	 {
   if ( $ip_part != "*" )
   {
  	 $new_ip[]	= $ip_part;
   }
	 }

	 $ip   	 = implode(".", $new_ip);
	 unset($new_ip);
   
// 	 $ip = preg_replace( "/\*/", '.*' , preg_quote($ip, "/") );
	 if ( preg_match( "/^$ip\$/", $IN['IP_ADDRESS']) )  
	 {
.....

	 }
 }
}

Ссылка на комментарий
Поделиться на других сайтах

  • 0
ну а ты попробуй

 

x.y.*.*

 

вместо x,y укажи свои первых два реальных октета. И заходи смело в форум :D

ради интереса сделал отладку своего кода и вроде все правильно, даже только в среднем октете звездочкой забанить можно ;)

Но для надежности непомешает еще чуток подправить

if ($ibforums->vars['ban_ip'])
{
 $ips = explode( "|", $ibforums->vars['ban_ip'] );
 foreach ($ips as $ip)
 {
  $ip = str_replace(array(".", "*"), array("\\.", ".*"), $ip);
  if (preg_match( "/^$ip\$/", $ibforums->input['IP_ADDRESS'] ))
  {
   $std->Error( array( LEVEL => 1, MSG => 'you_are_banned' ) );
  }
 }
}

т.к. в регулярном выражении точка считается любым символом

Ссылка на комментарий
Поделиться на других сайтах

  • 0
ради интереса сделал отладку своего кода и вроде все правильно

я не про твой а про стандартный.

Ссылка на комментарий
Поделиться на других сайтах

  • 0

у меня не работает короче :D

у меня такой код стандартный:

 	 $ip = preg_replace( "/\*/", '.*' , preg_quote($ip, "/") );

Ссылка на комментарий
Поделиться на других сайтах

Присоединиться к обсуждению

Вы можете ответить сейчас, а зарегистрироваться позже. Если у вас уже есть аккаунт, войдите, чтобы ответить от своего имени.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить на вопрос...

×   Вы вставили отформатированный текст.   Удалить форматирование

  Допустимо не более 75 смайлов.

×   Ваша ссылка была автоматически заменена на медиа-контент.   Отображать как ссылку

×   Ваши публикации восстановлены.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Зарузка...
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, вы соглашаетесь на использование файлов cookie, а также с нашим положением о конфиденциальности Политика конфиденциальности и пользовательским соглашением Условия использования.