- Readme First! - Read and follow the rules, otherwise your posts will be closed
There are currently, 41 guest(s) and 1 member(s) that are online. You are Anonymous user. You can register for free by clicking here
Nuke Cops :: View topic - phpBB 2.03 SQL Injection vulnerability in BBtoNuke ? [ ]
Author
Message
sixonetonoffun
Major
Joined: Jan 13, 2003
Posts: 892
Posted:
Sun Jan 19, 2003 4:12 pm
I haven't tested this at all and I know with some of the charectors the xss filter Pauls setup catch the exact exploit. But.... clever minds lol
phpBB SQL Injection vulnerability
PROGRAM: phpBB
VENDOR: phpBB Group
HOMEPAGE: http://www.phpbb.com/
VULNERABLE VERSIONS: 2.0.3, possibly others
IMMUNE VERSIONS: 2.0.4
LOGIN REQUIRED: yes
DESCRIPTION:
"phpBB is a UBB-style dissussion board written in PHP backended by a
MySQL database. It includes features such as posting/replying/editing
messages, private messages, private forums, user and anonymous
posting, robust theming, user ranking by posts or by special,
admin definable, ranks, and much more."
(direct quote from the program's project page at Freshmeat)
phpBB is published under the terms of the GNU General Public License.
It is a very popular program with lots of installations.
SUMMARY:
phpBB users can send private messages to each other. The program has
got a security hole, making it possible for a user to delete the text
of all private messages stored in the system.
TECHNICAL DETAILS:
The function for deleting private messages has got an SQL Injection
hole. If we submit data saying that we want to delete private
message number "1) OR 1=1 #", the text of all private messages for
all users on the system will be deleted.
The messages are stored in two tables, and the SQL Injection will
only work on one of them, so all the text bodies are deleted but the
subjects and metadata are only deleted if they belong to the current
user. This means that the subjects of the deleted messages will still
show up in the other users' folders. When a user clicks on a deleted
message, he or she will just be redirected back to the folder.
You can exploit this by POSTing the following values to
privmsg.php?folder=inbox&sid=[THE SID VALUE]:
mode=""
delete="true"
mark[]="1) OR 1=1 #"
confirm="Yes"
The current SID value is shown in the URL field, if you log in to
the system with cookies turned off.
COMMUNICATION WITH VENDOR:
The vendor was contacted on the 14th of January. Version 2.0.4 was
released on the 16th of January.
EXPLOIT:
I have attached a Perl exploit for this issue. It deletes the text
of all private messages. Before starting it, you have to log in
and get the SID value as described above.
// Ulf Harnhammar
VSU Security
sixonetonoffun
Major
Joined: Jan 13, 2003
Posts: 892
Posted:
Sun Jan 19, 2003 6:00 pm
I used this patch from migon on nukeforums
Putting line at the top of modules.php
$sid=$sid*1;
on all my sites believe it catches this as the script I modified bombs at
if (@ARGV != 2) { die "usage: $0 host sid\n"; }
I have not run against a none patched install therefore this does not answer the original question. Leave that one for someone else...
_________________www.netflake.com
www.glowoptics.com
Zhen-Xjell
Nuke Cops Founder
Joined: Nov 14, 2002
Posts: 5939
Posted:
Sun Jan 19, 2003 6:33 pm
Heh, I'll have to try it, thanks.
_________________ Paul Laudanski, Microsoft MVP Windows-Security
CastleCops: [de ] [en ] [wiki ]
Zhen-Xjell
Nuke Cops Founder
Joined: Nov 14, 2002
Posts: 5939
Posted:
Sun Jan 19, 2003 8:22 pm
How about this?
// session id check
if (!empty($HTTP_POST_VARS['sid']) || !empty($HTTP_GET_VARS['sid']))
{
$sid = (!empty($HTTP_POST_VARS['sid'])) ? $HTTP_POST_VARS['sid'] : $HTTP_GET_VARS['sid'];
}
else
{
$sid = '';
// session id check
if ($sid == '' || $sid != $userdata['session_id'])
{
message_die(GENERAL_ERROR, 'Invalid_session');
}
That's found a few times in the phpBB2 2.0.4 release. I'll try placing it appropriately into the mainfile.php here.
_________________ Paul Laudanski, Microsoft MVP Windows-Security
CastleCops: [de ] [en ] [wiki ]
sixonetonoffun
Major
Joined: Jan 13, 2003
Posts: 892
Posted:
Sun Jan 19, 2003 8:50 pm
My quick test for sessions was with IE6 (Cause its easy to change cookie settings)
Log onto site with uname
Change cookie settings on the IE toolbar>Tools>Internet Options>Privacy> Set the slider to high block all cookies.
Refresh the page if the session sid appears you are half way there to exploiting this.
The mainfile.php or modules.php
As migon pointed out the real fix would be to change all sql queries
Quote:
IMO Problem is in missing apostrophe in SQL queries
like here:
FROM ".$prefix."_stories where sid=$sid"
this make aplication unsave.
Basic way to prevent any SQLinjection in PHP aplications is add apostrophe to SQL
because than return SQL server error when put something like this %20or%20.
Filtering all GET/POST variables IMO slow down aplication
--
migon
Sorry for my english
http://www.nukeforums.com/forums/viewtopic.php?topic=10084&forum=41
I was really hoping to see the new sql layer fix this
~Peter
_________________www.netflake.com
www.glowoptics.com
sixonetonoffun
Major
Joined: Jan 13, 2003
Posts: 892
Posted:
Sun Jan 19, 2003 9:04 pm
Seems to be working look forward to hearing more of this phpbb patch.
I guess not yet still throws sid up now. When you disable cookies and login through the forum login.
_________________www.netflake.com
www.glowoptics.com
Zhen-Xjell
Nuke Cops Founder
Joined: Nov 14, 2002
Posts: 5939
Posted:
Mon Jan 20, 2003 10:38 am
For now I placed the $sid=$sid*1; in the file.
_________________ Paul Laudanski, Microsoft MVP Windows-Security
CastleCops: [de ] [en ] [wiki ]
Zhen-Xjell
Nuke Cops Founder
Joined: Nov 14, 2002
Posts: 5939
Posted:
Mon Jan 20, 2003 11:21 am
These are the changes to the privmsg.php file for 2.0.4:
Quote:
Index: privmsg.php
===================================================================
RCS file: /cvsroot/phpbb/phpBB2/Attic/privmsg.php,v
retrieving revision 1.96.2.9
diff -u -r1.96.2.9 privmsg.php
--- privmsg.php 19 Jul 2002 15:19:31 -0000 1.96.2.9
+++ privmsg.php 15 Jan 2003 14:01:10 -0000
@@ -6,7 +6,7 @@
* copyright : (C) 2001 The phpBB Group
* email : support@phpbb.com
*
- * $Id: privmsg.php,v 1.96.2.9 2002/07/19 15:19:31 psotfx Exp $
+ * $Id: privmsg.php,v 1.96.2.23 2003/01/15 00:38:13 psotfx Exp $
*
*
***************************************************************************/
@@ -69,6 +69,16 @@
$folder = 'inbox';
}
+// session id check
+if (!empty($HTTP_POST_VARS['sid']) || !empty($HTTP_GET_VARS['sid']))
+{
+ $sid = (!empty($HTTP_POST_VARS['sid'])) ? $HTTP_POST_VARS['sid'] : $HTTP_GET_VARS['sid'];
+}
+else
+{
+ $sid = '';
+}
+
//
// Start session management
//
@@ -83,9 +93,7 @@
//
if ( $cancel )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("privmsg.$phpEx?folder=$folder", true));
- exit;
+ redirect(append_sid("privmsg.$phpEx?folder=$folder", true));
}
//
@@ -153,7 +161,7 @@
$l_new_message = $lang['You_no_new_pm'];
}
- $l_new_message .= '<br /><br />' . sprintf($lang['Click_view_privmsg'], '<a href="' . append_sid("privmsg.".$phpEx."?folder=inbox") . '" onClick="jump_to_inbox();return false;" target="_new">', '</a>');
+ $l_new_message .= '<br /><br />' . sprintf($lang['Click_view_privmsg'], '<a href="' . append_sid("privmsg.".$phpEx."?folder=inbox") . '" onclick="jump_to_inbox();return false;" target="_new">', '</a>');
}
else
{
@@ -183,9 +191,7 @@
if ( !$userdata['session_logged_in'] )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=$folder&mode=$mode&" . POST_POST_URL . "=$privmsgs_id", true));
- exit;
+ redirect(append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=$folder&mode=$mode&" . POST_POST_URL . "=$privmsgs_id", true));
}
//
@@ -245,9 +251,7 @@
//
if ( !($privmsg = $db->sql_fetchrow($result)) )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("privmsg.$phpEx?folder=$folder", true));
- exit;
+ redirect(append_sid("privmsg.$phpEx?folder=$folder", true));
}
$privmsg_id = $privmsg['privmsgs_id'];
@@ -256,27 +260,36 @@
// Is this a new message in the inbox? If it is then save
// a copy in the posters sent box
//
- if ( ( $privmsg['privmsgs_type'] == PRIVMSGS_NEW_MAIL || $privmsg['privmsgs_type'] == PRIVMSGS_UNREAD_MAIL ) && $folder == 'inbox' )
+ if (($privmsg['privmsgs_type'] == PRIVMSGS_NEW_MAIL || $privmsg['privmsgs_type'] == PRIVMSGS_UNREAD_MAIL) && $folder == 'inbox')
{
- $sql = "UPDATE " . PRIVMSGS_TABLE . "
- SET privmsgs_type = " . PRIVMSGS_READ_MAIL . "
- WHERE privmsgs_id = " . $privmsg['privmsgs_id'];
- if ( !$db->sql_query($sql) )
+ // Update appropriate counter
+ switch ($privmsg['privmsgs_type'])
{
- message_die(GENERAL_ERROR, 'Could not update private message read status', '', __LINE__, __FILE__, $sql);
+ case PRIVMSGS_NEW_MAIL:
+ $sql = "user_new_privmsg = user_new_privmsg - 1";
+ break;
+ case PRIVMSGS_UNREAD_MAIL:
+ $sql = "user_unread_privmsg = user_unread_privmsg - 1";
+ break;
}
$sql = "UPDATE " . USERS_TABLE . "
- SET user_unread_privmsg = user_unread_privmsg - 1
+ SET $sql
WHERE uid = " . $userdata['user_id'];
if ( !$db->sql_query($sql) )
{
message_die(GENERAL_ERROR, 'Could not update private message read status for user', '', __LINE__, __FILE__, $sql);
}
- //
+ $sql = "UPDATE " . PRIVMSGS_TABLE . "
+ SET privmsgs_type = " . PRIVMSGS_READ_MAIL . "
+ WHERE privmsgs_id = " . $privmsg['privmsgs_id'];
+ if ( !$db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not update private message read status', '', __LINE__, __FILE__, $sql);
+ }
+
// Check to see if the poster has a 'full' sent box
- //
$sql = "SELECT COUNT(privmsgs_id) AS sent_items, MIN(privmsgs_date) AS oldest_post_time
FROM " . PRIVMSGS_TABLE . "
WHERE privmsgs_type = " . PRIVMSGS_SENT_MAIL . "
@@ -292,13 +305,29 @@
{
if ( $sent_info['sent_items'] >= $board_config['max_sentbox_privmsgs'] )
{
- $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TABLE . "
+ $sql = "SELECT privmsgs_id FROM " . PRIVMSGS_TABLE . "
WHERE privmsgs_type = " . PRIVMSGS_SENT_MAIL . "
AND privmsgs_date = " . $sent_info['oldest_post_time'] . "
AND privmsgs_from_userid = " . $privmsg['privmsgs_from_userid'];
+ if ( !$result = $db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not find oldest privmsgs', '', __LINE__, __FILE__, $sql);
+ }
+ $old_privmsgs_id = $db->sql_fetchrow($result);
+ $old_privmsgs_id = $old_privmsgs_id['privmsgs_id'];
+
+ $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TABLE . "
+ WHERE privmsgs_id = $old_privmsgs_id";
+ if ( !$db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs (sent)', '', __LINE__, __FILE__, $sql);
+ }
+
+ $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TEXT_TABLE . "
+ WHERE privmsgs_text_id = $old_privmsgs_id";
if ( !$db->sql_query($sql) )
{
- message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs', '', __LINE__, __FILE__, $sql);
+ message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs text (sent)', '', __LINE__, __FILE__, $sql);
}
}
}
@@ -335,14 +364,14 @@
'edit' => append_sid("privmsg.$phpEx?mode=edit&" . POST_POST_URL . "=$privmsg_id")
);
$post_icons = array(
- 'post_img' => '<a href="' . $post_urls['post'] . '"><img src="' . $images['pm_postmsg'] . '" alt="' . $lang['Post_new_pm'] . '" border="0"></a>',
+ 'post_img' => '<a href="' . $post_urls['post'] . '"><img src="' . $images['pm_postmsg'] . '" alt="' . $lang['Post_new_pm'] . '" border="0" /></a>',
'post' => '<a href="' . $post_urls['post'] . '">' . $lang['Post_new_pm'] . '</a>',
- 'reply_img' => '<a href="' . $post_urls['reply'] . '"><img src="' . $images['pm_replymsg'] . '" alt="' . $lang['Post_reply_pm'] . '" border="0"></a>',
+ 'reply_img' => '<a href="' . $post_urls['reply'] . '"><img src="' . $images['pm_replymsg'] . '" alt="' . $lang['Post_reply_pm'] . '" border="0" /></a>',
'reply' => '<a href="' . $post_urls['reply'] . '">' . $lang['Post_reply_pm'] . '</a>',
- 'quote_img' => '<a href="' . $post_urls['quote'] . '"><img src="' . $images['pm_quotemsg'] . '" alt="' . $lang['Post_quote_pm'] . '" border="0"></a>',
+ 'quote_img' => '<a href="' . $post_urls['quote'] . '"><img src="' . $images['pm_quotemsg'] . '" alt="' . $lang['Post_quote_pm'] . '" border="0" /></a>',
'quote' => '<a href="' . $post_urls['quote'] . '">' . $lang['Post_quote_pm'] . '</a>',
- 'edit_img' => '<a href="' . $post_urls['edit'] . '"><img src="' . $images['pm_editmsg'] . '" alt="' . $lang['Edit_pm'] . '" border="0"></a>',
- 'edit' => '<a href="' . $post_urls['edit'] . '">' . $lang['Edit_pm'] . '</a>'
+ 'edit_img' => '<a href="' . $post_urls['edit'] . '"><img src="' . $images['pm_editmsg'] . '" alt="' . $lang['Edit_pm'] . '" border="0" /></a>',
+ 'edit' => '<a href="' . $post_urls['edit'] . '" />' . $lang['Edit_pm'] . '</a>'
);
if ( $folder == 'inbox' )
@@ -408,7 +437,7 @@
$l_box_name = $lang['Sent'];
}
- $s_hidden_fields = '<input type="hidden" name="mark[]" value="' . $privmsgs_id . '" />';
+ $s_hidden_fields = '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" /><input type="hidden" name="mark[]" value="' . $privmsgs_id . '" />';
$page_title = $lang['Read_pm'];
include($phpbb_root_path . 'includes/page_header.'.$phpEx);
@@ -508,7 +537,7 @@
$aim_img = ( $privmsg['user_aim'] ) ? '<a href="aim:goim?screenname=' . $privmsg['user_aim'] . '&message=Hello+Are+you+there?"><img src="' . $images['icon_aim'] . '" alt="' . $lang['AIM'] . '" title="' . $lang['AIM'] . '" border="0" /></a>' : '';
$aim = ( $privmsg['user_aim'] ) ? '<a href="aim:goim?screenname=' . $privmsg['user_aim'] . '&message=Hello+Are+you+there?">' . $lang['AIM'] . '</a>' : '';
- $temp_url = append_sid("profile.$phpEx?mode=viewprofile&" . POST_USERS_URL . "=$poster_id");
+ $temp_url = append_sid("profile.$phpEx?mode=viewprofile&" . POST_USERS_URL . "=$user_id_from");
$msn_img = ( $privmsg['user_msnm'] ) ? '<a href="' . $temp_url . '"><img src="' . $images['icon_msnm'] . '" alt="' . $lang['MSNM'] . '" title="' . $lang['MSNM'] . '" border="0" /></a>' : '';
$msn = ( $privmsg['user_msnm'] ) ? '<a href="' . $temp_url . '">' . $lang['MSNM'] . '</a>' : '';
@@ -632,10 +661,15 @@
{
if ( !$userdata['session_logged_in'] )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=inbox", true));
- exit;
+ redirect(append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=inbox", true));
+ }
+
+ // session id check
+ if ($sid == '' || $sid != $userdata['session_id'])
+ {
+ message_die(GENERAL_ERROR, 'Invalid_session');
}
+
if ( isset($mark_list) && !is_array($mark_list) )
{
// Set to empty array instead of '0' if nothing is selected.
@@ -644,12 +678,12 @@
if ( !$confirm )
{
- $s_hidden_fields = '<input type="hidden" name="mode" value="' . $mode . '" />';
+ $s_hidden_fields = '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" /><input type="hidden" name="mode" value="' . $mode . '" />';
$s_hidden_fields .= ( isset($HTTP_POST_VARS['delete']) ) ? '<input type="hidden" name="delete" value="true" />' : '<input type="hidden" name="deleteall" value="true" />';
for($i = 0; $i < count($mark_list); $i++)
{
- $s_hidden_fields .= '<input type="hidden" name="mark[]" value="' . $mark_list[$i] . '" />';
+ $s_hidden_fields .= '<input type="hidden" name="mark[]" value="' . intval($mark_list[$i]) . '" />';
}
//
@@ -721,70 +755,99 @@
if ( count($mark_list) )
{
- $delete_sql_id = implode(', ', $mark_list);
-
- //
- // Need to decrement the new message counter of recipient
- // problem is this doesn't affect the unread counter even
- // though it may be the one that needs changing ... hhmmm
- //
- if ( $folder == 'outbox' )
+ $delete_sql_id = '';
+ for ($i = 0; $i < sizeof($mark_list); $i++)
{
- $sql = "SELECT privmsgs_to_userid
- FROM " . PRIVMSGS_TABLE . "
- WHERE privmsgs_id IN ($delete_sql_id)
- AND privmsgs_from_userid = " . $userdata['user_id'] . "
- AND privmsgs_type = " . PRIVMSGS_NEW_MAIL;
- if ( !($result = $db->sql_query($sql)) )
- {
- message_die(GENERAL_ERROR, 'Could not obtain user id list for outbox messages', '', __LINE__, __FILE__, $sql);
- }
-
- $update_pm_sql = '';
- while( $row = $db->sql_fetchrow($result) )
- {
- $update_pm_sql .= ( ( $update_pm_sql != '' ) ? ', ' : '' ) . $row['privmsgs_to_userid'];
- }
+ $delete_sql_id .= (($delete_sql_id != '') ? ', ' : '') . intval($mark_list[$i]);
+ }
- if ( $update_pm_sql != '' )
+ if ($folder == 'inbox' || $folder == 'outbox')
+ {
+ switch ($folder)
{
- $sql = "UPDATE " . USERS_TABLE . "
- SET user_new_privmsg = user_new_privmsg - 1
- WHERE uid IN ($update_pm_sql)";
- if ( !$db->sql_query($sql) )
- {
- message_die(GENERAL_ERROR, 'Could not update users new msg counters', '', __LINE__, __FILE__, $sql);
- }
+ case 'inbox':
+ $sql = "privmsgs_to_userid = " . $userdata['user_id'];
+ break;
+ case 'outbox':
+ $sql = "privmsgs_from_userid = " . $userdata['user_id'];
+ break;
}
- $sql = "SELECT privmsgs_to_userid
+ // Get information relevant to new or unread mail
+ // so we can adjust users counters appropriately
+ $sql = "SELECT privmsgs_to_userid, privmsgs_type
FROM " . PRIVMSGS_TABLE . "
WHERE privmsgs_id IN ($delete_sql_id)
- AND privmsgs_from_userid = " . $userdata['user_id'] . "
- AND privmsgs_type = " . PRIVMSGS_UNREAD_MAIL;
+ AND $sql
+ AND privmsgs_type IN (" . PRIVMSGS_NEW_MAIL . ", " . PRIVMSGS_UNREAD_MAIL . ")";
if ( !($result = $db->sql_query($sql)) )
{
message_die(GENERAL_ERROR, 'Could not obtain user id list for outbox messages', '', __LINE__, __FILE__, $sql);
}
- $update_pm_sql = '';
- while( $row = $db->sql_fetchrow($result) )
+ if ( $row = $db->sql_fetchrow($result))
{
- $update_pm_sql .= ( ( $update_pm_sql != '' ) ? ', ' : '' ) . $row['privmsgs_to_userid'];
- }
+ $update_users = $update_list = array();
+
+ do
+ {
+ switch ($row['privmsgs_type'])
+ {
+ case PRIVMSGS_NEW_MAIL:
+ $update_users['new'][$row['privmsgs_to_userid']]++;
+ break;
+
+ case PRIVMSGS_UNREAD_MAIL:
+ $update_users['unread'][$row['privmsgs_to_userid']]++;
+ break;
+ }
+ }
+ while ($row = $db->sql_fetchrow($result));
- if ( $update_pm_sql != '' )
- {
- $sql = "UPDATE " . USERS_TABLE . "
- SET user_unread_privmsg = user_unread_privmsg - 1
- WHERE uid IN ($update_pm_sql)";
- if ( !$db->sql_query($sql) )
+ if (sizeof($update_users))
{
- message_die(GENERAL_ERROR, 'Could not update users new msg counters', '', __LINE__, __FILE__, $sql);
+ while (list($type, $users) = each($update_users))
+ {
+ while (list($user_id, $dec) = each($users))
+ {
+ $update_list[$type][$dec][] = $user_id;
+ }
+ }
+ unset($update_users);
+
+ while (list($type, $dec_ary) = each($update_list))
+ {
+ switch ($type)
+ {
+ case 'new':
+ $type = "user_new_privmsg";
+ break;
+
+ case 'unread':
+ $type = "user_unread_privmsg";
+ break;
+ }
+
+ while (list($dec, $user_ary) = each($dec_ary))
+ {
+ $user_ids = implode(', ', $user_ary);
+
+ $sql = "UPDATE " . USERS_TABLE . "
+ SET $type = $type - $dec
+ WHERE uid IN ($user_ids)";
+ if ( !$db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not update user pm counters', '', __LINE__, __FILE__, $sql);
+ }
+ }
+ }
+ unset($update_list);
}
}
+ $db->sql_freeresult($result);
}
+ // Delete the messages
$delete_text_sql = "DELETE FROM " . PRIVMSGS_TEXT_TABLE . "
WHERE privmsgs_text_id IN ($delete_sql_id)";
$delete_sql = "DELETE FROM " . PRIVMSGS_TABLE . "
@@ -831,79 +894,182 @@
{
if ( !$userdata['session_logged_in'] )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=inbox", true));
- exit;
+ redirect(append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=inbox", true));
}
- //
- // See if recipient is at their savebox limit
- //
- $sql = "SELECT COUNT(privmsgs_id) AS savebox_items, MIN(privmsgs_date) AS oldest_post_time
- FROM " . PRIVMSGS_TABLE . "
- WHERE ( ( privmsgs_to_userid = " . $userdata['user_id'] . "
- AND privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . " )
- OR ( privmsgs_from_userid = " . $userdata['user_id'] . "
- AND privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . ") )";
- if ( !($result = $db->sql_query($sql)) )
+ // session id check
+ if ($sid == '' || $sid != $userdata['session_id'])
{
- message_die(GENERAL_ERROR, 'Could not obtain sent message info for sendee', '', __LINE__, __FILE__, $sql);
+ message_die(GENERAL_ERROR, 'Invalid_session');
}
+
+ if (sizeof($mark_list))
+ {
+ // See if recipient is at their savebox limit
+ $sql = "SELECT COUNT(privmsgs_id) AS savebox_items, MIN(privmsgs_date) AS oldest_post_time
+ FROM " . PRIVMSGS_TABLE . "
+ WHERE ( ( privmsgs_to_userid = " . $userdata['user_id'] . "
+ AND privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . " )
+ OR ( privmsgs_from_userid = " . $userdata['user_id'] . "
+ AND privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . ") )";
+ if ( !($result = $db->sql_query($sql)) )
+ {
+ message_die(GENERAL_ERROR, 'Could not obtain sent message info for sendee', '', __LINE__, __FILE__, $sql);
+ }
- $sql_priority = ( SQL_LAYER == 'mysql' ) ? 'LOW_PRIORITY' : '';
+ $sql_priority = ( SQL_LAYER == 'mysql' ) ? 'LOW_PRIORITY' : '';
- if ( $saved_info = $db->sql_fetchrow($result) )
- {
- if ( $saved_info['savebox_items'] >= $board_config['max_savebox_privmsgs'] )
+ if ( $saved_info = $db->sql_fetchrow($result) )
{
- $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TABLE . "
- WHERE ( ( privmsgs_to_userid = " . $userdata['user_id'] . "
- AND privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . " )
- OR ( privmsgs_from_userid = " . $userdata['user_id'] . "
- AND privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . ") )
- AND privmsgs_date = " . $saved_info['oldest_post_time'];
- if ( !$db->sql_query($sql) )
+ if ( $saved_info['savebox_items'] >= $board_config['max_savebox_privmsgs'] )
{
- message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs', '', __LINE__, __FILE__, $sql);
+ $sql = "SELECT privmsgs_id FROM " . PRIVMSGS_TABLE . "
+ WHERE ( ( privmsgs_to_userid = " . $userdata['user_id'] . "
+ AND privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . " )
+ OR ( privmsgs_from_userid = " . $userdata['user_id'] . "
+ AND privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . ") )
+ AND privmsgs_date = " . $saved_info['oldest_post_time'];
+ if ( !$result = $db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not find oldest privmsgs (save)', '', __LINE__, __FILE__, $sql);
+ }
+ $old_privmsgs_id = $db->sql_fetchrow($result);
+ $old_privmsgs_id = $old_privmsgs_id['privmsgs_id'];
+
+ $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TABLE . "
+ WHERE privmsgs_id = $old_privmsgs_id";
+ if ( !$db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs (save)', '', __LINE__, __FILE__, $sql);
+ }
+
+ $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TEXT_TABLE . "
+ WHERE privmsgs_text_id = $old_privmsgs_id";
+ if ( !$db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs text (save)', '', __LINE__, __FILE__, $sql);
+ }
}
}
- }
+
+ $saved_sql_id = '';
+ for ($i = 0; $i < sizeof($mark_list); $i++)
+ {
+ $saved_sql_id .= (($saved_sql_id != '') ? ', ' : '') . intval($mark_list[$i]);
+ }
- //
- // Process request
- //
- $saved_sql = "UPDATE " . PRIVMSGS_TABLE;
+ // Process request
+ $saved_sql = "UPDATE " . PRIVMSGS_TABLE;
- switch( $folder )
- {
- case 'inbox':
- $saved_sql .= " SET privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . "
- WHERE privmsgs_to_userid = " . $userdata['user_id'] . "
- AND ( privmsgs_type = " . PRIVMSGS_READ_MAIL . "
- OR privmsgs_type = " . PRIVMSGS_NEW_MAIL . "
- OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . ")";
- break;
+ // Decrement read/new counters if appropriate
+ if ($folder == 'inbox' || $folder == 'outbox')
+ {
+ switch ($folder)
+ {
+ case 'inbox':
+ $sql = "privmsgs_to_userid = " . $userdata['user_id'];
+ break;
+ case 'outbox':
+ $sql = "privmsgs_from_userid = " . $userdata['user_id'];
+ break;
+ }
- case 'outbox':
- $saved_sql .= " SET privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . "
- WHERE privmsgs_from_userid = " . $userdata['user_id'] . "
- AND ( privmsgs_type = " . PRIVMSGS_NEW_MAIL . "
- OR privmsgs_type = " . PRIVMSGS_UNERAD_MAIL . " ) ";
- break;
+ // Get information relevant to new or unread mail
+ // so we can adjust users counters appropriately
+ $sql = "SELECT privmsgs_to_userid, privmsgs_type
+ FROM " . PRIVMSGS_TABLE . "
+ WHERE privmsgs_id IN ($saved_sql_id)
+ AND $sql
+ AND privmsgs_type IN (" . PRIVMSGS_NEW_MAIL . ", " . PRIVMSGS_UNREAD_MAIL . ")";
+ if ( !($result = $db->sql_query($sql)) )
+ {
+ message_die(GENERAL_ERROR, 'Could not obtain user id list for outbox messages', '', __LINE__, __FILE__, $sql);
+ }
- case 'sentbox':
- $saved_sql .= " SET privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . "
- WHERE privmsgs_from_userid = " . $userdata['user_id'] . "
- AND privmsgs_type = " . PRIVMSGS_SENT_MAIL;
- break;
- }
+ if ( $row = $db->sql_fetchrow($result))
+ {
+ $update_users = $update_list = array();
+
+ do
+ {
+ switch ($row['privmsgs_type'])
+ {
+ case PRIVMSGS_NEW_MAIL:
+ $update_users['new'][$row['privmsgs_to_userid']]++;
+ break;
+
+ case PRIVMSGS_UNREAD_MAIL:
+ $update_users['unread'][$row['privmsgs_to_userid']]++;
+ break;
+ }
+ }
+ while ($row = $db->sql_fetchrow($result));
- if ( count($mark_list) )
- {
- $saved_sql_id = '';
- for($i = 0; $i < count($mark_list); $i++)
+ if (sizeof($update_users))
+ {
+ while (list($type, $users) = each($update_users))
+ {
+ while (list($user_id, $dec) = each($users))
+ {
+ $update_list[$type][$dec][] = $user_id;
+ }
+ }
+ unset($update_users);
+
+ while (list($type, $dec_ary) = each($update_list))
+ {
+ switch ($type)
+ {
+ case 'new':
+ $type = "user_new_privmsg";
+ break;
+
+ case 'unread':
+ $type = "user_unread_privmsg";
+ break;
+ }
+
+ while (list($dec, $user_ary) = each($dec_ary))
+ {
+ $user_ids = implode(', ', $user_ary);
+
+ $sql = "UPDATE " . USERS_TABLE . "
+ SET $type = $type - $dec
+ WHERE uid IN ($user_ids)";
+ if ( !$db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not update user pm counters', '', __LINE__, __FILE__, $sql);
+ }
+ }
+ }
+ unset($update_list);
+ }
+ }
+ $db->sql_freeresult($result);
+ }
+
+ switch ($folder)
{
- $saved_sql_id .= ( ( $saved_sql_id != '' ) ? ', ' : '' ) . $mark_list[$i];
+ case 'inbox':
+ $saved_sql .= " SET privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . "
+ WHERE privmsgs_to_userid = " . $userdata['user_id'] . "
+ AND ( privmsgs_type = " . PRIVMSGS_READ_MAIL . "
+ OR privmsgs_type = " . PRIVMSGS_NEW_MAIL . "
+ OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . ")";
+ break;
+
+ case 'outbox':
+ $saved_sql .= " SET privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . "
+ WHERE privmsgs_from_userid = " . $userdata['user_id'] . "
+ AND ( privmsgs_type = " . PRIVMSGS_NEW_MAIL . "
+ OR privmsgs_type = " . PRIVMSGS_UNERAD_MAIL . " ) ";
+ break;
+
+ case 'sentbox':
+ $saved_sql .= " SET privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . "
+ WHERE privmsgs_from_userid = " . $userdata['user_id'] . "
+ AND privmsgs_type = " . PRIVMSGS_SENT_MAIL;
+ break;
}
$saved_sql .= " AND privmsgs_id IN ($saved_sql_id)";
@@ -912,20 +1078,18 @@
{
message_die(GENERAL_ERROR, 'Could not save private messages', '', __LINE__, __FILE__, $saved_sql);
}
- }
+ redirect("privmsg.$phpEx?folder=savebox");
+ }
}
else if ( $submit || $refresh || $mode != '' )
{
-
if ( !$userdata['session_logged_in'] )
{
$user_id = ( isset($HTTP_GET_VARS[POST_USERS_URL]) ) ? '&' . POST_USERS_URL . '=' . intval($HTTP_GET_VARS[POST_USERS_URL]) : '';
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=$folder&mode=$mode" . $user_id, true));
- exit;
+ redirect(append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=$folder&mode=$mode" . $user_id, true));
}
-
+
//
// Toggles
//
@@ -986,6 +1150,12 @@
if ( $submit )
{
+ // session id check
+ if ($sid == '' || $sid != $userdata['session_id'])
+ {
+ message_die(GENERAL_ERROR, 'Invalid_session');
+ }
+
if ( !empty($HTTP_POST_VARS['username']) )
{
$to_username = $HTTP_POST_VARS['username'];
@@ -1070,15 +1240,31 @@
{
if ( $inbox_info['inbox_items'] >= $board_config['max_inbox_privmsgs'] )
{
- $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TABLE . "
+ $sql = "SELECT privmsgs_id FROM " . PRIVMSGS_TABLE . "
WHERE ( privmsgs_type = " . PRIVMSGS_NEW_MAIL . "
OR privmsgs_type = " . PRIVMSGS_READ_MAIL . "
OR privmsgs_type = " . PRIVMSGS_UNREAD_MAIL . " )
AND privmsgs_date = " . $inbox_info['oldest_post_time'] . "
AND privmsgs_to_userid = " . $to_userdata['user_id'];
+ if ( !$result = $db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not find oldest privmsgs (inbox)', '', __LINE__, __FILE__, $sql);
+ }
+ $old_privmsgs_id = $db->sql_fetchrow($result);
+ $old_privmsgs_id = $old_privmsgs_id['privmsgs_id'];
+
+ $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TABLE . "
+ WHERE privmsgs_id = $old_privmsgs_id";
+ if ( !$db->sql_query($sql) )
+ {
+ message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs (inbox)'.$sql, '', __LINE__, __FILE__, $sql);
+ }
+
+ $sql = "DELETE $sql_priority FROM " . PRIVMSGS_TEXT_TABLE . "
+ WHERE privmsgs_text_id = $old_privmsgs_id";
if ( !$db->sql_query($sql) )
{
- message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs', '', __LINE__, __FILE__, $sql);
+ message_die(GENERAL_ERROR, 'Could not delete oldest privmsgs text (inbox)', '', __LINE__, __FILE__, $sql);
}
}
}
@@ -1146,12 +1332,12 @@
$emailer->use_template('privmsg_notify', $to_userdata['user_lang']);
$emailer->extra_headers($email_headers);
$emailer->email_address($to_userdata['user_email']);
- $emailer->set_subject(); //$lang['Notification_subject']
+ $emailer->set_subject($lang['Notification_subject']);
$emailer->assign_vars(array(
'USERNAME' => $to_username,
'SITENAME' => $board_config['sitename'],
- 'EMAIL_SIG' => str_replace('<br />', "\n", "-- \n" . $board_config['board_email_sig']),
+ 'EMAIL_SIG' => (!empty($board_config['board_email_sig'])) ? str_replace('<br />', "\n", "-- \n" . $board_config['board_email_sig']) : '',
'U_INBOX' => $server_protocol . $server_name . $server_port . $script_name . '?folder=inbox')
);
@@ -1271,9 +1457,7 @@
if ( !($privmsg = $db->sql_fetchrow($result)) )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("privmsg.$phpEx?folder=$folder", true));
- exit;
+ redirect(append_sid("privmsg.$phpEx?folder=$folder", true));
}
$privmsg_subject = $privmsg['privmsgs_subject'];
@@ -1311,9 +1495,7 @@
if ( !($privmsg = $db->sql_fetchrow($result)) )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("privmsg.$phpEx?folder=$folder", true));
- exit;
+ redirect(append_sid("privmsg.$phpEx?folder=$folder", true));
}
$privmsg_subject = ( ( !preg_match('/^Re:/', $privmsg['privmsgs_subject']) ) ? 'Re: ' : '' ) . $privmsg['privmsgs_subject'];
@@ -1412,7 +1594,7 @@
$preview_message = make_clickable($preview_message);
$preview_message = str_replace("\n", '<br />', $preview_message);
- $s_hidden_fields = '<input type="hidden" name="folder" value="' . $folder . '" />';
+ $s_hidden_fields = '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" /><input type="hidden" name="folder" value="' . $folder . '" />';
$s_hidden_fields .= '<input type="hidden" name="mode" value="' . $mode . '" />';
if ( isset($privmsg_id) )
@@ -1534,7 +1716,7 @@
$post_a = $lang['Edit_message'];
}
- $s_hidden_fields = '<input type="hidden" name="folder" value="' . $folder . '" />';
+ $s_hidden_fields = '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" /><input type="hidden" name="folder" value="' . $folder . '" />';
$s_hidden_fields .= '<input type="hidden" name="mode" value="' . $mode . '" />';
if ( $mode == 'edit' )
{
@@ -1553,7 +1735,7 @@
'HTML_STATUS' => $html_status,
'SMILIES_STATUS' => $smilies_status,
'BBCODE_STATUS' => sprintf($bbcode_status, '<a href="' . append_sid("faq.$phpEx?mode=bbcode") . '" target="_phpbbcode">', '</a>'),
- 'FORUM_NAME' => $lang['Private_message'],
+ 'FORUM_NAME' => $lang['Private_Message'],
'BOX_NAME' => $l_box_name,
'INBOX_IMG' => $inbox_img,
@@ -1643,9 +1825,7 @@
//
if ( !$userdata['session_logged_in'] )
{
- $header_location = ( @preg_match('/Microsoft|WebSTAR|Xitami/', getenv('SERVER_SOFTWARE')) ) ? 'Refresh: 0; URL=' : 'Location: ';
- header($header_location . append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=inbox", true));
- exit;
+ redirect(append_sid("login.$phpEx?redirect=privmsg.$phpEx&folder=inbox", true));
}
//
@@ -1745,12 +1925,11 @@
OR ( privmsgs_from_userid = " . $userdata['user_id'] . "
AND privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . ") )";
- $sql .= "WHERE ( ( pm.privmsgs_to_userid = " . $userdata['user_id'] . "
- AND pm.privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . "
- AND u.uid = pm.privmsgs_from_userid )
- OR ( pm.privmsgs_from_userid = " . $userdata['user_id'] . "
- AND pm.privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . "
- AND u.uid = pm.privmsgs_from_userid ) )";
+ $sql .= "WHERE u.uid = pm.privmsgs_from_userid
+ AND ( ( pm.privmsgs_to_userid = " . $userdata['user_id'] . "
+ AND pm.privmsgs_type = " . PRIVMSGS_SAVED_IN_MAIL . " )
+ OR ( pm.privmsgs_from_userid = " . $userdata['user_id'] . "
+ AND pm.privmsgs_type = " . PRIVMSGS_SAVED_OUT_MAIL . " ) )";
break;
default:
@@ -1833,7 +2012,7 @@
break;
}
$post_pm = append_sid("privmsg.$phpEx?mode=post");
-$post_pm_img = '<a href="' . $post_pm . '"><img src="' . $images['pm_postmsg'] . '" alt="' . $lang['Post_new_pm'] . '" border="0"></a>';
+$post_pm_img = '<a href="' . $post_pm . '"><img src="' . $images['pm_postmsg'] . '" alt="' . $lang['Post_new_pm'] . '" border="0" /></a>';
$post_pm = '<a href="' . $post_pm . '">' . $lang['Post_new_pm'] . '</a>';
//
@@ -1903,7 +2082,7 @@
'L_SAVE_MARKED' => $lang['Save_marked'],
'S_PRIVMSGS_ACTION' => append_sid("privmsg.$phpEx?folder=$folder"),
- 'S_HIDDEN_FIELDS' => '',
+ 'S_HIDDEN_FIELDS' => '<input type="hidden" name="sid" value="' . $userdata['session_id'] . '" />',
'S_POST_NEW_MSG' => $post_new_mesg_url,
'S_SELECT_MSG_DAYS' => $select_msg_days,
@@ -1994,4 +2173,4 @@
include($phpbb_root_path . 'includes/page_tail.'.$phpEx);
-?>
\ No newline at end of file
+?>
_________________ Paul Laudanski, Microsoft MVP Windows-Security
CastleCops: [de ] [en ] [wiki ]
sixonetonoffun
Major
Joined: Jan 13, 2003
Posts: 892
Posted:
Tue Jan 21, 2003 8:29 am
Ok gang its time to get to work on a real patch here I have successfuly explioted this on nuke5.6 nuketobb 2.04 and presume it will work on 6.0 and as likely 6.5
If you need details pm me lmao j/k post back here.
_________________www.netflake.com
www.glowoptics.com
ArtificialIntel
Joined: Jan 31, 2004
Posts: -88
Posted:
Tue Jan 21, 2003 8:44 am
never make presumptions where nuke is concerned - especially nuke 6.5 which has far too many differences from Nuke 5.6 to make any presumptions about anything working.
I have a test site running if you want to test it on that.
Artificialintel
Zhen-Xjell
Nuke Cops Founder
Joined: Nov 14, 2002
Posts: 5939
Posted:
Tue Jan 21, 2003 11:53 am
I've been pre-occupied this week.. I hope to get some more time to work on this and other issues.
_________________ Paul Laudanski, Microsoft MVP Windows-Security
CastleCops: [de ] [en ] [wiki ]
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum