Programming Guidelines

Use of structure in page templates

Do not use the structure page template feature with unfiltered input. This can lead to XSS attacks.

Example potentially dangerous page template snippet:

<figcaption tal:content="structure context/image_caption" />

The reason this snippet is dangerous is because image_caption is not filtered input/output.

Manual filtering

If you need to use structure with unfiltered input, you can manually run Plone’s output filtering engine on arbitrary html.

Example:

from plone import api

def get_safe_html(context):
    transforms = api.portal.get_tool('portal_transforms')
    data = transforms.convertTo('text/x-html-safe', context.image_caption, mimetype='text/html',
                                context=context)
    return data.getData()

Persistent traversable object methods

Any persistent objects that can be traversed to (by accessing them via URL), needs to have careful consideration when writing methods.

A legacy artifact of Zope2 is that it automatically published methods with doc strings. If you forgot to specify permissions on a persistent traversable object, and it does writes on the database or discloses information it should not, you could be causing a security issue.

Do not:

class MyContent(DexterityItem):
    def foobar(self):
        """My doc string. This method is public!"""
        self.x = 'foobar'  # mutation

Do this:

class MyContent(DexterityItem):
    def foobar(self):
        # My doc string.
        self.x = 'foobar'  # mutation

Or this:

class MyContent(DexterityItem):
    security = ClassSecurityInfo()
    security.declarePrivate('foobar')
    def foobar(self):
        """My doc string. This method is public!"""
        self.x = 'foobar'  # mutation

Untrusted JavaScript Input

This isn’t a Plone specific guideline, this is for ALL JavaScript people write anywhere.

If you build HTML from user input, make sure to always escape the input.

A common pitfall in jQuery will look like this:

var value = '<script>alert("hi")</script>';
$('body').append($(value));

By default, jQuery is not safe. To do the previous example in jQuery, you could:

var $el = $('<div/>');
var value = '<script>alert("hi")</script>';
$el.text(value);
$('body').append($el);

In underscorejs templates make sure to use:

<%- … %>

Do not(underscorejs):

<%= … %>

Other considerations

Many modern frameworks are safe by default. For example, it is difficult to render untrusted, raw HTML in the ReactJS framework.