You are here: Home / Documentation / How To's / How to prevent link spam in the built-in contact-info form

How to prevent link spam in the built-in contact-info form

by nguyen — published Dec 07, 2014 11:52 AM, last modified Aug 16, 2016 10:50 AM
say no to spam

The default contact-info form that ships with Plone sometimes gets abused by spammers who include URLs in the subject and comments fields.

To prevent this:

  • Go to ZMI/portal_skins/plone_form_scripts/validate_site_feedback
  • Click the Customize button
  • Add if statements that check the three fields for 'http'
  • Press the Save Changes button

If any field contains "http" the form will be redisplayed with the error "No web addresses are allowed".

Here is the final controller validator source based on the shipped form:

from Products.CMFPlone import PloneMessageFactory as _
reg_tool = context.portal_registration

if not sender_from_address:
    state.setError('sender_from_address',
                   _(u'Please submit an email address.'),
                   'sender_from_address_required')
else:
    if reg_tool.isValidEmail(sender_from_address):
        pass
    else:
        state.setError('sender_from_address',
                       _(u'You entered an invalid email address.'),
                       'invalid_email')

if not (subject and subject.strip()):
    state.setError('subject',
                   _(u'Please enter a subject.'),
                   'subject_required')

if not (message and message.strip()):
    state.setError('message', _(u'Please enter a message'), 'message_required')

if 'http' in subject:
    state.setError('subject',
                   _(u'No web addresses are allowed.'),
                   'no_web_addresses_allowed')

if 'http' in sender_from_address:
    state.setError('sender_from_address',
                   _(u'No web addresses are allowed.'),
                   'no_web_addresses_allowed')

if 'http' in message:
    state.setError('message',
                   _(u'No web addresses are allowed.'),
                   'no_web_addresses_allowed')

if state.getErrors():
    context.plone_utils.addPortalMessage(
        _(u'Please correct the indicated errors.'), 'error')
    return state.set(status='failure')
else:
    return state

If you're using the math quiz question to prevent automated spam (see related items link below) the source will look like this:

from Products.CMFPlone import PloneMessageFactory as _
reg_tool = context.portal_registration

if not sender_from_address:
    state.setError('sender_from_address',
                   _(u'Please submit an email address.'),
                   'sender_from_address_required')
else:
    if reg_tool.isValidEmail(sender_from_address):
        pass
    else:
        state.setError('sender_from_address',
                       _(u'You entered an invalid email address.'),
                       'invalid_email')

if not (subject and subject.strip()):
    state.setError('subject',
                   _(u'Please enter a subject.'),
                   'subject_required')

if not (message and message.strip()):
    state.setError('message', _(u'Please enter a message'), 'message_required')

if not (quiz and quiz.strip()):
    state.setError('quiz', _(u'Please answer the question'), 'quiz_required')
else:
    if (quiz.strip().find('5') != 0):
        state.setError('quiz', _(u'Please answer the question correctly - enter a single digit'), 'quiz_required')

if 'http' in subject:
    state.setError('subject',
                   _(u'No web addresses are allowed.'),
                   'no_web_addresses_allowed')

if 'http' in sender_from_address:
    state.setError('sender_from_address',
                   _(u'No web addresses are allowed.'),
                   'no_web_addresses_allowed')

if 'http' in message:
    state.setError('message',
                   _(u'No web addresses are allowed.'),
                   'no_web_addresses_allowed')

if state.getErrors():
    context.plone_utils.addPortalMessage(
        _(u'Please correct the indicated errors.'), 'error')
    return state.set(status='failure')
else:
    return state
 

 

Navigation