Experimental project

This is a sandbox project, which contains experimental code for developer use only.

Summary

Provides cross-site scripting security for site admins. If the site is hacked using XSS, this reduces the risk of anything harmful being done by adding an IP-based captcha to dangerous forms. Furthermore, it tries to detect XSS attempts and notify the admin of it.

Detailed description

Cross-site scripting (XSS) is a real danger when administrating Drupal sites. Any (contrib) module may have a security bug in it, which allows hackers on the website to add a little script that posts forms with malicious input. But also other users with Full HTML permissions may have a bad intention. Especially when hosting several Drupal sites on the same server, this is a potential risk. Some good examples of dangerous forms that are vulnerable of XSS are the block admin page and the View contextual argument page, in which a PHP setting can be set. Potentially, this PHP code can containing anything; from removing all the sites files to sql dumping the complete database and providing it for download to the hacker. Note that disabling the PHP filter alone does not protect you from this danger; it is relatively easy to enable the module via XSS by posting the module page, as I have found out for myself. This module attempts to provide an answer against this risk for website administrators. It does so by adding a little captcha which is unbreakable by cross-site scripts. Although this module provides great protection for XSS for the forms it is applied to, the captcha can be quite annoying in practice so this module, by default, adds it only to forms that are considered 'risky'.

How does this module work?

As said, it adds a captcha field to all the risky forms. This field shows a little image, generated by gdlib, with a piece of text that should be read and typed in by the administrator manually. Because javascript cannot read the contents of this image, it can't set this field automatically. If it does not set the field, or incorrectly, an error occurs, the failed attempt is logged and the user gets a warning of an XSS attempt.

Notice that this is itself isn't enough protection, as the javascript could send the url of the captcha image via ajax to the hacker, and get back the response and fill it in automatically. That's why this little captcha image can only be downloaded from the IP address that requested the form in the first place. I believe that this protection is almost unbreakable, unless the javascript would 'guess' the text correctly. But as their are 7311616 text possibilities this is unlikely to happen.

Which forms are considered risky?

The module only protects those forms that are considered risky. All other forms are not protected against XSS! Whether or not a form is protected depends on the following rules.

  • Forms with some known form ids are ALWAYS considered risky by this module. These are forms that, for example, allow users to input PHP code. Other examples are the user permissions form and the modules form. See the function '_xssecurity_is_known_risky_form_id' in 'xxsecurity.module'.
  • Administrators with the permission 'administer xssecurity settings' may override, per form id (except those mentioned above), whether or not forms must be considered risky. See the settings screen (/admin/config/system/xssecurity): if the form id is not overridden here (not displayed bold in the form) then the rules below apply. To make a safe form risky, go to an instance of that form, and submit it while setting the checkbox setting that will make the form risky as added by this module.
  • Forms with some known form ids are by default considered safe. These include some node search forms and preview forms. When these are cross site scripted, it won't do any harm, so we don't consider them risky (unless they are overriden in the settings screen, as just mentioned). See '_xssecurity_is_known_safe_form_id'.
  • The XSSecurity settings form further provides the option 'xssecurity_protect_all_non_anonymous_forms'. If this is enabled, the form will be considered risky if and only if the anonymous user has NO access to it. The reasoning behind this is that, on some sites, better security against XSS for all admin forms is desired. By enabling this setting, and further specifying whether forms are (not) risky as described previously, the settings can be perfected.
  • If 'xssecurity_protect_all_non_anonymous_forms' is disabled, the form is considered safe.
  • An exception to these rules: when the current POST or GET values contain either '<?php' or '<?=' AND if the anonymous user has NO access to the form (see the xssecurity_protect_all_non_anonymous_forms setting) the form is, again, ALWAYS considered risky whatever the rules above are.
  • Notice that the drupal_alter hook 'xssecurity_form_is_risky' is always called after determining whether or not the form is risky according to the rules above. Using this alter hook, it can be altered, per form, whether or not it is risky.

Sometimes, when having to submit the same form a lot, the captcha can become quite annoying. Therefore an option is provided when the captcha is enabled, to temporarily 'unlock' the form. When enabled, all forms with the same form id are considered safe for the current user for the next hour.

Project information

  • Project categories: Security
  • Created by bvanmeurs on , updated