devel:security
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
devel:security [2009-06-25 08:53] – old revision restored 195.35.72.54 | devel:security [2021-12-01 22:02] (current) – andi | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Security Guidelines for Plugin Authors ====== | ====== Security Guidelines for Plugin Authors ====== | ||
- | Creating [[: | + | Creating [[: |
- | FIXME this page is in a very raw state and should be extended with more indepth info, links and examples. | + | :!: Improvement of this page is always welcome. It' |
+ | |||
+ | ===Summary=== | ||
+ | |||
+ | A list of the most common security issues and how to avoid them can be found on this page. A short summary: | ||
+ | * Cross Site Scripting (XSS) -- inserts malicious code into website to manipulate site in browser of user | ||
+ | * Cross Site Request Forgery (CSRF) -- tricks to let you self do unknowingly harmful actions on your site | ||
+ | * Remote Code Inclusion -- includes code on server that's executed there | ||
+ | * Information leaks -- there is too much information shown | ||
+ | * SQL injection -- one can do unwanted requests on your data | ||
+ | |||
+ | Also there is added a note about [[# | ||
- | A list of the most common security issues and how to avoid them can be found below. | ||
===== Cross Site Scripting (XSS) ===== | ===== Cross Site Scripting (XSS) ===== | ||
Line 15: | Line 25: | ||
DokuWiki' | DokuWiki' | ||
+ | ===Escaping output=== | ||
At an absolute minimum the plugin should ensure any raw data output has all HTML special characters converted to HTML entities using the [[phpfn> | At an absolute minimum the plugin should ensure any raw data output has all HTML special characters converted to HTML entities using the [[phpfn> | ||
Also any wiki data extracted and used internally (eg. user names) should be treated with suspicion. | Also any wiki data extracted and used internally (eg. user names) should be treated with suspicion. | ||
+ | |||
+ | ===Input checking=== | ||
+ | Check always all your input. Use whitelists, filters, conversions to the exact data type you mean e.g. from a number inputted as mixed php value to integer and more to ensure you have __only__ data you allowed. | ||
+ | |||
+ | Please also refer to our chapter on processing [[request vars]] like '' | ||
- | **See also:** | + | ==See also:== |
* [[wp> | * [[wp> | ||
Line 49: | Line 65: | ||
function render($mode, | function render($mode, | ||
if($mode != ' | if($mode != ' | ||
- | $R->doc .= '< | + | $R->doc .= '< |
} | } | ||
} | } | ||
Line 72: | Line 88: | ||
function render($mode, | function render($mode, | ||
if($mode != ' | if($mode != ' | ||
- | $R->doc .= '< | + | $R->doc .= '< |
} | } | ||
} | } | ||
Line 84: | Line 100: | ||
<code php> | <code php> | ||
- | < | + | < |
- | <input type=" | + | <input type=" |
- | <input type=" | + | <input type=" |
</ | </ | ||
</ | </ | ||
Line 92: | Line 108: | ||
Providing '' | Providing '' | ||
- | To fix the form use the [[phpfn> | + | To fix the form use the [[phpfn> |
<code php> | <code php> | ||
- | < | + | < |
- | <input type=" | + | <input type=" |
- | <input type=" | + | <input type=" |
</ | </ | ||
</ | </ | ||
+ | |||
+ | In general it is recommended to not hand-craft forms, but use DokuWiki' | ||
=== Classes and other Attributes === | === Classes and other Attributes === | ||
Line 111: | Line 129: | ||
</ | </ | ||
- | In the render method there might be code like this: | + | In the render method |
<code php> | <code php> | ||
- | $renderer-> | + | $renderer-> |
+ | .htmlspecialchars($message) | ||
+ | .'</ | ||
+ | |||
</ | </ | ||
- | 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: | + | 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 |
<code php> | <code php> | ||
- | $allowed = array(' | + | $allowed = array(' |
- | if(!in_array($class, | + | if(!in_array($class, |
$class = ' | $class = ' | ||
} | } | ||
- | $renderer-> | + | $renderer-> |
+ | .htmlspecialchars($message) | ||
+ | .'</ | ||
</ | </ | ||
- | === URLs === | + | ===input URLs === |
When a plugin accepts URLs as input you need to make sure, users can not pass the '' | When a plugin accepts URLs as input you need to make sure, users can not pass the '' | ||
Line 134: | Line 157: | ||
<code php> | <code php> | ||
- | if(!preg_match('/ | + | // empty URL on protocol mismatch |
+ | if(!preg_match('/ | ||
</ | </ | ||
+ | |||
+ | ===== Cross Site Request Forgery (CSRF) ===== | ||
+ | |||
+ | This vulnerability often appears into plugins due to the lack of understanding of this issue, often confused with the XSS. | ||
+ | |||
+ | Cross Site Request Forgery refers to an attack where the victim' | ||
+ | |||
+ | ===Adding security token=== | ||
+ | |||
+ | DokuWiki offers functions to help you deal against CSRF attacks. [[xref> | ||
+ | |||
+ | |||
+ | It is your resposibility as the plugin author to actually check the token before executing authorized actions using the [[xref> | ||
+ | |||
+ | ==See also== | ||
+ | |||
+ | * [[wp> | ||
+ | * [[https:// | ||
+ | |||
+ | ==== Typical Vulnerability Example ==== | ||
+ | |||
+ | Below is the simplest example to start. You may have a more complicated plugin of your own to secure, here is just a simple example based on form. | ||
+ | |||
+ | Imagine you want to know something which can be answered to Yes or No, you would have a form of this type: | ||
+ | |||
+ | <code html> | ||
+ | <form action="" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | Then you process this form as follows: | ||
+ | |||
+ | <code php> | ||
+ | if(isset($_GET[' | ||
+ | do_something_with_yn($_GET[' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | So a user is connected to answer this question, but he doesn' | ||
+ | Now the user is visiting a malicious website, one which know, or not, that the user may be connected to your DokuWiki. In this website, the developer included this HTML image tag: | ||
+ | |||
+ | <code html> | ||
+ | <img src=" | ||
+ | </ | ||
+ | |||
+ | What will the user's browser do then? | ||
+ | |||
+ | The browser will process this image as any other and will send a request to this URL. Your plugin will then see that $_GET[' | ||
+ | |||
+ | That's one of the examples of CSRF. Now, how to fix this security hole? | ||
+ | |||
+ | ==== Prevent CSRF ==== | ||
+ | |||
+ | Remember your form above? Let's add an input in it: | ||
+ | |||
+ | <code html> | ||
+ | <form action="" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | <input type=" | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | Do you see the first input? Yes? Good. Now you have to check the security token when you receive the form, before processing it: | ||
+ | |||
+ | <code php> | ||
+ | if(isset($_GET[' | ||
+ | do_something_with_yn($_GET[' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | As the malicious website will never find the value of the " | ||
+ | |||
+ | **Note:** If the security token is not valid, the checkSecurityToken() function displays a message which informs the user. | ||
+ | |||
+ | |||
===== Remote Code Inclusion ===== | ===== Remote Code Inclusion ===== | ||
Line 162: | Line 266: | ||
===== Reporting Security Issues ===== | ===== Reporting Security Issues ===== | ||
- | If you encounter an issue with a plugin please inform the author of the plugin via email. | + | If you encounter an issue with a plugin please inform the author of the plugin via email, optionally putting [[andi@splitbrain.org|Andi]] or the [[: |
- | Additionally a '' | + | Additionally a '' |
Once the issue was fixed and a new release was made, this field should be removed again. | Once the issue was fixed and a new release was made, this field should be removed again. | ||
- |
devel/security.1245912814.txt.gz · Last modified: 2009-06-25 08:53 by 195.35.72.54