PDA

View Full Version : Datamanger PM Recipient with HTMLl chars


Th3Dan
12-09-2013, 01:10 PM
Hello,

i made a plugin to notify users automated via PN


$pmdm = datamanager_init('PM', $vbulletin, ERRTYPE_ARRAY);
$pmdm->set('fromuserid', $vbulletin->userinfo['userid']);
$pmdm->set('fromusername', $vbulletin->userinfo['username']);
$pmdm->set('title', 'Test']);
$pmdm->set('message', $message);
$pmdm->set_recipients($tousername, null);
$pmdm->set('dateline', TIMENOW);
$pmdm->set_info('savecopy', 1);
$pmdm->set_info('receipt', 0);
$pmdm->pre_save();


$tousername is the name of the target user for the pn. I've an user with a '<' char in his username. This failed and i get an error in the $pmdm->errors array that the user can't be found. The '<' was masked as html so '&lt'. I took a look at the source and found the function in includes/class_dm_pm.php:


function set_recipients($recipientlist, &$permissions, $type = 'bcc')
{
global $vbphrase;
$names = array(); // names in the recipient list
$users = array(); // users from the recipient list found in the user table
$notfound = array(); // names from the recipient list NOT found in the user table
$recipients = array(); // users to whom the message WILL be sent
$errors = array();

$recipientlist = trim($recipientlist);

$this->info['permissions'] =& $permissions;

if (!empty($this->info['is_automated']))
{
$this->overridequota = true;
}

// pmboxfull needs $fromusername defined
if (($fromusername = $this->fetch_field('fromusername')) === null)
{
trigger_error('Set fromusername before calling set_recipients()', E_USER_ERROR);
}

if (($fromuserid = $this->fetch_field('fromuserid')) === null)
{
trigger_error('Set fromuserid before calling set_recipients()', E_USER_ERROR);
}
$fromuser = fetch_userinfo($fromuserid);

// check for valid recipient string
if ($recipientlist == '')
{
return false;
}

// split multiple recipients into an array
if (preg_match('/(?<!&#[0-9]{3}|&#[0-9]{4}|&#[0-9]{5});/', $recipientlist)) // multiple recipients attempted
{
$recipientlist = preg_split('/(?<!&#[0-9]{3}|&#[0-9]{4}|&#[0-9]{5});/', $recipientlist, -1, PREG_SPLIT_NO_EMPTY);
foreach ($recipientlist AS $recipient)
{
$recipient = trim($recipient);
if ($recipient != '')
{
$names[] = htmlspecialchars_uni($recipient);
}
}
}


I found the info that htmlspecialchars_uni() is used to display data in clean form and to prevent xss. So I think this function is masking the '<' because it's the beginning of any HTML tag and as &lt it will be displayed and not interpreted as HTML. But what can i do to avoid this? Is there another way so that pns to users with a '<' in the username can be send? I think there must be a way to avoid this. PNs in vBulletin are possible to users with a '<' in the name and I think vBulletin also uses this class.

Th3Dan
12-12-2013, 10:18 PM
Push

mokujin
12-13-2013, 01:00 PM
$this->db->escape_string($recipient);

Th3Dan
12-16-2013, 10:02 PM
No, i don't want to modify the vB source, that's the problem. The first code is my, the second one is from vBulletin (includes/class_dm_pm.php). I want to fix this without modify the core.

kh99
12-16-2013, 10:46 PM
I don't understand why that's happening, but you might try using unhtmlspecialchars($tousername).