[support] Spammers filling sessions table
Jeremy Andrews
lists at kerneltrap.org
Wed Mar 29 16:18:16 UTC 2006
On Wed, 29 Mar 2006 21:36:22 +0800
"Grant Malcolm" <grant.malcolm at gmail.com> wrote:
> Hi folks
>
> Anyone have a solution for this one? Drupal 4.6.5
>
> My site is getting hammered by spammers and I'm struggling
> to keep it going - particularly on a shared server.
>
> As near as I can tell a regular anonymous visitor generates
> a single row in the sessions table.
I was suffering from massive spam comment attacks on
KernelTrap.org which were choking the database. I finally
solved this by introducing form tokens on comments. I've
created a patch for Drupal 4.6.6, attached (untested).
Cheers,
-Jeremy
>
> I've been regularly deleting sessions where uid=0 but
> referrer and comment spammers are choking my sessions table
> with anonymous sessions. In an eight hour period I suddenly
> gained 14,700 rows in sessions table. In a half hour period
> towards the end of this before the db choked with too many
> connections, I had 500+ attempts to post comment spam.
>
> Bad behaviour and spam are blocking almost all of the
> comment spam from publication, but the site is choking in
> the meantime.
>
> I've tried session_limit module, but the spammers are
> spoofing random ips and ignoring the sessions, so it
> doesn't seem to have any effect.
>
> Any suggestions welcomed.
>
> Cheers
> Grant
>
> --
> *
> http://www.theatre.asn.au/
> Connect with your local theatre online
-------------- next part --------------
--- includes/common.inc.orig 2006-03-13 17:14:49.000000000 -0500
+++ includes/common.inc 2006-03-17 14:55:38.000000000 -0500
@@ -943,6 +943,53 @@
}
/**
+ * Set a hidden 'form_token' field to be included in a form, used to validate
+ * that the resulting submission was actually generated by a local form.
+ *
+ * @param $key
+ * A unique key to identify the form that is currently being displayed.
+ * This identical key is later used to validate that the resulting submission
+ * actually originated with this form.
+ * @result
+ * A themed HTML string representing the hidden token field.
+ */
+function form_token($key) {
+ // this private key should always be kept secret
+ if (!variable_get('drupal_private_key', '')) {
+ variable_set('drupal_private_key', mt_rand());
+ }
+
+ // the verification token is an md5 hash of the form key and our private key
+ return form_hidden('form_token', md5(session_id() . $key . variable_get('drupal_private_key', '')));
+}
+
+/**
+ * Verify that the hidden 'form_token' field was actually generated with our
+ * private key.
+ *
+ * @param $edit
+ * An array containing the form that needs to be validated.
+ * @param $key
+ * The same key that was used to generate the 'form_token'.
+ * @param $error_message
+ * An optional error message to display if the form does not validate.
+ * @result
+ * There is nothing returned from this function, but if the 'form_token' does
+ * not validate an error is generated, preventing the submission.
+ */
+function form_validate($edit, $key, $error_message = NULL) {
+ if ($error_message == NULL) {
+ // set a generic default error message
+ $error = t('Validation error, please try again. If this error persists, please contact the site administrator.');
+ }
+
+ if ($edit['form_token'] != md5(session_id() . $key . variable_get('drupal_private_key', ''))) {
+ // setting this error will cause the form to fail validation
+ form_set_error('form_token', $error);
+ }
+}
+
+/**
* File an error against the form element with the specified name.
*/
function form_set_error($name, $message) {
--- modules/comment.module.orig 2006-03-13 17:14:49.000000000 -0500
+++ modules/comment.module 2006-03-17 14:52:45.000000000 -0500
@@ -481,6 +481,8 @@
}
}
}
+ // verify that this submission was actually generated using a local form
+ form_validate($edit, 'comment'. $edit['nid'] . $edit['pid']);
return $edit;
}
@@ -1415,6 +1417,8 @@
$form .= form_hidden('cid', $edit['cid']);
$form .= form_hidden('pid', $edit['pid']);
$form .= form_hidden('nid', $edit['nid']);
+ // generate a token used to validate that submissions came from this form
+ $form .= form_token('comment'. $edit['nid'] . $edit['pid']);
$form .= form_submit(t('Preview comment'));
More information about the support
mailing list