Question: **Non-Technical Background info:** I am working for a school and we are building a new website using Django. The teachers that work for the school aren't technologically competent enough to use another MarkUp language such as MarkDown. We eventually decided that we should use a WYSIWYG editor, which poses security flaws. We aren't too worried about the teachers themselves, but more malicious students that might get the teacher's credentials.

**Technical Background info:** We are running using Django 1.3 and have not chosen a specific editor yet. We are leaning towards a javascript one such as TINYMCE, but can be persuaded to use anything that allows security and ease of use. Because the WYSIWYG editor will output HTML to be rendered into the document, we cannot simply escape it.

What is the best way to prevent malicious code while still making it easy for non-technical teachers to write posts?

Answer: 
This is late, but you can try [Bleach](https://github.com/jsocol/bleach), under the hood it uses the html5lib, and you'll also get tag balancing.

Here is a complete snippet:

settings.py

```
BLEACH_VALID_TAGS = ['p', 'b', 'i', 'strike', 'ul', 'li', 'ol', 'br',
                     'span', 'blockquote', 'hr', 'a', 'img']
BLEACH_VALID_ATTRS = {
    'span': ['style', ],
    'p': ['align', ],
    'a': ['href', 'rel'],
    'img': ['src', 'alt', 'style'],
}
BLEACH_VALID_STYLES = ['color', 'cursor', 'float', 'margin']

```

app/forms.py

```
import bleach
from django.conf import settings

class MyModelForm(forms.ModelForm):
    myfield = forms.CharField(widget=MyWYSIWYGEditor)

    class Meta:
        model = MyModel

    def clean_myfield(self):
        myfield = self.cleaned_data.get('myfield', '')
        cleaned_text = bleach.clean(myfield, settings.BLEACH_VALID_TAGS, settings.BLEACH_VALID_ATTRS, settings.BLEACH_VALID_STYLES)
        return cleaned_text #sanitize html

```

You can read the [bleach docs](http://bleach.readthedocs.org/en/latest/clean.html#tag-whitelist), so you can adapt it to your needs.
@SLaks is right that you need to do the sanitization on the server since students who steal a teacher's credentials could use those credentials to POST directly to your server.

[Python HTML sanitizer / scrubber / filter](https://stackoverflow.com/questions/699468/python-html-sanitizer-scrubber-filter) discusses existing HTML sanitizers available for python.

I would suggest starting with an empty white-list, then use the WYSIWYG editor to create a snippet of HTML using each button so that you know the varieties of HTML it produces, and then whitelist only the tags/attributes needed to support the HTML it produces. Hopefully it doesn't use the [CSS `style`](https://stackoverflow.com/questions/3607894/cross-site-scripting-in-css-stylesheets) attribute because those can also be an XSS vector.