Difference between revisions of "Security"

Jump to: navigation, search
(Security of web applications)
(Balanced security)
Line 32: Line 32:
When designing web applications we have to find out what our users are supposed to be doing and then find some reasonable balance between features and security.
When designing web applications we have to find out what our users are supposed to be doing and then find some reasonable balance between features and security.
==Moodle security design==
==Common types of security vulnerability==
==Common types of security vulnerability==

Revision as of 16:30, 29 November 2009

This page describes how to write secure Moodle code that is not vulnerable to anything that evil people my try to throw at it.

The page is organised around the common types of security vulnerability. For each one, it explains

  1. what the danger is,
  2. how Moodle is designed to avoid the problem,
  3. what you need to do as a Moodle developer to keep your code secure, and
  4. what you can do as an administrator, to make your Moodle more secure.

The explanation of each vulnerability is on a separate page, linked to in the list below.

This page also summarises all the key guidelines.

Security of web applications

Secure web app requirements

Some companies require maximum level of security for web applications. You can often see similar general recommendations:

  • separate administration backend
  • no sensitive information stored in web application
  • communication has to be encrypted using SSL
  • log all user actions
  • server applications have to be completely separated
  • no files uploaded by users on server
  • no rich text entered by users on server (limited plain text only)
  • validate user identity and actions via separate channel
  • always keep every software up-to-date
  • no 3rd party browser extensions recommended
  • use only one web page, do not open multiple windows with different sites, close/open browser before and after using the secure app

Web based banking systems are the best examples of these secure web applications. Security is the top most priority here, security incidents may cost money - either the customer, bank or insurance company, public image of the institution may be damaged too. Limiting factors may be cost of application development, maintenance, usability but also the cost of communication via the alternative channels.

Balanced security

As you can see many web applications today violate the secure app design rules. For example web based mail system have to accept rich text messages with file attachments, mail massages often contain very sensitive information. In fact the Web 2.0 idea goes directly agains the security design rules, everybody is submitting content - only app designer/administrator should be adding trusted content.

When designing web applications we have to find out what our users are supposed to be doing and then find some reasonable balance between features and security.

Moodle security design

Common types of security vulnerability

Summary of the guidelines

Authenticate the user

  • With very few exceptions, every script should call require_login or require_course_login as near the start as possible.

Check permissions

  • Before allowing the user to see anything or do anything, call to has_capability or require_capability.
  • Capabilities should be annotated with the appropriate risks.
  • If appropriate, restrict what people can see according to groups.

Don't trust any input from users

  • Use moodleforms whenever possible, with an appropriate setType method call for each field.
  • Before performing actions, use is_post_with_sesskey to check sesskey and that you are handling a POST request.
    • In Moodle 1.9, use data_submitted() && confirm_sesskey() instead.
  • Before destroying large amounts of data, add a confirmation step.
  • If not using a moodleform, clean input using optional_param or required_param with an appropriate PARAM_... type.
    • Do not access $_GET, $_POST or $_REQUEST directly.
    • Group optional_param and required_param calls together at the top of the script, to make them easy to find.

Similarly, clean data from other external resources like RSS feeds before use.

Clean and escape data before output

  • Use s or p to output plain text content.
  • use format_string to output content with minimal HTML like multi-lang spans (for example, course and activity names).
  • Use format_text to output all other content.
    • Only use $options->noclean if it requires a capability with RISK_XSS to input that content (for example web page resources).
  • Before Moodle 2.0, input from optional_param or required_param must have stripslashes or stripslashes_recursive applied if it is being output directly, rather than being stored in the database.
  • Data destined for JavaScript should be escaped using $PAGE->requires->data_for_js (Moodle 2.0) or addslashes_js (Moodle 1.9).

See Output functions for more details.

Escape data before storing it in the database

  • Use the XMLDB library. This takes care of most escaping issues for you.
  • When you must use custom SQL code, use place-holders to insert values into the queries.
    • Before Moodle 2.0, you have to build SQL by concatenating strings. Take particular care, especially with quoting values, to avoid SQL injection vulnerabilities.
  • Before Moodle 2.0, data loaded from the database must have addslashes or addslashes_object applied to it before it can be written back to the database. (addslashes should no longer be use anywhere in Moodle 2.0 code.)

Escape data before using it in shell commands

  • Avoid shell commands if at all possible.
    • Look to see if there is a PHP library instead.
  • If you can't avoid shell commands, use escapeshellcmd and escapeshellarg.

Log every request

  • Every script should call add_to_log.

Other good practice

... that helps with security.

  • Structure your code nicely, minimising the use of global variables. This makes the flow of data, and hence security, easier to verify.
  • Initialise objects ($x = new stdClass;) and arrays ($x = array()) before you first use them.
  • Test every input field with tricky input to ensure that it is escaped and un-escaped the right number of times everywhere, and that Unicode characters are not corrupted. My standard test input is:
< > & &lt; &gt; &amp; ' \' 碁 \ \\

See also