SQL Injection in phpBB's groupcp.php
BugTraq,
I have found an SQL injection vulnerability in phpBB. Hoever, I don't think
this is going to be be a wide spread problem as it will only work if you are
the moderator of a group.
How the SQL injection works:
In groupscp, it uses an array set to delete members from certain groups. This
array set is sent through a quick loop to put all the values into a variable
seperated by , s and then used in an IN check in the SQL query to delete the
members that you've selected.
Code:
$members = ( isset($HTTP_POST_VARS['approve']) ||
isset($HTTP_POST_VARS['deny']) ) ? $HTTP_POST_VARS['pending_members'] :
$HTTP_POST_VARS['members'];
$sql_in = '';
for($i = 0; $i < count($members); $i++)
{
$sql_in .= ( ( $sql_in != '' ) ? ', ' : '' ) . $members[$i];
}
After this the $sql_in variable is not checked or changed at all, and this is
where I found the SQL injection to be possible... There are two places this is
used, first is through a check on if you're the moderator of a group, if you
are it will run an if IN check on the array first:
$sql = "SELECT ug.user_id, ug.group_id
FROM " . AUTH_ACCESS_TABLE . " aa, " . USER_GROUP_TABLE . " ug
WHERE ug.user_id IN ($sql_in)
AND aa.group_id = ug.group_id
AND aa.auth_mod = 1
GROUP BY ug.user_id, ug.group_id
ORDER BY ug.user_id, ug.group_id";
>From this, it will pull a list of the users in the group and if they're
>moderators from being in the group... If they are, it will remove their
>securities.
Now the second one becomes more critical, this is after the check on if
moderator:
$sql = "DELETE FROM " . USER_GROUP_TABLE . "
WHERE user_id IN ($sql_in)
AND group_id = $group_id";
Since this again uses an IN check on the unchecked $sql_in, you can easily
replace it with something such as $sql_in = 1) or 1=1/*
That would cause, every person in a group to be automatically deleted from it.
To fix this vulnerability, it's fairly simple. Open your groupcp.php file.
Find
$sql_in .= ( ( $sql_in != '' ) ? ', ' : '' ) . $members[$i];
and replace it with
$sql_in .= ( ( $sql_in != '' ) ? ', ' : '' ) . intval($members[$i]);
I'm providing no proof of concept code because you can easily check if you're
vulnerable by searching for the first line in your groupcp.php file.
Thanks,
Zarath