WorkingWiki/Security

From projects

Jump to: navigation, search

WorkingWiki's power comes with some serious security risks, most of them in the denial of service or code injection categories. Allowing web site visitors to submit software to run on your server is inherently risky.

There are several categories of security concerns, all of them manageable in principle, and most, though not all, of them manageable here and now:

  • Access to private parts of the server and to the internet.
    • Control access using a mandatory access system and disk quota, and protect against SQL injection.
  • Excessive server load
    • Use setrlimit, nice, ionice, and time limits to keep programs within bounds.
  • HTML injection in the output
    • Sanitize all HTML before passing it on to clients.

All these measures are either built in to WorkingWiki or straightforward to implement, with the possible exception of the last. An HTML sanitizing step is on our wish list, and proposals or patches are welcome. See below for more detail on all these measures.

Even while its security is not (yet?) tightened sufficiently for a publicly edited wiki, WorkingWiki is certainly useful for closed wikis where all users are trusted, a situation in which, as long as the rest of MediaWiki is secure, it's no more risky than giving shell access to the same users. All the wikis we are currently running at McMaster are editable only by trusted users. They are all closed except for theobio/projects and a few others, which are publicly readable but can only be edited by trusted users who have passwords to log in to the wiki. That precaution is enough to make WorkingWiki a real option for collaborative research and publication, and it seems reasonable to expect that the code can ultimately be secured enough to make WorkingWiki a safe, powerful tool for public, crowd-driven research and programming.

Contents

Security measures

Here are some scenarios for security concerns in WorkingWiki, and countermeasures that can be taken. Some of these measures are in place and some are planned. On lalashan, we mainly protect ourselves by allowing only trusted users to be wiki editors.

  • User could write programs that print out or alter sensitive files on the server
    • This risk can be managed by using a Mandatory Access Control system such as TOMOYO Linux or AppArmor, to allow the programs invoked by WW to write only in the WW working directories (and in /tmp, most likely), and read only the files they absolutely need to read.
  • User programs could fill up the disk partition
    • This can be prevented by using a quota system to restrict how much disk space WorkingWiki's processes can fill. Currently all project processes are run as the web server's user id (typically 'apache' or 'www-data'). A separate user id could be created, or even a separate one for each wiki.
    • As long as we're only using closed wikis we haven't actually put a disk quota in place on lalashan, but it would be very easy to do.
  • Program execution could take up too many CPU cycles
    • Currently each make process is timed, and killed if it is still running after 3 minutes (this time limit is defined in WorkingWiki.php). Maybe finer-grained control is possible as well. (Background jobs are exempted from the time limit, though.)
    • We also use nice and ionice to make the WW jobs play well with others.
  • Accessing the network
    • It's no good to allow anonymous users to create projects that access the internet — they could use the wiki to send spam emails or make hostile attacks on third-party websites. This can be prohibited by using mandatory access control (see above).
  • Harmful output
    • The default rules for latex documents produce HTML files that are inserted into the wiki web page verbatim. A tricky or careless user could write make rules — or conceivably even particular latex documents — that produce HTML output that does bad things when it arrives at the user's web browser, like allowing a malicious party to log in using a wiki user's identity.
    • MediaWiki's file uploading feature includes functions that check uploaded files for dangerous content before allowing them onto the wiki. I have code to do that on project files as well (including source files), before allowing them to be displayed. Makefiles are allowed to create any files in the working directory (how could I stop them?) but files that don't pass the verification won't be allowed to go out to the browser.
      • This includes checking SVG and other files for embedded script content.
    • htmLawed might be another option for this validation step.
  • Excessively long output.
    • WW doesn't display oversize files in the wiki output. Instead it provides a link allowing the file to be downloaded.
  • Subversive input
    • Careful escaping of user input is crucial!
    • Filenames and project names need to be properly escaped when outputting to the web browser, when writing to the disk, and when constructing shell commands. File content must be escaped when outputting to the browser (except HTML and SVG - see above).
    • Overly long project names and filenames should be trapped.
    • WW doesn't create any SQL code directly. It accesses the database using MediaWiki's high-level class interface, which can be trusted to sanitize input strings.
    • Make sure all GET and POST data is checked before using.
    • AJAX is a special case of GET/POST... AJAX inputs must also be validated, if/when we start using AJAX.
    • Project descriptions might contain bad data. They are validated by the XML parsing step, but filenames, page names, project names must be mistrusted as user-supplied data.
    • See above and below regarding validation of project files' content before displaying.
    • Any other places input can arrive?

Project file validation

WorkingWiki now includes (as an optional feature, disabled by default) a modified version of the verify() function that MediaWiki uses to validate uploaded files before allowing them onto the wiki, to validate source and target files before allowing them to be displayed.

