DokuWiki

It's better when it's simple

Инструменты пользователя

Инструменты сайта


ru:devel:security

Руководство по безопасности для авторов плагинов

Создание плагинов для DokuWiki – очень простое занятие даже для новичков в PHP программировании. Для того, чтобы быть уверенным, что ваш плагин не подорвет безопасность всего wiki , в котором он инсталлирован, вам нужно следовать правилам перечисленным в этой статье.

FIXME эта статья находится в очень сыром состоянии и должна быть расширена более детальной информацией, ссылками и примерами.

Список наиболее общих проблем безопасности и как их избежать перечислен ниже.

Cross Site Scripting (XSS)

This is probably the most common vulnerability to be found in DokuWiki plugins.

Cross Site Scripting refers to an attack where malicious JavaScript code is introduced into a website. This can be used to redirect innocent users to malicious websites or to steal authentication cookies.

DokuWiki's plugin mechanism gives plugin developers a great deal of flexibility. In the case of syntax plugins in particular, the framework gives plugins the ability to work with raw unprocessed output. This means the wiki page data which reaches your plugin has not been processed at all. And there will be no further processing on the output after it leaves your plugin.

At an absolute minimum the plugin should ensure any raw data output has all HTML special characters converted to HTML entities using the htmlspecialchars function. DokuWiki provides a convenient shortcut called hsc() for the function. URLs values should be escaped using rawurlencode.

Also any wiki data extracted and used internally (eg. user names) should be treated with suspicion.

See also:

Typical Vulnerability Examples

Below are some very common problems shown. The examples are very simple to make the general problem clear. Your plugin is probably more complicated, but you need to keep track of the same vulnerabilities.

Syntax Bodies

Many simple syntax plugins will take some user input and format it in custom HTML.

Example: Here is a abridged syntax plugin to wrap a given input in a bold tag.

class syntax_plugin_bold extends DokuWiki_Syntax_Plugin {
    // common plugin functions ommited
 
    function connectTo($mode) {
        $this->Lexer->addSpecialPattern('!!!.*?!!!',$mode,'plugin_bold');
    }
 
    function handle($match, $state, $pos, &$handler){
        return array(substring($match,3,-3));
    }
 
    function render($mode, &$R, $data) {
        if($mode != 'xhtml') return false;
        $R->doc .= '<b>'.$data[0].'</b>';
    }
}

As you can see, the raw input data captured in the lexer pattern is just passed on to the render method, where no escaping at all is done. Malicious users could introduce what ever JavaScript and HTML code they want.

The fix is simple: proper escaping.

class syntax_plugin_bold extends DokuWiki_Syntax_Plugin {
    // common plugin functions ommited
 
    function connectTo($mode) {
        $this->Lexer->addSpecialPattern('!!!.*?!!!',$mode,'plugin_bold');
    }
 
    function handle($match, $state, $pos, &$handler){
        return array(substring($match,3,-3));
    }
 
    function render($mode, &$R, $data) {
        if($mode != 'xhtml') return false;
        $R->doc .= '<b>'.htmlspecialchars($data[0]).'</b>';
    }
}

Forms

When your plugin provides a form it is very common to validate the input and redisplay the form with the received user input when a validation error occurs.

Example: The following shows a form vulenerable to an XSS attack because it does not escape the user provided input correctly:

<form acttion="" method="post">
    <input type="text" name="q" value="<?php echo $_REQUEST['q']?>" />
    <input type="submit" />
</form>

Providing "><script>alert('bang')</script> as user input would exploit the vulnerability.

To fix the form use the htmlspecialchars function:

<form acttion="" method="post">
    <input type="text" name="q" value="<?php echo htmlspecialchars($_REQUEST['q'])?>" />
    <input type="submit" />
</form>

Classes and other Attributes

Often plugins will accept multiple parameters and options that are used to modify the output of the plugin.

Imagine a plugin accepting the following input to display a message box:

<msg warning>Do not believe anything!</msg>

In the render method there might be code like this:

$renderer->doc .= '<div class="msg_'.$class.'">'.htmlspecialchars($message).'</div>';

As you can see the message itself is properly escaped, but the class is not. Instead of escaping it might be more sensible to use a whitelist of allowed classes instead:

$allowed = array('notice','info','warning','error');
if(!in_array($class,$allowed){
    $class = 'notice'; //unknown input, fall back to a sane default
}
$renderer->doc .= '<div class="msg_'.$class.'">'.htmlspecialchars($message).'</div>';

URLs

When a plugin accepts URLs as input you need to make sure, users can not pass the javascript:// pseudo protocol.

Here is an example how a very simple check could look like, to make sure only http and https URLs are used.

if(!preg_match('/^https?:\/\//i',$url)) $url = ''; // empty URL on protocol mismatch

Remote Code Inclusion

This attack allows an attacker to inject (PHP) code into your application. This may occur on including files, or using unsafe operations functions like eval or system.

Always filter any input that will be used to load files or that is passed as an argument to external commands.

Information leaks

This attack may lead to the exposure of files that should usually be protected by DokuWiki's ACL or it might expose files on the server (like /etc/passwd).

Always filter any input that will be used to load files or that is passed as an argument to external commands.

Always use DokuWiki's ACL check functions when accessing page data.

SQL injection

This attack is rarely relevant in DokuWiki because no database is used. However if your plugin accesses a database always escape all values before using them in SQL statements.

More info:

Reporting Security Issues

If you encounter an issue with a plugin please inform the author of the plugin via email.

Additionally a securityissue field with a short description of the problem should be added to the data on the page of the plugin. This will create a red warning box and will delist the plugin from the main plugin list.

Once the issue was fixed and a new release was made, this field should be removed again.

ru/devel/security.txt · Последнее изменение: 2009-10-02 21:03 — 95.72.98.12

Если не указано иное, содержимое этой вики предоставляется на условиях следующей лицензии: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki