Package: phpbb2 Version: 2.0.13-2 Severity: wishlist Tags: patch This patch introduce the feature that force anonymous user to fill the confirmation code before posting any messages into the forum. This is the confirmation code like in the phpbb's registration page, that present the image of distorted characters of the corresponding confirmation code.
The patch has currently been used at http://linux.thai.net/phpbb2/ . See http://linux.thai.net/phpbb2/posting.php?mode=newtopic&f=2 that demonstrate how this patch is working. -- System Information: Debian Release: testing/unstable Architecture: i386 (i686) Kernel: Linux 2.6.10-5-386 Locale: LANG=C, LC_CTYPE=thai Versions of packages phpbb2 depends on: ii apache [httpd] 1.3.31-6ubuntu0.9 Versatile, high-performance HTTP s ii debconf 1.4.29ubuntu4 Debian configuration management sy ii php4 4:4.3.8-3ubuntu7.12 A server-side, HTML-embedded scrip ii php4-cgi 4:4.3.10-10ubuntu4.3 server-side, HTML-embedded scripti ii php4-mysql 4:4.3.8-3ubuntu7.12 MySQL module for php4 -- debconf information: * phpbb2/httpd: apache __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
diff -ur /usr/share/phpbb2/site/language/lang_english/lang_main.php phpbb2/site/language/lang_english/lang_main.php --- /usr/share/phpbb2/site/language/lang_english/lang_main.php 2005-02-28 02:30:45.000000000 +0700 +++ phpbb2/site/language/lang_english/lang_main.php 2006-02-25 02:51:06.000000000 +0700 @@ -605,6 +605,7 @@ $lang['Current_password_mismatch'] = 'The current password you supplied does not match that stored in the database.'; $lang['Password_long'] = 'Your password must be no more than 32 characters.'; $lang['Too_many_registers'] = 'You have made too many registration attempts. Please try again later.'; +$lang['Too_many_posts'] = 'You have made too many posting attempts. Please try again later.'; $lang['Username_taken'] = 'Sorry, but this username has already been taken.'; $lang['Username_invalid'] = 'Sorry, but this username contains an invalid character such as \'.'; $lang['Username_disallowed'] = 'Sorry, but this username has been disallowed.'; @@ -663,6 +664,7 @@ // $lang['Confirm_code_wrong'] = 'The confirmation code you entered was incorrect'; $lang['Too_many_registers'] = 'You have exceeded the number of registration attempts for this session. Please try again later.'; +$lang['Too_many_posts'] = 'You have exceeded the number of posting attempts for this session. Please try again later.'; $lang['Confirm_code_impaired'] = 'If you are visually impaired or cannot otherwise read this code please contact the %sAdministrator%s for help.'; $lang['Confirm_code'] = 'Confirmation code'; $lang['Confirm_code_explain'] = 'Enter the code exactly as you see it. The code is case sensitive and zero has a diagonal line through it.'; @@ -1022,4 +1024,4 @@ // That's all, Folks! // ------------------------------------------------- -?> \ No newline at end of file +?> diff -ur /usr/share/phpbb2/site/language/lang_thai/lang_main.php phpbb2/site/language/lang_thai/lang_main.php --- /usr/share/phpbb2/site/language/lang_thai/lang_main.php 2003-04-20 19:30:18.000000000 +0700 +++ phpbb2/site/language/lang_thai/lang_main.php 2006-02-25 03:12:34.000000000 +0700 @@ -658,6 +658,18 @@ // +// Visual confirmation system strings +// +$lang['Confirm_code_wrong'] = 'The confirmation code you entered was incorrect'; +$lang['Too_many_registers'] = 'You have exceeded the number of registration attempts for this session. Please try again later.'; +$lang['Too_many_posts'] = 'You have exceeded the number of posting attempts for this session. Please try again later.'; +$lang['Confirm_code_impaired'] = 'If you are visually impaired or cannot otherwise read this code please contact the %sAdministrator%s for help.'; +$lang['Confirm_code'] = 'Confirmation code'; +$lang['Confirm_code_explain'] = 'Enter the code exactly as you see it. The code is case sensitive and zero has a diagonal line through it.'; + + + +// // Memberslist // $lang['Select_sort_method'] = 'àÅ×Í¡ÇÔ¸ÕàÃÕ§ÅӴѺ'; @@ -1009,4 +1021,4 @@ // That's all Folks! // ------------------------------------------------- -?> \ No newline at end of file +?> diff -ur /usr/share/phpbb2/site/posting.php phpbb2/site/posting.php --- /usr/share/phpbb2/site/posting.php 2005-02-28 02:30:46.000000000 +0700 +++ phpbb2/site/posting.php 2006-02-27 10:35:12.000000000 +0700 @@ -31,6 +31,7 @@ // Check and set various parameters // $params = array('submit' => 'post', 'preview' => 'preview', 'delete' => 'delete', 'poll_delete' => 'poll_delete', 'poll_add' => 'add_poll_option', 'poll_edit' => 'edit_poll_option', 'mode' => 'mode'); +$params['confirm_code'] = 'confirm_code'; while( list($var, $param) = @each($params) ) { if ( !empty($HTTP_POST_VARS[$param]) || !empty($HTTP_GET_VARS[$param]) ) @@ -545,6 +546,60 @@ $poll_length = ( isset($HTTP_POST_VARS['poll_length']) && $is_auth['auth_pollcreate'] ) ? $HTTP_POST_VARS['poll_length'] : ''; $bbcode_uid = ''; + // Code copied from includes/usercp_register.php without modification, + // except the first condition line, + // if ($board_config['enable_confirm'] && $mode == 'register') + if ($board_config['enable_confirm'] && !$userdata['session_logged_in']) + { + if (empty($HTTP_POST_VARS['confirm_id'])) + { + $error = TRUE; + $error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong']; + } + else + { + $confirm_id = htmlspecialchars($HTTP_POST_VARS['confirm_id']); + if (!preg_match('/^[A-Za-z0-9]+$/', $confirm_id)) + { + $confirm_id = ''; + } + + $sql = 'SELECT code + FROM ' . CONFIRM_TABLE . " + WHERE confirm_id = '$confirm_id' + AND session_id = '" . $userdata['session_id'] . "'"; + if (!($result = $db->sql_query($sql))) + { + message_die(GENERAL_ERROR, 'Could not obtain confirmation code', __LINE__, __FILE__, $sql); + } + + if ($row = $db->sql_fetchrow($result)) + { + if ($row['code'] != $confirm_code) + { + $error = TRUE; + $error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong']; + } + else + { + $sql = 'DELETE FROM ' . CONFIRM_TABLE . " + WHERE confirm_id = '$confirm_id' + AND session_id = '" . $userdata['session_id'] . "'"; + if (!$db->sql_query($sql)) + { + message_die(GENERAL_ERROR, 'Could not delete confirmation code', __LINE__, __FILE__, $sql); + } + } + } + else + { + $error = TRUE; + $error_msg .= ( ( isset($error_msg) ) ? '<br />' : '' ) . $lang['Confirm_code_wrong']; + } + $db->sql_freeresult($result); + } + } + prepare_post($mode, $post_data, $bbcode_on, $html_on, $smilies_on, $error_msg, $username, $bbcode_uid, $subject, $message, $poll_title, $poll_options, $poll_length); if ( $error_msg == '' ) @@ -638,6 +693,22 @@ if( $preview ) { + // On preview action, do remove the current confirm_id entry in table, so + // that it won't be counted as attempts in ref_note{attempts} below + $confirm_id = htmlspecialchars($HTTP_POST_VARS['confirm_id']); + if (!preg_match('/^[A-Za-z0-9]+$/', $confirm_id)) + { + $confirm_id = ''; + } + + $sql = 'DELETE FROM ' . CONFIRM_TABLE . " + WHERE confirm_id = '$confirm_id' + AND session_id = '" . $userdata['session_id'] . "'"; + if (!$db->sql_query($sql)) + { + message_die(GENERAL_ERROR, 'Could not delete confirmation code', __LINE__, __FILE__, $sql); + } + $orig_word = array(); $replacement_word = array(); obtain_word_list($orig_word, $replacement_word); @@ -919,6 +990,102 @@ $hidden_form_fields = '<input type="hidden" name="mode" value="' . $mode . '" />'; +$confirm_image = ''; +if( !$userdata['session_logged_in'] ) +{ + // Visual Confirmation copied from includes/usercp_register.php with minor + // modification on the following 4 lines of code, + // if (!empty($board_config['enable_confirm']) && $mode == 'register') + // $s_hidden_fields .= '<input type="hidden" name="confirm_id" value="' . $confirm_id . '" />'; + // if ($row['attempts'] > 3) + // message_die(GENERAL_MESSAGE, $lang['Too_many_registers']); + // This attempts checking won't prevent the brute force attack, because the + // cracker can open new session to reset this attempts count. + // Unlike registering a new account, the attempts checking on the post or + // reply action should be relaxed, because some users may prefer to open + // many reply pages at the same time to post their comments. + // But it should be limited to some extent to prevent the CONFIRM_TABLE from + // having too much confirm_id records. + // (All confirm_id records of the expired session will be automatically + // cleared.) + // + // Visual Confirmation + $confirm_image = ''; + if (!empty($board_config['enable_confirm'])) + { + $sql = 'SELECT session_id + FROM ' . SESSIONS_TABLE; + if (!($result = $db->sql_query($sql))) + { + message_die(GENERAL_ERROR, 'Could not select session data', '', __LINE__, __FILE__, $sql); + } + + if ($row = $db->sql_fetchrow($result)) + { + $confirm_sql = ''; + do + { + $confirm_sql .= (($confirm_sql != '') ? ', ' : '') . "'" . $row['session_id'] . "'"; + } + while ($row = $db->sql_fetchrow($result)); + + $sql = 'DELETE FROM ' . CONFIRM_TABLE . " + WHERE session_id NOT IN ($confirm_sql)"; + if (!$db->sql_query($sql)) + { + message_die(GENERAL_ERROR, 'Could not delete stale confirm data', '', __LINE__, __FILE__, $sql); + } + } + $db->sql_freeresult($result); + + $sql = 'SELECT COUNT(session_id) AS attempts + FROM ' . CONFIRM_TABLE . " + WHERE session_id = '" . $userdata['session_id'] . "'"; + if (!($result = $db->sql_query($sql))) + { + message_die(GENERAL_ERROR, 'Could not obtain confirm code count', '', __LINE__, __FILE__, $sql); + } + + if ($row = $db->sql_fetchrow($result)) + { + // ref_note{attempts} + if ($row['attempts'] > 30) + { + message_die(GENERAL_MESSAGE, $lang['Too_many_posts']); + } + } + $db->sql_freeresult($result); + + $confirm_chars = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'); + + list($usec, $sec) = explode(' ', microtime()); + mt_srand($sec * $usec); + + $max_chars = count($confirm_chars) - 1; + $code = ''; + for ($i = 0; $i < 6; $i++) + { + $code .= $confirm_chars[mt_rand(0, $max_chars)]; + } + + $confirm_id = md5(uniqid($user_ip)); + + $sql = 'INSERT INTO ' . CONFIRM_TABLE . " (confirm_id, session_id, code) + VALUES ('$confirm_id', '". $userdata['session_id'] . "', '$code')"; + if (!$db->sql_query($sql)) + { + message_die(GENERAL_ERROR, 'Could not insert new confirm code information', '', __LINE__, __FILE__, $sql); + } + + unset($code); + + $confirm_image = (@extension_loaded('zlib')) ? '<img src="' . append_sid("profile.$phpEx?mode=confirm&id=$confirm_id") . '" alt="" title="" />' : '<img src="' . append_sid("profile.$phpEx?mode=confirm&id=$confirm_id&c=1") . '" alt="" title="" /><img src="' . append_sid("profile.$phpEx?mode=confirm&id=$confirm_id&c=2") . '" alt="" title="" /><img src="' . append_sid("profile.$phpEx?mode=confirm&id=$confirm_id&c=3") . '" alt="" title="" /><img src="' . append_sid("profile.$phpEx?mode=confirm&id=$confirm_id&c=4") . '" alt="" title="" /><img src="' . append_sid("profile.$phpEx?mode=confirm&id=$confirm_id&c=5") . '" alt="" title="" /><img src="' . append_sid("profile.$phpEx?mode=confirm&id=$confirm_id&c=6") . '" alt="" title="" />'; + $hidden_form_fields .= '<input type="hidden" name="confirm_id" value="' . $confirm_id . '" />'; + + $template->assign_block_vars('switch_confirm', array()); + } +} + switch( $mode ) { case 'newtopic': @@ -971,12 +1138,17 @@ // $template->assign_vars(array( 'USERNAME' => $username, + 'CONFIRM_IMG' => $confirm_image, 'SUBJECT' => $subject, 'MESSAGE' => $message, 'HTML_STATUS' => $html_status, 'BBCODE_STATUS' => sprintf($bbcode_status, '<a href="' . append_sid("faq.$phpEx?mode=bbcode") . '" target="_phpbbcode">', '</a>'), 'SMILIES_STATUS' => $smilies_status, + 'L_CONFIRM_CODE_IMPAIRED' => sprintf($lang['Confirm_code_impaired'], '<a href="mailto:' . $board_config['board_email'] . '">', '</a>'), + 'L_CONFIRM_CODE' => $lang['Confirm_code'], + 'L_CONFIRM_CODE_EXPLAIN' => $lang['Confirm_code_explain'], + 'L_SUBJECT' => $lang['Subject'], 'L_MESSAGE_BODY' => $lang['Message_body'], 'L_OPTIONS' => $lang['Options'], diff -ur /usr/share/phpbb2/templates/subSilver/posting_body.tpl phpbb2/templates/subSilver/posting_body.tpl --- /usr/share/phpbb2/templates/subSilver/posting_body.tpl 2005-02-28 02:30:45.000000000 +0700 +++ phpbb2/templates/subSilver/posting_body.tpl 2006-02-24 17:38:25.000000000 +0700 @@ -279,6 +279,16 @@ <td class="row2"><span class="genmed"><input type="text" class="post" tabindex="1" name="username" size="25" maxlength="25" value="{USERNAME}" /></span></td> </tr> <!-- END switch_username_select --> + <!-- Visual Confirmation --> + <!-- BEGIN switch_confirm --> + <tr> + <td class="row1" colspan="2" align="center"><span class="gensmall">{L_CONFIRM_CODE_IMPAIRED}</span><br /><br />{CONFIRM_IMG}<br /><br /></td> + </tr> + <tr> + <td class="row1"><span class="gen">{L_CONFIRM_CODE}: * </span><br /><span class="gensmall">{L_CONFIRM_CODE_EXPLAIN}</span></td> + <td class="row2"><input type="text" class="post" style="width: 200px" name="confirm_code" size="6" maxlength="6" value="" /></td> + </tr> + <!-- END switch_confirm --> <!-- BEGIN switch_privmsg --> <tr> <td class="row1"><span class="gen"><b>{L_USERNAME}</b></span></td>