MediaWiki's verify() function

  • looks inside the file to see what kind of content it contains, summarizing that result as a mime type
  • checks the deduced mime type against the file's extension, and rejects the file if the two don't match
  • checks the deduced mime type against the list in the global variable $wgMimeTypeBlacklist, and rejects the file if there's a match
  • runs a special check to see if Internet Explorer is likely to interpret the file as HTML and rejects the file if so
  • checks the file content for embedded scripts or other HTML-like content, and rejects it if any is found
  • checks the file for viruses, and rejects it if any are found.

Uploaded files are also checked for prohibited file extensions, before the verify() function is reached, using the global variables $wgFileExtensions, $wgFileBlacklist, and $wgStrictFileExtensions.

The WorkingWiki version also checks source and target files for prohibited file extensions, using the global variables $wwFileExtensionsForDisplay, $wwFileBlacklistForDisplay, and $wwStrictFileExtensionsForDisplay.

Its version of verify() does the same steps as the original, except that

  • HTML files are treated specially, since they are allowed to contain HTML code, though not script content.

Since we deal with a number of file types that MediaWiki does not generally contend with as uploads, we have to make a handful of changes to the mime-type data. I have added two entries to the include/mime.info file in the MediaWiki code and one to include/MimeMagic.php, to allow it to recognize XHTML, SVG, and XML files correctly. The rest of the changes are in include/mime.types, adding two file extensions for the text/html type and a list of them for the text/plain type. More extensions will probably need to be added to the text/plain type.

  • To do: make these modifications public. If you want them in the meantime, please contact me.

WW and Read-only wikis

A wiki can be made read-only for anonymous visitors, for instance by setting

$wgGroupPermissions['*']['read'] = true;
$wgGroupPermissions['*']['edit'] = false;
$wgGroupPermissions['*']['createpage'] = false;
$wgGroupPermissions['*']['createaccount'] = false;
$wgGroupPermissions['*']['move'] = false;
$wgGroupPermissions['*']['writeapi'] = false;
$wgGroupPermissions['*']['upload'] = false;
$wgGroupPermissions['*']['reupload'] = false;
$wgGroupPermissions['*']['reupload-shared'] = false;
$wgGroupPermissions['*']['minoredit'] = false;

in the LocalSettings.php file. When that is done, viewers who are not logged in to the wiki can read pages but can not edit them or do the other indicated actions.

The WW interface needs to respect these settings and their intentions by making sure that the features it adds to the wiki don't allow users to make changes to project data or other parts of the wiki when they are supposed to prevented from editing.

As long as this restriction is consistently implemented, there should be no reason not to make a WorkingWiki-enabled wiki available read-only to the public, because visitors will not be able to create harmful projects, only to look at the content.

WorkingWiki currently includes a range of measures to prevent users from modifying the wiki when they are not supposed to. We have the option of inventing new kinds of access, giving fine-grain control over which users are allowed to do operations that modify the contents of WW working directories or whatever, but I've chosen to lump all modifications of WW data into the 'edit' category. When a user is not allowed to edit pages, the following restrictions are applied:

  • The Special:ManageProject page doesn't offer the 'sync', 'remove', 'rm/make', 'upload missing source files', 'set' (set source files' page locations), 'make', 'clear working directory', 'sync all source files', and 'import files' actions.
  • Working directory listings (provided by Special:GetProjectFile) don't offer the 'sync', 'make', 'rm/make', 'remove', 'clear working directory', and 'sync all source files' actions.
  • The 'Import project' link does not appear in the sidebar.
  • Red links to not-yet-created projects do not appear in the sidebar.
  • The 'sync', 'remove', 'rm/make', 'set', 'clear working directory', and 'sync all source files' actions are blocked if they are invoked despite the lack of interface for invoking them (they are called by a 'ww-action' argument in an HTTP GET request, which could be constructed by a creative wiki visitor, or sent by a form that was loaded at an earlier time, for instance if the browser was logged in and then logged out).
  • The Special:ImportProjectFiles and Special:ImportProject pages refuse to upload files.
  • Uploading files via Special:Upload and editing wiki pages are disallowed by MediaWiki, which makes it impossible for users without edit permission to change the contents of WW source files.

Other features, such as viewing project files and browsing the project description and working directory, are allowed to read-only users:

  • The 'export' action is allowed.
  • Make operations that occur when wiki pages are viewed, to create target files in order to display them, are not blocked, because people who can't change source files shouldn't be able to do harm by running make on the existing ones, and make shouldn't do anything when it's run again after it's already done its work.
  • The make=yes option to Special:GetProjectFile is also allowed, since it is presumed harmless and is used internally by a number of WW features. (The 'make' buttons would also be safe by the same token, but would be pointless, so they are removed.)

some things to do

  • A "more secure" option in which only trusted users are allowed to modify makefiles, certain other source code?
  • Add easy support for restricted installations of WW: latex-only, for instance, or allowing source files but not custom makefiles. An easy way to do this might be just to not allow the other programs in the AppArmor or Tomoyo configuration.
Personal tools
Projects
Go: