Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Hardening new Roles system

From MoodleDocs

New roles add great freedom when assigning rights to students. The problem might arise when students are assigned permission that allows adding of content that is not cleaned before display - such as editting Resources, adding activities, etc. They could then use any type of XSS attack to gain full administrative access without any restrictions.

Proposed solution (updated with feedback and ideas from the rest)

Risk bitmap in capabilities

Add risk bitmap field to each capability. Each bit indicates presence of different risk associated with given capability.

Basic risks

  • access to private personal information - ex: backups with user details, non public information in profile (hidden email), etc.
  • missing XSS protection - entering of uncleaned content such as HTML with javascript or unprotected uploaded files
  • dangerous global configuration changes - various settings that might render whole site unoperable, changing trust bitmaps
  • some more if needed (can be added later)

Implementation

  • add new LONGINT column riskbitmap to table capabilities
  • define risks and assign them to capabilities in mod/xxx/db/access.php
  • link wiki pages with explanation to each risk from capabilities page
  • allow risk based filtering of capabilities admin/roles/manage.php (optional)

The user interface would be minimal, icons and maybe colors indicating each risk together with description links which we need anyway. Developers would be deciding about the risks, the risk assignment would be hardcoded in access description file, no GUI needed.

Benefits

  1. proper documentation of risks associated with capabilities, easy to explain
  2. solid foundation for regular code audits (mainly XSS prevention and personal information disclosure)


User trust bitmap

Indicate what kind of trust each user has. Match the risk bitmap of capability and user trust bitmap in both has_capability() and require_capability()

Implementation

  • add new LONGINT column trustbitmap to user table
  • add capability moodle/site:managetrustbitmaps with dangerous global configuration risk
  • add trust checks to has_capability() and require_capability()
  • add GUI
    • preset trust bitmap for new users
    • changing of trust bitmaps
    • add field to user/edit.php
    • request trust level change form - something like new course request (optional)
  • fix upgrade to assign trust bitmaps based on original teacher or administrator rights
  • patch user import script and synchronizations (optional)

Benefits

  1. This part is optional and can be implemented later.
  2. Trust manager or admin has full control over potentially dangerous capabilities - it is necessary for large sites (or connected sites in the future).
  3. Trust bitmap mechanism can be turned off by single configuration switch (both GUI and checks) - needed for small insecure workshop sites.
  4. General protection against future bugs in role and capability management code.


moodle/site:trusttext capability

see Proposed solution 2 bellow...

I am thinking about two questions:

  • Where would be trusttext used?
  • How to implement it securely and with minimal changes to Moodle core and current coding practices?

Where would be trusttext used?

There are two different possibilities:

  1. remove XSS risk from some capabilities so that we can assign them to all participants
  2. allowing trusted users to bypass text cleaning in some modules
Removing XSS risk from some capabilities

Unfortunately there is no list of XSS risky capabilities yet. I did not find any module capability that would not be suitable for all participants. Only some course capabilities are possible candidates then. Some of the capabilities are safe to assign to anybody now; some of them are not XSS safe yet and must be fixed first. In any case all course capabilities must be first reviewed before removing XSS or privacy risk flags.

Martin wanted to let all users to create and edit activities and resources. Would trusttext make it secure? I am afraid not, because it is not only about javascript in HTML text but also about uploaded files. Most of the creative work on web involves both files and HTML - could you imagine web page resource without images? If users can not upload new files their course building experience would be severely limited.

Result: I did not find any capability with XSS risk that could be improved by trusttext. Can you find any example?

Allowing trusted users to bypass text cleaning in some modules

Which modules are candidates?

  • Forum - posts
  • Glossary - entries
  • Chat - messages

Special modules

  • Database - this module is specific because content is constructed from the template and participants submissions, the cleaning is done on the final product. The problem here is that if we want to remove the cleaning and enable javascript in templates, we must be sure that the template editor understands web security and its problems properly. I would recommend different capability than trusttext for this module with much higher risk.

Do you know any other module that could use the cleaning bypassing?

Trusttext implementation options

Martin proposed to store the cleaning bypass flag directly in the text and patch Moodle core. It seems there are not so many places where trusttext can be used, that is why I would be more inclined to add new column to forum_post, glossary_entries and chat_messages to indicate cleaning bypass and keep the rest of Moodle as is. Changes would be only needed in few modules. It might be better to call the capability "moodle/site:cleaningbypass" and add XSS risk to it.

Cleaning bypass login description

  • add cleaningbypass column to forum_posts with default 0 (no need to check existing data)
  • add cleaning bypass checkbox to forum post form
  • if user does not have capability, disable/hide the checkbox
  • check capability again after submitting
  • if user edits his/her post, do not change the bypass flag
  • if user edits somebody else's post, clean&edit or edit without cleaning
  • do extra checks that the author still has the cleaning bypass capability before each formatting of post (optional)
  • do not request cleaning in format_text() if needed when printing forum posts
  • do the same for other modules

Solution 1 now exactly what I would like to see.Tim Hunt 04:40, 24 August 2006 (CDT)

There are actually MANY places where it would be good to allow trusted users to enter text that would suffer from normal cleaning. Quiz questions, labels, course descriptions, database comments, HTML block, Activity descriptions, assignments, blogs, etc etc. I don't think it's practical to consider adding a new column for all these things (with all the backup/restore/exchange implications), especially when a much easier solution is described below and will tackle the immediate problem (XSS). I do agree the risk system is a good idea to implement as well, to help guide and educate users about the capabilities they are changing. Martin Dougiamas 02:46, 25 August 2006 (CDT)

Actually, quiz question text (and feedback, and other text input by the teacher) is not cleaned at the moment.--Tim Hunt 04:11, 25 August 2006 (CDT)

Proposed solution 2 (independent of above)

  1. Have one new capability called "moodle/site:trusttext".
  2. Certain roles who you trust to edit text and allow to have Javascript, EMBED etc can have permission for this capability set to "allow" (these people are generally teachers).
  3. When saving a text from a user, modules can call a function on the text and insert a special tag (eg ####TRUST#####) if the current user is trusted (and actively REMOVE all such tags if the user is NOT trusted).
  4. When displaying the text with format_text(), a new parameter needs to be passed to enable the trust system ($options->usetrust = true).
  5. If $options->usetrust is present, each text is checked for ####TRUST#### in the text and output is cleaned appropriately, depending on whether the tag was found. If this new parameter is not present (eg in old modules or 3rd party modules) then all such tags are removed and the text is always fully cleaned.
  6. For caching, the text is stored in the final form as it is now.

Example

Storing the text

Here is the original text from the user:

  Elephant says <script>alert('hello')</script>

Here it's converted before storage:

  $text = apply_trust_to_text($text);

For a trusted user, this will return this text for storage:

  ####TRUST####Elephant says <script>alert('hello')</script>

For an untrusted user, this will return:

  Elephant says <script>alert('hello')</script>

Showing the text

If the tag is found AND the code is trust-enabled then cleaning is NOT done, and only that special tag is removed before output.

 Elephant says <script>alert('hello')</script>

If not found then cleaning is done fully (as it is now in Moodle):

 Elephant says