View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0007741 | mantisbt | feature | public | 2007-01-28 01:17 | 2022-08-11 07:21 |
Reporter | TomSpilman | Assigned To | |||
Priority | normal | Severity | feature | Reproducibility | N/A |
Status | acknowledged | Resolution | open | ||
Product Version | 1.0.1 | ||||
Summary | 0007741: Captcha for guest reports and comments | ||||
Description | I've had some spam traffic issues on our mantis tracker lately via the guest account. The quick and simple fix is to require registration to enter bugs and comment on them. The problem is that i've found that less bugs get reported when the reporting system requires registration. So i'd like to allow guest reporting on our tracker, but limit the ability for scripts to be used to spam the system. The best option here seems to be adding a required captcha test when a guest reports or comments on an issue. It seems like the existing code from the signup captcha should allow for quick implementation. This feature should be an option for the admin. | ||||
Tags | No tags attached. | ||||
Attached Files | bugnote_add.php (2,264 bytes)
<?php # Mantis - a php based bugtracking system # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org # Copyright (C) 2002 - 2004 Mantis Team - mantisbt-dev@lists.sourceforge.net # This program is distributed under the terms and conditions of the GPL # See the README and LICENSE files for details # -------------------------------------------------------- # $Id: bugnote_add.php,v 1.46 2005/07/25 16:34:10 thraxisp Exp $ # -------------------------------------------------------- ?> <?php # Insert the bugnote into the database then redirect to the bug page ?> <?php require_once( 'core.php' ); // If we're anonymous... check the public key from // the captcha test first! $f_public_key = gpc_get_int( 'public_key', '' ); $f_captcha = gpc_get_string( 'captcha', '' ); $f_captcha = strtolower( trim( $f_captcha ) ); if ( current_user_is_anonymous() ) { // If we have no key or it's invalid then display the captcha again. $t_key = strtolower( substr( md5( config_get( 'password_confirm_hash_magic_string' ) . $f_public_key ), 1, 5) ); if ( $t_key != $f_captcha ) { include_once( 'bugnote_captcha.php' ); return; } } $t_core_path = config_get( 'core_path' ); require_once( $t_core_path.'bug_api.php' ); require_once( $t_core_path.'bugnote_api.php' ); ?> <?php $f_bug_id = gpc_get_int( 'bug_id' ); $f_private = gpc_get_bool( 'private' ); $f_bugnote_text = gpc_get_string( 'bugnote_text', '' ); if ( bug_is_readonly( $f_bug_id ) ) { error_parameters( $f_bug_id ); trigger_error( ERROR_BUG_READ_ONLY_ACTION_DENIED, ERROR ); } access_ensure_bug_level( config_get( 'add_bugnote_threshold' ), $f_bug_id ); $t_bug = bug_get( $f_bug_id, true ); if( $t_bug->project_id != helper_get_current_project() ) { # in case the current project is not the same project of the bug we are viewing... # ... override the current project. This to avoid problems with categories and handlers lists etc. $g_project_override = $t_bug->project_id; } $f_bugnote_text = trim( $f_bugnote_text ); # check for blank bugnote if ( !is_blank( $f_bugnote_text ) ) { bugnote_add( $f_bug_id, $f_bugnote_text, $f_private ); email_bugnote_add( $f_bug_id ); } print_successful_redirect_to_bug( $f_bug_id ); ?> bugnote_captcha.php (1,736 bytes)
<?php # Mantis - a php based bugtracking system # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org # Copyright (C) 2002 - 2004 Mantis Team - mantisbt-dev@lists.sourceforge.net # This program is distributed under the terms and conditions of the GPL # See the README and LICENSE files for details # -------------------------------------------------------- # $Id: bugnote_add2.php # -------------------------------------------------------- ?> <?php # Insert the bugnote into the database then redirect to the bug page ?> <?php require_once( 'core.php' ); html_page_top1(); html_page_top2(); $t_key = mt_rand( 0,99999 ); ?> <br> <br> <center> <form name="captcha_form" method="post" action="bugnote_add.php"> <input type="hidden" name="bug_id" value="<?php echo gpc_get_int( 'bug_id' ) ?>"> <input type="hidden" name="private" value="<?php echo gpc_get_bool( 'private' ) ?>"> <input type="hidden" name="bugnote_text" value="<?php echo gpc_get_string( 'bugnote_text', '' ) ?>"> <table class="width50" cellspacing="1"> <tr> <td class="form-title" colspan="3"> <?php echo lang_get( 'add_bugnote_button' ) ?> </td> </tr> <tr class="row-1"> <td class="category"> <?php echo "Guest accounts must enter this code as it is shown in the box on the right" ?>: </td> <td> <?php print_captcha_input( 'captcha', '' ) ?> </td> <td> <img src="make_captcha_img.php?public_key=<?php echo $t_key ?>"> <input type="hidden" name="public_key" value="<?php echo $t_key ?>"> </td> </tr> <tr> <td class="center" colspan="3"> <input type="submit" class="button" value="<?php echo lang_get( 'add_bugnote_button' ) ?>" /> </td> </tr> </table> </form> </center> <br> <br> <?php html_page_bottom1a( __FILE__ ); ?> bug_report.php.diff (979 bytes)
--- C:/Users/Niklas/Downloads/mantisbt-1.2.3/bug_report.php Di 14. Sep 15:40:10 2010 +++ C:/Users/Niklas/Downloads/bug_report.php Do 11. Nov 15:18:45 2010 @@ -78,6 +78,20 @@ $t_bug_data->target_version = gpc_get_string( 'target_version', '' ); } + // begin stone captcha check for anon user + if (current_user_is_anonymous()) + { + $f_captcha = gpc_get_string( 'captcha', '' ); + $f_public_key = gpc_get_int( 'public_key', '' ); + $f_captcha = strtolower( trim( $f_captcha ) ); + $t_key = strtolower( substr( md5( config_get( 'password_confirm_hash_magic_string' ) . $f_public_key ), 1, 5) ); + + if ( $t_key != $f_captcha ) { + trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); + } + } + // end of stone captcha check for anon user + # if a profile was selected then let's use that information if ( 0 != $t_bug_data->profile_id ) { if ( profile_is_global( $t_bug_data->profile_id ) ) { bug_report_page.php.diff (1,085 bytes)
--- C:/Users/Niklas/Downloads/mantisbt-1.2.3/bug_report_page.php Di 14. Sep 15:40:10 2010 +++ C:/Users/Niklas/Downloads/bug_report_page.php Do 11. Nov 15:18:52 2010 @@ -511,6 +511,26 @@ <label><input <?php echo helper_get_tab_index() ?> type="checkbox" id="report_stay" name="report_stay" <?php check_checked( $f_report_stay ) ?> /> <?php echo lang_get( 'check_report_more_bugs' ) ?></label> </td> </tr> + + <?php //begin stone's captcha for anon login + if (current_user_is_anonymous()) + { + ?> + <tr class="row-1"> + <td class="category"> + <span class="required">*</span><?php echo lang_get( 'signup_captcha_request' ) ?>: + </td> + <td> + <?php print_captcha_input( 'captcha', '' ) ?> + + <img src="make_captcha_img.php?public_key=<?php echo $t_key ?>"> + <input type="hidden" name="public_key" value="<?php echo $t_key ?>"> + </td> + </tr> + <?php + } + //end of stone's captcha for anon login?> + <tr> <td class="left"> <span class="required"> * <?php echo lang_get( 'required' ) ?></span> bugnote_add.php.diff (1,104 bytes)
--- C:/Users/Niklas/Downloads/mantisbt-1.2.3/bugnote_add.php Di 14. Sep 15:40:10 2010 +++ C:/Users/Niklas/Downloads/bugnote_add.php Do 11. Nov 15:16:48 2010 @@ -36,7 +36,21 @@ $f_private = gpc_get_bool( 'private' ); $f_time_tracking = gpc_get_string( 'time_tracking', '0:00' ); $f_bugnote_text = trim( gpc_get_string( 'bugnote_text', '' ) ); + + // begin stone captcha check for anon user + if (current_user_is_anonymous()) + { + $f_captcha = gpc_get_string( 'captcha', '' ); + $f_public_key = gpc_get_int( 'public_key', '' ); + $f_captcha = strtolower( trim( $f_captcha ) ); + $t_key = strtolower( substr( md5( config_get( 'password_confirm_hash_magic_string' ) . $f_public_key ), 1, 5) ); + if ( $t_key != $f_captcha ) { + trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); + } + } + // end of stone captcha check for anon user + $t_bug = bug_get( $f_bug_id, true ); if( $t_bug->project_id != helper_get_current_project() ) { # in case the current project is not the same project of the bug we are viewing... bugnote_add_inc.php.diff (983 bytes)
--- C:/Users/Niklas/Downloads/mantisbt-1.2.3/bugnote_add_inc.php Di 14. Sep 15:40:10 2010 +++ C:/Users/Niklas/Downloads/bugnote_add_inc.php Do 11. Nov 15:18:31 2010 @@ -68,8 +68,28 @@ ?> </td> </tr> + <?php } ?> +<?php //begin stone's captcha for anon login + if (current_user_is_anonymous()) + { + ?> + <tr class="row-1"> + <td class="category"> + <span class="required">*</span><?php echo lang_get( 'signup_captcha_request' ) ?>: + </td> + <td> + <?php print_captcha_input( 'captcha', '' ) ?> + + <img src="make_captcha_img.php?public_key=<?php echo $t_key ?>"> + <input type="hidden" name="public_key" value="<?php echo $t_key ?>"> + </td> + </tr> + <?php + } + //end of stone's captcha for anon login?> + <?php if ( config_get('time_tracking_enabled') ) { ?> <?php if ( access_has_bug_level( config_get( 'time_tracking_edit_threshold' ), $f_bug_id ) ) { ?> <tr <?php echo helper_alternate_class() ?>> | ||||
I really need this fix! |
|
I got home to find over 40 spam posts in the bug notes on our mantis tracker, so i collected my own bounty. I've attached my changes to bugnote_add.php and my bugnote_captcha.php. It's a very simple implementation, but it seems to work fine. I'll look to do the same on bug reports as well soon. With someone who knows the system better to clean it up, it would make a great addition to Mantis. |
|
Another advantage for requiring registration is that you are more likely to get feedback when you ask questions. But I agree that this should be an administrator's decision. If you end up implementing the captcha for reports as well, please attach a zip file with all modified PHP files. |
|
@TomSpilman: Here is a workaround until this is implemented - give anonymous Viewer profile, but then, from Manage Config > Workflow Thresholds, give them the right to create reports (but NOT to add/edit notes). This will help you get rid of a lot of spam, while guests would still be able to add reports. The downside is that genuine guests won't be able to add notes, but it's still a decent compromise solution until Captcha codes will be introduced. EDIT: There is a small "bug" (?) with that set-up though, namely that guests have to follow an external link to the "Report Issue" page in order to create the report. I'm not yet decided if that's a good or a bad thing. On one hand it increases the chance that I get only genuine reporters, if they have to follow the links we have on the project website or forum, on the other hand, if one of these reporters who prefers to stay anonymous puts the Mantis View Issues page in their favorites, they won't have the Report Issue link on top to use it. |
|
Since i fixed this by adding a Captcha to my old copy of Mantis i've had zero spam posts.... so as far as i'm concerned this bug is fixed for me. If Mantis didn't adopt my modification thats ok with me i guess. |
|
My solution:
</tr>
that's all you need to do. |
|
I´ve uploaded diffs with fixes. They include captchas for bugnotes and bug reports for anonymous users. |
|
i forgot 1 line to randomize the captcha before the image (<img src="make_captcha......): $t_key = mt_rand( 0,99999 ); put this line in bug_report_page.php, bug_report_advanced_page.php, and bugnote_add_inc.php otherwise the captcha will always be the same, and essentially useless. |
|
Ok, I´ve corrected the diff´s (the .new files) |
|
we have diffs, can't it be added to the code now? is there still development happening on mantis? |
|
Submitting a patch increases the chances of improvement eventually making it into MantisBT core. All contributions are welcome and greatly appreciated. Patch submissions can be made in several ways. In the order of preference:
Kindly avoid to upload entire modified PHP files. Please make sure that your submissions adhere to our Coding Guidelines [2], if they don't your patch might be rejected. [1] https://github.com/mantisbt/mantisbt |
|
A very simple workaround I did is to use JS to rename the note field onfocus. This eliminates all the bots. Obviously this is an obscurity thing, but I doubt many spammers are going to code their bots just to Mantis. I don't know Mantis's currently policy on whether JS is required or not, but to me I think we can assume a user has it nowadays. |
|
Here is the patch for version 2.25.5. Who needs it - use it. I have neither the time nor the desire to issue a request on Github in accordance with the rules. 0001-2.25.5_capcha.patch (7,267 bytes)
From c471bfc76fd08ceb46a4fc2d5541377e0f4ef0d8 Mon Sep 17 00:00:00 2001 From: Simon Litt <slsoft@bk.ru> Date: Thu, 11 Aug 2022 13:33:51 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=B0=D0=BF=D1=87=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bug_report.php | 7 ++++++ bug_report_page.php | 47 +++++++++++++++++++++++++++++++++++ bug_view_inc.php | 3 +++ bugnote_add.php | 7 ++++++ bugnote_add_inc.php | 44 ++++++++++++++++++++++++++++++++ config/custom_strings_inc.php | 4 +++ 6 files changed, 112 insertions(+) diff --git a/bug_report.php b/bug_report.php index 80747fb..fbfa03d 100644 --- a/bug_report.php +++ b/bug_report.php @@ -84,6 +84,13 @@ if( $f_master_bug_id > 0 ) { $t_project_id = $f_project_id; } +$f_captcha = gpc_get_string( 'captcha', '' ); +$f_captcha = mb_strtolower( trim( $f_captcha ) ); +$t_securimage = new Securimage(); +if( $t_securimage->check( $f_captcha ) == false ) { + trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); +} + $t_issue = array( 'project' => array( 'id' => $t_project_id ), 'reporter' => array( 'id' => auth_get_current_user_id() ), diff --git a/bug_report_page.php b/bug_report_page.php index 6c05baf..62abc6a 100644 --- a/bug_report_page.php +++ b/bug_report_page.php @@ -75,6 +75,9 @@ require_api( 'string_api.php' ); require_api( 'utility_api.php' ); require_api( 'version_api.php' ); +require_css( 'login.css' ); +require_js( 'login.js' ); + $f_master_bug_id = gpc_get_int( 'm_id', 0 ); if( $f_master_bug_id > 0 ) { @@ -758,6 +761,50 @@ if( $t_show_attachments ) { </label> </td> </tr> + <?php //begin stone's captcha for anon login + if (current_user_is_anonymous()) + { + ?> + <tr class="row-1"> + <td class="category"> + <span class="required"> * </span><?php echo lang_get( 'signup_captcha_request' ) ?>: + </td> + <td> + <?php + + $t_securimage_path = 'vendor/dapphp/securimage'; + $t_securimage_show = $t_securimage_path . '/securimage_show.php'; + $t_securimage_play = $t_secur__FILE__image_path . '/securimage_play.swf?' + . http_build_query( array( + 'audio_file' => $t_securimage_path . '/securimage_play.php', + 'bgColor1=' => '#fff', + 'bgColor2=' => '#fff', + 'iconColor=' => '#777', + 'borderWidth=' => 1, + 'borderColor=' => '#000', + ) ); + + ?> + <span id="captcha-input" class="input"> + <?php print_captcha_input( 'captcha' ); ?> + + <span id="captcha-image" class="captcha-image" style="padding-right:3px;"> + <img src="<?php echo $t_securimage_show; ?>" alt="visual captcha" /> + <ul id="captcha-refresh"><li><a href="#" onclick="window.refresh=function(e){var img = $('#captcha-image img');var captcha = img.attr('src');img.attr('src', captcha.split('?', 1) + '?' + Math.random());$('#captcha-field').focus();e.preventDefault();}"><?php + echo lang_get( 'signup_captcha_refresh' ); + ?></a></li></ul> + </span> + + <object type="application/x-shockwave-flash" width="19" height="19" + data="<?php echo $t_securimage_play; ?>"> + <param name="movie" value="<?php echo $t_securimage_play; ?>" /> + </object> + </span> + </td> + </tr> + <?php + } +//end of stone's captcha for anon login?> </table> </div> </div> diff --git a/bug_view_inc.php b/bug_view_inc.php index 7d39c9d..cdb6d13 100644 --- a/bug_view_inc.php +++ b/bug_view_inc.php @@ -77,6 +77,9 @@ require_api( 'version_api.php' ); require_css( 'status_config.php' ); +require_css( 'login.css' ); +require_js( 'login.js' ); + $f_issue_id = gpc_get_int( 'id' ); $f_history = gpc_get_bool( 'history', config_get( 'history_default_visible' ) ); diff --git a/bugnote_add.php b/bugnote_add.php index 39b5d52..db530a6 100644 --- a/bugnote_add.php +++ b/bugnote_add.php @@ -60,6 +60,13 @@ $t_data = array( 'payload' => $t_payload, ); +$f_captcha = gpc_get_string( 'captcha', '' ); +$f_captcha = mb_strtolower( trim( $f_captcha ) ); +$t_securimage = new Securimage(); +if( $t_securimage->check( $f_captcha ) == false ) { + trigger_error( ERROR_SIGNUP_NOT_MATCHING_CAPTCHA, ERROR ); +} + $t_command = new IssueNoteAddCommand( $t_data ); $t_command->execute(); diff --git a/bugnote_add_inc.php b/bugnote_add_inc.php index 30bc58b..da47db8 100644 --- a/bugnote_add_inc.php +++ b/bugnote_add_inc.php @@ -119,7 +119,51 @@ require_api( 'lang_api.php' ); <textarea name="bugnote_text" id="bugnote_text" class="<?php echo $t_bugnote_class ?>" rows="7"></textarea> </td> </tr> +<?php +//begin stone's captcha for anon login + if (current_user_is_anonymous()) + { + ?> + <tr class="row-1"> + <td class="category"> + <span class="required"> * </span><?php echo lang_get( 'signup_captcha_request' ) ?>: + </td> + <td> + <?php + + $t_securimage_path = 'vendor/dapphp/securimage'; + $t_securimage_show = $t_securimage_path . '/securimage_show.php'; + $t_securimage_play = $t_secur__FILE__image_path . '/securimage_play.swf?' + . http_build_query( array( + 'audio_file' => $t_securimage_path . '/securimage_play.php', + 'bgColor1=' => '#fff', + 'bgColor2=' => '#fff', + 'iconColor=' => '#777', + 'borderWidth=' => 1, + 'borderColor=' => '#000', + ) ); + + ?> + <span id="captcha-input" class="input"> + <?php print_captcha_input( 'captcha' ); ?> + + <span id="captcha-image" class="captcha-image" style="padding-right:3px;"> + <img src="<?php echo $t_securimage_show; ?>" alt="visual captcha" /> + <ul id="captcha-refresh"><li><a href="#" onclick="window.refresh=function(e){var img = $('#captcha-image img');var captcha = img.attr('src');img.attr('src', captcha.split('?', 1) + '?' + Math.random());$('#captcha-field').focus();e.preventDefault();}"><?php + echo lang_get( 'signup_captcha_refresh' ); + ?></a></li></ul> + </span> + <object type="application/x-shockwave-flash" width="19" height="19" + data="<?php echo $t_securimage_play; ?>"> + <param name="movie" value="<?php echo $t_securimage_play; ?>" /> + </object> + </span> + </td> + </tr> + <?php + } +//end of stone's captcha for anon login?> <?php if( config_get( 'time_tracking_enabled' ) ) { if( access_has_bug_level( config_get( 'time_tracking_edit_threshold' ), $f_bug_id ) ) { diff --git a/config/custom_strings_inc.php b/config/custom_strings_inc.php index 8bae9a1..eb7ea79 100644 --- a/config/custom_strings_inc.php +++ b/config/custom_strings_inc.php @@ -9,6 +9,8 @@ switch( $g_active_language ) { $s_process_bug_button = 'В процессе'; $s_email_notification_title_for_status_bug_process = 'Следующая задача В ПРОЦЕССЕ:'; + + $s_signup_captcha_request = 'Введите код с картинки'; break; default: # english @@ -18,5 +20,7 @@ switch( $g_active_language ) { $s_testing_bug_button = 'Ready for Process'; $s_email_notification_title_for_status_bug_testing = 'The following issue is ready for PROCESS.'; + + $s_signup_captcha_request = 'Enter the code from the image'; break; } -- 2.35.1 |
|