Loading...
 
Skip to main content

Secure Coding Practice Guidelines

General Coding Guidelines

The main security risks Tiki developers must avoid are:

Avoid using $_REQUEST

Only when both $_GET and $_POST variables are expected should $_REQUEST be used. Post variables are not accessible to a number of attacks, so if there is no reason to accept $_GET, don't.

Adding data manipulations (preventing CSRF)

under what conditions a check needs to be made. Basic implementation of ticket and referrer check.

Displaying data (preventing XSS)

The primary defense against XSS is to ensure data from users is always output properly quoted and escaped.

Data output by Smarty templates can be escaped using the Smarty escape modifier. Tiki's escape modifier is based on Smarty's built-in escape modifier. This modifier takes an optional argument to define the context where the data occurs.

More rarely, data is formatted in PHP code. In this case, PHP's htmlspecialchars() built-in function can be used. It is also possible to use the Smarty escape modifier by calling smarty_modifier_escape(); for example:

Copy to clipboard
$javaScriptEscapedTitle = smarty_modifier_escape($title, 'javascript');

XSS Filtering

Every file that can run directly (most notably the files that begin with tiki-) needs to have a $inputConfiguration declaration before tiki-setup.php is called. Each $_POST and $_GET variable should be filtered here to prevent XSS attacks. It's a tiki policy to filter every variable even if the code does not permit an XSS attack for two reasons:

  • Code modification in the future may open security issues.
  • It allows auditing of variables in the future, to double check the page is XSS-proof.


Note that 'staticKeyFilters' will not work with array content, they must be placed in 'staticKeyFiltersForArrays'.

It is highly encouraged that each page also unsets all variables not filtered through $inputConfiguration. This is done by setting 'catchAllUnset' to null. This practice helps us audit pages for XSS protection and prevents accidental omission of variables. If it's not possible to unset the remaining variables, a comment should be left as to the reason why so efforts are not duplicated in securing the page.

A list of available filters and what they do may be seen here: lib/core/TikiFilter.php. In general, the best practice is to choose the filter that imposes the most strict conditions that will work in a given situation. The 'xss' and lastly 'none' filters should only ever be used if no other options are available.
You can read more about filtering in tiki here: Filtering Best Practices

Below is a code example that shows how variables may be filtered on a page that uses the variables: send, priority, from & taffyArray:

Copy to clipboard
$inputConfiguration = [[ 'staticKeyFilters' => [ 'send' => 'word', 'priority' => 'int', 'from' => 'striptags', ], 'staticKeyFiltersForArrays' => [ 'taffyArray' => 'digits', ], 'catchAllUnset' => null ]];

Adding a File

Feature & Permission Checks


Every file that can be run directly (most notably the files that begin with tiki-) should begin with limiting access to that file based on the user's permissions and also features enabled in tiki. If it's a feature that is always on and has no special user privileges to access, then these checks are not needed.

The following code is how tiki-calendar_import.php implements these checks:

Copy to clipboard
$access->check_feature('feature_calendar'); $access->check_permission('tiki_p_admin_calendar');

Direct Access Check


Any file that is not simply a library (a file filled with a single class), and is not intended to be called directly should prevent direct access to the file with the following code:

Copy to clipboard
if (basename($_SERVER['SCRIPT_NAME']) === basename(__FILE__)) { die('This script may only be included.'); }

Command Line Interface (CLI) Checks


Any file that is intended to be run from the command line only should restrict access to CLI only with the following code:

Copy to clipboard
if (isset($_SERVER['REQUEST_METHOD'])) { die('Only available through command-line.'); }

Adding a Directory

Prevent Directory Browsing

It's a convention in tiki to prevent directory browsing. The security gains may be negligible in many instances, but perhaps critical in a few. In any new directory simply drop a blank file titled: index.php into it. This prevents directory browsing under most server conditions.

Whitelisting File Types

If your directory is in the root folder, you will need to add a .htaccess file that whitelists file types that may be directly called by a browser. All subfolders take their rules from the parent folder so therefore do not need a new .htaccess. Below is an example of a .htaccess file that prevents access to all files except images, note that these files may still be read and accessed by PHP, through an include statement or otherwise:

Copy to clipboard
<FilesMatch ".*"> <IfModule mod_authz_core.c> Require all denied </IfModule> <IfModule !mod_authz_core.c> order deny,allow deny from all </IfModule> </FilesMatch> <FilesMatch "\.(jpe?g|png|svg|gif)$"> <IfModule mod_authz_core.c> Require all granted </IfModule> <IfModule !mod_authz_core.c> Allow from all </IfModule> </FilesMatch> # -- Prevent Directory Browsing -- # Options -Indexes

Adding a Third-Party Library

Remove unnecessary files

Some standard directories and files are removed in CleanVendors such as demo, docs and test etc, but other default files, especially PHP and some HTML ones, need to be removed specifically there. The clean function is run after composer update and install so the developer needs to make sure no problematic example files remain in vendors_bundled and add the code to remove any leftovers if necessary.

Whitelisting files accessed by browsers

Sometimes possibly dangerous files need to be included in a library for it to work, so vendor_bundled/.htaccess prevents anything apart from images, JavaScript and CSS to be accessed from the browser. Any exceptions to this should be added to this .htaccess file. This is unusual, however.

Show PHP error messages