News:

Bored?  Looking to kill some time?  Want to chat with other SMF users?  Join us in IRC chat or Discord

Main Menu

2.0.12 / 2.0.13 Spiders not shown in Online User List

Started by s3cc0, January 14, 2017, 12:11:30 PM

Previous topic - Next topic

s3cc0

Hello. Are the spiders being shown in the online user list of your forum?

On my forum they are no longer shown after upgrading to 2.0.12, and the problem persist now in 2.0.13.

Those are the settings:



Can anybody confirm this feature is still working in 2.0.12/2.0.13? I'm trying to figure if this is a problem on my side or a bug introduced with the last patches.



Hacker, Pirate, Milf Hunter, Owner of Bitcoin Garden Forum

lurkalot

Working in all my sites, and they have the same settings as in your screen shot. All running SMF 2.0.13

s3cc0

Ok. Then the problem is on my side. I did some research and probably discovered where the problem could be...

First I noticed an error appearing after the update:

Quotehttp://bitcoingarden.org/forum/index.php?action=whoApply Filter: Only show the errors with the same message2: Invalid argument supplied for foreach()Apply Filter: Only show the errors from this file File: /home/fb/domains/bitcoingarden.org/public_html/forum/Sources/Who.php
Line: 227

The line erroring is:

Quoteforeach (safe_unserialize($modSettings['spider_name_cache']) as $id => $name)

Now I had a look at the changelog between 2.0.11 and 2.0.12 and I noticed the serialize function has been completely rewritten. The new function is the safe_unserialize mentioned above.

I think something changed in the way the function manages the data; it looks like the new function crashes processing the spider_name_cache array, while the old serialize was handling it with no problems.

This makes sense as in the past I enriched the list of bots to include something like 400 bots. (see below)



I'm trying to figure which record is causing the problem. I tried to delete the ones containing weird chars like %, ! and stuff like that, but no luck. I'm a bit lost...

1) Maybe the array is just too long? I don't think it should...

2) Maybe there's a forbidden keyword in the bot list? Wasn't the function re-written to avoid sql injection hacks?

3) Maybe I copy-pasted a non standard char?

Hacker, Pirate, Milf Hunter, Owner of Bitcoin Garden Forum

Arantor


s3cc0

Quote from: Arantor on January 15, 2017, 03:23:11 AM
Add another one, then remove it.

Test done. Added a new one, removed it after 20 minutes. Nothing changed.
Hacker, Pirate, Milf Hunter, Owner of Bitcoin Garden Forum

Arantor

I would wonder if the 2.0.13 patch was applied correctly. 2.0.12 would definitely have aborted on your list of spiders since it caps serialised arrays to 256 items and you have 400 but that should be rectified in 2.0.13.

s3cc0

Quote from: Arantor on January 15, 2017, 06:08:28 AM
I would wonder if the 2.0.13 patch was applied correctly. 2.0.12 would definitely have aborted on your list of spiders since it caps serialised arrays to 256 items and you have 400 but that should be rectified in 2.0.13.

I think the 2.0.13 update was applied correctly. All tests were successful and the update completed regularly.
Hacker, Pirate, Milf Hunter, Owner of Bitcoin Garden Forum

Arantor

Take a look at Subs.php and specifically at the safe_unserialise function as to whether there's a test early on for the length of string over 4096 as a first check.

s3cc0

This is how the safe_unserialize function looks like. I'm not much skilled in PHP. I see a check for empty string at the very begin but I don't think there's a check for strings over 4096 bytes.

function _safe_unserialize($str)
{
// Input  is not a string.
if(empty($str) || !is_string($str))
return false;

$stack = array();
$expected = array();

/*
* states:
*   0 - initial state, expecting a single value or array
*   1 - terminal state
*   2 - in array, expecting end of array or a key
*   3 - in array, expecting value or another array
*/
$state = 0;
while($state != 1)
{
$type = isset($str[0]) ? $str[0] : '';
if($type == '}')
$str = substr($str, 1);

else if($type == 'N' && $str[1] == ';')
{
$value = null;
$str = substr($str, 2);
}
else if($type == 'b' && preg_match('/^b:([01]);/', $str, $matches))
{
$value = $matches[1] == '1' ? true : false;
$str = substr($str, 4);
}
else if($type == 'i' && preg_match('/^i:(-?[0-9]+);(.*)/s', $str, $matches))
{
$value = (int)$matches[1];
$str = $matches[2];
}
else if($type == 'd' && preg_match('/^d:(-?[0-9]+\.?[0-9]*(E[+-][0-9]+)?);(.*)/s', $str, $matches))
{
$value = (float)$matches[1];
$str = $matches[3];
}
else if($type == 's' && preg_match('/^s:([0-9]+):"(.*)/s', $str, $matches) && substr($matches[2], (int)$matches[1], 2) == '";')
{
$value = substr($matches[2], 0, (int)$matches[1]);
$str = substr($matches[2], (int)$matches[1] + 2);
}
else if($type == 'a' && preg_match('/^a:([0-9]+):{(.*)/s', $str, $matches) && $matches[1] < 256)
{
$expectedLength = (int)$matches[1];
$str = $matches[2];
}

// Object or unknown/malformed type.
else
return false;

switch($state)
{
case 3: // In array, expecting value or another array.
if($type == 'a')
{

$stack[] = &$list;
$list[$key] = array();
$list = &$list[$key];
$expected[] = $expectedLength;
$state = 2;
break;
}
if($type != '}')
{
$list[$key] = $value;
$state = 2;
break;
}

// Missing array value.
return false;

case 2: // in array, expecting end of array or a key
if($type == '}')
{
// Array size is less than expected.
if(count($list) < end($expected))
return false;

unset($list);
$list = &$stack[count($stack)-1];
array_pop($stack);

// Go to terminal state if we're at the end of the root array.
array_pop($expected);

if(count($expected) == 0)
$state = 1;

break;
}

if($type == 'i' || $type == 's')
{
// Array size exceeds expected length.
if(count($list) >= end($expected))
return false;

$key = $value;
$state = 3;
break;
}

// Illegal array index type.
return false;

// Expecting array or value.
case 0:
if($type == 'a')
{

$data = array();
$list = &$data;
$expected[] = $expectedLength;
$state = 2;
break;
}

if($type != '}')
{
$data = $value;
$state = 1;
break;
}

// Not in array.
return false;
}
}

// Trailing data in input.
if(!empty($str))
return false;

return $data;
}
Hacker, Pirate, Milf Hunter, Owner of Bitcoin Garden Forum

Arantor

Hmmm, that looks like it has been patched. I wonder how come it broke with (quite a bit) more data in it. I'd be sceptical about it being an invalid character though.

s3cc0

I finally sorted it out. I reduced the number of spiders at 250 and it is working fine now.

Tested again adding a few more spiders and the list disappeared again. List went back again once I removed them.

I'm not 100% if it is a matter of number of elements in the array (in my case limit is close to 256) or if it is a matter of total length of array in bytes. In any case, the problem was the list too long.

Thank you guys for helping me debug this.

Hacker, Pirate, Milf Hunter, Owner of Bitcoin Garden Forum

THE BRA1N

#11
Same issue here after updating to 2.0.12 and 13. I will try reducing the number of spiders to see if that works.

Edit - it worked!

Advertisement: